Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Когда модель ИИ получает запрос, содержащий список функций, он может выбрать один или несколько из них для вызова, чтобы завершить запрос. Когда модель выбирает функцию, её должен вызывать Semantic Kernel.
Подсистема вызова функции в семантическом ядре имеет два режима вызова функции: авто и вручную.
В зависимости от режима вызова, Semantic Kernel либо выполняет сквозной вызов функции, либо передаёт вызывающей стороне контроль над процессом вызова функции.
Автоматическое вызов функции
Автоматическое вызов функции — это режим по умолчанию подсистемы вызова функции семантического ядра. При выборе одной или нескольких функций модель искусственного интеллекта автоматически вызывает выбранные функции семантического ядра. Результаты этих вызовов функций добавляются в журнал чата и автоматически отправляются в модель в последующих запросах. Затем модель анализирует историю чата, при необходимости выбирает дополнительные функции или формирует окончательный ответ. Этот подход полностью автоматизирован и не требует ручного вмешательства со стороны вызывающей стороны.
Tip
Автоматическое вызов функции отличается от поведения выбора автоматической функции. Прежнее определяет, следует ли автоматически вызывать функции Semantic Kernel, а последний определяет, следует ли автоматически выбирать функции моделью ИИ.
В этом примере показано, как использовать вызов автоматической функции в семантическом ядре. Модель искусственного интеллекта решает, какие функции нужно вызвать, чтобы выполнить запрос, а Semantic Kernel делает всё остальное и вызывает их автоматически.
using Microsoft.SemanticKernel;
IKernelBuilder builder = Kernel.CreateBuilder();
builder.AddOpenAIChatCompletion("<model-id>", "<api-key>");
builder.Plugins.AddFromType<WeatherForecastUtils>();
builder.Plugins.AddFromType<DateTimeUtils>();
Kernel kernel = builder.Build();
// By default, functions are set to be automatically invoked.
// If you want to explicitly enable this behavior, you can do so with the following code:
// PromptExecutionSettings settings = new() { FunctionChoiceBehavior = FunctionChoiceBehavior.Auto(autoInvoke: true) };
PromptExecutionSettings settings = new() { FunctionChoiceBehavior = FunctionChoiceBehavior.Auto() };
await kernel.InvokePromptAsync("Given the current time of day and weather, what is the likely color of the sky in Boston?", new(settings));
from semantic_kernel.connectors.ai.function_choice_behavior import FunctionChoiceBehavior
from semantic_kernel.connectors.ai.open_ai import OpenAIChatCompletion
from semantic_kernel.connectors.ai.prompt_execution_settings import PromptExecutionSettings
from semantic_kernel.functions.kernel_arguments import KernelArguments
from semantic_kernel.kernel import Kernel
kernel = Kernel()
kernel.add_service(OpenAIChatCompletion())
# Assuming that WeatherPlugin and DateTimePlugin are already implemented
kernel.add_plugin(WeatherPlugin(), "WeatherPlugin")
kernel.add_plugin(DateTimePlugin(), "DateTimePlugin")
query = "What is the weather in Seattle today?"
arguments = KernelArguments(
settings=PromptExecutionSettings(
# By default, functions are set to be automatically invoked.
# If you want to explicitly enable this behavior, you can do so with the following code:
# function_choice_behavior=FunctionChoiceBehavior.Auto(auto_invoke=True),
function_choice_behavior=FunctionChoiceBehavior.Auto(),
)
)
response = await kernel.invoke_prompt(query, arguments=arguments)
Tip
В ближайшее время в пакет SDK для Java будут обновлены дополнительные обновления.
Некоторые модели ИИ поддерживают параллельные вызовы функций, где модель выбирает несколько функций для вызова. Это может быть полезно в случаях, когда вызов выбранных функций занимает много времени. Например, ИИ может выбрать получение последних новостей и текущего времени одновременно, а не сделать круговую поездку для каждой функции.
Семантический ядро может вызывать эти функции двумя способами:
- Последовательно: функции вызываются друг за другом. Это поведение принимается по умолчанию.
-
Одновременно: функции вызываются одновременно. Это можно включить, задав свойству
FunctionChoiceBehaviorOptions.AllowConcurrentInvocationзначениеtrue, как показано в примере ниже.
using Microsoft.SemanticKernel;
IKernelBuilder builder = Kernel.CreateBuilder();
builder.AddOpenAIChatCompletion("<model-id>", "<api-key>");
builder.Plugins.AddFromType<NewsUtils>();
builder.Plugins.AddFromType<DateTimeUtils>();
Kernel kernel = builder.Build();
// Enable concurrent invocation of functions to get the latest news and the current time.
FunctionChoiceBehaviorOptions options = new() { AllowConcurrentInvocation = true };
PromptExecutionSettings settings = new() { FunctionChoiceBehavior = FunctionChoiceBehavior.Auto(options: options) };
await kernel.InvokePromptAsync("Good morning! What is the current time and latest news headlines?", new(settings));
Иногда модель может выбирать несколько функций для вызова. Это часто называется параллельным вызовом функций. При выборе нескольких функций в модели искусственного интеллекта Semantic Kernel будет вызывать их одновременно.
Tip
С помощью соединителя OpenAI или Azure OpenAI можно отключить параллельные вызовы функций, выполнив следующие действия:
from semantic_kernel.connectors.ai.open_ai import OpenAIChatPromptExecutionSettings
from semantic_kernel.connectors.ai.function_choice_behavior import FunctionChoiceBehavior
settings = OpenAIChatPromptExecutionSettings(
function_choice_behavior=FunctionChoiceBehavior.Auto(),
parallel_tool_calls=False
)
Вызов функции вручную
В случаях, когда вызывающая сторона хочет лучше контролировать процесс вызова функции, можно использовать ручной вызов функции.
Если вызов функции вручную включен, семантический ядро не вызывает функции, выбранные моделью ИИ. Вместо этого он возвращает список выбранных функций вызывающему объекту, который затем может решить, какие функции вызывать, вызывать их последовательно или параллельно, обрабатывать исключения и т. д. Результаты вызова функции необходимо добавить в историю чата и передать обратно модели, которая проанализирует их и решит, нужно ли вызывать дополнительные функции или сгенерировать окончательный ответ.
В приведенном ниже примере показано, как использовать вызов функции вручную.
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
IKernelBuilder builder = Kernel.CreateBuilder();
builder.AddOpenAIChatCompletion("<model-id>", "<api-key>");
builder.Plugins.AddFromType<WeatherForecastUtils>();
builder.Plugins.AddFromType<DateTimeUtils>();
Kernel kernel = builder.Build();
IChatCompletionService chatCompletionService = kernel.GetRequiredService<IChatCompletionService>();
// Manual function invocation needs to be enabled explicitly by setting autoInvoke to false.
PromptExecutionSettings settings = new() { FunctionChoiceBehavior = Microsoft.SemanticKernel.FunctionChoiceBehavior.Auto(autoInvoke: false) };
ChatHistory chatHistory = [];
chatHistory.AddUserMessage("Given the current time of day and weather, what is the likely color of the sky in Boston?");
while (true)
{
ChatMessageContent result = await chatCompletionService.GetChatMessageContentAsync(chatHistory, settings, kernel);
// Check if the AI model has generated a response.
if (result.Content is not null)
{
Console.Write(result.Content);
// Sample output: "Considering the current weather conditions in Boston with a tornado watch in effect resulting in potential severe thunderstorms,
// the sky color is likely unusual such as green, yellow, or dark gray. Please stay safe and follow instructions from local authorities."
break;
}
// Adding AI model response containing chosen functions to chat history as it's required by the models to preserve the context.
chatHistory.Add(result);
// Check if the AI model has chosen any function for invocation.
IEnumerable<FunctionCallContent> functionCalls = FunctionCallContent.GetFunctionCalls(result);
if (!functionCalls.Any())
{
break;
}
// Sequentially iterating over each chosen function, invoke it, and add the result to the chat history.
foreach (FunctionCallContent functionCall in functionCalls)
{
try
{
// Invoking the function
FunctionResultContent resultContent = await functionCall.InvokeAsync(kernel);
// Adding the function result to the chat history
chatHistory.Add(resultContent.ToChatMessage());
}
catch (Exception ex)
{
// Adding function exception to the chat history.
chatHistory.Add(new FunctionResultContent(functionCall, ex).ToChatMessage());
// or
//chatHistory.Add(new FunctionResultContent(functionCall, "Error details that the AI model can reason about.").ToChatMessage());
}
}
}
Примечание.
Классы FunctionCallContent и FunctionResultContent используются для представления вызовов функций модели ИИ и результатов вызова функции семантического ядра соответственно. Они содержат сведения о выбранной функции, таких как идентификатор функции, имя и аргументы, а также результаты вызова функции, такие как идентификатор вызова функции и результат.
В следующем примере показано, как использовать вызов функции вручную с API завершения потокового чата. Обратите внимание на использование FunctionCallContentBuilder класса для создания вызовов функций из содержимого потоковой передачи.
Из-за характера потоковой передачи API вызовы функций также передаются. Это означает, что вызывающий объект должен создавать вызовы функции из содержимого потоковой передачи перед их вызовом.
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
IKernelBuilder builder = Kernel.CreateBuilder();
builder.AddOpenAIChatCompletion("<model-id>", "<api-key>");
builder.Plugins.AddFromType<WeatherForecastUtils>();
builder.Plugins.AddFromType<DateTimeUtils>();
Kernel kernel = builder.Build();
IChatCompletionService chatCompletionService = kernel.GetRequiredService<IChatCompletionService>();
// Manual function invocation needs to be enabled explicitly by setting autoInvoke to false.
PromptExecutionSettings settings = new() { FunctionChoiceBehavior = Microsoft.SemanticKernel.FunctionChoiceBehavior.Auto(autoInvoke: false) };
ChatHistory chatHistory = [];
chatHistory.AddUserMessage("Given the current time of day and weather, what is the likely color of the sky in Boston?");
while (true)
{
AuthorRole? authorRole = null;
FunctionCallContentBuilder fccBuilder = new ();
// Start or continue streaming chat based on the chat history
await foreach (StreamingChatMessageContent streamingContent in chatCompletionService.GetStreamingChatMessageContentsAsync(chatHistory, settings, kernel))
{
// Check if the AI model has generated a response.
if (streamingContent.Content is not null)
{
Console.Write(streamingContent.Content);
// Sample streamed output: "The color of the sky in Boston is likely to be gray due to the rainy weather."
}
authorRole ??= streamingContent.Role;
// Collect function calls details from the streaming content
fccBuilder.Append(streamingContent);
}
// Build the function calls from the streaming content and quit the chat loop if no function calls are found
IReadOnlyList<FunctionCallContent> functionCalls = fccBuilder.Build();
if (!functionCalls.Any())
{
break;
}
// Creating and adding chat message content to preserve the original function calls in the chat history.
// The function calls are added to the chat message a few lines below.
ChatMessageContent fcContent = new ChatMessageContent(role: authorRole ?? default, content: null);
chatHistory.Add(fcContent);
// Iterating over the requested function calls and invoking them.
// The code can easily be modified to invoke functions concurrently if needed.
foreach (FunctionCallContent functionCall in functionCalls)
{
// Adding the original function call to the chat message content
fcContent.Items.Add(functionCall);
// Invoking the function
FunctionResultContent functionResult = await functionCall.InvokeAsync(kernel);
// Adding the function result to the chat history
chatHistory.Add(functionResult.ToChatMessage());
}
}
from semantic_kernel.connectors.ai.function_choice_behavior import FunctionChoiceBehavior
from semantic_kernel.connectors.ai.open_ai import OpenAIChatCompletion
from semantic_kernel.connectors.ai.prompt_execution_settings import PromptExecutionSettings
from semantic_kernel.contents.chat_history import ChatHistory
from semantic_kernel.contents.function_call_content import FunctionCallContent
from semantic_kernel.contents.function_result_content import FunctionResultContent
from semantic_kernel.kernel import Kernel
kernel = Kernel()
chat_completion_service = OpenAIChatCompletion()
# Assuming that WeatherPlugin is already implemented
kernel.add_plugin(WeatherPlugin(), "WeatherPlugin")
settings = PromptExecutionSettings(
function_choice_behavior=FunctionChoiceBehavior.Auto(auto_invoke=False),
)
chat_history = ChatHistory()
chat_history.add_user_message("What is the weather in Seattle on 10th of September 2024 at 11:29 AM?")
response = await chat_completion_service.get_chat_message_content(chat_history, settings, kernel=kernel)
function_call_content = response.items[0]
assert isinstance(function_call_content, FunctionCallContent)
# Need to add the response to the chat history to preserve the context
chat_history.add_message(response)
function = kernel.get_function(function_call_content.plugin_name, function_call_content.function_name)
function_result = await function(kernel, function_call_content.to_kernel_arguments())
function_result_content = FunctionResultContent.from_function_call_content_and_result(
function_call_content, function_result
)
# Adding the function result to the chat history
chat_history.add_message(function_result_content.to_chat_message_content())
# Invoke the model again with the function result
response = await chat_completion_service.get_chat_message_content(chat_history, settings, kernel=kernel)
print(response)
# The weather in Seattle on September 10th, 2024, is expected to be [weather condition].
Примечание.
Классы FunctionCallContent и FunctionResultContent используются для представления вызовов функций модели ИИ и результатов вызова функции семантического ядра соответственно. Они содержат сведения о выбранной функции, таких как идентификатор функции, имя и аргументы, а также результаты вызова функции, такие как идентификатор вызова функции и результат.
Tip
В ближайшее время в пакет SDK для Java будут обновлены дополнительные обновления.