抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

A2A(Agent-to-Agent)协议是Google在2025年推出的开放标准,旨在解决不同AI Agent之间的通信和协作问题。随着AI Agent生态的爆发式增长,A2A协议正在成为连接异构Agent系统的关键基础设施。本文详细介绍A2A协议的设计理念、核心概念和实践应用。

为什么需要A2A协议

当前Agent生态的困境

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
┌─────────────────────────────────────────────────────────────────┐
│ Agent孤岛问题 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 现状:每个Agent都是独立的孤岛 │
│ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ Agent A │ │ Agent B │ │ Agent C │ │
│ │ (公司A) │ │ (公司B) │ │ (公司C) │ │
│ └─────────┘ └─────────┘ └─────────┘ │
│ │ │ │ │
│ │ 无法通信 │ 无法协作 │ │
│ ▼ ▼ ▼ │
│ 各自的工具 各自的格式 各自的协议 │
│ │
│ 问题: │
│ 1. 不同厂商的Agent无法互操作 │
│ 2. 集成多个Agent需要大量定制开发 │
│ 3. 没有统一的发现和调用机制 │
│ 4. 安全和认证机制各不相同 │
│ │
└─────────────────────────────────────────────────────────────────┘

A2A的解决方案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
┌─────────────────────────────────────────────────────────────────┐
│ A2A协议愿景 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 统一的Agent通信标准 │
│ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ Agent A │◀──▶│ Agent B │◀──▶│ Agent C │ │
│ └─────────┘ └─────────┘ └─────────┘ │
│ │ │ │ │
│ └──────────────┼──────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ A2A协议层 │ │
│ │ │ │
│ │ - 统一通信 │ │
│ │ - 能力发现 │ │
│ │ - 任务委托 │ │
│ │ - 安全认证 │ │
│ └─────────────┘ │
│ │
│ 效果:任何符合A2A标准的Agent都可以互相发现和协作 │
│ │
└─────────────────────────────────────────────────────────────────┘

A2A协议核心概念

1. Agent Card(Agent名片)

Agent Card是Agent的”身份证”,描述Agent的能力和接口:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
{
"name": "TravelAgent",
"description": "专业的旅行规划助手,可以搜索航班、预订酒店、规划行程",
"url": "https://travel-agent.example.com",
"version": "1.0.0",
"provider": {
"organization": "TravelCorp",
"url": "https://travelcorp.com"
},
"capabilities": {
"streaming": true,
"pushNotifications": true,
"stateTransitionHistory": true
},
"authentication": {
"schemes": ["Bearer", "OAuth2"]
},
"defaultInputModes": ["text", "text/plain"],
"defaultOutputModes": ["text", "text/plain", "application/json"],
"skills": [
{
"id": "search_flights",
"name": "搜索航班",
"description": "根据出发地、目的地和日期搜索可用航班",
"tags": ["travel", "flights", "booking"],
"examples": [
"搜索明天从北京到上海的航班",
"查找下周一最便宜的机票"
]
},
{
"id": "book_hotel",
"name": "预订酒店",
"description": "搜索并预订酒店住宿",
"tags": ["travel", "hotels", "accommodation"]
},
{
"id": "plan_itinerary",
"name": "规划行程",
"description": "根据目的地和偏好生成详细旅行计划",
"tags": ["travel", "planning"]
}
]
}

2. 核心角色

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
┌─────────────────────────────────────────────────────────────────┐
│ A2A角色模型 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────┐ │
│ │ Client Agent │ 发起请求的Agent │
│ │ (客户端Agent) │ - 发现其他Agent │
│ │ │ - 发起任务请求 │
│ │ │ - 接收结果 │
│ └────────┬────────┘ │
│ │ │
│ │ A2A Protocol │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Remote Agent │ 提供服务的Agent │
│ │ (远程Agent) │ - 发布Agent Card │
│ │ │ - 处理任务请求 │
│ │ │ - 返回执行结果 │
│ └─────────────────┘ │
│ │
│ 关键原则: │
│ - Agent对等:任何Agent既可以是Client也可以是Remote │
│ - 能力不透明:Client不需要知道Remote Agent内部实现 │
│ - 协议统一:所有交互遵循统一的消息格式 │
│ │
└─────────────────────────────────────────────────────────────────┘

