引言
上一章我們熟悉了 OpenAI 的 function calling 的執行原理,這一章節我們講解一下 function calling 在 Semantic Kernel 的應用。
在OpenAIPromptExecutionSettings跟 LLM 交互過程中,ToolCallBehavior的屬性之前我們的章節有介紹過
-
ToolCallBehavior:屬性用於獲取或設置如何處理工具調用的行為。// Enable auto function calling OpenAIPromptExecutionSettings openAIPromptExecutionSettings = new() { ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions };1.
EnableKernelFunctions:會向模型提供內核的插件函數信息,但不會自動處理函數調用請求。模型需要顯式發起函數調用請求,並系統會傳播這些請求給適當的處理程序來執行。OpenAIPromptExecutionSettings settings = new() { ToolCallBehavior = ToolCallBehavior.EnableKernelFunctions }; var chatHistory = new ChatHistory(); ChatMessageContent result = await chat.GetChatMessageContentAsync(chatHistory, settings, kernel); //手動調用 IEnumerable<FunctionCallContent> functionCalls = FunctionCallContent.GetFunctionCalls(result);EnableKernelFunctions:需要通過 FunctionCallContent 手動調用
2.
AutoInvokeKernelFunctions:除了向模型提供內核的插件函數信息外,還會嘗試自動處理任何函數調用請求。模型發起函數調用請求後,系統會自動執行相應的操作,並將結果返回給模型,而無需模型顯式處理函數調用的過程。
模型推薦
建議使用 OpenAI 的最新模型(如 gpt-3.5-turbo-1106 或 gpt-4-1106-preview)以獲得最佳的工具調用體驗。OpenAI 的最新模型通常具有更好的性能和更高的準確性,因此使用這些模型可以提高工具調用的效果。
我這裏是公司提供的
Azure OpenAI的服務,我自己通過yarp代理了一層做了相關服務的認證
{
"InternalAzureOpenAI": {
"Endpoint": "https://localhost:7079",
"ModelId": "gpt-35-turbo-1106",
"ApiKey": "***"
}
}
實戰
接下來我們會問一下大模型當前北京的天氣情況
定義 Prompts
var template = "我想知道現在北京的天氣狀況?";
定義 kernel
var kernel = Kernel.CreateBuilder()
.AddAzureOpenAIChatCompletion(config.ModelId, endpoint: config.Endpoint, apiKey: config.ApiKey)
.Build();
註冊 kernel function 到 plugins
定義方法
static string GetWeatherForCity(string cityName)
{
return $"{cityName} 25°,天氣晴朗。";
}
為 Kernel 提供插件
kernel.ImportPluginFromFunctions("WeatherPlugin", new[]
{
kernel.CreateFunctionFromMethod(GetWeatherForCity, "GetWeatherForCity", "獲取指定城市的天氣")
});
手動調用 function calling
根據上面的描述 手動處理function calling的關鍵實際上是ToolCallBehavior.EnableKernelFunctions參數。
OpenAIPromptExecutionSettings settings = new OpenAIPromptExecutionSettings()
{
Temperature = 0,
ToolCallBehavior = ToolCallBehavior.EnableKernelFunctions
};
需要用到Semantic Kernel的IChatCompletionService的會話服務
var chatHistory = new ChatHistory();
chatHistory.AddSystemMessage("You are a useful assistant.");
chatHistory.AddUserMessage(template);
Console.WriteLine($"User: {template}");
var chat = kernel.GetRequiredService<IChatCompletionService>();
while (true)
{
ChatMessageContent result = await chat.GetChatMessageContentAsync(chatHistory, settings, kernel);
if (result.Content is not null)
{
Console.Write(result.Content);
}
IEnumerable<FunctionCallContent> functionCalls = FunctionCallContent.GetFunctionCalls(result);
if (!functionCalls.Any())
{
break;
}
chatHistory.Add(result); // Adding LLM response containing function calls(requests) to chat history as it's required by LLMs.
foreach (var functionCall in functionCalls)
{
try
{
FunctionResultContent resultContent = await functionCall.InvokeAsync(kernel); // Executing each function.
chatHistory.Add(resultContent.ToChatMessage());
}
catch (Exception ex)
{
chatHistory.Add(new FunctionResultContent(functionCall, ex).ToChatMessage());
}
}
Console.WriteLine();
}
輸出
=====>手動function calling
User: 我想知道現在北京的天氣狀況?
Assistant:現在北京的天氣是晴朗,氣温為25°C。
自動調用 function calling
和手動的區別就是上面描述的OpenAIPromptExecutionSettings配置的ToolCallBehavior屬性值不同
OpenAIPromptExecutionSettings openAIPromptExecutionSettings = new OpenAIPromptExecutionSettings()
{
Temperature = 0,
ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions
};
自動
function calling從本質上來講是隱藏了跟大模型多次交互的邏輯,有Semantic Kernel框架自動幫我們調用
核心代碼
var chatHistory = new ChatHistory();
chatHistory.AddSystemMessage("You are a useful assistant.");
chatHistory.AddUserMessage(template);
Console.WriteLine($"User: {template}");
var chatService = kernel.GetRequiredService<IChatCompletionService>();
var result = await chatService.GetChatMessageContentAsync(chatHistory, openAIPromptExecutionSettings, kernel);
Console.Write("Assistant:" + result.ToString());
輸出
=====>自動function calling
User: 我想知道現在北京的天氣狀況?
Assistant:北京現在的天氣狀況是晴朗,氣温為25°C。
最後
在本章中,我們探討了在 OpenAI 的 function calling 在 Semantic Kernel 中的應用。通過對 ToolCallBehavior 屬性的設置,我們可以靈活地控制工具調用的行為,從手動調用到自動調用,為用户提供了更加便捷和高效的體驗。
建議在實踐中使用 OpenAI 的最新模型(如 gpt-3.5-turbo-1106 或 gpt-4-1106-preview)以獲得最佳的工具調用效果。同時,通過合理配置 OpenAIPromptExecutionSettings 中的參數,可以更好地適配不同的場景和需求。
希望本章內容能夠幫助您更深入地理解 function calling 在 Semantic Kernel 中的運用,為您的項目和應用帶來更多可能性和創新。
示例代碼
本文源代碼