在前兩天的內容中,寫了 AI Agent 的概念以及 Semantic Kernel 的 Function Calling 機制。但隨著 AI Agent 概念的火熱,也許該思考一下:是不是所有的 LLM 應用都需要設計成 Agent?
首先還是得聲明一下,Agent 定義為具有決策能力,能夠根據需求變化調用外部系統具有行動能力。
先說明本篇僅僅是從我個人的論點,也許答案可能會讓一些追求技術潮流的開發者失望:凡是都該是個 Agent,我個人覺的並非如此並不是的。
事實上,很多場景下,傳統的「輸入 → LLM → 輸出」模式不僅更簡單、更穩定,也更符合實際需求。今天我們就來聊聊什麼時候該用 Agent,什麼時候該回歸簡單,以及如何在 Semantic Kernel 中實現這兩種不同的設計模式。
先看幾個常見的 LLM 應用場景:
輸入:一段 2 小時的會議錄音逐字稿
處理:請幫我整理出會議的重點摘要,包含決議事項和待辦任務
輸出:結構化的會議摘要文件
輸入:一篇部落格文章
處理:請為這篇文章生成 5 個相關的標籤
輸出:#技術分享 #AI應用 #程式開發 #Semantic Kernel #最佳實務
輸入:一段中文技術文件
處理:請將以下內容翻譯成英文,保持技術術語的準確性,請盡可能使用自然流暢的短語句表達,避免逐字翻譯以及文謅謅的句子
輸出:對應的英文技術文件
應該不難發現,這些應用都有一個共同特點:任務目標明確、流程固定、不需要動態決策。
在這些場景中:
如果我們硬是要把這些應用包裝成 Agent,添加 Function Calling、多步驟推理等複雜機制,反而會:
任務複雜且多步驟
需要動態決策
具備學習與適應能力
單一、明確的轉換任務
對穩定性要求很高
大量批次處理
對於簡單的生成任務,我們可以直接使用 Semantic Kernel 的基本功能,不需要 Function Calling,甚至連對話歷史記錄都可以不用:
public class DocumentSummaryService
{
private readonly Kernel _kernel;
public DocumentSummaryService()
{
_kernel = Kernel.CreateBuilder()
.AddOpenAIChatCompletion(
apiKey: Config.OpenAI_ApiKey,
modelId: "gpt-4")
.Build();
}
public async Task<string> SummarizeAsync(string document)
{
string prompt = $"""
請為以下文件生成摘要,包含:
1. 主要重點(3-5 點)
2. 關鍵決議事項
3. 後續行動項目
文件內容:
{document}
請用繁體中文回覆,格式要清楚易讀。
""";
var response = await _kernel.InvokePromptAsync(prompt);
return response.ToString();
}
}
這種設計的優點:
而對於需要動態決策的複雜任務,我們則使用完整的 Agent 架構:
public class TravelPlannerAgent
{
private readonly Kernel _kernel;
public TravelPlannerAgent()
{
var builder = Kernel.CreateBuilder()
.AddOpenAIChatCompletion(
apiKey: Config.OpenAI_ApiKey,
modelId: "gpt-4");
_kernel = builder.Build();
// 註冊各種工具
_kernel.Plugins.AddFromType<WeatherService>();
_kernel.Plugins.AddFromType<HotelBookingService>();
_kernel.Plugins.AddFromType<RestaurantService>();
_kernel.Plugins.AddFromType<TransportationService>();
}
public async Task<string> PlanTripAsync(string destination, int days, string preferences)
{
ChatHistory history = new();
string systemPrompt = $"""
你是一個專業的旅遊規劃助理,能夠:
1. 查詢目的地天氣資訊
2. 搜尋並推薦住宿
3. 規劃餐廳與美食
4. 安排交通方式
請根據使用者需求,主動使用適當的工具來規劃行程。
""";
history.AddDeveloperMessage(systemPrompt);
history.AddUserMessage($"幫我規劃{destination}的{days}天行程,我的偏好是:{preferences}");
var settings = new OpenAIPromptExecutionSettings
{
FunctionChoiceBehavior = FunctionChoiceBehavior.Auto()
};
var chatService = _kernel.GetRequiredService<IChatCompletionService>();
var response = await chatService.GetChatMessageContentAsync(history, settings, _kernel);
return response.Content;
}
}
在決定使用哪種模式時,可以問自己這些問題:
在實際專案中,我會建議採用漸進式的演進策略:
先用最簡單的生成模式解決核心問題,驗證商業價值和技術可行性。
在使用過程中識別哪些環節確實需要更複雜的邏輯,哪些地方用戶會遇到困難。
只針對真正需要的部分引入 Agent 機制,保持其他部分的簡單性。
根據實際使用情況和使用者實際回饋,持續調整架構設計。
技術選型的智慧不在於使用最新、最複雜的技術,而在於選擇最適合當下問題的解決方案。AI Agent 是個強大的概念,但並不意味著所有 LLM 應用都需要變成 Agent。在 Semantic Kernel 的世界裡,有足夠的靈活性來實現各種不同的架構模式。關鍵是要根據實際需求,在簡單性與複雜性之間找到適當的平衡點。
記住:好的架構設計是解決問題的藝術,而不是展示技術的舞台。有時候,最簡單的方案就是最好的方案。