3. Task(任务)

Task是A2A协议的核心工作单元:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
{
"id": "task_12345",
"sessionId": "session_abc",
"status": {
"state": "working",
"message": "正在搜索符合条件的航班...",
"timestamp": "2025-12-21T10:30:00Z"
},
"artifacts": [
{
"name": "flight_options",
"parts": [
{
"type": "application/json",
"data": {
"flights": [
{
"airline": "国航",
"flightNo": "CA1234",
"departure": "08:00",
"arrival": "10:30",
"price": 1200
}
]
}
}
]
}
],
"history": [
{
"role": "user",
"parts": [{"type": "text", "text": "帮我搜索明天北京到上海的航班"}]
},
{
"role": "agent",
"parts": [{"type": "text", "text": "好的,我来搜索明天的航班..."}]
}
]
}

4. 任务状态机

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
┌─────────────────────────────────────────────────────────────────┐
│ Task状态转换 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ │
│ │ submitted│ 任务已提交 │
│ └────┬─────┘ │
│ │ │
│ ▼ │
│ ┌──────────┐ │
│ ┌────▶│ working │◀────┐ Agent正在处理 │
│ │ └────┬─────┘ │ │
│ │ │ │ │
│ 需要更多 ┌───┴───┐ │ │
│ 输入 │ │ 用户提供 │
│ │ ▼ ▼ 更多输入 │
│ │ ┌──────┐ ┌──────────┐ │
│ └─│input │ │completed │ 任务完成 │
│ │required│ └──────────┘ │
│ └──────┘ │
│ │ │
│ │ 超时/取消 │
│ ▼ │
│ ┌──────────┐ │
│ │ canceled │ 任务取消 │
│ └──────────┘ │
│ │
│ 状态说明: │
│ - submitted: 任务已提交,等待处理 │
│ - working: Agent正在执行任务 │
│ - input_required: 需要用户提供更多信息 │
│ - completed: 任务成功完成 │
│ - canceled: 任务被取消 │
│ - failed: 任务执行失败 │
│ │
└─────────────────────────────────────────────────────────────────┘

A2A协议详解

协议架构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
┌─────────────────────────────────────────────────────────────────┐
│ A2A协议栈 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ 应用层 │ │
│ │ Agent业务逻辑、技能实现、任务处理 │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ A2A协议层 │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ Agent Card │ │ Task │ │ Message │ │ │
│ │ │ 能力发现 │ │ 任务管理 │ │ 消息格式 │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ 传输层 │ │
│ │ HTTP/HTTPS、WebSocket、Server-Sent Events │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ 安全层 │ │
│ │ OAuth 2.0、API Key、mTLS │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘

API端点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
┌─────────────────────────────────────────────────────────────────┐
│ A2A API端点 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 发现端点: │
│ GET /.well-known/agent.json │
│ └── 获取Agent Card,了解Agent能力 │
│ │
│ 任务端点: │
│ POST /tasks/send │
│ └── 创建新任务或发送消息到现有任务 │
│ │
│ GET /tasks/{taskId} │
│ └── 获取任务当前状态 │
│ │
│ POST /tasks/{taskId}/cancel │
│ └── 取消正在执行的任务 │
│ │
│ 流式端点: │
│ POST /tasks/sendSubscribe │
│ └── 创建任务并订阅实时更新(SSE) │
│ │
│ 推送端点: │
│ POST /tasks/{taskId}/pushNotification │
│ └── Agent主动推送任务更新 │
│ │
└─────────────────────────────────────────────────────────────────┘

消息格式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# A2A消息结构
class Message:
role: str # "user" 或 "agent"
parts: List[Part] # 消息内容部分
metadata: dict # 可选元数据

