Sdílet prostřednictvím


Průvodce migrací volání funkcí

Sémantické jádro postupně přechází z aktuálních funkcí volajících schopností, reprezentovaných ToolCallBehavior třídou, na nové vylepšené schopnosti reprezentované FunctionChoiceBehavior třídou. Nová funkce je nezávislá na službách a není svázaná s žádnou konkrétní službou AI, na rozdíl od aktuálního modelu. Proto se nachází v sémantických abstrakcích jádra a budou je používat všechny konektory AI pracující s modely AI podporujícími funkce.

Tento průvodce vám pomůže migrovat kód do nových funkcí volání funkcí.

Migrace ToolCallBehavior.AutoInvokeKernelFunctions chování

Chování ToolCallBehavior.AutoInvokeKernelFunctions je ekvivalentní FunctionChoiceBehavior.Auto chování v novém modelu.

// Before
var executionSettings = new OpenAIPromptExecutionSettings { ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions };

// After
var executionSettings = new OpenAIPromptExecutionSettings { FunctionChoiceBehavior = FunctionChoiceBehavior.Auto() };

Chování Migrate ToolCallBehavior.EnableKernelFunctions

Chování ToolCallBehavior.EnableKernelFunctions je ekvivalentní FunctionChoiceBehavior.Auto chování se zakázaným automatickým vyvoláním.

// Before
var executionSettings = new OpenAIPromptExecutionSettings { ToolCallBehavior = ToolCallBehavior.EnableKernelFunctions };

// After
var executionSettings = new OpenAIPromptExecutionSettings { FunctionChoiceBehavior = FunctionChoiceBehavior.Auto(autoInvoke: false) };

Chování Migrate ToolCallBehavior.EnableFunctions

Toto ToolCallBehavior.EnableFunctions chování odpovídá FunctionChoiceBehavior.Auto chování, které je nakonfigurované se seznamem funkcí se zakázaným automatickým vyvoláním.

var function = kernel.CreateFunctionFromMethod(() => DayOfWeek.Friday, "GetDayOfWeek", "Returns the current day of the week.");

// Before
var executionSettings = new OpenAIPromptExecutionSettings() { ToolCallBehavior = ToolCallBehavior.EnableFunctions(functions: [function.Metadata.ToOpenAIFunction()]) };

// After
var executionSettings = new OpenAIPromptExecutionSettings { FunctionChoiceBehavior = FunctionChoiceBehavior.Auto(functions: [function], autoInvoke: false) };

Chování Migrate ToolCallBehavior.RequireFunction

Toto ToolCallBehavior.RequireFunction chování odpovídá FunctionChoiceBehavior.Required chování, které je nakonfigurované se seznamem funkcí se zakázaným automatickým vyvoláním.

var function = kernel.CreateFunctionFromMethod(() => DayOfWeek.Friday, "GetDayOfWeek", "Returns the current day of the week.");

// Before
var executionSettings = new OpenAIPromptExecutionSettings() { ToolCallBehavior = ToolCallBehavior.RequireFunction(functions: [function.Metadata.ToOpenAIFunction()]) };

// After
var executionSettings = new OpenAIPromptExecutionSettings { FunctionChoiceBehavior = FunctionChoiceBehavior.Required(functions: [function], autoInvoke: false) };

Nahrazení použití tříd volání funkcí specifických pro konektory

Funkce volání funkcí v sémantickém jádru umožňuje vývojářům získat přístup k seznamu funkcí zvolených modelem AI dvěma způsoby:

  • Použití tříd ChatToolCall volání specifického pro konektor nebo ChatCompletionsFunctionToolCall, které jsou k dispozici prostřednictvím ToolCalls vlastnosti položky specifické pro OpenAIChatMessageContent OpenAI v historii chatu.
  • Použití tříd volání nezávislé na konektorech, jako jsou FunctionCallContent, dostupné prostřednictvím Items vlastnosti položky nezávislé ChatMessageContent na konektoru v historii chatu.

