函数调用模式
当 AI 模型收到包含函数列表的提示时,可以选择其中一个或多个用于调用以完成提示。 模型选择函数时,需要 由语义内核调用 它。
语义内核中的函数调用子系统有两种函数调用模式: 自动 和 手动。
根据调用模式,语义内核要么执行端到端函数调用,要么为调用方提供对函数调用进程的控制。
自动函数调用
自动函数调用是语义内核函数调用子系统的默认模式。 当 AI 模型选择一个或多个函数时,语义内核会自动调用所选函数。 这些函数调用的结果将添加到聊天历史记录,并在后续请求中自动发送到模型。 然后,模型会根据聊天历史记录的原因,根据需要选择其他函数,或生成最终响应。 此方法是完全自动化的,无需调用方进行手动干预。
此示例演示如何在语义内核中使用自动函数调用。 AI 模型决定要调用哪些函数来完成提示,语义内核执行其余操作并自动调用它们。
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));
某些 AI 模型支持并行函数调用,其中模型选择多个函数进行调用。 在调用所选函数需要很长时间时,这非常有用。 例如,AI 可以选择同时检索最新新闻和当前时间,而不是按函数进行往返。
语义内核可以通过两种不同的方式调用这些函数:
- 顺序:函数逐个调用。 这是默认行为。
- 同时:同时调用函数。 可以通过将
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));
手动函数调用
如果调用方希望更好地控制函数调用过程,则可以使用手动函数调用。
启用手动函数调用后,语义内核不会自动调用 AI 模型选择的函数。 相反,它会向调用方返回所选函数的列表,然后可以决定要调用哪些函数、按顺序或并行调用它们、处理异常等。 函数调用结果需要添加到聊天历史记录并返回到模型,这会导致有关这些结果的原因,并确定是选择其他函数还是生成最终响应。
下面的示例演示如何使用手动函数调用。
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 类分别用于表示 AI 模型函数调用和语义内核函数调用结果。 它们包含有关所选函数的信息,例如函数 ID、名称和参数,以及函数调用结果,例如函数调用 ID 和结果。
即将推出
更多信息即将推出。
即将推出
更多信息即将推出。