iT邦幫忙

2026 iThome 鐵人賽

DAY 23
0

Day 22 處理完 memory poisoning 後,我準備把 Helpdesk Agent 拆成多個角色。直覺上,一個查 VPN、另一個查 Wi-Fi,兩邊同時工作應該會更快。

問題是,多一個 Agent,也會多一份 prompt、context、模型呼叫與失敗狀態。這篇先做最小的 orchestrator-workers 實驗:兩個 worker 並行呼叫真實模型,其中一路在回傳後注入下游故障,看看另一個結果會不會一起消失。

今天真正呼叫 LLM 的位置

使用者 Prompt
  → fan-out policy:只允許兩個已註冊 worker
  ├─ vpn_specialist  → Live LLM
  └─ wifi_specialist → Live LLM → 測試故障注入
  → result collector
  → 只回傳通過檢查的 worker 結果

兩個 worker 使用同一個模型端點,但 system prompt 與責任範圍不同。它們目前沒有寫入工具,也不是能長時間自主執行的完整 Agent。這是縮小過的 orchestration security experiment,目的是看清楚 worker 數量、責任歸屬與失敗傳播。

先問:這個任務真的需要 Multi-Agent 嗎?

LangChain 的 Multi-agent 文件直接提醒,不是每個複雜任務都需要多 Agent;一個 Agent 搭配適當工具與動態 context,常常就能完成同樣工作。官方列出的主要理由是 context 管理、分散開發與平行處理。LangChain:Multi-agent

Anthropic 的 agent engineering 文章也建議先找最簡單的解法,只有在成效值得額外延遲與成本時才增加複雜度。Anthropic:Building effective agents

對這個 Helpdesk 範例來說,如果只是查一份 VPN SOP,單一 Agent 已經足夠。當問題同時跨 VPN 與 Wi-Fi,而且兩個方向可以獨立分析,worker 才有平行執行的理由。

比較項目 Single-agent 兩個 worker
模型呼叫 1 次 2 次
Context 同一份 context 每個 worker 各拿縮小後的 context
失敗狀態 一條路徑 每個 worker 都可能各自失敗
責任歸屬 較容易追蹤 必須記錄 worker、輸入、輸出與彙總者

並行縮短等待,不會把成本變成一半

Day 23 使用 ThreadPoolExecutor 同時送出兩個模型請求。等待時間可以重疊,但模型服務仍然處理了兩份 prompt,也產生兩份 output。

因此 trace 會留下:

vpn_specialist   requested
wifi_specialist  requested
vpn_specialist   completed
wifi_specialist  completed
model_call_count 2_calls

LangChain 的比較也把 model calls 與 tokens processed 分開計算。平行模式可能降低牆鐘時間,卻不會自動降低 token 使用量。LangChain:Multi-agent performance comparison

我把責任切到 Agent ID,而不是只留一段總答案

如果最後只保存一段合併文字,出錯時很難知道是哪個 worker 產生的。因此每個模型事件都以 worker ID 命名,collector 也只接受已註冊 worker 的結果。

Day 23 的責任分工很窄:

  • vpn_specialist:只能提供 VPN 排障建議。
  • wifi_specialist:只能提供 Wi-Fi 排障建議。
  • orchestration policy:限制 worker allowlist 與 fan-out 數量。
  • result collector:保留成功結果,隔離失敗結果。

這裡沒有任何一個 worker 能建立工單、修改帳號或把權限轉交給別人。多 Agent 不代表每個 Agent 都要拿到完整工具箱。

我故意讓 Wi-Fi worker 在完成後失敗

我沒有等待真實服務剛好故障。兩個 worker 都完成模型呼叫後,程式會對 Wi-Fi 路徑注入一個清楚標示的 mock downstream failure:

wifi_dependency failed
failure_propagation contained

故障發生在模型已回覆之後,所以 Wi-Fi 那次模型成本已經產生。collector 不採用它的結果,也不會因此刪除 VPN worker 已完成的內容。

這個設計測的是 failure isolation,不是宣稱模型本身失敗。若兩個 worker 都失敗,整次執行才會安全停止;只失敗一個時,回覆必須標示 partial result,不能把缺少的部分說成成功。

image

這還不是完整的自主 Multi-Agent

這個實驗有意保留三個限制:worker 沒有寫入工具、沒有共享長期記憶,彙總也由確定性程式完成。它比較接近最小 orchestrator-workers workflow,不是兩個 Agent 自由討論到得出答案。

這樣比較適合現在的目的。我先確認安全邊界能處理額外模型呼叫與部分失敗,再決定是否值得加入 worker tools、共享 state 或更長的 loop。

重要程式碼

fan-out policy 先拒絕未知、重複或超過上限的 worker:

def limit_parallel_workers(requested_workers, *, max_workers=2):
    accepted = []
    decisions = []
    for worker_id in requested_workers:
        if worker_id not in KNOWN_WORKERS:
            decisions.append(
                PolicyDecision(False, "worker_allowlist", "blocked", "未知 worker")
            )
            continue
        if worker_id in accepted:
            decisions.append(
                PolicyDecision(False, "duplicate_worker", "blocked", "不得重複執行")
            )
            continue
        if len(accepted) >= max_workers:
            decisions.append(
                PolicyDecision(False, "parallel_fanout_budget", "limited", "超過上限")
            )
            continue
        accepted.append(worker_id)
    return tuple(accepted), tuple(decisions)

兩個模型請求並行執行,結果回來後再分別判定:

with ThreadPoolExecutor(max_workers=len(workers)) as executor:
    futures = {
        worker_id: executor.submit(
            model.ask,
            system_prompt=prompts[worker_id],
            user_message=user_message,
            tools=(),
        )
        for worker_id in workers
    }

successful = {
    worker_id: answer
    for worker_id, answer in answers.items()
    if worker_id not in failures
}

我怎麼驗證

單元測試會檢查未知與重複 worker 無法進入計畫、fan-out 上限固定為 2,以及 Wi-Fi 路徑失敗後仍保留 VPN 結果。Promptfoo 另外加入 multi_agent_failure_is_contained,固定檢查成功與失敗 worker 不會混在一起。Live 測試則確認兩個 worker 都真的呼叫目前設定的模型,trace 最後出現 failure_propagation contained。

下一篇會繼續追 handoff。Agent 把工作交給另一個 Agent 時,我不會讓權限跟著整包複製過去。

本日程式碼

day-23-multi-agent-failure-isolation


上一篇
Day 22|我只騙了 Agent 一次,它卻記了很久
系列文
從 LLM、Agent 到 Guardrails:30 天打造可控、安全、可驗證的 AI Agent 共 23 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言