AI Agent 是怎麼溝通的?設計了一堆 Agent,打算怎麼讓它們溝通 — 全部都 spawn sub-agent?還是一個 session 一個,然後讓它們彼此交換資訊?
Claude Code 的做法其實意外簡單,直接寫檔案、讀檔案、加個鎖 🫠
用 sub-agent 的時候,最常見的模式就是:parent 把 prompt 丟給 child,child 做完回傳結果。這就是 OS 裡的 pipe — stdin 進、stdout 出,單向、parent-child only。
很直覺。但很快會碰到瓶頸 — 如果兩個 agent 需要橫向溝通?除了 pipe,實務上還有什麼作法?
研究了三個系統怎麼設計 Agent Communication
- Claude Code Agent Teams(以下根據逆向分析和社群開源重製觀察)— 每個 teammate 是獨立的 CLI process,透過 tmux pane spawn。溝通方式是寫 JSON 到
~/.claude/teams/{team}/inboxes/{agent}.json。對,檔案系統當 message bus。寫入用flock()做互斥鎖,讀取用 polling - OpenClaw — Gateway process(Node.js + WebSocket)當中央樞紐,agent 透過
sessions_send做跨 session 溝通。還有 reply-back loop 讓兩個 agent 自動多輪對話 - A2A Protocol — Google 推的,現在歸 Linux Foundation。每個 agent 透過
/.well-known/agent-card.json公開 Agent Card 做 discovery。A2A 支援多種 HTTP(S) binding,常見的是 JSON-RPC 2.0 + SSE,也支援 webhook / push notifications
三個底層都是 structured text serialization — 差異在 transport 跟 topology。
這整件事就是作業系統的 IPC 問題
以前作業系統學的 process、thread、IPC、flock、shared memory、message queue — 全部在 agent 系統裡重演了一遍:
- Process → Agent
- OS → Harness(Claude Code / OpenClaw)
fork()+exec()→ spawn sub-agent- pipe → stdin/stdout(sub-agent 溝通)
- file +
flock()→ filesystem mailbox(Agent Teams) - TCP socket → WebSocket(OpenClaw Gateway)
- HTTP/RPC → JSON-RPC(A2A protocol)
- shared memory → shared message pool(如 MetaGPT 的設計)
- signal → hook events(TeammateIdle)
- process state → task lifecycle(pending → working → completed)
- permission 繼承 → teammate 繼承 lead 的 permission mode
- context switch → compaction + session summary
連經典問題都一模一樣:
- Scheduling — 誰跑下一個?Claude Teams 用 self-claim(agent 去 task queue 搶,lowest-ID-first);OpenClaw 用 Gateway routing。對應 cooperative vs preemptive scheduling
- Context switch — OS 要保存 register state;agent 的 context switch 就是 compaction + session summary。每次被喚醒要從 mailbox 讀訊息重建 context — 這就是 agent 世界的 TLB miss
- Memory isolation vs sharing — 什麼放 shared memory、什麼 process-local?= 哪類 memory 該跨 agent 共享?Claude Teams 全 isolated 只透過 mailbox 傳 summary;MetaGPT 的 semantic 層 shared(message pool)
- Permission — Claude Teams 比較像 permission mode inheritance:teammate 繼承 lead 的 permission mode;OpenClaw 有 role/scope/cap/permission 組合的細粒度權限模型
像 network stack 一樣分層來看
把這個類比推到底,agent 溝通的 protocol 層級也跟 network stack 一樣可以分層來看(這是我理解的模型,開發方便思考用):
- L4 應用層 — OS: HTTP/gRPC → Agent: A2A / ACP(跨組織 agent 互通)
- L3 傳輸層 — OS: TCP/IP → Agent: JSON-RPC over HTTP + SSE
- L2 系統層 — OS: IPC → Agent: mailbox / sessions_send / stdin
- L1 核心層 — OS: process+memory → Agent: LLM session + context window
- L0 硬體層 — OS: CPU+RAM → Agent: model inference + token budget
A2A 活在 L4,Claude Teams mailbox 活在 L2 — 它們不衝突,解決的問題完全不同。
順便釐清一個很多人搞混的東西 — MCP vs A2A:
- MCP = agent-to-tool(垂直整合)— 讓 agent 呼叫外部資料庫、API = system call
- A2A = agent-to-agent(水平整合)— 讓 agent 跟另一個 agent 談判 = 跨 process 溝通
兩者互補不衝突。A2A 官方 spec 直接說這是 complementary protocols。
整理出一個五層決策模型
設計 agent 溝通的時候,由下往上逐層決定,前一層的選擇會 constrain 後一層的選項:
Layer 0 — Environment(agent 在哪?)
- Same process → function call 就夠(Smolagents / LangGraph)
- Same machine → file 或 unix socket(Claude Code)
- Same network → WebSocket 或 HTTP(OpenClaw)
- Open internet → 必須 HTTP + 認證(A2A)
OS 類比:「process 在同一台機器上還是跨網路」— 直接決定能用哪些 IPC。這層通常不是自己選的,是被 harness 給定的。
Layer 1 — Transport(怎麼傳?)
- pipe(stdin/stdout)→ parent-child 委派,零設定
- file +
flock()→ 任意拓撲、持久化、好 debug - WebSocket → 雙向、持久連線、需 server
- HTTP → stateless、跨網路、最通用
越往左延遲越低耦合越高,越往右越獨立但越慢。跟 OS 選 IPC 機制的 tradeoff curve 一模一樣。
Claude Teams 選 file 是因為精準判斷了自己的 environment — 所有 agent 保證在 same machine,file I/O 比任何 message queue 都好 debug。直接 cat 那個 inbox 就能看發生什麼事。
Layer 2 — Topology(誰跟誰講?)
- Hierarchy → parent 完全控制(sub-agent)
- Star → 中央協調(OpenClaw Gateway)
- Peer → 橫向交換、無瓶頸(A2A)
- Pub/Sub → 多對多、事件驅動(如 MetaGPT message pool)
transport 跟 topology 是解耦的。WebSocket 不必然是 star,HTTP 不必然是 P2P — 選 star 常出於營運簡化(不用每個 agent 各自開 port),不是技術限制。pipe 通常被 OS 結構用為 hierarchy(parent-child, named pipe)。
Layer 3 — Protocol(什麼格式?)
定義三件事:
- Message envelope — sender、recipient、timestamp、message ID
- Interaction pattern — fire-and-forget / request-response / streaming / conversation(多輪)
- Task lifecycle — 狀態機(submitted → working → input-required → completed / failed)
Protocol 的複雜度跟環境不確定性成正比 — 內部用薄 protocol(Claude Teams 就是 JSON-in-JSON),對外用厚 protocol(A2A 有完整的 JSON-RPC 2.0 + OAuth 2.0)。
Layer 4 — Content Contract(傳什麼?)
前四層只是把 bytes 送到。這層決定對方能不能用。Agent 之間傳的不是隨便一段文字,是經過 memory selection 和 compression 的結構化內容。可以有完美的 transport,但 agent A 傳了一大坨 raw context dump,agent B 的 context window 直接爆掉,溝通就失敗了。
Content Contract 才是 agent 溝通成敗的真正關鍵 — 也是目前所有系統做得最狂野的一層。
附上三大實作的完整對照
Claude Teams vs OpenClaw vs A2A:
- Environment — same machine / same server / open internet
- Transport — file I/O / WebSocket / HTTP
- Topology — star+peer / hub / peer
- Envelope — JSON-in-JSON / tool params / JSON-RPC 2.0
- Discovery — config.json / session key / Agent Card(well-known URL)
- Task 狀態 — 3 狀態 / async+callback / 完整狀態機
- Streaming — ✗ / reply-back loop / SSE + webhook
- 權限控制 — 繼承 lead / role+scope+cap / OAuth 2.0 + Bearer
Agent Communication 決策模型
- Agent 跑在哪?(決定 transport 選項)
- 怎麼傳?(IPC 機制)
- 誰跟誰?(topology)
- 什麼格式?(protocol 薄厚度)
- 傳什麼?(content contract — 最難的一層)
1-4 是協定、5 是內容。
