A2A 協定

最後更新: 2026-03-18 19:10:43 +0800 +0800
原文以英文撰寫。您正在閱讀AI翻譯版本。

又在重新發明 MCP。

Agent2Agent Protocol(簡稱 A2A)是一種用於獨立 AI agent 應用程式之間通訊的開放協定。它讓一個 agent 能夠探索另一個 agent 的能力、交付工作、持續多輪互動、追蹤長時間執行的工作,並在不知道遠端 agent 如何實作的情況下接收結構化結果。

A2A 由 Google 發起,之後捐贈給 Linux Foundation。它不受框架、模型、語言或供應商限制。使用 Java 建置的 A2A 用戶端,可以與使用不同模型及 agent 框架、以 Python 建置的遠端 agent 協作。

重要的邊界如下:

text
Agent A 知道 Agent B 提供什麼,以及如何與其通訊。
Agent A 不需要知道 Agent B 的提示、記憶、工具、模型或原始碼。

本文說明已發布的 A2A v1.0 資料模型。規格仍在演進,因此正式環境實作應協商並驗證遠端 Agent Card 宣告的協定版本。

A2A 解決的問題 #

假設一般助理必須安排商務旅行。它可能需要與下列 agent 協作:

  • 航班 agent;
  • 飯店 agent;
  • 雇主差旅政策 agent;
  • 地面交通 agent;以及
  • 費用管理 agent。

沒有共用協定時,每一對系統都需要自訂整合:

text
協調器 -> 航空公司供應商的私有 API
協調器 -> 飯店供應商的私有 API
協調器 -> 政策 agent 的自訂 WebSocket
協調器 -> 費用 agent 的訊息佇列

每個整合都必須自行發明:

  • 能力描述;
  • 請求與回應結構描述;
  • 驗證中繼資料;
  • 進度事件;
  • 取消行為;
  • 檔案處理;
  • 對話識別碼;
  • 長時間執行工作的模型;以及
  • 錯誤表示方式。

隨著獨立開發的 agent 數量增加,這些點對點介面卡的建置與治理成本會變高。

當遠端操作具有決定性且完整指定時,傳統 REST API 可以解決部分問題。但 agent 互動通常不那麼僵化:

text
用戶端:請依照公司政策安排差旅。
Agent:我需要員工 ID 與偏好的出發時間範圍。
用戶端:員工 E-1042,18:00 之後。
Agent:唯一符合政策的航班會在飯店入住時間之後抵達。可以申請例外嗎?
用戶端:可以;準備例外申請,但不要購買任何東西。

工作具有狀態,可能需要釐清或授權,可能持續很長時間,也可能產生多個持續演進的成品。A2A 將這種互動外框標準化,同時將領域推理留給各個 agent。

從整合矩陣到單一協定 #

如果每個 agent 都有專屬介面,連接 \(N\) 個 agent 可能需要接近 \(N \times (N - 1)\) 個有方向的整合。使用 A2A 後,每個實作都以共用協定為目標:

text
Agent A --\
Agent B ----> A2A 資料模型與操作
Agent C --/

這不會消除領域差異。航班預訂技能與安全性檢閱技能仍會接受不同資訊。A2A 標準化的是能力的宣告方式,以及工作、狀態、內容和結果的交換方式。

A2A 不是什麼 #

A2A 是:

  • agent 應用程式之間的線路協定與互動模型;
  • 適用於跨越程序、框架、團隊和組織邊界的情境;以及
  • 為不透明且可能長時間執行的 agent 所設計。

A2A 不是:

  • LLM;
  • agent 框架;
  • 協調演算法;
  • 提示格式;
  • 工作流程引擎;
  • 模型路由系統;
  • 身分提供者;
  • 註冊表 API 標準;
  • 保證已宣告的 agent 值得信任;或
  • 定義良好的普通 API 的替代品。

如果遠端能力只是一個 getExchangeRate(from, to),普通 API 或工具協定可能更清楚。當遠端對象是能夠推理、協商、維護工作狀態、要求更多資訊並回傳複雜交付物的自主協作者時,A2A 才具有價值。

A2A 與 MCP #

A2A 與 Model Context Protocol 解決不同問題:

協定關係典型遠端能力
MCPagent 到工具或資源查詢資料庫、讀取檔案、呼叫 API
A2Aagent 到 agent研究、協商、規劃、委派和交付結果

一個 agent 可以同時使用兩者:

text
差旅協調器
  |
  | A2A:「尋找符合政策的航班選項」
  v
航班 Agent
  |
  | MCP:呼叫庫存與定價工具
  v
航空公司系統

MCP 向 agent 暴露相對受限的原語。A2A 將獨立 agent 暴露為不透明的協作者。將每個 agent 都包裝成一個大型工具,會隱藏有用的工作生命週期、釐清、成品和非同步行為;將每個簡單工具都視為 agent,則會增加不必要的自主性與複雜性。

三個協定層 #

A2A v1.0 分離三個層次:

  1. 規範資料模型: Agent Card、Message、Task、Part、Artifact、事件、安全宣告和擴充。
  2. 抽象操作: 傳送 Message、串流 Message、取得/列出或取消 Task、訂閱 Task 更新、管理推播通知設定,以及取得擴充 Agent Card。
  3. 繫結: 對應至 JSON-RPC、gRPC、HTTP+JSON 或受治理的自訂繫結。

