iT邦幫忙

2025 iThome 鐵人賽

DAY 22
0

昨天我們學會了如何將 AI 員工們排成一條整齊的流水線(Sequential),讓他們循序漸進地完成任務。這固然有效,但如果今天客人點了一道需要即興發揮、腦力激盪的創意料理,那固定的流水線可能就不夠靈活了。

這時候,我們的廚房需要召開一場「最強大腦會議」!這就是我們今天要介紹的進階協作模式:Magentic Orchestration


從流水線到會議室:Magentic 的核心精神

Magentic 的靈感源自於開源專案 Magentic-One,它將 Agent 的協作提升到一個新的層次。如果說 Sequential Orchestration 是一個固定的工作流,那麼 Magentic 則更像一個由一位「經理人」協調的自由討論會議

這位經理人,我們稱之為 Magentic Manager,他不像流水線上的領班只負責傳遞任務。他更像是一位專案經理或總指揮

  1. 任務拆解: 當收到一個複雜任務,他會先將其拆解成多個可執行的子任務。
  2. 智慧委派: 他會根據子任務的特性,動態地將其委派給最適合的專家 Agent。
  3. 進度追蹤: 他會監控每個 Agent 的執行狀況,確保任務順利進行。
  4. 結果整合: 最後,他會將所有 Agent 的產出進行綜合、整理,形成最終的完整答案。

這種模式的優勢在於,它賦予了 AI 團隊極大的彈性。當面對一個未知或複雜的問題時,Agent 們可以像一個真正的團隊一樣,相互協作、各司其職,最終達成目標。


程式碼實戰:協作完成一道頂級牛排套餐

接下來,我們將模擬一個頂級廚房的運作流程。一道客製化的牛排套餐,需要多位主廚協力完成。

我們的團隊成員將會是:

  • SousChefAgent (副主廚):擅長食材準備與醬汁調配。
  • GrillMasterAgent (烤台主廚):專精於火候控制,負責將牛排煎至完美熟度。
  • HeadChefAgent (行政主廚):負責掌控全局,確保每道菜都完美無瑕,並完成最終擺盤。

在這個範例中,我們將透過提示詞 (Prompt) 賦予 HeadChefAgent 協調與總結的能力,並在主程式中模擬他的指揮邏輯。

using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
using Microsoft.SemanticKernel.Plugins.Core;
using Microsoft.SemanticKernel.Agents;
using System;
using System.Threading.Tasks;
using System.Text;
using Microsoft.SemanticKernel.Agents.Orchestration.GroupChat;
using Microsoft.SemanticKernel.Agents.Runtime.InProcess;
using System.Linq;
using System.Threading;
using Microsoft.Extensions.Configuration;
using Microsoft.SemanticKernel.Agents.Magentic;
using Microsoft.SemanticKernel.Connectors.OpenAI;

// 步驟 1: 初始化 Kernel 與 AI 服務
var config = new ConfigurationBuilder()
    .AddUserSecrets<Program>()
    .Build();
var builder = Kernel.CreateBuilder()
    .AddOpenAIChatCompletion(
        modelId: "gpt-5-nano",
        apiKey: config["OpenAI:ApiKey"]!);

var kernel = builder.Build();

// 步驟 2: 建立專家主廚 Agents
var sousChefAgent = new ChatCompletionAgent
{
    Kernel = kernel,
    Instructions = "你是一位經驗豐富的副主廚。你的任務是根據客人的喜好,提出一種獨特的牛排醬汁配方,並描述製作方法。",
    Description = "副主廚"
};

var grillMasterAgent = new ChatCompletionAgent
{
    Kernel = kernel,
    Instructions = "你是一位專業的烤台主廚。你的任務是根據客人對牛排熟度的要求,描述將牛排煎至完美熟度的步驟與技巧。",
    Description = "烤台主廚"
};

// 步驟 3: 建立 Head Chef Agent (透過提示詞賦予其指揮能力)
var headChefAgent = new ChatCompletionAgent
{
    Kernel = kernel,
    Instructions = "你是一位米其林三星級行政主廚。你的任務是協調團隊成員(副主廚和烤台主廚),將他們的成果整合成一道完整、精緻擺盤的客製化牛排套餐介紹。套餐介紹需包含醬汁、牛排熟度與擺盤說明。",
    Description = "行政主廚"
};
ChatHistory history = [];
InProcessRuntime runtime = new();
await runtime.StartAsync();

