Поделиться через


Руководство по миграции вызовов функций

Семантический ядро постепенно переходит от текущих возможностей вызова функций, представленных классом, к новым расширенным возможностям, представленным ToolCallBehavior классом FunctionChoiceBehavior . Новая возможность не зависит от службы и не привязана к какой-либо конкретной службе искусственного интеллекта, в отличие от текущей модели. Поэтому он находится в абстракции семантического ядра и будет использоваться всеми соединителями ИИ, работающими с моделями ИИ с поддержкой функций.

Это руководство поможет вам перенести код в новые возможности вызова функции.

Перенос поведения ToolCallBehavior.AutoInvokeKernelFunctions

Поведение ToolCallBehavior.AutoInvokeKernelFunctions эквивалентно FunctionChoiceBehavior.Auto поведению в новой модели.

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

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

Миграция ToolCallBehavior.EnableKernelFunctions

Поведение ToolCallBehavior.EnableKernelFunctions эквивалентно FunctionChoiceBehavior.Auto поведению с отключенным автоматическим вызовом.

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

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

Перенос поведения ToolCallBehavior.EnableFunctions

Поведение ToolCallBehavior.EnableFunctions эквивалентно FunctionChoiceBehavior.Auto поведению, которое настроено со списком функций с отключенным автоматическим вызовом.

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) };

Перенос поведения ToolCallBehavior.RequireFunction

Поведение ToolCallBehavior.RequireFunction эквивалентно FunctionChoiceBehavior.Required поведению, которое настроено со списком функций с отключенным автоматическим вызовом.

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) };

Замена использования классов вызовов функций для конкретного соединителя

Функции вызова функций в семантическом ядре позволяют разработчикам получить доступ к списку функций, выбранных моделью ИИ двумя способами:

  • Использование классов вызовов функций, относящихся к соединителюOpenAIChatMessageContent, таких ChatToolCall или ChatCompletionsFunctionToolCall, доступных через ToolCalls свойство элемента OpenAI в журнале чата.
  • Используя классы вызовов функции, не зависящие от соединителя, например FunctionCallContent, доступные через Items свойство элемента, не зависящем ChatMessageContent от соединителя, в журнале чата.

Оба способа поддерживаются в данный момент текущими и новыми моделями. Однако настоятельно рекомендуется использовать не зависящий от соединителя подход для доступа к вызовам функций, так как он более гибкий и позволяет коду работать с любым соединителем ИИ, поддерживающим новую модель вызова функций. Кроме того, учитывая, что текущая модель будет устарела в ближайшее время, теперь рекомендуется перенести код в новую модель, чтобы избежать критических изменений в будущем.

Таким образом, если вы используете вызов функции вручную с классами вызовов функций для конкретного соединителя, например в этом фрагменте кода:

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();
}

Вы можете рефакторинговать его для использования классов, не зависящих от соединителя:

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();
}

Приведенные выше фрагменты кода демонстрируют перенос кода, использующего соединитель OpenAI AI. Аналогичный процесс миграции можно применить к соединителям Gemini и Mistral AI при обновлении для поддержки новой модели вызова функций.

Следующие шаги

Теперь после переноса кода в новую модель вызовов функций вы можете узнать, как настроить различные аспекты модели, которые могут лучше соответствовать конкретным сценариям, ссылаясь на раздел поведения вызовов функций.

Скоро

Дополнительные сведения в ближайшее время.

Скоро

Дополнительные сведения в ближайшее время.