探索Semantic Kernel內建外掛:深入瞭解HttpPlugin的應用

董瑞鹏發表於2024-06-25

前言

上一章我們熟悉了Semantic Kernel中的內建外掛和對ConversationSummaryPlugin外掛進行了實戰,本章我們講解一下另一個常用的內建外掛HttpPlugin的應用。

上一章對ConversationSummaryPlugin總結進行了調整之後,順便給Semantic Kernel提了一個PR已經被採納了,在此記錄一下!

image

.Net: refactor : SummarizeConversation #6719

HttpPlugin

HttpPlugin外掛屬於Native Plugins原生外掛。它提供了Http的功能,允許使用者透過Http協議與外部進行互動。

我們對這個外掛的整體進行分析一下

建構函式

提供了兩個建構函式。第一個建構函式沒有引數,它呼叫了第二個建構函式,並傳遞null作為引數。

第二個建構函式接受一個HttpClient型別的引數,如果未提供,則使用HttpClientProvider.GetHttpClient()方法獲取一個新的HttpClient例項。

   public HttpPlugin() : this(null)
   {
   }

    [ActivatorUtilitiesConstructor]
    public HttpPlugin(HttpClient? client = null) =>
     this._client = client ?? HttpClientProvider.GetHttpClient();

這裡重點說一下第二個建構函式,支援HttpClient的建構函式,這就有更多的可玩性了,比如可以定義一個HttpclientHandler對請求進行新增自定義的HttpHeader或者進行引數的拼接轉發等操作。

Native functions

GetAsync:傳送一個HTTP GET請求,並返回響應體作為字串。
PostAsync:傳送一個HTTP POST請求,帶有請求體,並返回響應體作為字串。
PutAsync:傳送一個HTTP PUT請求,帶有請求體,並返回響應體作為字串。
DeleteAsync:傳送一個HTTP DELETE請求,並返回響應體作為字串。

實戰

第一步需要安裝Nuget

NuGet\Install-Package Microsoft.SemanticKernel.Plugins.Core -Version 1.14.1-alpha

該包目前只有預覽版本,如果用VS的包管理器安裝,那需要勾選包括預覽發行版

Semantic Kernel註冊外掛有兩種方式:

kernel.ImportPluginFromType<HttpPlugin>();
var httpclient = new HttpClient();
kernel.ImportPluginFromObject(new HttpPlugin(httpclient));

以上兩種方式對應兩種生命週期的註冊

建立的介面

image

這個介面都很簡單 對我們Student物件的增刪改查

public class Student
{
 
    public string Name { get; set; }


    public int Age { get; set; }

}

執行測試

我們的測試程式還是以Semantic Kernel的會話服務,自動觸發function calling的形式

// Get chat completion service
var chatCompletionService = kernel.GetRequiredService<IChatCompletionService>();

// Start the conversation
Console.Write("User > ");
string? userInput;
while ((userInput = Console.ReadLine()) is not null)
{
    // Add user input
    history.AddUserMessage(userInput);

    // Enable auto function calling
    OpenAIPromptExecutionSettings openAIPromptExecutionSettings = new()
    {
        ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions
    };

    // 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);

    // Get user input again
    Console.Write("User > ");
}

Get請求測試

User > 幫我向https://localhost:7014/Student發一個get請求
Assistant > 向https://localhost:7014/Student發起GET請求後成功得到了響應,返回的資料顯示包含了一個學生的資訊。該學生名為 張三,年齡為16歲。這表明請求執行成功,獲取到了預期的資料。

Post請求測試

HttpPlugin的這個功能比較雞肋,可以看一下程式碼

 [KernelFunction]
 [Description("Makes a POST request to a uri")]
 public Task<string> PostAsync([Description("The URI of the request")] string uri, [Description("The body of the request")] string body, CancellationToken cancellationToken = default(CancellationToken))
 {
     return SendRequestAsync(uri, HttpMethod.Post, new StringContent(body), cancellationToken);
 }

引數形式是new StringContent(body),也就是說MediaTypeHeaderValue媒體型別預設為 StringContent text/plain

Asp.Net Core 只能接收Post請求json格式的string,不能接收原始string
content-typetext/plainpost請求,如果支援需要自定義實現沒有提供對應的MediaTypeFormatter

所以說這個外掛的Post請求場景侷限,真正用到生產還需要自己去實現一個外掛!!!

User > 向https://localhost:7014/student 發一個post請求
Assistant > 已成功向 https://localhost:7014/student 傳送了 POST 請求。如果需要傳送具體的資料,請提供要包含在請求體內的 JSON 資料。

其他

PutDelete類似。

最後

可以借鑑HttpPlugin的實現思路在專案中靈活的執行,如果不支援那就可以自定義外掛來完成需求的開發,還是比較期待這個外掛能夠更加完善的一點,在未來以更靈活的方式支援Post等請求的多種形式。

相關文章