規範的 Protocol Buffer 定義具有規範效力。繫結會以不同方式序列化相同概念。用戶端應使用持續維護的 SDK,而不應假設某個 JSON-RPC 範例描述所有繫結。

官方專案維護 Python、Go、Java、JavaScript、.NET 和 Rust 的 SDK,另有獨立的範例儲存庫。

參與者 #

一次互動包含三個概念上的參與者:

  • 使用者: 其目標促成請求的人類或自動化系統。
  • A2A 用戶端: 代表使用者啟動協定操作的應用程式或用戶端 agent。
  • A2A 伺服器: 發布 A2A 介面並執行工作的遠端 agent。

同一個應用程式可以同時是伺服器和用戶端。差旅協調器在處理使用者請求的同時,也作為航班和飯店 agent 的用戶端。

text
使用者
  -> A2A 伺服器:差旅協調器
       -> A2A 用戶端:航班 Agent
       -> A2A 用戶端:飯店 Agent
       -> A2A 用戶端:政策 Agent

A2A 不標準化協調器的規劃邏輯。它可以使用固定工作流程、規則引擎、LLM 規劃器或人工決策。

Agent 探索 #

A2A 伺服器透過 Agent Card 描述自己。Agent Card 是一份 JSON 文件,包含:

  • agent 名稱、描述、提供者和版本;
  • 一個或多個支援的介面和 A2A 協定版本;
  • 支援的協定繫結;
  • 預設輸入與輸出媒體類型;
  • 可選的串流、推播通知和擴充卡片能力;
  • 安全性配置與需求;
  • 技能、描述、標籤、範例和媒體類型;以及
  • 可選的簽章和擴充。

簡化的 v1.0 Agent Card 如下:

json
{
  "name": "Corporate Travel Agent",
  "description": "Plans policy-compliant business travel",
  "version": "3.4.0",
  "provider": {
    "organization": "Example Travel",
    "url": "https://travel.example"
  },
  "supportedInterfaces": [
    {
      "url": "https://agents.example/a2a/travel",
      "protocolBinding": "HTTP+JSON",
      "protocolVersion": "1.0"
    }
  ],
  "capabilities": {
    "streaming": true,
    "pushNotifications": true,
    "extendedAgentCard": true
  },
  "defaultInputModes": [
    "text/plain",
    "application/json"
  ],
  "defaultOutputModes": [
    "text/plain",
    "application/json"
  ],
  "skills": [
    {
      "id": "plan-business-trip",
      "name": "Plan a Business Trip",
      "description": "Finds policy-compliant flight and hotel options",
      "tags": ["travel", "flight", "hotel", "corporate-policy"],
      "examples": [
        "Plan a trip from Singapore to Helsinki for 12-16 October"
      ],
      "inputModes": ["text/plain", "application/json"],
      "outputModes": ["application/json"]
    }
  ]
}

確切的 JSON 欄位名稱源自 v1.0 規範模型。應透過 SDK 或產生的結構描述驗證卡片,而不是接受任意 JSON。

探索策略 #

對於以網域為基礎的探索,標準 well-known URL 是:

text
https://agent.example/.well-known/agent-card.json

其他實用方法包括:

  • 策展型註冊表: 企業目錄或市集依據技能、提供者、地理位置或信任政策回傳已核准的 Agent Card。
  • 直接設定: 部署資訊清單為封閉的一組 agent 提供已知的卡片 URL。
  • 已驗證的擴充卡片: 公開卡片宣告基本能力;已驗證的操作會回傳可供該呼叫者使用的敏感技能或介面。

A2A 標準化卡片,而不是集中式註冊表的 API。

應將探索結果視為政策輸入,而不是自動信任。在呼叫 agent 之前,用戶端可能需要檢查:

  • 受信任的發行者或註冊表;
  • 卡片簽章;
  • 允許的網域和 TLS 身分;
  • 協定版本;
  • 所需的繫結;
  • 支援的媒體類型;
  • 核准的提供者;
  • 資料駐留;
  • 安全性配置;
  • 合約關係;以及
  • 該技能是否已獲得目前使用者授權。

Agent Card 的變更頻率低於 Task,應使用正常的 HTTP 快取,包括 Cache-Control、ETag 和條件式請求。

Agent Card 交換的時機 #

Agent Card 是探索期間使用的控制平面中繼資料,通常在第一次 A2A 操作之前取得:

text
用戶端 -> 探索或接收 Agent Card
用戶端 -> 驗證信任、版本、繫結、安全性與媒體類型
用戶端 -> 從 supportedInterfaces 選取介面 URL
用戶端 -> 將 A2A 操作傳送至該介面

通常不會將卡片附加到每個 Message。用戶端可以快取卡片,並依照正常 HTTP 快取規則或本機政策更新。

A2A 伺服器 必須提供 Agent Card,但 v1.0 允許數種探索機制:標準 well-known URI、註冊表或目錄,以及直接設定的卡片 URL 或卡片內容。因此,/.well-known/agent-card.json 是慣用的可互通位置,但不是交換卡片的唯一合規方式。

