返回資料庫
A2A

將 A2A 與既有代理框架整合:Hermes Agent 示範

最後更新:2026年7月13日

為什麼 A2A 對代理編排很重要

Agent2Agent 協定(A2A)是 Google 於 2025 年 4 月提出的開放標準,用於代理間通訊。它定義了一個 AI 代理如何發現另一個代理的能力、向它發送任務、接收串流輸出,並在任務的生命週期中追蹤狀態——全部透過 JSON-RPC 2.0 進行,且不假設雙方代理共用同一個框架、同一個模型提供者,或同一個部署拓撲。

A2A 填補了 MCP 未涵蓋的缺口。MCP 將代理連接到工具和資料來源——它是一個工具呼叫協定。A2A 則將代理連接到代理。一個需要特定能力(定價邏輯、目錄搜尋、RFQ 處理)的代理,可以將工作委派給透過 A2A 端點暴露該能力的遠端代理,以 A2A 任務的形式接收結果,然後繼續自己的工作流程。兩個協定是互補的:MCP 給代理雙手;A2A 給代理同事。

A2A 規範定義了三個核心原語:

  • Agent Card — 一個位於 /.well-known/agent-card.json 的 JSON 文件,描述代理的身分、能力、技能和服務端點。這是代理之間互相發現的方式。
  • Task — 工作單元。用戶端透過 message/send(非串流)或 message/stream(串流)發送任務。任務在狀態之間轉換:submittedworkinginput-requiredcompletedfailedcanceled
  • Artifact — 任務執行過程中產生的結構化輸出,在可用時即串流傳送給用戶端。

對於 B2B 部署而言,價值主張很明確:與其建構一個做所有事的單體代理,不如組合各自擁有一個領域的專用代理——它們透過協定協調,而非透過共享記憶體或硬編碼的函式呼叫。

整合問題

大多數既有的代理框架不支援 A2A。它們有自己的原生 API 介面、自己的任務模型、自己的串流機制。Hermes Agent(由 Nous Research 開發)在 /v1/chat/completions 暴露了一個 OpenAI 相容的 API Server,以及一個基於 run 的 SSE 串流介面,位於 /v1/runs/v1/runs/{id}/eventsOpenClawPOST /v1/responses 提供了一個 OpenResponses 相容 API。LangGraph 有自己的圖表執行模型。CrewAI 有自己的 crew 調度。

這些框架都不會為了支援 A2A 而重寫內部。它們也不應該這樣做——它們的原生 API 很好地服務了自己的生態系。問題是:它們能否在不改變自身程式碼的情況下參與 A2A 代理網路?

答案是一個橋接層——一個位於 A2A 協定和框架原生 API 之間的元件。橋接層一端實作 A2A 的 JSON-RPC 介面(Agent Card、任務生命週期、串流),另一端轉譯為框架的原生呼叫。框架不知道自己正透過 A2A 被呼叫。A2A 用戶端也不知道是哪個框架在執行任務。

本文以 Hermes Agent 為示範,走過橋接模式。同樣的模式也適用於 OpenClaw 和其他框架——唯一需要改變的只是橋接 handler。

橋接架構

此模式的一個可用參考實作是 a2a_daemon_engine——一個 A2A 協定常駐程式,以閘道模組方式運行,並將執行路由到可插拔的 handler。架構如下:

A2A Client (any agent or application)
  │
  POST /{endpoint_id}/a2a  (message/send | message/stream)
  │
  ▼
Gateway (auth, routing, SSE client management)
  │
  ▼
A2A Daemon Executor
  │
  resolve_agent(uuid) → Database lookup
  load_agent_handler()  ← data-driven, metadata-based routing
  │
  ├── HermesAgentHandler
  │     → POST /v1/runs → GET /v1/runs/{id}/events → SSE streaming
  │     → POST /v1/chat/completions (non-streaming)
  │
  └── [AnyFrameworkHandler]  ← same interface, different translation
        → framework's native API

橋接層有三層:

  1. A2A 協定層 — 處理 JSON-RPC 分派、Agent Card 服務、任務狀態機和 A2A SDK EventQueue。這與框架無關,對每個整合都相同。

  2. 閘道傳輸層 — 處理 HTTP、認證、SSE 用戶端生命週期和路由。同樣與框架無關。閘道擁有線路;橋接層擁有轉譯。

  3. 框架 handler — 唯一的框架特定程式碼。它實作一個 ask_model() 介面:接受 A2A 訊息部分和情境、呼叫框架的原生 API、將回應轉換回 A2A 訊息部分,並(在串流模式下)將 token 增量轉發到 SSE 通道。

新增一個框架只需寫一個 handler 類別。其餘的一切——協定介面、閘道分派、SSE 管理、任務持久化——都是共享基礎設施。

示範:Hermes Agent 橋接

HermesAgentHandler 是完整的範例。它將 A2A 任務語意橋接到 Hermes Agent API Server。該 handler 支援兩種執行模式:

非串流:message/send 搭配 message_response

