iT邦幫忙

2025 iThome 鐵人賽

DAY 6
0

想像一下,你家 AI 廚師雖然會跟你聊天,知道怎麼寫食譜,但他只能「說」要做什麼菜,卻沒辦法真的「動手」去切菜、開火、甚至是打開電燈。這不是很可惜嗎?

這就是 Plugins 的存在價值。如果說 Kernel 是那位擁有思考和規劃能力的「大腦」,那麼 Plugins 就是它的「手」和「腳」。Plugins 能夠將我們現有的程式碼,包裝成一個 AI 可以理解並調用的「工具」。如此一來,你的 AI 就不再是空談的哲學家,而是能真正動手解決問題的實踐家。


什麼是 Plugin?讓 AI 擁有超能力

在 Semantic Kernel 的世界裡,Plugin 是一個能賦予 AI 額外能力的程式碼集合。它可以是:

  • 原生程式碼 Plugin (Native Code Plugin):就是你自己寫的 C#, Python 或 Java 程式碼,例如呼叫資料庫、發送 API 請求、或執行檔案操作。
  • 開放式 API Plugin (OpenAPI Plugin):將既有的 RESTful API 服務匯入,讓 AI 可以直接與外部系統互動,例如訂購披薩、查詢天氣或發送簡訊。
  • Prompt Plugin:將一系列提示詞和邏輯打包,讓 AI 可以執行更複雜的文字任務,例如寫一篇完整的部落格文章。

今天,我們就從最基礎、也是最核心的原生程式碼 Plugin 開始,一步步打造你的第一把「廚師刀」。


你的第一把廚師刀:LightsPlugin

我們來做一個最簡單的範例,一個能夠控制電燈的 Plugin。這個 Plugin 裡面會有兩個功能:一個是開燈,一個是關燈。

using System.ComponentModel;
using Microsoft.SemanticKernel;

public class LightsPlugin
{
    // 為你的 Plugin 函式加上註解和描述,讓 AI 知道這個函式是做什麼的
    [KernelFunction, Description("打開燈。")]
    public string TurnOn()
    {
        Console.WriteLine("打開電燈!");
        return "電燈已打開。";
    }

    [KernelFunction, Description("關閉燈。")]
    public string TurnOff()
    {
        Console.WriteLine("關閉電燈!");
        return "電燈已關閉。";
    }
}

在這個程式碼中,有幾個關鍵點:

  1. 我們定義了一個公開類別 LightsPlugin
  2. 在每個方法前,我們使用 [KernelFunction] 這個屬性來標記,告訴 Semantic Kernel:「嘿,這個方法是個可供 AI 呼叫的工具喔!」
  3. 我們也使用了 [Description] 屬性來為每個方法提供簡短的說明。這一步非常重要,因為 AI 會根據這些描述來決定它應該呼叫哪個函式。描述得越清楚,AI 越能精準地選擇對應的工具。

將 Plugins 加入你的廚房 (Kernel)

光寫好刀具還不夠,你得把它們放到廚房裡,讓廚師隨時都能取用。這一步非常簡單,只需要一行程式碼,我們在建構 Kernel 時,把這個 LightsPlugin 實例加進去就行了。

using Microsoft.SemanticKernel;

// 1. 建立 Kernel Builder
var builder = Kernel.CreateBuilder()
    .AddOpenAIChatCompletion("gpt-4o", "YOUR_OPENAI_API_KEY");

// 2. 建立我們的 Plugin 實例
var lightsPlugin = new LightsPlugin();

// 3. 將 Plugin 加入 Kernel
// 這裡的 "Lights" 是你的 Plugin 名稱,可以自訂
builder.Plugins.AddFromObject(lightsPlugin, "Lights");

// 4. 建構 Kernel
var kernel = builder.Build();

Console.WriteLine("🏠 燈光控制範例啟動!");
Console.WriteLine("你可以用自然語言來控制燈光,例如:");
Console.WriteLine("- 請幫我打開燈");
Console.WriteLine("- 關燈");
Console.WriteLine("- 輸入 'quit' 離開\n");

while (true)
{
    Console.Write("💬 請輸入指令: ");
    var userInput = Console.ReadLine();

    if (string.IsNullOrWhiteSpace(userInput))
        continue;

    if (userInput.ToLower() is "quit" or "exit" or "離開")
    {
        Console.WriteLine("👋 再見!");
        break;
    }

    try
    {
        Console.WriteLine();
        OpenAIPromptExecutionSettings settings = new() { FunctionChoiceBehavior = FunctionChoiceBehavior.Auto() };

        // 建立 Kernel Arguments
        var arguments = new KernelArguments(executionSettings: settings)
        {
            ["userInput"] = userInput,
        };

        // 使用更符合 Semantic Kernel 規格的 Prompt
        var prompt = @"
你是一個智慧燈光控制助手。請根據用戶的指令呼叫適當的函式。

用戶指令:{{$userInput}}

請分析用戶的意圖:
- 如果用戶想要打開燈光(如:打開燈、開燈、亮燈、點燈等),請呼叫 TurnOn 函式
- 如果用戶想要關閉燈光(如:關燈、關閉燈、熄燈、關掉燈等),請呼叫 TurnOff 函式

請直接呼叫對應的函式。";

        var result = await kernel.InvokePromptAsync(prompt, arguments);

        Console.WriteLine($"🤖 AI 回應: {result}");
    }
    catch (Exception ex)
    {
        Console.WriteLine($"❌ 發生錯誤: {ex.Message}");
    }

    Console.WriteLine();
}

當你將這個 Plugin 加入 Kernel 後,Semantic Kernel 會自動掃描 LightsPlugin 類別中所有標記了 [KernelFunction] 的方法,並將它們註冊為一個個可供 AI 調用的工具。這些工具會被序列化成一個 AI 模型能夠理解的 JSON 格式(這就是 Function Calling 的基礎),從而實現「AI 大腦」與「你的程式碼」的無縫接軌。


今日小結

今天,我們完成了 AI 滿漢全席的第二道主菜——Plugins。你學會了:

  • Plugin 是什麼,以及它如何賦予 AI 執行具體任務的能力。
  • 如何建立一個簡單的原生程式碼 Plugin,並用 [KernelFunction][Description] 屬性來定義工具。
  • 如何將這個工具掛載到你的 Kernel 廚房中。

從現在開始,你的 AI 就不再是只會聊天的虛擬助理,而是真正能動手幫你解決問題的「AI 員工」了!接下來的幾天,我們會更深入探討這些工具的應用,並揭開 Function Calling 這場盛宴最精彩的一幕。

完整程式碼範例


上一篇
Day 5: 食材的藝術:什麼是提示詞 (Prompts) 與模板?
下一篇
Day 7: 聊天的記憶:用 ChatHistory 讓對話有溫度
系列文
AI 全餐,好吃嗎?用 Semantic Kernel 打造你的客製化滿漢全席!8
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言