寫於 2026 年 8 月 22 日,9 月才上線(部落格的發佈額度在 8 月中用完了,稿子積壓了三週)。文中對 A2A 的描述以 8 月 22 日的官方文件與 repo 狀態為準,你讀到時規格可能已經改版。

2025 年 3 月 25 日,一個 repo 落下第一顆 commit,訊息就兩個字:Initial commit。接下來兩個禮拜,那個 repo 一顆 commit 都沒有。4 月 9 日一天之內,llms.txt 進來了,README 補上介紹影片跟整段核心概念,PR 一個接一個。一個專案被推出去見人的時候就長這樣。

那個 repo 叫 A2A,全名 Agent2Agent。當時 MCP 的第一版規格(版本編號就叫 2024-11-05)已經公開快五個月,工具鏈剛長起來,每個人都在寫自己的 MCP server。所以第一個反應幾乎都一樣:我已經有 MCP 了,你這個是要幹嘛。

這個問題問得對,而且答案跟功能表沒什麼關係。

在那之前,你只能把另一個 agent 包成工具

你手上有兩個 agent。A 讀 codebase 出計畫,B 跑測試跟部署,兩個各有一套 MCP 工具、各自跑在不同機器上,可能還是不同公司的。你要讓 A 使喚 B,唯一的路是把 B 包成一個 MCP server,開一個 run_deploy(branch, env) 之類的工具給 A 呼叫。

跑得起來。小規模真的跑得起來,在沒有別的選項的時候,這也是最直覺的一條路。

問題在包裝的那一層會漏。A2A 官方的對照文件在描述 MCP 那一側時,把「工具」的特徵寫得很死:These are typically primitives with well-defined, structured inputs and outputs. They perform specific, often stateless, functions. 有明確結構化輸入輸出、通常無狀態的基本單元。計算機、資料庫查詢、天氣 API 都是。

B 不是這種東西。

卡住的地方是那個中途反問

工具像電梯按鈕。你按下 5 樓,它就走。它不會在三樓停下來打給你說「5 樓今天在整修,你要改去 6 樓嗎」。

agent 像你外包出去的同事。他會在第三天傳一則訊息問你一個你根本沒想到的問題,你不回,他就停在那裡。

這聽起來像文學修辭,直到你翻開 A2A 規格附的 specification/a2a.proto,看 TaskState 那個列舉。九個值,其中兩個的註解特別標了 interrupted state

1
2
3
4
// Indicates that the agent requires additional user input to proceed. This is an interrupted state.
TASK_STATE_INPUT_REQUIRED = 6;
// Indicates that authentication is required to proceed. This is an interrupted state.
TASK_STATE_AUTH_REQUIRED = 8;

剩下七個裡,TASK_STATE_UNSPECIFIED 是未知狀態,其餘六個不是進行中就是終局:SUBMITTEDWORKINGCOMPLETEDFAILEDCANCELEDREJECTED。只有那兩個的意思是「我暫停了,球在你那邊」。

一次 function call 沒有這個狀態。函式不會回傳一個「我需要你補一點東西才能繼續,這是我目前的進度,你回覆之後我接著跑」。它要嘛回值、要嘛丟例外。你硬要在 MCP 工具裡表達這件事,只能自己發明一套:回一包特殊的 JSON 說「請再呼叫我一次並帶上 X」,然後在 A 那邊寫一堆膠水去認這個約定。膠水是你自己家的,換一個對象就要重寫一次。

再加上 timeout。工具呼叫的心智模型是「馬上會回」,一個跑四十分鐘、中間會吐三份中間結果的任務塞不進去。A2A 給了三種收結果的方式,規格 §3.5 寫明是 three complementary mechanisms:輪詢(Get Task)、串流、以及 webhook 推播。文件對輪詢的建議情境我覺得很誠實,Best for: Simple integrations, infrequent updates, clients behind restrictive firewalls。防火牆後面的客戶端就是收不到推播,那就輪詢,不用假裝有更漂亮的解法。

