精彩(且驚人)的Semantic Kernel入門範例

之前開直播的時候,和線上朋友聊到,因為AI的出現,未來的應用程式,勢必會和現在有所不同。

先不要跳到黃仁勳說的,未來『每個開發人員都可以直接用自然語言做程式設計』(這樣也太駭人聽聞了一點),先看看眼下我們可以做到什麼程度。

你會發現透過 Semantic Kernel,這個所謂的 AI 開發框架,已經可以做到,讓 AI 自己決定何時(以及如何)呼叫一個類別(Class)中的方法(Method)。而我們只需要讓用戶輸入對話與機器人對談,就可以控制程式運行的流程與邏輯。也就是說,現在不需要滑鼠點選,不用選單操作,只要與機器人透過自然語言對談(底下的範例是打字,但當然可以是語音),就可以操控系統。

我前陣子一直說的,AI 會讓 GUI 有著天翻地覆的改變,意即如此。

看底下這個類別的程式碼:

//控制開關燈的類別
public class LightPlugin
{
    //當前燈的狀態
    public bool IsOn { get; set; } = false;

    [KernelFunction]
    [Description("取得燈的狀態")]
    public string GetState()
    {
        return IsOn ? "on" : "off";
    }

    [KernelFunction]
    [Description("改變燈的狀態")]
    public string ChangeState(bool newState)
    {
        this.IsOn = newState;
        var state = GetState();

        // Print the state to the console
        Console.WriteLine($"[Light is now {state}]");

        return state;
    }
}

上面這個很簡單的 LightPlugin 類別,具有兩個方法:GetState 和 ChangeState。這兩個方法都被標記為 [KernelFunction],這意味著它們可以直接被 AI 呼叫。

LightPlugin 類別中有一個全域屬性IsOn ,指的是當前的燈是開著還是關的

從這邊你會看到, LightPlugin 這個類別包含的一個狀態(屬性),和兩個行為(方法),你可以將其比擬成一個IoT智慧型家電的控制物件,透過改變這個物件就可以控制家電。請在心裡想像一下,如果你過去,要寫程式讓用戶來操作這個物件,進而控制電燈的開或關,你會怎麼做?

做一個控制面板(GUI)? 還是做一個選單操作介面(Menu)? 來控制這個燈光的開啟和關閉。

那如果,這個控制機制要改成語音控制呢? 例如我希望用戶能夠用說的,電腦就能夠回報目前燈光的狀況,或是幫你直接開關燈,你是不是必須多撰寫很多程式碼,才能完成?

好,我們接著來看底下的程式碼,看看Semantic Kernel是如何完成這需求的:

private static async global::System.Threading.Tasks.Task Main(string[] args)
{
    //Azure OpenAI 服務資訊 
    var DeployName = "👉模型佈署名稱👈";
    var Endpoint = "https://👉API端點👈.openai.azure.com/";
    var ApiKey = "👉ApiKey👈";

    // 建立 kernel builder, 掛上 Azure OpenAI
    var builder = Kernel.CreateBuilder()
                .AddAzureOpenAIChatCompletion(DeployName, Endpoint, ApiKey);
    builder.Plugins.AddFromType<LightPlugin>(); // 將 LightPlugin 加入 Kernel
    Kernel kernel = builder.Build();

    // 建立 chat history 物件,並且加入系統提示訊息(System Prompt)
    var history = new ChatHistory();
    history.AddSystemMessage("你是一個親切的智能家庭助理,可以協助用戶回答問題,交談時請使用中文。");

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

    // 開始對談
    Console.Write("User > ");
    string? userInput;
    while (!string.IsNullOrEmpty(userInput = Console.ReadLine()))
    {
        // Add user input
        history.AddUserMessage(userInput);

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

        // 從 AI 取得對談結果
        var result = await chatCompletionService.GetChatMessageContentAsync(
            history,
            executionSettings: openAIPromptExecutionSettings,
            kernel: kernel);

        // 顯示結果
        Console.WriteLine("Assistant > " + result);

        // 將對話加入歷史訊息
        history.AddMessage(result.Role, result.Content ?? string.Empty);

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

先看上面這段程式碼,搭配 剛才的LightPlugin之後,執行結果如下:
圖片

想像一下,這是一個智能助理管家(畢竟上面的 prompt 我們是這麼說的),當你回家了,這個AI會跟你說話:

歡迎回家!需要我為您開啟燈光或是播放輕快的音樂來放鬆一下嗎?

接著你說:

現在好黑,燈是開著嗎?

AI 想知道燈的狀況,因此它自己去呼叫了 LightPlugin 的 GetState() 方法,告訴你目前燈是關的,並且問你要不要開燈?

對不起,目前的燈光是關閉的,要我立即為您打開燈光嗎?

你說…

幫我開燈

這個敘述會促使 AI 去執行 LightPlugin 類別的ChangeState()方法,自動傳入參數 True,這時,燈開了,然後出現底下訊息

[Light is now on]
好的,燈已經打開了。如果還有其他需要的話,隨時告訴我喔。

後面的動作就不用我多解釋了,你用口語化的指令,告訴AI說,你要關燈,它就幫你關燈。你人在國外出差,要問家裡的燈是開是關,它就幫你查詢狀態,並且回報:

是的,您的家中燈光目前是關閉的。如果您需要改變狀態或有其他需要,隨時讓我知道。

這個系統的操作,不是用滑鼠、不是用選單、不是用手機 app,單純就是用口語化的指令,來控制一切。整個流程,由 AI 自己決定何時(when)/如何(How)呼叫 LightPlugin 的什麼(What) Method(方法),全部用 語意(Semantic) 為核心,所以這個框架被稱為 Semantic Kernel 我想是再適當不過的了。

你再看一下操作的影片,有沒有很讓人震驚?

誰控制這一切的? 誰回應了用戶的對談? 並且決定何時呼叫 API(或method),當然是 GPT 模型,看底下這段:

    //Azure OpenAI 
    var DeployName = "👉模型佈署名稱👈";
    var Endpoint = "https://👉API端點👈.openai.azure.com/";
    var ApiKey = "👉ApiKey👈";

    // Create a new kernel builder
    var builder = Kernel.CreateBuilder()
                .AddAzureOpenAIChatCompletion(DeployName, Endpoint, ApiKey);
    builder.Plugins.AddFromType<LightPlugin>(); // Add the LightPlugin to the kernel
    Kernel kernel = builder.Build();

kernel builder 建立了以 AzureOpenAIChatCompletion 方法為核心的 AI Kernel,並且添加了 LightPlugin 這個類別作為 Plugin。

接著,我們配置了 System Message (role為system的prompt):

  // 建立 chat history 物件,並且加入系統提示訊息
  var history = new ChatHistory();
  history.AddSystemMessage("你是一個親切的智能家庭助理,可以協助用戶回答問題,交談時請使用中文。");

最後建立了 chatCompletionService 物件,並且開啟了對話迴圈,然後程式就動起來了:

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

     // 開始對談
     Console.Write("User > ");
     string userInput;
     while ((userInput = Console.ReadLine()) != 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 > ");
     }

迴圈中,我們只是透過 AddUserMessage() 方法把用戶輸入的訊息傳遞給 AI,並且透過 GetChatMessageContentAsync() 方法取得回傳結果,這樣的對話之間,AI 就自己決定了要進行的行為,要呼叫的 API(Method),這還不驚人嗎?

以後的程式的核心,可能不是我寫的邏輯,而是 AI 決定的邏輯,我們只是提供了在什麼狀況下要呼叫什麼方法的指引(注意 LightPlugin類別的那兩個方法身上掛的 KernelFunction Attribute 與 Description Attribute ),然後,事就這麼成了。

在上面的範例中,應用程式的『核心』,已經不是我寫的邏輯,應用程式的核心,是AI。我只是提供AI所需要的功能(Plugin),然後用戶就可以透過與AI對談,完成所有的 Actions(行為)。

沒有複雜的UI操作介面,沒有複雜的邏輯指令,全都是自然語言溝通,全部是AI。

我第一次看到的時候是很震驚的,想像一下,如果上面的 LightPlugin類別是一個個的API,那未來的程式開發方式是不是會大大的改變?

我們會不會迎向一個透過自然語言就可以操作的系統? 甚至一個透過語音就可以控制的作業系統? 果真實現,那鋼鐵人裡面的人工智能助理Jarvis,還會遠嗎?


相關課程:
ChatGPT(Azure OpenAI) 對談機器人開發實戰 (studyhost.tw)
參考資料:
https://learn.microsoft.com/zh-tw/semantic-kernel/overview/

留言

這個網誌中的熱門文章

在POC或迷你專案中使用 LiteDB

使用Qdrant向量資料庫實作語意相似度比對

專業的價值...

使用 Airtable 在小型需求上取代傳統資料庫

周末讀書會 - 一如既往