Agent Orchestration
Agent 編排設計,涵蓋 Tool Loop、多 Agent 協作、System Prompt 設計,以及錯誤恢復機制。
設計問題
用戶說:「幫我查一下 John 上週寄的那封關於合約的信,然後把裡面的截止日期加到我的行事曆。」
這不是一個 API 呼叫能搞定的事。Agent 需要:
- 搜尋 email(可能要嘗試不同的關鍵字)
- 篩選結果,找到正確的信
- 讀取完整內容,提取截止日期
- 呼叫行事曆 API 建立事件(需要用戶確認)
每一步的結果決定下一步怎麼做。這就是 Agent 編排的問題。
核心問題:如何設計一個 Agent 系統,讓 LLM 能安全、高效地完成多步驟任務?
工具循環(Tool Loop)
基本模式
Agent 的核心是一個 Think → Act → Observe 循環:
While (未完成 AND 步數未超限):
1. Think: LLM 根據上下文決定下一步
→ 直接回答(結束)
→ 呼叫某個工具
2. Act: 執行工具,取得結果
3. Observe: 把工具結果加入上下文
4. 回到 Think每一輪循環,LLM 都能看到之前所有工具呼叫的結果,基於這些資訊做出下一個決定。
停止條件
停止條件:stepCountIs(10)為什麼需要限制步數?
- 成本控制:每一步都消耗 token。10 步大約是 $0.01-0.05
- 防止無限循環:LLM 偶爾會陷入重複嘗試的死循環
- 延遲控制:每步 1-3 秒,10 步就是 10-30 秒
- 實務觀察:絕大多數任務在 3-5 步內就能完成
超過步數限制怎麼辦?
Agent 在步數耗盡時會被迫生成一個回應。它可能會說:「我找到了一些線索但需要更多資訊。你能告訴我...嗎?」這比無限循環好得多。
工具設計
工具的結構
每個工具需要定義:
Tool {
name: string ← 工具名稱
description: string ← 何時使用這個工具(給 LLM 看)
inputSchema: ZodSchema ← 參數的型別定義
execute: (input) → output ← 實際執行的函式
}description 是最關鍵的部分
它決定了 LLM 何時選擇使用這個工具。
壞的 description:
"Search emails"好的 description:
"Search emails using both keyword and semantic search.
Returns metadata with snippets only — use getEmails tool
to fetch full content of specific emails."好的 description 告訴 LLM:
- 這個工具做什麼
- 它返回什麼(snippet,不是全文)
- 下一步該做什麼(用 getEmails 取全文)
工具集的合併
Agent 同時擁有多種來源的工具:
最終工具集 = 內建工具(email 搜尋等)+ MCP 工具(Calendar、Tasks)合併時需要注意命名衝突。如果兩個來源都有一個叫 search 的工具,就需要重命名或建立命名空間。
多 Agent 協作
為什麼不只用一個 Agent?
考慮 HITL 流程。如果主 Agent 先搜尋了 5 分鐘 email,最後才決定要建立行事曆事件,這時候暫停等用戶確認,前面的搜尋工作就白費了(因為用戶可能拒絕,導致整個請求重來)。
更好的做法:先快速判斷是否需要 HITL,再開始主要工作。
Approval Agent(HITL 前置判斷)
主流程:
1. Approval Agent(1 步)→ 需要 HITL 嗎?
YES → 立即送出確認請求 → 結束請求
NO → 繼續
2. 執行已批准的工具(如果有)
3. Main Agent(≤10 步)→ 完成任務Approval Agent 的設計:
角色:HITL 規劃者
工具:只有需要人工介入的 MCP 工具(被 HITL 包裝過的版本)
步數限制:1 步
規則:
- 如果需要外部工具 → 呼叫(觸發 ApprovalRequiredError)
- 如果不需要 → 返回 "NO_TOOL"
- 不要回答用戶的問題
- 不要解釋推理過程為什麼限制 1 步?它的任務很簡單,只要判斷「這個請求是否涉及外部操作」即可。一步就夠了。
Agent 間的資料流
System Prompt 設計
工具選擇策略
在 system prompt 中明確指引 Agent 何時使用什麼工具:
工具選擇規則:
- Email 相關 → search / filterEmails / getEmails
- 行事曆相關 → findCalendarEvents / MCP tools
- 任務相關 → MCP tools
- 一般問答 → 不用工具,直接回答為什麼要明確指引?
LLM 有時候會「過度使用」工具(明明可以直接回答卻去搜尋),或「使用錯誤」的工具(該用語意搜尋卻用了精確篩選)。明確的規則減少這些錯誤。
工作流指引
告訴 Agent 具體的工作流程,而非讓它自己摸索:
Email 搜尋的三步工作流:
STEP 1 - 瀏覽:
USE 'filterEmails' when: 條件明確(特定人、日期、關鍵字)
USE 'search' when: 語意搜尋(概念、問題、主題)
STEP 2 - 審查:
看 snippet 是否足夠回答
判斷哪些需要全文
STEP 3 - 深入:
USE 'getEmails' 取需要的全文這像是給新員工的操作手冊。它不是在限制能力,而是用經過驗證的流程提高效率。
動態 System Prompt
System prompt 不是靜態的。它根據可用的工具動態調整:
if calendarToolAvailable:
→ 正常的行事曆指引
else:
→ "Calendar integration is not configured.
If the user asks, explain it's unavailable."這避免了 Agent 嘗試呼叫不存在的工具,或對用戶做出無法兌現的承諾。
錯誤恢復
工具執行失敗
工具可能因為各種原因失敗(API 超時、資料格式錯誤等)。Agent 應該能看到錯誤並調整策略。
工具的失敗會作為 output-error 狀態返回:
Tool result: { state: "output-error", errorText: "API timeout" }Agent 看到這個後可能:
- 重試(用不同的參數)
- 換一個工具
- 告訴用戶「暫時無法查詢」
ApprovalRequiredError
這不是真正的「錯誤」,而是一個控制流信號:
HITL 包裝的工具被呼叫
→ 不執行真正的邏輯
→ 記錄工具名稱和參數
→ 拋出 ApprovalRequiredError
→ 被上層捕獲
→ 轉為確認請求串流給前端用 Error 作為控制流有爭議,但在這個場景中很合適,因為它利用了 Agent 框架的錯誤處理管道,不需要額外的中斷機制。
生產考量
可觀測性
Agent 的多步驟執行很難調試。你需要能看到:
- 每一步 Agent 的思考過程
- 每個工具呼叫的輸入和輸出
- 每步的 token 消耗
- 總的延遲分佈
工具如 Langfuse、LangSmith、OpenTelemetry 可以提供這種可視性。
成本控制
- Per-step cost cap:如果單次呼叫超過 X token,警告或終止
- Per-conversation cap:整個對話的總 token 不超過 Y
- Rate limiting:每用戶每分鐘 / 每天的請求限制
Agent 評估
評估 Agent 的品質比評估普通 LLM 更難,因為涉及工具選擇和多步驟推理:
- 端到端評估:給定問題,Agent 最終的答案是否正確
- 工具選擇評估:Agent 是否選了對的工具
- 效率評估:Agent 用了幾步完成任務(越少越好)
- 失敗模式分析:Agent 在什麼類型的問題上出錯
重點總結
| 設計決策 | 選擇 | 原因 |
|---|---|---|
| 循環模式 | Think → Act → Observe | 標準的 Agent 架構 |
| 步數限制 | 10 步 | 平衡能力和成本 |
| 多 Agent | Approval + Main | 前置 HITL 判斷,避免浪費 |
| 工具指引 | System prompt 中明確規則 | 減少工具選擇錯誤 |
| 錯誤恢復 | Agent 自己看到錯誤並調整 | 利用 LLM 的靈活性 |
| 動態 prompt | 根據可用工具調整 | 避免幻覺 |
Last updated on