團隊協定
掌握帶有 request_id 的請求-回應 FSM,實現可靠的多代理協調。
你將學到什麼
當多個代理協作時,它們需要共享語言。沒有結構化協定的話,訊息會遺失、回應亂序到達,代理會浪費週期等待已經到達的回覆。團隊協定通過管理每次互動的有限狀態機(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 階段之間轉換、從共享佇列自動認領任務、以及在無需人工介入監督的情況下獨立運作。