class Part:
type: str # MIME类型:text/plain, application/json, image/png等
text: str # 文本内容(type为text时)
data: dict # 结构化数据(type为json时)
file: FileData # 文件数据(type为文件时)

# 示例:多模态消息
message = {
"role": "user",
"parts": [
{
"type": "text",
"text": "帮我分析这张图片中的产品"
},
{
"type": "image/png",
"file": {
"name": "product.png",
"bytes": "base64_encoded_data..."
}
}
]
}

实现A2A Agent

Python实现示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import List, Optional, Dict, Any
from enum import Enum
import uuid
from datetime import datetime

app = FastAPI()

# 数据模型
class TaskState(Enum):
SUBMITTED = "submitted"
WORKING = "working"
INPUT_REQUIRED = "input_required"
COMPLETED = "completed"
CANCELED = "canceled"
FAILED = "failed"

class Part(BaseModel):
type: str
text: Optional[str] = None
data: Optional[Dict[str, Any]] = None

class Message(BaseModel):
role: str
parts: List[Part]

class TaskStatus(BaseModel):
state: TaskState
message: Optional[str] = None
timestamp: str = None

class Task(BaseModel):
id: str
sessionId: Optional[str] = None
status: TaskStatus
artifacts: List[Dict] = []
history: List[Message] = []

class SendTaskRequest(BaseModel):
id: Optional[str] = None
sessionId: Optional[str] = None
message: Message
acceptedOutputModes: List[str] = ["text/plain"]

# 存储
tasks: Dict[str, Task] = {}

# Agent Card端点
@app.get("/.well-known/agent.json")
async def get_agent_card():
return {
"name": "WeatherAgent",
"description": "提供全球天气查询服务",
"url": "https://weather-agent.example.com",
"version": "1.0.0",
"capabilities": {
"streaming": True,
"pushNotifications": False
},
"skills": [
{
"id": "get_weather",
"name": "查询天气",
"description": "查询指定城市的当前天气和预报",
"examples": [
"北京今天天气怎么样",
"查询上海未来三天的天气"
]
}
]
}

# 发送任务端点
@app.post("/tasks/send")
async def send_task(request: SendTaskRequest):
# 创建或获取任务
task_id = request.id or str(uuid.uuid4())

if task_id in tasks:
# 现有任务,添加新消息
task = tasks[task_id]
task.history.append(request.message)
else:
# 新任务
task = Task(
id=task_id,
sessionId=request.sessionId or str(uuid.uuid4()),
status=TaskStatus(
state=TaskState.SUBMITTED,
timestamp=datetime.now().isoformat()
),
history=[request.message]
)
tasks[task_id] = task

# 处理任务
result = await process_task(task, request.message)

return {
"id": task.id,
"sessionId": task.sessionId,
"status": task.status.dict(),
"artifacts": task.artifacts
}

async def process_task(task: Task, message: Message) -> Task:
"""处理任务逻辑"""
task.status = TaskStatus(
state=TaskState.WORKING,
message="正在查询天气信息...",
timestamp=datetime.now().isoformat()
)

# 提取用户请求
user_text = ""
for part in message.parts:
if part.type == "text" or part.type == "text/plain":
user_text = part.text
break

# 模拟天气查询
weather_result = get_weather_data(user_text)

# 更新任务状态和结果
task.status = TaskStatus(
state=TaskState.COMPLETED,
timestamp=datetime.now().isoformat()
)

task.artifacts = [{
"name": "weather_info",
"parts": [{
"type": "text/plain",
"text": weather_result
}]
}]

# 添加Agent回复到历史
task.history.append(Message(
role="agent",
parts=[Part(type="text", text=weather_result)]
))

return task

def get_weather_data(query: str) -> str:
"""模拟天气数据获取"""
# 实际应用中调用天气API
return f"根据您的查询'{query}',北京今天晴,气温15-23°C,适合外出。"

# 获取任务状态
@app.get("/tasks/{task_id}")
async def get_task(task_id: str):
if task_id not in tasks:
raise HTTPException(status_code=404, detail="Task not found")
return tasks[task_id]