// 步驟 4: 執行 Magentic Orchestration
StandardMagenticManager manager =
           new(kernel.GetRequiredService<IChatCompletionService>(), new OpenAIPromptExecutionSettings())
           {
               MaximumInvocationCount = 5,
           };
MagenticOrchestration orchestration =
    new(manager, sousChefAgent, grillMasterAgent, headChefAgent)
    {
        ResponseCallback = (response) =>
        {
            history.Add(response);
            return ValueTask.CompletedTask;
        }
    };
var customerOrder = "我想要一份三分熟(medium rare)的菲力牛排,希望醬汁能帶點辛辣,並且擺盤要非常漂亮。";
Console.WriteLine($"[客人點餐]: {customerOrder}");
Console.WriteLine("[行政主廚]: 收到!馬上開始處理。");

// 行政主廚將任務拆解並指派給副主廚
Console.WriteLine($"[行政主廚]: 副主廚,請根據客人的喜好,準備一份辛辣醬汁的配方。");
var sousChefResult = await orchestration.InvokeAsync(customerOrder, runtime);
string sousChefOutput = await sousChefResult.GetValueAsync(TimeSpan.FromSeconds(180));
Console.WriteLine($"[副主廚產出]: \n{sousChefOutput}");

// 行政主廚將客人的要求和副主廚的結果傳給烤台主廚
Console.WriteLine($"[行政主廚]: 烤台主廚,這份牛排要三分熟,請處理。");
var grillMasterPrompt = $"這是客人的點餐需求:{customerOrder}。請描述如何將牛排煎至完美。";
var grillMasterResult = await orchestration.InvokeAsync(grillMasterPrompt, runtime);
string grillMasterOutput = await grillMasterResult.GetValueAsync(TimeSpan.FromSeconds(180));
Console.WriteLine($"[烤台主廚產出]: \n{grillMasterOutput}");

// 行政主廚整合最終報告,完成擺盤
Console.WriteLine($"[行政主廚]: 準備擺盤,整合最終介紹...");
var finalPrompt = new StringBuilder();
finalPrompt.AppendLine("這是副主廚和烤台主廚的成果,請將它們整合成一份完整的套餐介紹文案。");
finalPrompt.AppendLine("--- 醬汁配方 ---");
finalPrompt.AppendLine(sousChefOutput);
finalPrompt.AppendLine("--- 牛排熟度 ---");
finalPrompt.AppendLine(grillMasterOutput);

var finalMealDescription = await orchestration.InvokeAsync(finalPrompt.ToString(), runtime);

Console.WriteLine("\n--- 完美上菜:客製化牛排套餐 ---");
Console.WriteLine(await finalMealDescription.GetValueAsync(TimeSpan.FromSeconds(180)));

await runtime.RunUntilIdleAsync();

foreach (ChatMessageContent message in history)
{
    Console.WriteLine($"{message.Role} {message.AuthorName}: {message.Content}");
}

程式碼解析:

  • 我們建立了三個不同的 ChatCompletionAgent,每個都擁有明確的職責(instructions)。
  • 雖然程式碼中是我們手動將一個 Agent 的輸出當作另一個 Agent 的輸入,但這正是在模擬 Magentic Manager 的核心邏輯:由一個協調者來決定任務的順序和數據的流向
  • 關鍵概念: ChatHistoryAgentThread 在這裡扮演了關鍵角色。我們將它與 managerAgent 綁定,但當我們需要呼叫 researcherAgentdeveloperAgent 時,我們仍然在同一個 thread 上進行。這保證了所有的對話和產出都累積在同一個歷史紀錄中,讓 managerAgent 在最後整合時能看到完整的上下文。

系列總結與預告

Magentic Orchestration 的力量在於其靈活性和高階抽象。它讓我們能夠將 AI 應用從單一任務執行器,提升為一個能夠自主思考、分工協作的「智慧團隊」。這場由 AI 經理人指揮的大腦會議,將為企業級複雜應用的開發帶來無限可能。

明天,我們將跳出 Semantic Kernel 的框架,探討 Agent 如何擁有**「長期記憶」**的能力,並介紹如何整合 Mem0 這個外部記憶層。讓我們一起解鎖 Agent 的記憶力,讓他們能更懂你的心!


完整程式碼範例


上一篇
Day 21: 循序漸進:Sequential & Handoff Orchestration
下一篇
Day 23: 為 Agent 裝上長期記憶:整合 Mem0
系列文
AI 全餐,好吃嗎?用 Semantic Kernel 打造你的客製化滿漢全席!24
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言