opaque 這個字才是分界線

前面講的都是症狀。設計取捨寫在規格 §1.2 的五條指導原則裡,最後一條叫 Opaque Execution

Agents collaborate based on declared capabilities and exchanged information, without needing to share their internal thoughts, plans, or tool implementations.

agent 之間合作,靠的是宣告出來的能力跟交換的資訊,不需要分享內部的想法、計畫、工具實作。連 repo 的 description 都把這個字擺進去了:an open protocol enabling communication and interoperability between opaque agentic applications.

這條把兩個協定徹底分開。MCP 的世界裡,工具是你的。你寫的、你部署的、你看得到原始碼,你甚至知道它連哪一台資料庫。信任是預設值,因為東西在你家。

A2A 假設的是相反的情況。對面那個 agent 屬於別的團隊、別的公司、別的技術棧。它用什麼模型、拆成幾個 subagent、內部呼叫了哪些工具,你不會知道,而且協定刻意不讓你知道。你能看到的只有它自己貼出來的一張名片。

那張名片叫 Agent Card,一份 JSON,放在 https://{server_domain}/.well-known/agent-card.json。看到 .well-known 大概就懂了,跟 robots.txt 是同一種思路:互不認識的雙方要建立第一次接觸,得先有一個大家都同意的固定位置。規格 §8.2 列的探索方式只有三種:well-known URI、註冊中心或目錄、事先設定好的 URL。沒有第四種。

一個協定要同時服務「你自己家的工具」跟「別人家的黑箱」,就得在信任模型上劈腿。它得同時假設你看得到實作、又假設你看不到。這種協定寫得出來,但兩邊都會很難用。

2025 年 6 月,repo 換了主人

v0.1.0 的 tag 打在 2025 年 5 月 20 日,接下來兩個月版本跳得飛快,v0.2.1 到 v0.2.6 全擠在五月底到七月中。而就在這段密集發版的中間,repo 換了主人。

一行指令就看得到:

1
2
gh api repos/google/A2A --jq '.full_name'
# → a2aproject/A2A

你打 google/A2A,GitHub 回你 a2aproject/A2A。repo 從 Google 的組織搬走了。a2aproject 這個組織是 2025 年 6 月 20 日建的,簡介只有一句 Donated to the Linux Foundation by Google;三天後,GOVERNANCE.md 的第一顆 commit 落下。README 的 About 段寫得直白:The A2A Protocol is an open source project under the Linux Foundation, contributed by Google.

搬家不只是換個網址。GOVERNANCE.md 第一句是 The Agent2Agent project is governed by the Technical Steering Committee. The Committee has eight seats, each held by the following companies: 八個席次,八家公司:Google、Microsoft、Cisco、Amazon Web Services、Salesforce、ServiceNow、SAP、IBM。每一席都有具名的人跟 GitHub 帳號,Microsoft 那席是 Darrel Miller,掛的頭銜是 Partner API Architect。TSC 開會在 Linux Foundation 的平台上,連續六週沒出席會被判定成 inactive、不計入法定人數,連這條都寫進治理文件了。

一個「讓不同家的 agent 互通」的協定,如果治理權還握在其中一家手上,另外七家憑什麼把自己的 agent 接上去。這件事跟規格寫得多漂亮完全無關,它是這種協定能不能活下來的前提。過戶辦完一個多月後,7 月 30 日出了 v0.3.0,然後版本號就停在那裡七個多月沒再動。

2026 年 3 月 12 日,v1.0

v1.0.0 在 2026 年 3 月 12 日發布,5 月 28 日補了 v1.0.1。官方公告的定調很克制:

The v1.0 release emphasizes maturity rather than reinvention: the core ideas remain intact, while rough edges have been removed, ambiguous areas clarified, and enterprise deployment requirements addressed more directly.

強調的是成熟度,沒打算重新發明。這句話在協定圈子裡通常是好消息,代表沒有人要把你去年寫的東西全部作廢。

