想像一下,你家 AI 廚師雖然會跟你聊天,知道怎麼寫食譜,但他只能「說」要做什麼菜,卻沒辦法真的「動手」去切菜、開火、甚至是打開電燈。這不是很可惜嗎?
這就是 Plugins 的存在價值。如果說 Kernel 是那位擁有思考和規劃能力的「大腦」,那麼 Plugins 就是它的「手」和「腳」。Plugins 能夠將我們現有的程式碼,包裝成一個 AI 可以理解並調用的「工具」。如此一來,你的 AI 就不再是空談的哲學家,而是能真正動手解決問題的實踐家。
在 Semantic Kernel 的世界裡,Plugin 是一個能賦予 AI 額外能力的程式碼集合。它可以是:
今天,我們就從最基礎、也是最核心的原生程式碼 Plugin 開始,一步步打造你的第一把「廚師刀」。
我們來做一個最簡單的範例,一個能夠控制電燈的 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 "電燈已關閉。";
}
}
在這個程式碼中,有幾個關鍵點:
LightsPlugin
。[KernelFunction]
這個屬性來標記,告訴 Semantic Kernel:「嘿,這個方法是個可供 AI 呼叫的工具喔!」[Description]
屬性來為每個方法提供簡短的說明。這一步非常重要,因為 AI 會根據這些描述來決定它應該呼叫哪個函式。描述得越清楚,AI 越能精準地選擇對應的工具。光寫好刀具還不夠,你得把它們放到廚房裡,讓廚師隨時都能取用。這一步非常簡單,只需要一行程式碼,我們在建構 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。你學會了:
[KernelFunction]
和 [Description]
屬性來定義工具。從現在開始,你的 AI 就不再是只會聊天的虛擬助理,而是真正能動手幫你解決問題的「AI 員工」了!接下來的幾天,我們會更深入探討這些工具的應用,並揭開 Function Calling 這場盛宴最精彩的一幕。