# 取消任务
@app.post("/tasks/{task_id}/cancel")
async def cancel_task(task_id: str):
if task_id not in tasks:
raise HTTPException(status_code=404, detail="Task not found")

task = tasks[task_id]
task.status = TaskStatus(
state=TaskState.CANCELED,
message="任务已取消",
timestamp=datetime.now().isoformat()
)
return {"status": "canceled"}

客户端调用示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import httpx
import asyncio

class A2AClient:
def __init__(self, agent_url: str):
self.agent_url = agent_url
self.client = httpx.AsyncClient()

async def discover(self) -> dict:
"""发现Agent能力"""
response = await self.client.get(
f"{self.agent_url}/.well-known/agent.json"
)
return response.json()

async def send_task(
self,
message: str,
task_id: str = None,
session_id: str = None
) -> dict:
"""发送任务"""
payload = {
"message": {
"role": "user",
"parts": [{"type": "text", "text": message}]
}
}
if task_id:
payload["id"] = task_id
if session_id:
payload["sessionId"] = session_id

response = await self.client.post(
f"{self.agent_url}/tasks/send",
json=payload
)
return response.json()

async def get_task(self, task_id: str) -> dict:
"""获取任务状态"""
response = await self.client.get(
f"{self.agent_url}/tasks/{task_id}"
)
return response.json()

# 使用示例
async def main():
client = A2AClient("https://weather-agent.example.com")

# 1. 发现Agent能力
agent_card = await client.discover()
print(f"Agent: {agent_card['name']}")
print(f"Skills: {[s['name'] for s in agent_card['skills']]}")

# 2. 发送任务
result = await client.send_task("北京今天天气怎么样?")
print(f"Task ID: {result['id']}")
print(f"Status: {result['status']['state']}")

# 3. 获取结果
if result['artifacts']:
for artifact in result['artifacts']:
for part in artifact['parts']:
print(f"Result: {part.get('text', part.get('data'))}")

asyncio.run(main())

流式通信

Server-Sent Events (SSE)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
import asyncio
import json

@app.post("/tasks/sendSubscribe")
async def send_task_subscribe(request: SendTaskRequest):
"""创建任务并订阅流式更新"""

async def event_generator():
task_id = str(uuid.uuid4())

# 发送任务创建事件
yield f"event: task_created\ndata: {json.dumps({'id': task_id})}\n\n"

# 发送处理中状态
yield f"event: status_update\ndata: {json.dumps({'state': 'working', 'message': '正在处理...'})}\n\n"

# 模拟流式输出
response_text = "北京今天天气晴朗,气温15-23度,适合外出活动。"
for i, char in enumerate(response_text):
await asyncio.sleep(0.05) # 模拟延迟
yield f"event: artifact_chunk\ndata: {json.dumps({'text': char, 'index': i})}\n\n"

# 发送完成状态
yield f"event: task_completed\ndata: {json.dumps({'state': 'completed'})}\n\n"

return StreamingResponse(
event_generator(),
media_type="text/event-stream",
headers={
"Cache-Control": "no-cache",
"Connection": "keep-alive"
}
)

客户端订阅

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import httpx

async def subscribe_to_task(agent_url: str, message: str):
"""订阅任务流式更新"""
async with httpx.AsyncClient() as client:
async with client.stream(
"POST",
f"{agent_url}/tasks/sendSubscribe",
json={
"message": {
"role": "user",
"parts": [{"type": "text", "text": message}]
}
}
) as response:
async for line in response.aiter_lines():
if line.startswith("event:"):
event_type = line[7:].strip()
elif line.startswith("data:"):
data = json.loads(line[5:])
print(f"[{event_type}] {data}")

A2A与MCP的关系