handler 呼叫 Hermes API Server 的 POST /v1/chat/completions——OpenAI 相容端點。請求將轉換後的 A2A 訊息部分作為 chat completion 承載攜帶。Hermes 處理請求(模型推論、工具呼叫、代理推理)並回傳單一回應。handler 將回應轉換為帶有 ROLE_AGENT 的 A2A Message,並將其發送到 SDK EventQueue。

用戶端收到一個包含完整代理文字的單一 JSON-RPC 回應。沒有中間狀態事件,沒有串流區塊——請求會阻塞直到 Hermes 完成。

串流:message/send 搭配 task_executionstream: true

handler 呼叫 POST /v1/runs 建立一個 run,然後開啟一個到 GET /v1/runs/{id}/events 的 SSE 連線。Hermes 隨事件發生即串流:token 增量、推理元資料、工具呼叫/結果通知、批准請求和生命週期事件(run.created、run.completed、run.failed)。

handler 在背景執行緒中執行一個排空迴圈。每個 message.delta 事件被推送到閘道的 SSE 管理器,以即時交付給已連線的用戶端。handler 將 token 累積到單一緩衝區中。當 run.completed 到達時,累積的文字作為單一 A2A Message 發送到 SDK EventQueue,而 COMPLETED 狀態事件僅推送到 SSE。

這種雙路徑設計——SSE 用於即時區塊,SDK EventQueue 用於最終累積訊息——是對 A2A SDK v2 的一個約束的回應,如下所述。

跨代理邊界的人類介入批准

Hermes 支援人類介入批准閘——當代理需要許可才能執行敏感操作時,它會暫停並發出批准請求。橋接層將此轉譯為 A2A 的 INPUT_REQUIRED 狀態,向呼叫代理(或人類操作員)發出需要輸入的信號。回應透過 POST /v1/runs/{id}/approval 傳回,run 隨即繼續。

這正是橋接模式展現其價值之處。A2A 將 INPUT_REQUIRED 定義為一等任務狀態。Hermes 有自己的批准機制。橋接層將兩者互相映射,而呼叫代理——它本身可能是一個在不同框架上運行的 A2A 用戶端——看到的是一個標準的協定狀態轉換,而非 Hermes 特定的細節。一個代理委派鏈可以包含一個需要人類批准的步驟(採購授權、資料存取決策、報價批准),而 A2A 協定將該閘透明地跨框架邊界傳遞。

A2A 狀態映射

A2A 定義了一個任務狀態機:submittedworkinginput-required | completed | failed | canceled。每個框架有自己的事件詞彙。橋接層在兩者之間映射。

Hermes 事件到狀態的映射:

Hermes SSE Event A2A Task State Bridge Action
run.created WORKING 註冊 run_id 以支援取消
message.delta WORKING 累積 token;逐區塊發送到 SSE
reasoning.available WORKING 推理元資料——不發出 token
tool.call / tool.result WORKING 僅工具執行元資料
approval.required INPUT_REQUIRED 發出批准區塊;儲存 pending_approval
run.completed COMPLETED 設定串流事件;累積最終文字
run.failed FAILED 發出錯誤區塊;設定 FAILED 狀態
POST /v1/runs/{id}/stop CANCELED 透過 tasks/cancel 外部取消
POST /v1/runs/{id}/approval (繼續 run) 透過 operation="approval_response" 解決

這張表是橋接層的核心。每個框架整合都會產生一張等價的表——左側是框架的原生事件,右側是 A2A 狀態,中間是橋接動作。參考實作中的 HERMES_INTEGRATION.md 文件記錄了確切的 Hermes 事件格式、配置鍵和端到端流程細節。

A2A SDK v2 約束與雙路徑修正

A2A SDK v2(a2a-sdk==1.0.2)對 on_message_send 路徑施加了兩個約束,形塑了每個橋接實作:

  1. 僅允許單一 Message。 向 SDK EventQueue 發出多個 Message 物件會引發 InvalidAgentResponseError: Multiple Message objects received.
  2. 不允許 TaskStatusUpdateEvent。 狀態事件會引發 InvalidAgentResponseError: Received TaskStatusUpdateEvent in message mode.

一個天真的橋接層會為每個 token 增量發出一個 Message——自然的串流模式。SDK 會拒絕這種做法。它也會拒絕在 message/send 路徑上的狀態事件(WORKING、COMPLETED)。

修正方式是一個雙路徑輸出通道:

  • SSE(閘道管理): Token 區塊即時推送到 SSE。已連線的用戶端看到串流輸出隨事件發生。狀態事件(WORKING、COMPLETED、FAILED)也僅發送到 SSE。
  • SDK EventQueue: 串流完成後,一個包含完整回應文字的單一累積 Message 被發送到 SDK EventQueue。這就是 JSON-RPC message/send 回應所回傳的內容。

用戶端透過 SSE 獲得即時串流,並透過 SDK 獲得乾淨的單一訊息 JSON-RPC 回應。兩個通道都正常運作;都不違反 SDK 約束。此模式與框架無關——無論後端是 Hermes、OpenClaw 或任何未來的 handler,它都適用。

將同模式套用於 OpenClaw

