Skip to content

.Net: Function calling abstraction #6083

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

SergeyMenshykh
Copy link
Member

@SergeyMenshykh SergeyMenshykh commented May 1, 2024

Motivation and Context

Today, every AI connector in SK that supports function calling has its own implementation of tool call behavior model classes. These classes are used to configure the way connectors advertise and invoke functions. For example, the behavior classes can describe which functions should be advertised to LLM by a connector, whether the functions should be called automatically by the connector, or if the connector caller will invoke them himself manually, etc.

All the tool call behavior classes are the same in terms of describing the desired function call behavior. However, the classes have a mapping functionality to map the function call behavior to the connector-specific model classes, and that's what makes the function calling classes non-reusable between connectors.

Additionally, today, it's not possible to specify function calling behavior declaratively in YAML, MD, and Kernel(config.json) prompts.

Description

This PR introduces a few function choice behavior classes that allow configure function calling behavior in connector agnostic way:

  • FunctionChoiceBehavior - an abstract class that used as a base class for all the choice behaviors described below.
  • AutoFunctionChoiceBehavior - inherits the FunctionChoiceBehavior class and contains configuration to tell LLM to decide itself whether to call kernel or provided function(s) or not.
  • RequiredFunctionChoiceBehavior - inherits the FunctionChoiceBehavior class and contains configuration forcing LLM to call one or more kernel or provided functions.
  • NoneFunctionChoiceBehavior - inherits the FunctionChoiceBehavior class and contains configuration to tell the model not to call functions and only generate a user-facing message.

Callers can specify one of the function choice behaviors using the new property, FunctionChoiceBehavior, which has been added to the PromptExecutionSettings class. Here's an example:

PromptExecutionSettings settings = new PromptExecutionSettings() 
{ 
   FunctionChoiceBehavior = FunctionChoiceBehavior.Auto()
};

var result = await completionService.GetChatMessageContentAsync(chatHistory, settings, kernel);

The function choice behavior can be configured in JSON and YAML prompts as well:

"execution_settings": {
    "service-gpt4": {
       "model_id": "gpt4",
       "temperature": 0.7,
       "function_choice_behavior": {
           "type": "auto",
           "functions": [
              "p1.f1"
           ]
        }
    }
}
execution_settings:
  service-gpt4:
    model_id: gpt-4
    temperature: 1.0
    function_choice_behavior:
      type: auto
      functions:
      - p1.f1

Closes - #5253, #5954

ADR - #6099

Contribution Checklist

SergeyMenshykh and others added 30 commits April 5, 2024 23:02
Co-authored-by: Stephen Toub <stoub@microsoft.com>
Co-authored-by: Stephen Toub <stoub@microsoft.com>
…lling.cs

Co-authored-by: Stephen Toub <stoub@microsoft.com>
…Content.cs

Co-authored-by: Stephen Toub <stoub@microsoft.com>
Co-authored-by: Stephen Toub <stoub@microsoft.com>
…r one of the KernelArguments constructors.
SergeyMenshykh and others added 20 commits June 11, 2024 14:30
…ors/FunctionChoiceBehavior.cs

Co-authored-by: Roger Barreto <19890735+RogerBarreto@users.noreply.github.com>
…ling if no functions provided by funciton choice behavior.
}

// If both behaviors are specified, we can't handle that.
if (executionSettings.FunctionChoiceBehavior is not null && executionSettings.ToolCallBehavior is not null)
Copy link
Member

@stephentoub stephentoub Jun 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reading this again, it's still really confusing to me that both of these things exist. If we're going to delete the existing one as part of OpenAI SDK update work, maybe for now we just mark it editor browsable never and obsolete with a message telling folks to use the new one? Altough that's odd as well if the new surface area is marked experimental. Ugh.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In Python, while still in v1, we're marking the FunctionCallBehavior as deprecated, and logging warnings to use the new FunctionChoiceBehavior. If a customer still configures the FunctionCallBehavior class, we're using a model validator to map the FunctionCallBehavior to FunctionChoiceBehavior. Anytime the old FunctionCallBehavior gets an update, so does FunctionChoiceBehavior. This allows us to only make decisions based off of FunctionChoiceBehavior and makes for easier cleanup when we do remove FunctionCallBehavior.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reading this again, it's still really confusing to me that both of these things exist. If we're going to delete the existing one as part of OpenAI SDK update work, maybe for now we just mark it editor browsable never and obsolete with a message telling folks to use the new one? Altough that's odd as well if the new surface area is marked experimental. Ugh.

We plan to remove the ToolCallBehavior property and the corresponding code that uses it as part of the OpenAI SDK update work. The PR will be retargeted and merged into the feature-connectors-openai branch.

The experimental attributes will be removed, as the new function choice behavior functionality replaces the tool call behavior that was released for a while.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, thanks

SergeyMenshykh and others added 2 commits June 24, 2024 01:35
…choice behavior related functionality that is going to replace existing tool calling functionality
[JsonDerivedType(typeof(AutoFunctionChoiceBehavior), typeDiscriminator: "auto")]
[JsonDerivedType(typeof(RequiredFunctionChoiceBehavior), typeDiscriminator: "required")]
[JsonDerivedType(typeof(NoneFunctionChoiceBehavior), typeDiscriminator: "none")]
public abstract class FunctionChoiceBehavior
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we evaluate how this adapts to requirements for assistant-agent tool-choice?

https://platform.openai.com/docs/api-reference/runs/createRun#runs-createrun-tool_choice

I wonder if there's a way to not bind this base abstraction so tightly to chat-completion only? Maybe there is an even more generic base abstraction? The current form might not adapt so well for assistants.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why would we not / are we not using the same content types for agents?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kernel.core kernel Issues or pull requests impacting the core kernel .NET Issue or Pull requests regarding .NET code
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

7 participants