如果公開卡片宣告 extendedAgentCard,已授權的用戶端稍後可以呼叫 Get Extended Agent Card。該已驗證卡片可以揭露呼叫者特定的技能或介面,而這些資訊不應在匿名探索時公開。

Message 與 Part #

Message 是一次通訊回合,包含:

  • 由呼叫者產生的 messageId;
  • ROLE_USER 或 ROLE_AGENT 角色;
  • 一個或多個 Part;
  • 可選的 contextId 和 taskId;
  • 可選的先前 Task 參照;
  • 可選的中繼資料;以及
  • 宣告的擴充。

Part 恰好包含一種內容表示:

內容用途
text純文字內容
data結構化 JSON 值
url外部內容的參照
raw內嵌位元組,在 JSON 中以 Base64 表示

Part 也可以包含 MIME mediaType、檔名和中繼資料:

json
{
  "messageId": "msg-01JZ8P...",
  "role": "ROLE_USER",
  "parts": [
    {
      "text": "Review the attached contract for renewal risk.",
      "mediaType": "text/plain"
    },
    {
      "url": "https://files.example/contracts/42",
      "filename": "contract.pdf",
      "mediaType": "application/pdf",
      "metadata": {
        "sha256": "..."
      }
    },
    {
      "data": {
        "jurisdiction": "Singapore",
        "riskTolerance": "low"
      },
      "mediaType": "application/json"
    }
  ]
}

對於大型檔案,應使用 URL,而不是在每一個協定跳轉中放入 Base64 資料。URL 應為短期有效、限制給預定 agent、經過完整性檢查,並防止混淆代理人存取。

媒體協商很重要。用戶端宣告其接受的輸出媒體類型,Agent Card 描述 agent 支援的媒體類型。當技能提供 application/json 時,機器協調器應要求結構化資料,而不是解析散文。

直接 Message 與具狀態 Task #

Send Message 操作可以回傳:

  • 立即且自包含的回應 Message;或
  • 用於具狀態或長時間執行工作的 Task。

例如,agent 可以直接回答能力問題:

text
用戶端:你能檢閱受新加坡法律管轄的合約嗎?
Agent:可以。

檢閱一份 300 頁的合約應建立 Task,以便追蹤、中斷、取消,並與輸出 Artifact 建立關聯。

Task 模型 #

Task 包含:

  • 伺服器產生的 Task ID;
  • 伺服器產生的 context ID;
  • 目前狀態和時間戳;
  • 可選的狀態 Message;
  • Message 歷史;
  • 零個或多個 Artifact;以及
  • 中繼資料。

生命週期狀態如下:

狀態意義
TASK_STATE_SUBMITTED已接受,但尚未主動處理
TASK_STATE_WORKING處理中
TASK_STATE_INPUT_REQUIRED需要更多使用者或用戶端資訊
TASK_STATE_AUTH_REQUIRED需要額外的頻外驗證
TASK_STATE_COMPLETED成功的終端結果
TASK_STATE_FAILED終端處理失敗
TASK_STATE_CANCELED終端取消
TASK_STATE_REJECTEDAgent 拒絕工作

INPUT_REQUIRED 和 AUTH_REQUIRED 會中斷處理,但不是終端狀態。用戶端可以傳送與 Task 關聯的另一個 Message 來繼續工作。

終端 Task 是不可變的。修正或細化會在相同 context 中建立新的 Task,並參照先前的 Task:

text
context C
  task T1:產生行程       -> completed -> artifact A1
  task T2:更換上午航班   -> completed -> artifact A2
            參照 T1

這提供可稽核性:每個 Task 都是輸入、狀態和輸出的穩定單位。

Context 與 Task ID #

contextId 將相關的 Task 和 Message 分組。taskId 識別一個工作單位:

text
context:「規劃赫爾辛基旅行」
  task:尋找航班
  task:預訂飯店
  task:申請政策例外

不要將 context ID 與驗證、授權或租戶身分混淆。它是由伺服器指派的不透明關聯控制代碼。伺服器仍必須驗證已驗證的呼叫者是否可以存取每一個被參照的 context、task 和 artifact。

Artifact #

Artifact 是具體的 Task 輸出,而不是對話狀態 Message。範例包括:

  • 行程;
  • 安全性報告;
  • 產生的原始碼;
  • PDF 合約分析;
  • 圖像;
  • 結構化報價清單;或
  • 部署資訊清單。

Artifact 具有在其 Task 內唯一的 ID、名稱、描述、Parts、中繼資料和可選的擴充:

json
{
  "artifactId": "offers-v1",
  "name": "flight-offers.json",
  "description": "Policy-compliant flight options",
  "parts": [
    {
      "mediaType": "application/json",
      "data": {
        "currency": "SGD",
        "offers": [
          {
            "offerId": "F-812",
            "price": 1420.30,
            "refundable": true
          }
        ]
      }
    }
  ],
  "metadata": {
    "expiresAt": "2026-07-20T10:15:00Z"
  }
}

Artifact 不會自動持久化,也不自動值得信任。用戶端必須驗證其結構描述、媒體類型、大小、完整性、來源、到期時間和業務意義。

