如何讓其他模型也能在SemanticKernel中呼叫本地函式

mingupupup發表於2024-07-05

在SemanticKernel的入門例子中:

// Import packages
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
using Microsoft.SemanticKernel.Connectors.OpenAI;

// Create a kernel with Azure OpenAI chat completion
var builder = Kernel.CreateBuilder().AddAzureOpenAIChatCompletion(modelId, endpoint, apiKey);

// Add enterprise components
builder.Services.AddLogging(services => services.AddConsole().SetMinimumLevel(LogLevel.Trace));

// Build the kernel
Kernel kernel = builder.Build();
var chatCompletionService = kernel.GetRequiredService<IChatCompletionService>();

// Add a plugin (the LightsPlugin class is defined below)
kernel.Plugins.AddFromType<LightsPlugin>("Lights");

// Enable planning
OpenAIPromptExecutionSettings openAIPromptExecutionSettings = new() 
{
    ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions
};

// Create a history store the conversation
var history = new ChatHistory();

// Initiate a back-and-forth chat
string? userInput;
do {
    // Collect user input
    Console.Write("User > ");
    userInput = Console.ReadLine();

    // Add user input
    history.AddUserMessage(userInput);

    // Get the response from the AI
    var result = await chatCompletionService.GetChatMessageContentAsync(
        history,
        executionSettings: openAIPromptExecutionSettings,
        kernel: kernel);

    // Print the results
    Console.WriteLine("Assistant > " + result);

    // Add the message from the agent to the chat history
    history.AddMessage(result.Role, result.Content ?? string.Empty);
} while (userInput is not null)

只要使用:

// Enable planning
OpenAIPromptExecutionSettings openAIPromptExecutionSettings = new() 
{
    ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions
};

就可以實現本地函式的呼叫了,這很酷,也是最吸引我的地方。

但我在實踐的過程中,發現直接這樣子,只有OpenAI的模型與Moonshot AI可以用,而其他模型的本地函式呼叫都無效。

如何能使用一個開源的模型實現本地函式呼叫,那就非常酷。

在SemanticKernel的討論區,我也發現世界各地的人也都有這種需求,不想只用OpenAI,也要使用其他的模型,在SemanticKernel中實現本地函式呼叫。

image-20240705175357335

在這個討論區,官方最初將這個轉化為一個問題:

image-20240705175701905

點進這個問題:

image-20240705175818171

這是對應的翻譯:

我們的聯結器(OpenAI、Mistral、Gemini)支援函式呼叫功能,但並非特定 AI 提供商的每個模型都支援它。您需要檢視 AI 提供商的官方文件,瞭解您要使用的具體模型及其功能。看起來 Phi-3 不支援開箱即用的函式呼叫。雖然,我認為可以對其進行微調以支援這一點。對於電燈開關外掛示例,我們建議使用支援開箱即用函式呼叫的 AI 模型,以便快速上手。下面是 Azure OpenAI 中的可用模型、其功能和可用區域的列表:
https://learn.microsoft.com/en-us/azure/ai-services/openai/concepts/models

我將關閉此問題,因為它與電燈開關外掛無關。如果您看到任何其他問題,請隨時開啟一個新的。謝謝!

有一位老哥推薦了一個專案能夠實現這個目的:

image-20240705180008794

對應的翻譯:

看看這個專案 https://github.com/Jenscaasen/UniversalLLMFunctionCaller。透過提示模板,它嘗試模仿本機函式呼叫。我嘗試了 ollama 和 phi3 mini、llama3,效果很好。

我也去嘗試使用這個專案:

image-20240705180118266

簡介的翻譯如下:

一個整合到語義核心中的計劃器,可以在所有基於LLMs聊天(Mistral、Bard、Claude、LLama 等)上實現函式呼叫。

根據這個專案提供的方法我去嘗試了一下:

把這個專案中的類,新增到自己的專案中:

image-20240705180340482

新增這兩個外掛到自己的專案中,用於測試:

image-20240705180434072

構建kernel:

 var handler = new OpenAIHttpClientHandler();
 var builder = Kernel.CreateBuilder()
 .AddOpenAIChatCompletion(
    modelId: "",
    apiKey: "",
    httpClient: new HttpClient(handler));
 _kernel = builder.Build();          
 _kernel.ImportPluginFromType<TimePlugin>("Time");
 _kernel.ImportPluginFromType<MathPlugin>("Math");

測試程式碼:

   UniversalLLMFunctionCaller planner = new(_kernel);
   string ask = "What is the current hour number, plus 6?";
   Debug.WriteLine(ask);
   string result = await planner.RunAsync("What is the current hour number, plus 6?");
   Debug.WriteLine(result);

Qwen/Qwen2-7B-Instruct的輸出:

image-20240705180847211

測試的時候是18:09分,18+6 =24,成功執行了本地函式用於獲取當前時間與進行加法。

但並不是每個模型使用這個都能成功進行本地函式呼叫。

image-20240705181242672

根據矽基流動提供的模型,我根據這個demo進行測試,可行的結果如下:

Qwen/Qwen2-72B-Instruct
Qwen/Qwen2-7B-Instruct
Qwen/Qwen1.5-110B-Chat
Qwen/Qwen1.5-32B-Chat
Qwen/Qwen1.5-7B-Chat
deepseek-ai/DeepSeek-V2-Chat
01-ai/Yi-1.5-34B-Chat-16K

可供遇到這個問題的人參考。

相關文章