Aktuální i nové modely v současné době podporují oba způsoby. Důrazně ale doporučujeme používat přístup k voláním funkcí nezávislý na konektorech, protože je flexibilnější a umožňuje kódu pracovat s libovolným konektorem AI, který podporuje nový model volání funkcí. Vzhledem k tomu, že aktuální model bude brzy zastaralý, je teď vhodný čas migrovat kód do nového modelu, abyste se vyhnuli zásadním změnám v budoucnu.

Pokud tedy použijete ruční vyvolání funkce s třídami volání specifické pro konektor, jako je v tomto fragmentu kódu:

using System.Text.Json;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
using Microsoft.SemanticKernel.Connectors.OpenAI;
using OpenAI.Chat;

var chatHistory = new ChatHistory();

var settings = new OpenAIPromptExecutionSettings() { ToolCallBehavior = ToolCallBehavior.EnableKernelFunctions };

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

// Current way of accessing function calls using connector specific classes.
var toolCalls = ((OpenAIChatMessageContent)result).ToolCalls.OfType<ChatToolCall>().ToList();

while (toolCalls.Count > 0)
{
    // Adding function call from AI model to chat history
    chatHistory.Add(result);

    // Iterating over the requested function calls and invoking them
    foreach (var toolCall in toolCalls)
    {
        string content = kernel.Plugins.TryGetFunctionAndArguments(toolCall, out KernelFunction? function, out KernelArguments? arguments) ?
            JsonSerializer.Serialize((await function.InvokeAsync(kernel, arguments)).GetValue<object>()) :
            "Unable to find function. Please try again!";

        // Adding the result of the function call to the chat history
        chatHistory.Add(new ChatMessageContent(
            AuthorRole.Tool,
            content,
            metadata: new Dictionary<string, object?>(1) { { OpenAIChatMessageContent.ToolIdProperty, toolCall.Id } }));
    }

    // Sending the functions invocation results back to the AI model to get the final response
    result = await chatCompletionService.GetChatMessageContentAsync(chatHistory, settings, kernel);
    toolCalls = ((OpenAIChatMessageContent)result).ToolCalls.OfType<ChatToolCall>().ToList();
}

Refaktoringem můžete použít třídy nezávislé na konektorech:

using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;

var chatHistory = new ChatHistory();

var settings = new PromptExecutionSettings() { FunctionChoiceBehavior = FunctionChoiceBehavior.Auto(autoInvoke: false) };

var messageContent = await chatCompletionService.GetChatMessageContentAsync(chatHistory, settings, kernel);

// New way of accessing function calls using connector agnostic function calling model classes.
var functionCalls = FunctionCallContent.GetFunctionCalls(messageContent).ToArray();

while (functionCalls.Length != 0)
{
    // Adding function call from AI model to chat history
    chatHistory.Add(messageContent);

    // Iterating over the requested function calls and invoking them
    foreach (var functionCall in functionCalls)
    {
        var result = await functionCall.InvokeAsync(kernel);

        chatHistory.Add(result.ToChatMessage());
    }

    // Sending the functions invocation results to the AI model to get the final response
    messageContent = await chatCompletionService.GetChatMessageContentAsync(chatHistory, settings, kernel);
    functionCalls = FunctionCallContent.GetFunctionCalls(messageContent).ToArray();
}

Výše uvedené fragmenty kódu ukazují, jak migrovat kód, který používá konektor OpenAI AI. Podobný proces migrace lze použít u konektorů Gemini a Mistral AI, když se aktualizují tak, aby podporovaly nový model volání funkcí.

Další kroky

Po migraci kódu do nového modelu volání funkcí teď můžete pokračovat a zjistit, jak nakonfigurovat různé aspekty modelu, které můžou lépe odpovídat vašim konkrétním scénářům, a to v části chování volání funkce.

Již brzy

Další informace budou brzy k dispozici.

Již brzy

Další informace budou brzy k dispozici.