當前位置: 妍妍網 > 碼農

深入探討Function Calling:在Semantic Kernel中的套用實踐

2024-05-31碼農

引言

上一章我們熟悉了 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

    定義方法

    staticstringGetWeatherForCity(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 中的運用,為您的計畫和套用帶來更多可能性和創新。

    範例程式碼 本文原始碼 [1]

    參考資料

    [1]

    本文原始碼: https://github.com/Dong-Ruipeng/SK-WorkBook