跳到主要內容

Routing Pattern 深入比較:LLM 分類 + RunnableBranch vs Coordinator + Sub-Agent

閱讀時間約 8 分鐘

什麼是 Routing Pattern?

Routing(路由)是 Agentic Design Patterns 中最基礎的分流機制:根據輸入內容,動態決定要走哪條處理路徑。

輸入
  ↓
[Router:判斷類型]
  ↓           ↓           ↓
[路徑 A]   [路徑 B]   [路徑 C]

實作上有兩種主流做法,本文深入比較它們的差異。


做法一:LLM 分類 + RunnableBranch(LangGraph)

運作流程

使用者輸入
    ↓
[Coordinator LLM:輸出 'booker' / 'info' / 'unclear']
    ↓
[RunnableBranch:依關鍵字執行對應 handler]

核心程式碼

coordinator_router_prompt = ChatPromptTemplate.from_messages([
    ("system", """分析使用者請求,決定要委派給哪個 handler。
     - 訂房/訂機票 → 輸出 'booker'
     - 其他問題 → 輸出 'info'
     只輸出一個詞。"""),
    ("user", "{request}")
])

delegation_branch = RunnableBranch(
    (lambda x: x['decision'].strip() == 'booker', booking_handler),
    (lambda x: x['decision'].strip() == 'info', info_handler),
    unclear_handler  # 預設路徑
)

特性

  • 你寫規則:路由邏輯由你在 Prompt 中明確定義
  • 輸出可預期:LLM 只回一個關鍵字,程式碼依此分支
  • 透明可調試:每次決策的關鍵字都可以 log 下來

做法二:Coordinator + Sub-Agent Auto-Flow(Google ADK)

運作流程

使用者輸入
    ↓
[Coordinator:有明確的委派規則 instruction]
    ↓  (LLM 同時參考 Coordinator 指令 + 各 Sub-Agent 描述)
[Sub-Agent A / Sub-Agent B / ...]

核心程式碼

booking_agent = Agent(
    name="Booker",
    description="處理所有訂房、訂機票的請求"  # ← LLM 路由的依據
)

info_agent = Agent(
    name="Info",
    description="回答一般資訊與知識性問題"
)

coordinator = Agent(
    instruction=(
        "你是主協調者。分析請求後委派給專門 agent,不要自己直接回答。"
        "訂房訂機票 → Booker;其他問題 → Info"
    ),
    sub_agents=[booking_agent, info_agent]  # ← 框架自動啟用 Auto-Flow
)

特性

  • LLM 判斷:框架把 Coordinator 指令 + Sub-Agent 描述一起交給 LLM
  • 彈性擴充:新增 Sub-Agent 只需定義 description,不用改分支邏輯
  • 適合複雜情境:LLM 能理解模糊請求的意圖

直接比較

面向LLM 分類 + RunnableBranchCoordinator + Sub-Agent
路由邏輯由誰定義開發者寫在 PromptLLM 綜合判斷
模糊請求的處理依 Prompt 品質而定較強,有 description 輔助
新增路徑的成本需改 Prompt + 加分支只需加一個 Sub-Agent
透明度高(可 log 關鍵字)低(決策在 LLM 內部)
適合場景分類明確、規則固定情境多樣、Agent 種類多

案例對比

案例一:「幫我安排去東京的行程」

LLM 分類 + RunnableBranch

  • 模糊!「安排行程」可能是訂房,也可能是問景點
  • 如果 Prompt 沒有涵蓋這個邊界案例,可能分類錯誤

Coordinator + Sub-Agent

  • Booker 的 description 是「訂房訂機票」
  • Info 的 description 是「一般資訊」
  • LLM 可以根據意圖更彈性地判斷與委派

案例二:「退款我的訂單 #12345」

LLM 分類 + RunnableBranch

  • 只要 Prompt 有定義「退款 → refund handler」,判斷準確
  • 明確案例表現與 Sub-Agent 相當

Coordinator + Sub-Agent

  • RefundAgent 的 description 清楚說明職責
  • 準確委派,但多了一層 LLM 呼叫的開銷

案例三:新增「投訴處理」路徑

LLM 分類 + RunnableBranch

# 要改三個地方:Prompt、branches dict、RunnableBranch 條件
branches["complaint"] = complaint_handler

Coordinator + Sub-Agent

# 只需加一個 Agent
complaint_agent = Agent(name="Complaint", description="處理客戶投訴")
coordinator = Agent(sub_agents=[..., complaint_agent])  # 加進去就好

選用建議

✅ 選 LLM 分類 + RunnableBranch,當:
   - 分類情境明確、邊界清楚
   - 需要高透明度(audit log)
   - 不想依賴特定 Agent 框架

✅ 選 Coordinator + Sub-Agent,當:
   - Agent 種類多且持續增加
   - 使用者輸入多樣、情境複雜
   - 使用 Google ADK 等支援 Auto-Flow 的框架

結語

兩種做法都是合法的 Routing Pattern 實作,沒有絕對的優劣。核心差異在於誰負責路由邏輯:你(開發者)還是 LLM。

隨著 Agent 系統規模增長,Coordinator + Sub-Agent 的擴充彈性通常更有優勢;但在規則明確、需要精準控制的場景,LLM 分類 + RunnableBranch 的透明度反而是優點。

選對工具,而不是選「更新」的工具。

回應

0 / 1000

還沒有回應,成為第一個留言的人吧。