核心操作 #

與繫結無關的 v1.0 操作包括:

操作用途
Send Message開始或繼續互動
Send Streaming Message開始互動並接收增量事件
Get Task取得目前 Task 狀態、歷史和 Artifacts
List Tasks以篩選器和分頁列出已授權的 Tasks
Cancel Task要求 agent 取消進行中的工作
Subscribe to Task重新連線到作用中 Task 的更新
Manage Task Push Notification Config建立、讀取、列出或刪除 webhook 設定
Get Extended Agent Card取得呼叫者特定的 Agent Card 詳細資料

繫結與端點對應 #

Agent Card 中的介面 URL 和 protocolBinding 決定這些抽象操作如何在線路上呈現。

使用 JSON-RPC 時,宣告的介面 URL 是所有操作共用的一個 HTTP 端點。像 /a2a 這樣的 URL 只是實作選擇;A2A 規格不要求該路徑。用戶端傳送包含 JSON-RPC 本文的普通 HTTP 請求,並由 method 欄位選取 A2A 操作:

http
POST /a2a HTTP/1.1
Host: agents.example
Content-Type: application/json

{
  "jsonrpc": "2.0",
  "id": "request-17",
  "method": "SendMessage",
  "params": {
    "message": {
      "messageId": "msg-01JZ8P...",
      "role": "ROLE_USER",
      "parts": [{"text": "Hello"}]
    }
  }
}

JSON-RPC 在此是疊加在 HTTP 上的協定慣例,不是 HTTP 的替代品。HTTP 提供傳輸、標頭、驗證和狀態碼;JSON-RPC 標準化本文欄位 method、params、id、result 和 error,以及請求關聯、通知和協定錯誤語意。其他協定也能在 WebSocket 或標準輸入輸出等傳輸上使用 JSON-RPC,但 A2A 的 JSON-RPC 繫結特別使用 HTTP(S),並以 Server-Sent Events 進行串流。

所有 JSON-RPC A2A 方法都傳送至同一個宣告的 URL:

A2A 操作JSON-RPC 方法
Send MessageSendMessage
Send Streaming MessageSendStreamingMessage
Get TaskGetTask
List TasksListTasks
Cancel TaskCancelTask
Subscribe to TaskSubscribeToTask
建立推播設定CreateTaskPushNotificationConfig
取得推播設定GetTaskPushNotificationConfig
列出推播設定ListTaskPushNotificationConfigs
刪除推播設定DeleteTaskPushNotificationConfig
Get Extended Agent CardGetExtendedAgentCard

HTTP+JSON 繫結則使用相對於其宣告介面基底 URL 的不同資源導向路徑:

HTTP 端點A2A 操作
POST /message:sendSend Message
POST /message:stream使用 SSE 的 Send Streaming Message
GET /tasks/{id}Get Task
GET /tasksList Tasks
POST /tasks/{id}:cancelCancel Task
POST /tasks/{id}:subscribe使用 SSE 的 Subscribe to Task
POST /tasks/{id}/pushNotificationConfigs建立推播設定
GET /tasks/{id}/pushNotificationConfigs/{configId}取得推播設定
GET /tasks/{id}/pushNotificationConfigs列出推播設定
DELETE /tasks/{id}/pushNotificationConfigs/{configId}刪除推播設定
GET /extendedAgentCardGet Extended Agent Card

這些路徑屬於 HTTP+JSON 繫結;JSON-RPC 實作不會為每個操作暴露一個 HTTP 路由。gRPC 繫結同樣暴露 RPC 方法,而不是這些 REST 路徑。

阻塞與非阻塞傳送 #

Send Message 設定控制呼叫是否等待:

  • returnImmediately 為 false 或省略時,會等待 Task 到達終端或中斷狀態。
  • returnImmediately 為 true 時,會在建立 Task 後回傳;用戶端會輪詢、訂閱或等待推播通知。

簡化的 HTTP+JSON 請求如下:

http
POST /message:send HTTP/1.1
Host: agents.example
Authorization: Bearer eyJ...
Content-Type: application/json

{
  "message": {
    "messageId": "msg-01JZ8P...",
    "role": "ROLE_USER",
    "parts": [
      {
        "text": "Review repository example/payments for critical vulnerabilities",
        "mediaType": "text/plain"
      }
    ]
  },
  "configuration": {
    "acceptedOutputModes": [
      "application/json",
      "text/markdown"
    ],
    "historyLength": 10,
    "returnImmediately": true
  }
}

立即回應可能包含:

json
{
  "task": {
    "id": "task-sec-2048",
    "contextId": "ctx-release-91",
    "status": {
      "state": "TASK_STATE_SUBMITTED",
      "timestamp": "2026-07-20T08:30:00Z"
    }
  }
}

此範例針對 v1.0 HTTP+JSON 繫結。請使用 SDK 取得精確的請求與回應包裝格式。

串流與非同步工作 #

Agent 工作通常持續時間超過一般請求逾時。A2A 提供三種更新模式。

輪詢 #

用戶端傳送非阻塞請求,並定期呼叫 Get Task:

text
Send Message -> Task(submitted)
Get Task     -> Task(working)
Get Task     -> Task(completed, artifacts=[...])

輪詢很簡單,且能夠在程序重新啟動後繼續。應使用指數退避、抖動和伺服器提示,而不是每幾毫秒輪詢一次。

串流 #

如果 Agent Card 宣告支援串流,Send Streaming Message 會回傳串流。依據繫結,HTTP 可以使用 Server-Sent Events,gRPC 可以使用伺服器串流。

Task 生命週期串流從 Task 開始,接著發出:

  • 狀態變更或中間狀態 Message 的 TaskStatusUpdateEvent;
  • 新增或增量更新 Artifact 的 TaskArtifactUpdateEvent。
text
Task(submitted)
Status(working: "正在掃描相依性")
Artifact(report, append=true, chunk=1)
Status(working: "正在分析可到達的呼叫路徑")
Artifact(report, append=true, chunk=2, lastChunk=true)
Status(completed)

Artifact 更新會標示資料是否附加到現有 Artifact,以及最後一個區塊是否已抵達。用戶端應依照 task 和 artifact ID 組合區塊、強制套用大小限制,並在重新連線時避免重複內容。

如果串流在 Task 仍為作用中時中斷,Subscribe to Task 可以恢復接收後續更新。在處理串流資料前持久化 Task ID,使復原仍然可行。

推播通知 #

對於持續數分鐘、數小時或數天的工作,如果 agent 宣告支援推播通知,用戶端可以註冊 HTTPS webhook:

text
用戶端 -> Agent:啟動 Task 並註冊回呼
用戶端中斷連線
Agent 執行工作
Agent -> 用戶端 webhook:Task 完成
用戶端 -> Agent:Get Task

通知會告知用戶端狀態已變更;用戶端通常會在之後擷取具權威性的 Task。

Webhook 支援會引入嚴重風險:

  • SSRF: 惡意呼叫者提供內部或雲端中繼資料 URL。
  • 冒充: 攻擊者傳送偽造的完成事件。
  • 重播: 有效的舊事件再次被處理。
  • 放大: 伺服器被誘導向第三方大量傳送請求。
  • 重複傳送: 網路重試造成同一事件被傳送多次。

伺服器應允許清單或驗證回呼擁有權,並限制輸出網路。接收端應驗證傳送者,檢查發行者、受眾、到期時間、task ID 和唯一事件 ID,拒絕過期事件,並以冪等方式處理通知。

輸入與驗證中斷 #

長時間執行的工作可能需要另一個使用者決策:

text
用戶端 -> Agent:「預訂最符合政策的選項」
Agent -> 用戶端:Task(INPUT_REQUIRED)
                「兩個選項具有相同的政策評分。要優先較低價格還是可退款票價?」
用戶端 -> Agent:Message(taskId=T1,「優先可退款票價」)
Agent -> 用戶端:Task(WORKING)
Agent -> 用戶端:Task(COMPLETED, artifact=booking)

AUTH_REQUIRED 表示工作期間需要額外授權。例如,差旅 agent 可能發現需要使用者授權航空公司帳戶。

用戶端應在頻外執行 OAuth 或同意流程,然後繼續該 Task。不要僅因為 agent 要求驗證,就將密碼、重新整理權杖或可重複使用的祕密作為普通 Message 文字傳送。

詳細範例:企業差旅 #

考慮一個協調由不同系統獨立營運之 agent 的公司助理。

參與者 #

text
差旅協調器
  -> 政策 Agent
  -> 航班 Agent
  -> 飯店 Agent
  -> 費用 Agent

每個遠端系統都發布 Agent Card。協調器的核准註冊表包含受信任的卡片,以及各提供者的 OAuth audience。

流程 #

  1. 使用者提出請求:

    text
    規劃 10 月 12 日至 16 日從新加坡前往赫爾辛基的差旅。
    我需要在星期一 09:00 的會議前抵達。
    暫時不要進行購買。
  2. 協調器將員工等級、成本中心、航線和日期,以結構化 Parts 傳送給政策 Agent。

  3. 政策 Agent 回傳含有政策 Artifact 的已完成 Task:

    json
    {
      "cabin": "economy",
      "maxNightlyHotelRate": 240,
      "currency": "EUR",
      "approvalRequiredAbove": 1800
    }
  4. 協調器在自己的工作流程中平行啟動航班和飯店 Task。它只傳送每個 agent 所需的政策欄位。

  5. 航班 Agent 串流狀態:

    text
    working: 正在搜尋直飛航線
    working: 直飛航線違反抵達限制
    working: 正在搜尋一次轉機航線
    completed: artifact flight-offers.json
  6. 飯店 Agent 因為有兩個辦公地點而進入 INPUT_REQUIRED。協調器詢問使用者,並使用選定的辦公地點繼續同一個 Task。

  7. 協調器合併兩個結構化 Artifact,計算完整的行程選項,並呈現給使用者。

  8. 使用者選取一個選項。這會在相同的協調 context 中建立新的預訂 Task,不會變更已完成的搜尋 Task。

  9. 由於總額超過政策門檻,費用 Agent 建立核准 Task 並設定推播通知。幾小時後,經理核准。

  10. 協調器接收已驗證的通知,取得 Task,確認核准金額和到期時間,然後才繼續預訂 Task。

