跳至主要內容
模組 2:多 Agent 4 / 6
中階 Session 10 Protocols FSM

團隊協定

掌握帶有 request_id 的請求-回應 FSM,實現可靠的多代理協調。

2026年3月20日 17 分鐘閱讀

你將學到什麼

當多個代理協作時,它們需要共享語言。沒有結構化協定的話,訊息會遺失、回應亂序到達,代理會浪費週期等待已經到達的回覆。團隊協定通過管理每次互動的有限狀態機(FSM)來解決這個問題。

完成後,你將了解:

  • 請求-回應 FSM 及其狀態
  • request_id 如何確保訊息關聯
  • 團隊通訊的結構化訊息格式
  • 錯誤處理:逾時、重試和回退策略

問題是什麼

想像兩個代理一起工作。代理 A 請代理 B 審查一些程式碼。代理 B 完成後發回回饋。但代理 A 已經發送了另一個請求。現在代理 B 的回應到達了 — 它回答的是哪個請求?

沒有協定的話,團隊通訊有三種失敗模式:

1. LOST MESSAGES
   Agent A sends request → Agent B never sees it → Agent A waits forever

2. MISMATCHED RESPONSES
   Agent A sends request #1, then request #2
   Agent B responds twice — which response goes with which request?

3. RACE CONDITIONS
   Both agents edit the same file without knowing
   Result: merge conflict or overwritten work

如何運作

請求-回應 FSM

每個代理對代理的互動都遵循一個有限狀態機:

                    send request
    ┌──────┐      (with request_id)     ┌──────────────┐
    │      │ ──────────────────────────▶ │              │
    │ IDLE │                             │ REQUEST_SENT │
    │      │ ◀────────┐                 │              │
    └──────┘          │                 └──────┬───────┘
       ▲              │                        │
       │              │ timeout/               │ acknowledgment
       │              │ error                  │ received
       │              │                        ▼
       │              │                 ┌──────────────┐
       │              ├──────────────── │   WAITING    │
       │              │                 └──────┬───────┘
       │              │                        │ response arrives
       │              │                        ▼
       │              │                 ┌──────────────────┐
       │              └──────────────── │ RESPONSE_RECEIVED│
       │                                └────────┬─────────┘
       │              process result             │
       └─────────────────────────────────────────┘
  • IDLE — 代理可用。可以發送或接收請求。
  • REQUEST_SENT — 訊息已派送。等待確認。
  • WAITING — 已確認。等待實際結果。
  • RESPONSE_RECEIVED — 結果到達。處理它,返回 IDLE。

FSM 確保每個請求都有一個完整的生命週期。沒有訊息同時存在於兩個狀態中。

request_id 模式

request_id 將請求與回應綁定在一起。每個請求獲得一個唯一識別碼,每個回應都回傳它:

Agent A (Implementer)              Agent B (Reviewer)
       │                                  │
       │  ┌──────────────────────────┐    │
       │  │ type: "request"          │    │
       ├─▶│ request_id: "req-0042"   │───▶│
       │  │ action: "review_code"    │    │
       │  │ payload: { file, diff }  │    │
       │  └──────────────────────────┘    │
       │                                  │
       │         ... time passes ...      │
       │                                  │
       │  ┌──────────────────────────┐    │
       │◀─│ type: "response"         │◀───│
       │  │ request_id: "req-0042"   │    │
       │  │ status: "completed"      │    │
       │  │ payload: { feedback }    │    │
       │  └──────────────────────────┘    │

即使代理 A 在此期間發送了其他請求,request_id: "req-0042" 告訴它這個回應確切地回答了哪個請求。

結構化訊息格式

每個協定訊息都遵循一致的 schema:

{
  "type": "request | response | status | broadcast",
  "from": "agent-name",
  "to": "agent-name | all",
  "request_id": "req-0042",
  "action": "review_code | run_tests | fix_issue",
  "payload": { "data": {} },
  "metadata": { "priority": "normal", "timeout_ms": 30000 }
}

