A2A ( Agent2Agent ) 協定是 Google 在 2025 年時提出的,記憶中應該下面這個連結 :
https://developers.googleblog.com/en/a2a-a-new-era-of-agent-interoperability/?utm_source=chatgpt.com
它主要的目的就是如同它的名稱 :
讓 Agent 與 Agent 可以互相進行的協助
🤔 那和 MCP 的差別是 ?
簡單的概念差別就是這樣。
然後這段話是 Google 官方提到和 MCP 的關係,概念上和上面說的差不多 :
A2A is an open protocol that complements Anthropic's Model Context Protocol (MCP), which provides helpful tools and context to agents. Drawing on Google's internal expertise in scaling agentic systems, we designed the A2A protocol to address the challenges we identified in deploying large-scale, multi-agent systems for our customers. A2A empowers developers to build agents capable of connecting with any other agent built using the protocol and offers users the flexibility to combine agents from various providers. Critically, businesses benefit from a standardized method for managing their agents across diverse platforms and cloud environments. We believe this universal interoperability is essential for fully realizing the potential of collaborative AI agents.
然後這張 Google 官方的圖,我自已覺得解釋的很到位。
🤔設計原則 A2A design principles
先來說一下這個 Protocol 這個的 5 個設計原則,它們會和我們下面詳細的協定內容息息相關,以下為官方原文 :
https://a2a-protocol.org/latest/topics/what-is-a2a/#key-design-principles-of-a2a
雖然這個和第一版的設計原則有些地方不太一樣,但大至還是差不多,下面這是第一版的,差別應該是在 Embrace agentic capabilities 這個,其它 4 個都一樣,但這個有部份是包含在 Opaque Execution,所以也沒差多少。
https://developers.googleblog.com/en/a2a-a-new-era-of-agent-interoperability/?utm_source=chatgpt.com
🤔A2A 協定大綱
整份 Specification 在下面這個連結中,然後我們先摘要一下重點,然後接下來再開始說說每個部份。
https://a2a-protocol.org/latest/specification/
A2A 總共支援以下 3 種傳輸協定,也就是說你的 server 實作時,會選擇其中一種來實作,然後接下來 client 就是會用這個模式來和你溝通。
並且他們每一種在 method 上都有一些要求規範,大部份都是 {category}/{action} 這種的概念,然後轉化成不同 Transport,如下表 :
🤔 順到問一下那 client 端,要如何知識 server 支援什麼 transport ?
The Agent Card
等等會提到。
https://a2a-protocol.org/latest/specification/#4-authentication-and-authorization
先說一下,因為有很多新手朋朋們會搞錯,所以簡單說明一下這兩個字的差別 :
然後還記得我們在 MCP 寫的嗎 ? 它事實上只要求 Authorization 這塊要用 OAuth 2.0。
然後在 A2A 這裡是兩個都要,然後它們在 A2A 的差別方式為
Client 透過 AgentCard 中的 authentication 欄位發現伺服器所需的驗證機制
但是他的確在 Authorization 這裡,沒有像 MCP 一樣要求如果要實作一定要 Oauth 2.0
https://a2a-protocol.org/latest/specification/#5-agent-discovery-the-agent-card
它應該是整個 A2A 的核心,它定議了你的 Agent 會什麼、如何溝通之類的
當我們在建立 A2A server 時,會需要先在某個地方,來讓其它 Agent 可以知道你的資訊,然後這個地方官方是建議放在下面這個地方 ( 但不強制 ) :
https://{server_domain}/.well-known/agent-card.json
然後裡面這個至少需要以下的資訊 :
然後以下為官方一個完整的 Agent Card,然後 skills 的範例事實上就很像我們 MCP 的 tool 那的東西。
{
"protocolVersion": "0.2.9",
"name": "GeoSpatial Route Planner Agent",
"description": "Provides advanced route planning, traffic analysis, and custom map generation services. This agent can calculate optimal routes, estimate travel times considering real-time traffic, and create personalized maps with points of interest.",
"url": "https://georoute-agent.example.com/a2a/v1",
"preferredTransport": "JSONRPC",
"additionalInterfaces" : [
{"url": "https://georoute-agent.example.com/a2a/v1", "transport": "JSONRPC"},
{"url": "https://georoute-agent.example.com/a2a/grpc", "transport": "GRPC"},
{"url": "https://georoute-agent.example.com/a2a/json", "transport": "HTTP+JSON"}
],
"provider": {
"organization": "Example Geo Services Inc.",
"url": "https://www.examplegeoservices.com"
},
"iconUrl": "https://georoute-agent.example.com/icon.png",
"version": "1.2.0",
"documentationUrl": "https://docs.examplegeoservices.com/georoute-agent/api",
"capabilities": {
"streaming": true,
"pushNotifications": true,
"stateTransitionHistory": false
},
"securitySchemes": {
"google": {
"type": "openIdConnect",
"openIdConnectUrl": "https://accounts.google.com/.well-known/openid-configuration"
}
},
"security": [{ "google": ["openid", "profile", "email"] }],
"defaultInputModes": ["application/json", "text/plain"],
"defaultOutputModes": ["application/json", "image/png"],
"skills": [
{
"id": "route-optimizer-traffic",
"name": "Traffic-Aware Route Optimizer",
"description": "Calculates the optimal driving route between two or more locations, taking into account real-time traffic conditions, road closures, and user preferences (e.g., avoid tolls, prefer highways).",
"tags": ["maps", "routing", "navigation", "directions", "traffic"],
"examples": [
"Plan a route from '1600 Amphitheatre Parkway, Mountain View, CA' to 'San Francisco International Airport' avoiding tolls.",
"{\"origin\": {\"lat\": 37.422, \"lng\": -122.084}, \"destination\": {\"lat\": 37.7749, \"lng\": -122.4194}, \"preferences\": [\"avoid_ferries\"]}"
],
"inputModes": ["application/json", "text/plain"],
"outputModes": [
"application/json",
"application/vnd.geo+json",
"text/html"
]
},
{
"id": "custom-map-generator",
"name": "Personalized Map Generator",
"description": "Creates custom map images or interactive map views based on user-defined points of interest, routes, and style preferences. Can overlay data layers.",
"tags": ["maps", "customization", "visualization", "cartography"],
"examples": [
"Generate a map of my upcoming road trip with all planned stops highlighted.",
"Show me a map visualizing all coffee shops within a 1-mile radius of my current location."
],
"inputModes": ["application/json"],
"outputModes": [
"image/png",
"image/jpeg",
"application/json",
"text/html"
]
}
],
"supportsAuthenticatedExtendedCard": true,
"signatures": [
{
"protected": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpPU0UiLCJraWQiOiJrZXktMSIsImprdSI6Imh0dHBzOi8vZXhhbXBsZS5jb20vYWdlbnQvandrcy5qc29uIn0",
"signature": "QFdkNLNszlGj3z3u0YQGt_T9LixY3qtdQpZmsTdDHDe3fXV9y9-B3m2-XgCpzuhiLt8E0tV6HXoZKHv4GtHgKQ"
}
]
}
🤔 然後上面那題 client 端,要如何知識 server 支援什麼 transport ?
就是看 preferredTransport
這個欄位。
在 A2A 基本上除了 Agent Card 以下,還有以下二種主要的溝通元素,那就是 :
這兩個很重要的原因就在於,如果要實作 A2A 支援的功能,那大部份都是和這兩個有關,我簡單貼一下官網說要實作的東西,是不是都和這兩個有關 ?
🤔 一定要實作的方法
🤔 可選的要實作的方法
🤔 上面提到的 Agent 與 Agent 的上下文要如何處理呢 ?
在 A2A 會用 contextId 識別,那些是同一個事情,然後送請求時,會帶這它。也就是說每個 Agent 會透過這個唯一編號,來在各 Agent 管理這份相關的上下文,所以這也代表其它 Agent 不會拿到你的上下文。
https://a2a-protocol.org/latest/topics/life-of-a-task/#example-follow-up-scenario
上面都是在說文謅謅的東西,這裡來實際上根據以上的東西,用情境範例來理解它整個溝通流程與結構。
🤔 情境 1 : 發現 Agent 與進行最簡單的 say hello ~
這裡就是大部份最開始的情境,都會先透過上面提到的Agent Card
來知道其它 Agent 的資訊。
🤔 情境 2 : 請幫我整理這 30 天的學習資料,然後寄信到這個 email 信箱 ( 通知版本 )
整個流程大概就會如下 :
message/send
裡面說了我要做啥。然後 message/send payload 大概會長的如下 :
{
"jsonrpc": "2.0",
"id": "req-001",
"method": "message/send",
"params": {
"message": {
"role": "user",
"parts": [
{
"kind": "text",
"text": "請幫我整理這 30 天的學習資料,然後寄信到 user@example.com"
}
],
"messageId": "6dbc13b5-bd57-4c2b-b503-24e381b6c8d6"
},
"configuration": {
"pushNotificationConfig": {
"url": "https://my-app.com/webhook/a2a-notifications",
"token": "secure-client-token-xyz",
"authentication": {
"schemes": ["Bearer"]
}
}
}
}
}
🤔 情境 3 : 請幫我整理這 30 天的學習資料,然後寄信到這個 email 信箱 ( 輪詢 )
然後這個是如果我們不用通知,而是用輪詢的情況下的流程 ( 現實中還是有可能,例如你們服務封閉,外網是打不進去的 )。
message/send
裡面說了我要做啥,payload 大約如下。// 1. 發送訊息 (message/send)
{
"jsonrpc": "2.0",
"id": "req-001",
"method": "message/send",
"params": {
"message": {
"role": "user",
"parts": [
{
"kind": "text",
"text": "請幫我整理這 30 天的學習資料,然後寄信到 user@example.com"
}
],
"messageId": "6dbc13b5-bd57-4c2b-b503-24e381b6c8d6"
}
}
}
// Server 回應
{
"jsonrpc": "2.0",
"id": "req-001",
"result": {
"id": "363422be-b0f9-4692-a24d-278670e7c7f1",
"contextId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
"status": {
"state": "working"
},
"kind": "task"
}
}
// 2. 查詢任務狀態 (tasks/get)
{
"jsonrpc": "2.0",
"id": "req-002",
"method": "tasks/get",
"params": {
"id": "363422be-b0f9-4692-a24d-278670e7c7f1"
}
}
// Server 回應 - 進行中
{
"jsonrpc": "2.0",
"id": "req-002",
"result": {
"id": "363422be-b0f9-4692-a24d-278670e7c7f1",
"contextId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
"status": {
"state": "working"
},
"kind": "task"
}
}
// Server 回應 - 完成
{
"jsonrpc": "2.0",
"id": "req-003",
"result": {
"id": "363422be-b0f9-4692-a24d-278670e7c7f1",
"contextId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
"status": {
"state": "completed"
},
"artifacts": [
{
"artifactId": "9b6934dd-37e3-4eb1-8766-962efaab63a1",
"name": "learning_summary.pdf",
"parts": [
{
"kind": "text",
"text": "學習報告已整理完成並寄送至 user@example.com"
}
]
}
],
"kind": "task"
}
}
整體來說,我自已覺得整個 A2A 協定比 MCP 協定還簡單不少,當初在看 MCP 時還花比較多時間理解,但這個只是我自已的感覺。