A2A 的價值 #

航班和飯店提供者保留自己的模型、工具、定價系統和規劃邏輯。協調器看到的是已宣告的技能、Task 狀態、Messages 和 Artifacts。提供者可以替換內部框架,而不必改變協作契約。

A2A 不解決交易原子性。如果航班成功而飯店失敗,協調器仍需要補償邏輯、具有到期時間的預訂,或領域特定的交易工作流程。

詳細範例:軟體交付 #

版本發布協調器協調由不同工程團隊擁有的 agent:

text
編碼 Agent -> 測試 Agent -> 安全性 Agent -> 部署 Agent

流程 #

  1. 編碼 Agent 完成 Task T1 並產生:

    • Git commit 參照;
    • patch Artifact;
    • change-summary Artifact;以及
    • 預期的測試範圍。
  2. 協調器分別向測試 Agent 和安全性 Agent 傳送 Message。每個 Message 都參照 T1,但只包含經授權、可用於該儲存庫和操作的短期儲存庫認證資料。

  3. 測試 Agent 串流:

    text
    Task submitted
    正在編譯 payments 模組
    正在執行 1,842 個單元測試
    正在執行 37 個整合測試
    Artifact: junit-results.xml
    Task completed
  4. 安全性 Agent 回傳 INPUT_REQUIRED:

    text
    此修補程式變更了授權行為。此端點是供服務身分、終端使用者,還是兩者使用?
  5. 協調器從程式碼擁有者取得答案,並繼續相同的安全性 Task。

  6. 安全性 Agent 以結構化發現結果完成:

    json
    {
      "decision": "block",
      "findings": [
        {
          "severity": "high",
          "file": "AuthorizationService.java",
          "line": 118,
          "summary": "Tenant constraint omitted"
        }
      ]
    }
  7. 協調器不會呼叫部署。它為編碼 Agent 建立 refinement Task T4,參照 T1 和安全性 Task,並要求修正。

  8. 新的修補程式會取得新的測試和檢閱 Task。已完成的 Task 仍是不可變的稽核記錄。

  9. 是否允許部署,由決定性的版本發布政策決定,而不是由 LLM 的散文決定。

A2A 的價值 #

每個團隊都可以使用不同的框架建置自己的 agent。結果會是具型別的 Artifact,而不是從聊天內容擷取的文字。串流會為昂貴的測試套件提供進度;中斷的 Task 支援提問,而不必捨棄先前的工作。

協定不會使產生的程式碼變得安全。分支保護、授權、可重現建置、簽章、隔離執行和人工核准仍然是必要的。

詳細範例:保險理賠 #

理賠受理 agent 從行動應用程式接收文字、圖像和文件:

text
理賠受理 Agent
  -> 損害評估 Agent
  -> 承保範圍 Agent
  -> 詐欺檢閱 Agent
  -> 維修網路 Agent

多模態交換 #

受理 Message 包含:

  • 描述事故的文字;
  • 透過受限 URL 參照的圖像 Part;
  • PDF 警察報告;
  • 結構化車輛和保單資料;以及
  • 用於完整性驗證的雜湊。

損害評估 Agent 回傳:

  • 人類可讀的摘要;
  • 受損元件的結構化清單;
  • 加註圖像 Artifact;以及
  • 不確定性分數。

承保範圍 Agent 會看到保單條款,但不會看到不必要的事故圖像。詐欺 Agent 會收到符合其職責的遮罩證據。協調器在每次 A2A 呼叫前進行資料最小化。

Human in the Loop #

如果評估信心較低,Task 會進入 INPUT_REQUIRED:

text
請提供一張與地面高度相同的左後輪照片。

行動使用者上傳另一張圖像,受理 agent 繼續相同的 Task。

如果估計損失超過門檻,工作流程會建立個別的人工作業員 Task。A2A 追蹤協作,但具有法律後果的決定仍由決定性的理賠政策和合格的人員作出。

A2A 的價值 #

Parts 支援在一次互動中傳送文字、結構化資料和檔案參照。Task 能夠跨越間歇性的行動網路連線持續存在。Artifacts 表示持久交付物,遠端專業 agent 仍保持不透明。

實作仍必須強制執行同意、保留、區域處理、醫療資料規則,並對每個 Artifact URL 實施嚴格授權。

詳細範例:採購與協商 #

採購 agent 需要從數個供應商 agent 取得 500 台筆記型電腦的報價。這說明 agent 不只是無狀態的價格工具。

流程 #

  1. 用戶端將必要規格、交貨地點、服務條款和回應期限傳送給三個核准的供應商 agent。

  2. 每個供應商建立一個 Task,並可能提出釐清問題。

  3. 供應商回傳包含價格、庫存、保固、到期時間和商業條款的報價 Artifact。

  4. 採購 agent 在新的 Task 中要求細化:

    text
    保持相同的硬體和交貨日期。提供三年保固,並報價價格差額。
  5. 每個細化都參照先前的 Task 和報價 Artifact。

  6. 用戶端追蹤報價版本,因為 Artifact 系譜和接受情況是用戶端的責任。

  7. 決定性政策引擎比較強制條款。模型可以摘要取捨,但不能免除要求。

  8. 人類核准選定的報價。

  9. 獨立的購買 Task 使用冪等性金鑰和狹窄授權執行訂單。