四種訊息類型:

  • request — 「請做這個工作」(需要回應)
  • response — 「這是結果」(參照一個 request_id)
  • status — 「這是我的當前狀態」(資訊性,不需要回應)
  • broadcast — 「所有人都應該知道這個」(發送給所有團隊成員)

錯誤處理

協定必須處理三種失敗情境:

┌────────────────────────────────────────────────┐
│  1. TIMEOUT                                     │
│     No response in 30s → retry once → escalate  │
│                                                  │
│  2. REJECTION                                    │
│     Agent cannot handle request                  │
│     { status: "rejected", reason: "out_of_scope"}│
│     → reassign to another agent                  │
│                                                  │
│  3. PARTIAL FAILURE                              │
│     Agent completed part of the work             │
│     { status: "partial",                         │
│       completed: [...], failed: [...] }          │
│     → retry failed parts or fallback             │
└────────────────────────────────────────────────┘

當所有重試都失敗時,請求代理會嘗試自己完成工作(獨立執行),而不是無限期地阻塞。

關鍵洞見

沒有協定,團隊通訊會變得混亂。FSM 通過使每次互動都具有確定性來防止訊息遺失和競爭條件。

request_id 模式解決了分散式系統中最困難的問題:關聯性。這與 HTTP 請求-回應、資料庫交易和訊息佇列確認背後的原理相同。代理可以非同步工作而不會失去追蹤 — 實作者可以發送程式碼進行審查、繼續下一個任務,並在回饋到達時正確處理,因為 request_id 將它們綁定在一起。

實作範例

一個完整的團隊互動:實作者發送程式碼給審查者,收到回饋,修復問題。

STEP 1: Implementer sends review request
─────────────────────────────────────────
{
  type: "request", from: "implementer", to: "reviewer",
  request_id: "req-0042", action: "review_code",
  payload: {
    file: "src/auth/login.ts",
    diff: "+function validateToken(token) { ... }"
  }
}
State: IDLE → REQUEST_SENT

STEP 2: Reviewer acknowledges
─────────────────────────────────────────
{
  type: "status", from: "reviewer", to: "implementer",
  request_id: "req-0042",
  payload: { status: "acknowledged", eta_ms: 15000 }
}
State: REQUEST_SENT → WAITING

STEP 3: Reviewer sends feedback
─────────────────────────────────────────
{
  type: "response", from: "reviewer", to: "implementer",
  request_id: "req-0042", status: "completed",
  payload: {
    approved: false,
    issues: [
      { line: 12, severity: "high", message: "Token expiry not checked" },
      { line: 25, severity: "medium", message: "Missing error handling" }
    ]
  }
}
State: WAITING → RESPONSE_RECEIVED

STEP 4: Implementer processes, returns to IDLE
─────────────────────────────────────────
Reads issues, applies fixes, sends new request (req-0043) for re-review.
State: RESPONSE_RECEIVED → IDLE

每個步驟都有明確的狀態轉換。實作者永遠不需要猜測審查者是否收到了請求,或者回饋指的是什麼。

協定設計原則

DO:  Specific actions ("review_code", "run_tests", "fix_lint")
     Enough context in payload for standalone execution
     Realistic timeouts based on expected work duration

DON'T: Generic actions ("do_work") — too ambiguous
       Large file contents when a path suffices
       Timeouts too short — causes unnecessary retries

前後對比

沒有團隊協定有團隊協定
訊息沒有結構每條訊息遵循 schema
無法將回應匹配到請求request_id 提供關聯性
代理阻塞等待回覆FSM 追蹤狀態,實現非同步工作
失敗導致靜默掛起逾時和重試處理錯誤
競爭條件破壞狀態確定性的狀態轉換

下一堂課

第 11 堂課涵蓋自主代理 — 代理如何在 WORK 和 IDLE 階段之間轉換、從共享佇列自動認領任務、以及在無需人工介入監督的情況下獨立運作。