OpenClaw 的 Gateway API 暴露了與 Hermes 不同的原生介面,但橋接模式完全相同。一個 OpenClawHandler 會實作相同的 ask_model() 介面,並將 A2A 任務語意轉譯為 OpenClaw Gateway 呼叫:

  • 非串流映射到 POST /v1/responses,A2A 訊息部分轉換為 OpenResponses 輸入項。回應被轉換回 A2A Message
  • 串流映射到 POST /v1/responses 搭配 stream: true,消耗 SSE 事件串流並將 token 增量轉發到 A2A SSE 通道。OpenResponses 串流格式使用 response.output_text.delta 作為 token 區塊,response.completed 作為完成——事件名稱不同,橋接結構相同。
  • 代理選擇使用 model 欄位(openclaw/<agentId>)或 x-openclaw-agent-id 標頭,從 A2A 代理元資料映射。
  • 對話連續性利用 OpenClaw 的 previous_response_iduser 欄位進行穩定的 session 路由,這自然地映射到 A2A 任務持久化。

OpenClaw 的狀態映射表如下:

OpenClaw Event A2A Task State Bridge Action
response.created WORKING 註冊 response ID
response.output_text.delta WORKING 累積 token;發送到 SSE
response.completed COMPLETED 累積最終文字;發出 Message
response.failed FAILED 發出錯誤;設定 FAILED

相同的欄位、相同的結構、不同的事件名稱。橋接 handler 是框架之間唯一需要改變的部分。

配置:元資料驅動路由

代理路由是元資料驅動的,而非環境變數驅動的。資料庫中的每個代理記錄在 metadata JSON 欄位中攜帶其 handler 配置。對於 Hermes 支援的代理:

{
  "module_name": "a2a_daemon_engine.handlers.a2a_hermes_handler",
  "class_name": "HermesAgentHandler",
  "hermes_api_url": "http://127.0.0.1:8642",
  "hermes_api_key": "hermes-local-key",
  "hermes_model": "hermes-agent",
  "hermes_timeout": 300.0
}

對於 OpenClaw 支援的代理,元資料會指向 OpenClaw handler:

{
  "module_name": "a2a_daemon_engine.handlers.a2a_openclaw_handler",
  "class_name": "OpenClawHandler",
  "openclaw_api_url": "http://127.0.0.1:3000",
  "openclaw_api_key": "openclaw-key",
  "openclaw_agent_id": "pricing-agent",
  "openclaw_timeout": 300.0
}

配置解析遵循一個優先順序鏈:代理元資料(DB)→ 設定字典 → Config 預設值(環境變數)。每個代理的覆寫優先於全域預設值。兩個代理可以指向不同的框架——一個指向 Hermes 處理推理密集型任務,另一個指向 OpenClaw 處理工作流程編排任務——而 A2A 協定介面對呼叫代理來說看起來完全相同。

這帶來了什麼能力

橋接模式提供了三種從零建構難以組裝的能力:

1. 帶串流的代理間委派。 A2A 用戶端代理可以向 Hermes 支援的代理發送任務,並透過 SSE 接收即時 token 串流。呼叫代理不需要知道遠端代理執行的是 Hermes——它看到的是一個帶有 Agent Card 和 JSON-RPC 介面的 A2A 端點。

2. 跨代理邊界的人類介入批准。 框架原生的批准閘(Hermes 批准請求、OpenClaw 操作員批准)映射到 A2A INPUT_REQUIRED 狀態。一個代理委派鏈可以包含一個需要人類批准的步驟,而 A2A 協定將該狀態轉換傳回原始代理或操作員——無論鏈中的每個代理執行在哪個框架上。

3. 從單一閘道進行多框架路由。 相同的閘道、相同的執行器、相同的 A2A 協定介面服務於不同框架的 handler。新增一個框架只需寫一個 handler 類別並插入一個代理記錄——不需要新的部署,不需要新的協定實作。

參考實作還支援 AWS Lambda 分派以實現無伺服器 A2A、實驗性 gRPC 傳輸與雙向串流,以及雙後端持久化(DynamoDB 或 PostgreSQL),透過複合分區鍵實現多租戶隔離。a2a_daemon_engine 儲存庫及其 Hermes 整合指南包含完整的實作、配置參考和狀態映射細節。


一家中型經銷商需要報價代理與目錄代理溝通,目錄代理再與庫存代理溝通——每個代理由不同框架支撐,每個代理由不同團隊擁有。A2A 給這些代理一個共享的協定。一個橋接層讓 Hermes Agent、OpenClaw 和任何其他框架都能參與,而無需重寫內部。a2a_daemon_engine 是該橋接模式的一個可用參考實作,以 Hermes Agent 示範。

申請一個範圍明確的建構

為期一週的發掘。您會拿到系統清單、工作流程地圖和固定範圍——無論您最終是否與我們合作開發。

想為您的系統建構這個嗎?

這裡的每份文件都來自真實的生產工作。如果您有目標系統和工作流程想法,我們可以在一週內確定範圍。

申請客製開發

為期一週的發掘階段。您會拿到系統清單、工作流程地圖和固定範圍——無論您最終是否與我們合作開發。