A2A 的價值 #

協商是多輪的,而且每個供應商都擁有自己的推理和庫存工具。Task 和 Artifact 提供一致的機制,而不會強迫所有供應商使用一個專有的 agent SDK。

A2A 不標準化報價結構描述。買方和供應商仍需要共用領域結構描述,或為可由機器比較的商業條款使用擴充。

安全性模型 #

A2A 重用標準 Web 安全性,而不是將認證資料放入協定 Message。

Agent Card 宣告支援的安全性配置和需求。用戶端在頻外取得認證資料,然後透過傳輸標頭傳送:

http
Authorization: Bearer eyJ...

正式環境的 A2A 介面應使用 HTTPS 並驗證伺服器身分。跨組織部署通常使用 OAuth 2.0/OIDC、工作負載身分、mTLS 或其組合。

驗證回答呼叫者是誰。每個操作仍需要授權:

  • 此呼叫者可以呼叫此技能嗎?
  • 它可以存取此 task 和 context 嗎?
  • 它可以參照此 artifact 嗎?
  • 它可以要求此輸出模態嗎?
  • 它可以取消此工作嗎?
  • 遠端 agent 可以代表此終端使用者執行底層操作嗎?

不透明執行保護的是實作細節,而不是使用者。惡意或遭入侵的 agent 仍可能回傳有害內容、濫用委派的認證資料,或在工作未成功時宣稱工作成功。

委派 #

當一個 agent 跨越另一個 agent 的邊界代表使用者行動時,應保留:

  • 政策要求時的終端使用者身分;
  • 呼叫工作負載身分;
  • 租戶;
  • audience;
  • 已授權的 scopes;
  • 目的與同意;
  • 權杖到期時間;以及
  • trace context。

不要僅因為兩個 agent 在技術上都能接受,就轉送範圍寬泛的 bearer token。應將其交換為短期、綁定 audience 且只包含遠端技能所需 scopes 的 token。

不受信任的內容 #

每個 Message、Part、Artifact、Agent Card 和被參照的檔案都是不受信任的輸入。應套用:

  • JSON 和媒體類型驗證;
  • 位元組數、歷史和巢狀限制;
  • 惡意軟體掃描;
  • 解壓縮限制;
  • URL 配置和目的地限制;
  • 對轉譯輸出的內容安全性政策;
  • prompt injection 防禦;
  • 輸出結構描述驗證;以及
  • 獨立於 agent 文字的網域授權。

不要直接在具特權的應用程式來源中轉譯 HTML Artifact。

可靠性與工作流程語意 #

A2A 提供 Task 狀態,但不是分散式交易協調器。用戶端和伺服器仍需要:

  • 持久化 Task 儲存;
  • 冪等的業務操作;
  • 請求去重;
  • 帶抖動的有界重試;
  • 截止時間和到期時間;
  • 取消傳播;
  • 部分成功的補償;
  • Artifact 完整性和保留;
  • 背壓;
  • 併發限制;以及
  • 程序重新啟動後的復原。

已取消的 Task 不代表外部副作用已被復原。航班可能已經開票,或電子郵件已經寄出。應將取消與業務補償分開建模。

網路失敗會產生歧義:

text
用戶端傳送「購買」
伺服器執行購買
回應遺失
用戶端不知道購買是否已發生

對具有重大後果的操作,使用領域冪等性金鑰和可查詢的業務參照。messageId 識別協定 Message,但除非實作明確定義並持久化該行為,否則不應將其作為唯一的業務保證。

Task 和 Artifact 需要保留政策。除非服務合約明確保證,否則用戶端不能假設可以永遠取得已完成的 Task。

可觀測性 #

在 A2A 呼叫之間傳播 W3C Trace Context 標頭。有用的 span 屬性和日誌包括:

  • 遠端 agent 身分和版本;
  • 協定和繫結版本;
  • 操作;
  • Task 和 context ID;
  • 技能;
  • 狀態轉換;
  • 媒體類型;
  • Artifact 大小;
  • 重試次數;
  • 延遲;以及
  • 已驗證的用戶端應用程式。

不要將提示文字、文件內容、存取權杖或個人資料放入指標標籤。包含 Message 或 Artifact 的日誌需要遮罩、存取控制和保留限制。

重要指標包括:

  • 按操作統計的請求和錯誤率;
  • Task 佇列和執行延遲;
  • 各狀態的 Task;
  • 等待輸入或驗證所花費的時間;
  • 串流中斷與重新訂閱率;
  • 推播通知傳送失敗;
  • 取消延遲;
  • Artifact 位元組數;以及
  • 下游模型和工具成本。

將具有後果的操作與診斷記錄分開稽核。

擴充 #

擴充可以在不變更核心協定的情況下增加行為或資料。Agent Card 會以穩定 URI、描述、參數及用戶端是否必須理解該擴充來宣告每個擴充。

當必要的擴充不受支援時,用戶端不得呼叫 agent。可選擴充應能正常降級。