协议对比

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
┌─────────────────────────────────────────────────────────────────┐
│ A2A vs MCP │
├─────────────────────────────────────────────────────────────────┤
│ │
│ MCP(Model Context Protocol) │
│ ├── 定位:连接LLM与工具/数据源 │
│ ├── 场景:Agent内部能力扩展 │
│ ├── 关系:Agent ←→ 工具 │
│ └── 类比:给Agent装上"手"和"眼" │
│ │
│ A2A(Agent-to-Agent Protocol) │
│ ├── 定位:Agent之间的通信协作 │
│ ├── 场景:多Agent协作系统 │
│ ├── 关系:Agent ←→ Agent │
│ └── 类比:让Agent能够"交流"和"协作" │
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ 组合使用 │ │
│ │ │ │
│ │ ┌─────────┐ A2A ┌─────────┐ │ │
│ │ │ Agent A │◀───────────────────▶│ Agent B │ │ │
│ │ └────┬────┘ └────┬────┘ │ │
│ │ │ MCP │ MCP │ │
│ │ ▼ ▼ │ │
│ │ ┌─────────┐ ┌─────────┐ │ │
│ │ │ 工具/ │ │ 工具/ │ │ │
│ │ │ 数据源 │ │ 数据源 │ │ │
│ │ └─────────┘ └─────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘

协同工作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# Agent使用MCP连接工具,使用A2A连接其他Agent

class TravelPlanningAgent:
def __init__(self):
# MCP连接:内部工具
self.mcp_tools = {
"database": MCPClient("postgresql://..."),
"calendar": MCPClient("google-calendar://..."),
}

# A2A连接:外部Agent
self.a2a_agents = {
"flight": A2AClient("https://flight-agent.com"),
"hotel": A2AClient("https://hotel-agent.com"),
"weather": A2AClient("https://weather-agent.com"),
}

async def plan_trip(self, destination: str, dates: str):
# 使用A2A调用其他Agent
flight_task = await self.a2a_agents["flight"].send_task(
f"搜索到{destination}的航班,{dates}"
)

hotel_task = await self.a2a_agents["hotel"].send_task(
f"搜索{destination}的酒店,{dates}"
)

weather_task = await self.a2a_agents["weather"].send_task(
f"{destination}的天气预报"
)

# 使用MCP保存到数据库
await self.mcp_tools["database"].execute(
"INSERT INTO trips ...",
{
"flights": flight_task["artifacts"],
"hotels": hotel_task["artifacts"],
"weather": weather_task["artifacts"]
}
)

return self.compile_trip_plan(flight_task, hotel_task, weather_task)

安全与认证

认证机制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# A2A支持多种认证方式

# 1. API Key认证
headers = {
"Authorization": "Bearer your-api-key"
}

# 2. OAuth 2.0
oauth_config = {
"client_id": "your-client-id",
"client_secret": "your-client-secret",
"token_url": "https://auth.example.com/token"
}

# 3. mTLS(双向TLS)
ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
ssl_context.load_cert_chain(certfile="client.crt", keyfile="client.key")

Agent Card中的认证声明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
{
"name": "SecureAgent",
"authentication": {
"schemes": ["Bearer", "OAuth2"],
"oauth2": {
"authorizationUrl": "https://auth.example.com/authorize",
"tokenUrl": "https://auth.example.com/token",
"scopes": {
"read": "读取数据",
"write": "写入数据",
"admin": "管理权限"
}
}
},
"security": {
"mtls": {
"required": true,
"caUrl": "https://example.com/ca.crt"
},
"rateLimit": {
"requests": 100,
"period": "minute"
}
}
}

实际应用场景

企业Agent网络

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
┌─────────────────────────────────────────────────────────────────┐
│ 企业Agent生态 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 用户请求:"帮我安排下周的出差行程并提交报销预申请" │
│ │
│ ┌──────────────┐ │
│ │ 协调Agent │ │
│ │ (Orchestrator)│ │
│ └──────┬───────┘ │
│ │ A2A │
│ ┌───────────────┼───────────────┐ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ 行程Agent │ │ 财务Agent │ │ 审批Agent │ │
│ │ │ │ │ │ │ │
│ │ - 订机票 │ │ - 预算检查 │ │ - 发起审批 │ │
│ │ - 订酒店 │ │ - 报销申请 │ │ - 通知上级 │ │
│ └────────────┘ └────────────┘ └────────────┘ │
│ │ │ │ │
│ │ A2A │ A2A │ A2A │
│ ▼ ▼ ▼ │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ 携程API │ │ 财务系统 │ │ OA系统 │ │
│ └────────────┘ └────────────┘ └────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘

跨组织协作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# 不同公司的Agent通过A2A协作

# 供应商Agent
class SupplierAgent:
async def handle_order_inquiry(self, task):
"""处理订单查询"""
# 检查库存、报价
return {
"available": True,
"price": 1000,
"delivery_date": "2025-12-25"
}

# 采购Agent
class PurchasingAgent:
def __init__(self):
self.suppliers = [
A2AClient("https://supplier-a.com/agent"),
A2AClient("https://supplier-b.com/agent"),
A2AClient("https://supplier-c.com/agent"),
]

async def find_best_supplier(self, product: str, quantity: int):
"""并行询价所有供应商"""
tasks = []
for supplier in self.suppliers:
task = supplier.send_task(
f"询价:{product},数量:{quantity}"
)
tasks.append(task)

results = await asyncio.gather(*tasks)

# 选择最优供应商
best = min(results, key=lambda x: x["artifacts"][0]["price"])
return best

最佳实践

Agent Card设计

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
┌─────────────────────────────────────────────────────────────────┐
│ Agent Card最佳实践 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 1. 清晰的能力描述 │
│ ├── 用自然语言描述Agent能做什么 │
│ ├── 提供具体的使用示例 │
│ └── 标明能力边界和限制 │
│ │
│ 2. 合理的Skill划分 │
│ ├── 每个Skill对应一个独立功能 │
│ ├── 使用有意义的标签便于发现 │
│ └── 避免Skill过于细碎或过于笼统 │
│ │
│ 3. 版本管理 │
│ ├── 使用语义化版本号 │
│ ├── 保持向后兼容 │
│ └── 记录变更日志 │
│ │
│ 4. 明确的输入输出 │
│ ├── 声明支持的输入/输出格式 │
│ ├── 提供Schema定义 │
│ └── 说明必填和可选字段 │
│ │
└─────────────────────────────────────────────────────────────────┘

错误处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class A2AError(Exception):
def __init__(self, code: str, message: str, details: dict = None):
self.code = code
self.message = message
self.details = details or {}

# 标准错误响应
error_response = {
"error": {
"code": "INVALID_REQUEST",
"message": "无法解析请求参数",
"details": {
"field": "message.parts",
"reason": "至少需要一个part"
}
}
}

# 错误处理中间件
@app.exception_handler(A2AError)
async def a2a_error_handler(request, exc):
return JSONResponse(
status_code=400,
content={
"error": {
"code": exc.code,
"message": exc.message,
"details": exc.details
}
}
)

总结

A2A协议核心价值

1
2
3
4
5
6
7
┌─────────────────────────────────────────────────────────────────┐
│ 1. 互操作性:不同厂商的Agent可以无缝协作 │
│ 2. 标准化:统一的发现、通信、任务管理机制 │
│ 3. 灵活性:支持同步/异步、流式/批量多种模式 │
│ 4. 安全性:内置认证授权机制 │
│ 5. 可扩展:支持多模态、自定义扩展 │
└─────────────────────────────────────────────────────────────────┘

关键组件

组件 作用
Agent Card Agent能力声明和发现
Task 工作单元和状态管理
Message 统一的消息格式
Artifact 任务产出物
SSE 流式通信支持

与其他协议的关系

1
2
3
4
5
6
7
A2A协议

├── 与MCP互补:MCP连接工具,A2A连接Agent

├── 基于HTTP:利用成熟的Web技术栈

└── 支持OAuth:集成标准认证机制

A2A协议为构建大规模、跨组织的Agent生态系统提供了标准化基础,是实现”Agent互联网”愿景的关键一步。随着更多厂商采纳A2A标准,AI Agent的协作能力将迎来质的飞跃。