真正動到的地方集中在企業要的那幾樣。Agent Card 可以簽章了,讓你在互動之前先用密碼學驗證對方的身分跟 metadata,跨組織的時候沒這個不行。單一 endpoint 可以安全託管多個 agent。安全流程也整個翻新一輪,公告用的說法是把那些 no longer aligned with current best practices 的舊模式移掉。

傳輸這塊 v1.0 的做法值得抄。規格裡 protocol binding 的頂層章節就三個:JSON-RPC、gRPC、HTTP+JSON/REST。這不是我數出來的,規格自己在講自訂 binding 那章開頭就先聲明過,the A2A protocol provides three standard bindings (JSON-RPC, gRPC, and HTTP+JSON/REST)

§5.1 那條硬要求比數量重要得多:一個 agent 如果宣稱支援多個協定,這些協定 MUST 提供完全相同的操作集、語意等價的結果、一致的錯誤對應、同一套認證方式。

這規定聽起來像廢話,做起來不是。大部分同時提供 REST 跟 gRPC 的服務,兩邊功能覆蓋率都不一樣,總有幾個端點只在其中一邊。A2A 把「不准這樣」寫進規格,理由很清楚:客戶端要能自由挑協定,前提是挑哪個都一樣。

至於 WebSocket,規格裡確實查得到,但它每次出現都是在講自訂 binding 的段落裡當範例,示範怎麼用一個 URI(https://example.com/bindings/websocket/v1)去標一個自己定義的 binding。它在規格裡的身分就是範例,標準 binding 的清單裡沒有它。這種地方最容易看走眼,因為 WebSocket 在別的協定裡確實常見,孤立看完全合理。

升級路徑也想過了。v1.0 對互動協定有 breaking change,但 AgentCard 是往後相容的,一個 agent 可以同時宣告支援 v0.3 跟 v1.0,客戶端就能一批一批搬,不用全公司挑同一天切換。

把時間線拉到今天

gh api repos/a2aproject/A2A 回來的狀態是 archived: falseApache-2.0pushed_at 停在前一天晚上,兩萬五千多顆星。這是還在動的東西。

那對一個每天開 Claude Code 的人來說,現在該怎麼擺?

MCP 那條線已經在你手上,A2A 那條線還在別人手上。你今天寫的每個 MCP server 都是在餵你自己的 agent 吃工具,這件事你完全控制得了。A2A 要成立需要對面也有人,而對面現在多半是同一家公司裡別的團隊,或是 SaaS 廠商還沒開出來的 endpoint。

但分界線值得現在就記住,因為它決定你把東西擺在哪一層。官方那個修車廠的例子比一堆架構圖好懂:客人跟店長講話走 A2A,店長派工給技師走 A2A,技師去掃故障碼、查維修手冊、叫舉升機走 MCP(scan_vehicle_for_error_codes(vehicle_id='XYZ123') 這種),技師要跟零件商調貨又回到 A2A。

判準就一句:對方是不是一個你不需要看穿的東西。是,A2A。否,MCP。

接下來

公告最後一段講了社群現在在忙什麼:多語言的 v1.0 SDK 支援。這是最無聊、但最決定成敗的一段。協定寫得再乾淨,沒有你那個語言的堪用 SDK,它對你就等於不存在。

有幾件事我沒有答案。三個 binding 的功能等價要求,在真實實作裡撐不撐得住?§12 允許自訂 binding,這是彈性還是分裂的起點?八家公司的 TSC 到了治理文件說的 steady state(專案成立滿 18 個月之後)會換成什麼組成?

還有一件得說清楚:這篇從頭到尾只讀了規格、官方文件跟 repo 狀態,我沒有實際架起兩個 agent 讓它們用 A2A 對話過。上面所有判斷都是讀出來的,不是跑出來的。

那顆 Initial commit 落下到現在快滿十七個月。下一個值得盯的時間點,大概是你的技術棧裡第一次出現一個不是你自己寫的 A2A endpoint 的那天。


參考來源