當多個獨立實作需要可互通的語意時,才使用擴充,而不是只為了攜帶某個應用程式的私有中繼資料。供應商擴充可能重新造成 A2A 試圖降低的鎖定,因此應盡可能讓核心互動保持可用,並精確記錄相容性。

實作 A2A 伺服器 #

實際的伺服器實作可依下列步驟進行:

  1. 定義範圍狹窄的技能集合,以及其輸入/輸出媒體類型。
  2. 發布最小化的公開 Agent Card。
  3. 先選擇一個官方繫結和 SDK。
  4. 在 HTTP 或傳輸邊界執行驗證。
  5. 授權技能、Task、context 和 Artifact。
  6. 驗證 Message,並安全地解參照檔案。
  7. 決定何時回傳直接 Message,以及何時建立 Task。
  8. 在確認非阻塞工作前持久化 Task。
  9. 發出有效的狀態轉換和不可變的終端狀態。
  10. 以完整性與保留中繼資料儲存或參照 Artifact。
  11. 只有在中間更新具有價值時才加入串流。
  12. 只有在具備 SSRF 防護和已驗證傳遞時才加入推播通知。
  13. 傳播追蹤資訊並記錄稽核事件。
  14. 發布相容性與保留保證。

Agent 的內部實作可以使用 LLM、決定性工作流程、人工作業佇列、工具或其他 A2A agent。不要將思維鏈或內部認證資料暴露為狀態 Message。

實作 A2A 用戶端 #

健全的用戶端應:

  1. 從受信任的來源探索 Agent Card。
  2. 驗證並快取它。
  3. 選取雙方支援的協定版本、繫結和媒體類型。
  4. 強制執行本機信任和資料分享政策。
  5. 取得綁定 audience 的認證資料。
  6. 產生並持久化 Message 關聯資料。
  7. 傳送所需的最小 context。
  8. 立即持久化回傳的 Task 和 context ID。
  9. 處理直接 Message 與 Task 回應。
  10. 處理每一種 Task 狀態,包括拒絕和驗證。
  11. 以冪等方式重新連線、輪詢或處理推播通知。
  12. 在使用 Artifact 前驗證它。
  13. 在執行具有後果的後續操作前套用決定性政策。
  14. 記錄委派 Task 之間的追蹤和稽核關係。

不要讓 LLM 選擇任意 Agent Card URL,然後立即向它們傳送認證資料或私人資料。探索和呼叫都需要允許清單或信任政策。

何時使用 A2A #

在下列情況使用 A2A:

  • 不同擁有者的 agent 必須互通;
  • 遠端系統確實是 agent,而不是單一函式;
  • 能力探索很有用;
  • 互動可能需要釐清或協商;
  • 工作是長時間執行或可恢復的;
  • 需要豐富或增量式 Artifact;
  • 內部 agent 實作必須保持不透明;或
  • 多種語言和框架必須共用一份契約。

在下列情況,應優先使用普通 API、事件結構描述、工作流程活動或 MCP 工具:

  • 輸入和輸出完全具有決定性;
  • 一個短請求總是能完成操作;
  • 沒有有意義的對話或 Task 生命週期;
  • 雙方屬於一個緊密耦合的應用程式;
  • 強靜態領域結構描述比 agent 的彈性更重要;或
  • 加入自主行為會帶來風險,卻沒有使用者價值。

常見錯誤 #

  1. 將探索視為信任。 Agent Card 描述宣告;是否信任由政策決定。
  2. 將認證資料放進 Message。 使用傳輸層驗證和頻外授權。
  3. 使用 context ID 作為授權。 它只是個不透明的群組識別碼。
  4. 將所有使用者 context 傳送給每個 agent。 依委派技能最小化資料。
  5. 在有結構化輸出時解析散文。 協商適當的媒體類型。
  6. 重新啟動終端 Task。 在相同 context 中建立新的 Task,並參照先前的 Task。
  7. 假設取消會復原副作用。 實作領域補償。
  8. 信任任意推播 URL。 防止 SSRF 並驗證回呼。
  9. 假設串流具有持久性。 持久化 ID,並支援重新訂閱或輪詢。
  10. 混淆 A2A 與協調。 用戶端仍負責工作流程和失敗政策。
  11. 混淆 A2A 與 MCP。 Agent 透過 A2A 協作;Agent 透過 MCP 使用受限工具。
  12. 讓協調模型擁有最終權限。 決定性程式碼必須強制執行權限、預算和核准規則。
  13. 忽略協定協商。 Card 可以公開多種繫結和版本。
  14. 原封不動地使用 1.0 之前的舊範例。 v1.0 規範模型變更了欄位名稱、列舉和繫結結構。

A2A 的價值不在於 agent 可以互相傳送 JSON;普通 HTTP 已經能夠做到這一點。它的價值在於提供共享模型,用於探索不透明的 agent、委派具狀態的工作、協商模態、處理中斷,以及擷取增量或持久化結果。這個共用層讓跨框架協作成為可能,同時將業務結構描述、協調、信任與安全性留給理解這些問題的應用程式。

評論

在 GitHub 上閱讀或評論(發表評論需要登入)