为什么需要 A2A
现在的 AI Agent 生态是一个个孤岛。你用 LangChain 搭了个客服 Agent,隔壁团队用 AutoGen 做了个数据分析 Agent——它们互相不知道对方的存在。
A2A(Agent-to-Agent Protocol)是 Google 在 2025 年 4 月发布的开放协议,目标就是打破这些孤岛。就像 HTTP 让不同浏览器和服务器能通信一样,A2A 让不同框架、不同厂商、不同语言的 Agent 能互相发现和协作。
之前:
LangChain Agent ──❌── AutoGen Agent
CrewAI Agent ──❌── 自研 Agent
之后:
LangChain Agent ──A2A── AutoGen Agent
CrewAI Agent ──A2A── 自研 Agent
任何 Agent ──A2A── 任何 Agent
四大核心概念
A2A 协议定义了四个核心概念,理解它们就理解了 A2A 的全部。
1. Agent Card:Agent 的名片
每个 Agent 对外暴露一个 JSON 文件(/.well-known/agent.json),描述自己是谁、能做什么、怎么联系。
{
"name": "TravelPlanner",
"description": "专业旅游规划 Agent,支持多约束行程优化",
"url": "https://travel-agent.example.com",
"provider": {
"organization": "TravelAgent Inc.",
"url": "https://travelagent.com"
},
"capabilities": {
"streaming": true,
"pushNotifications": true,
"stateTransitionHistory": true
},
"defaultInputModes": ["text", "text/plain"],
"defaultOutputModes": ["text", "text/plain"],
"skills": [
{
"id": "itinerary-planning",
"name": "行程规划",
"description": "根据用户需求生成多天旅游行程",
"tags": ["travel", "planning", "optimization"],
"examples": [
"帮我规划一个3天的西安旅游行程",
"带老人去北京4天,少走路的行程"
]
},
{
"id": "weather-query",
"name": "天气查询",
"description": "查询目的地实时天气和预报",
"tags": ["weather", "forecast"]
}
]
}
Agent Card 是整个协议的入口。一个 Agent 发现了另一个 Agent 的 Card,就知道它能干什么、怎么调。
2. Task:任务的唯一标识
A2A 把每一次任务抽象为一个 Task 对象,有唯一 ID 和完整生命周期。
{
"id": "task_abc123",
"sessionId": "session_xyz789",
"status": {
"state": "working",
"message": {
"role": "agent",
"parts": [{"type": "text", "text": "正在查询西安景点信息..."}]
},
"timestamp": "2025-06-19T10:30:00Z"
},
"history": [
{
"role": "user",
"parts": [{"type": "text", "text": "帮我规划一个3天西安游"}]
}
]
}
Task 的状态流转:
submitted → working → input-required → working → completed
↓ ↓
failed canceled
input-required 是一个关键状态——当 Agent 需要用户补充信息时(比如"你是自驾还是坐高铁?"),Task 进入这个状态等待输入,而不是傻等或报错。
3. Message:对话的载体
Message 是 Agent 之间交换信息的基本单位。它借鉴了 Google 的 Gemini API 设计,用 parts 数组支持多模态内容。
{
"role": "agent",
"parts": [
{
"type": "text",
"text": "我帮你规划了一个3天西安行程:\n\n第1天:兵马俑、华清池\n第2天:古城墙、回民街\n第3天:大雁塔、陕西历史博物馆"
},
{
"type": "data",
"data": {
"itinerary": {
"days": 3,
"total_budget": 2500,
"pois": ["兵马俑", "华清池", "古城墙", "回民街", "大雁塔", "陕西历史博物馆"]
}
}
}
]
}
parts 的设计很巧妙——同一个消息里可以既有自然语言、又有结构化数据、还有文件引用。
4. Artifact:任务的产出物
当 Agent 完成了长时间任务(如生成了一份完整的行程 PDF),结果以 Artifact 形式返回。
{
"artifactId": "artifact_001",
"name": "西安3日行程.pdf",
"parts": [
{
"type": "file",
"file": {
"url": "https://travel-agent.example.com/files/itinerary_abc123.pdf",
"mimeType": "application/pdf",
"name": "西安3日行程.pdf"
}
}
]
}
Artifact 和 Message 的关系:Message 是过程中的交流,Artifact 是最终的产出。
实际通信流程
以一个典型的跨 Agent 协作为例:用户的个人助手 Agent(Assistant Agent)找专业的旅游规划 Agent(Travel Agent)帮忙。
Assistant Agent Travel Agent
│ │
│ ① 发现 Agent Card │
│─────────────────────────────────>│
│ GET /.well-known/agent.json │
│<─────────────────────────────────│
│ {skills: [itinerary-planning]} │
│ │
│ ② 创建 Task │
│─────────────────────────────────>│
│ POST /tasks │
│ {message: "规划3天西安游"} │
│<─────────────────────────────────│
│ {taskId: "task_001", │
│ state: "submitted"} │
│ │
│ ③ 轮询 Task 状态 │
│─────────────────────────────────>│
│ GET /tasks/task_001 │
│<─────────────────────────────────│
│ {state: "working"} │
│ │
│ ④ 获取结果 │
│─────────────────────────────────>│
│ GET /tasks/task_001 │
│<─────────────────────────────────│
│ {state: "completed", │
│ artifact: {...}} │
或者用 SSE 流式接收状态变更,避免轮询:
GET /tasks/task_001?stream=true
→ event: status-update, state: working
→ event: status-update, state: working, message: "正在查询天气..."
→ event: status-update, state: completed, artifact: {...}
A2A vs MCP:别搞混了
这是最常被问的问题——A2A 和 MCP(Model Context Protocol)有什么区别?
| 维度 | A2A | MCP |
|---|---|---|
| 解决什么问题 | Agent 之间怎么通信 | Agent 和工具怎么通信 |
| 类比 | HTTP(服务间通信) | USB-C(设备接口) |
| 谁调谁 | Agent 调 Agent | Agent 调 Tool |
| 提出方 | Anthropic | |
| 协议载体 | JSON-RPC over HTTP | JSON-RPC over stdio/SSE |
一句话区分:MCP 是给 Agent 装轮子(工具),A2A 是给 Agent 装电话(通信)。
两者不冲突——一个 Agent 可以同时支持 MCP(调工具)和 A2A(调其他 Agent)。MCP 连接纵向的工具链,A2A 编织横向的协作网。
代码示例:搭建一个 A2A Agent
Google 提供了官方的 Python SDK 来快速构建 A2A Agent。
定义 Agent
from a2a.server import A2AServer
from a2a.server.agent import Agent
class TravelAgent(Agent):
def get_agent_card(self):
return {
"name": "TravelPlanner",
"description": "专业旅游规划",
"skills": [
{
"id": "itinerary-planning",
"name": "行程规划",
"description": "生成多天旅游行程",
}
]
}
async def execute(self, task):
query = task.current_message.get_text()
itinerary = await self.plan_itinerary(query)
return {
"message": {
"role": "agent",
"parts": [
{"type": "text", "text": itinerary},
{"type": "data", "data": {"itinerary": itinerary}}
]
},
"state": "completed"
}
# 启动服务
server = A2AServer(agent=TravelAgent())
server.start(host="0.0.0.0", port=8080)
调用另一个 Agent
from a2a.client import A2AClient
client = A2AClient("https://travel-agent.example.com")
# 创建任务
task = await client.create_task(
message="帮我规划3天西安游,预算3000"
)
# 等待完成
result = await client.wait_for_completion(task.id)
print(result.artifact)
A2A 带来的可能性
A2A 打破框架壁垒后,会催生几类新的应用模式:
模式一:Agent 市场
像 App Store 一样,专门的 Agent 可以被发现和调用。用户不需要一个全能 Agent,只需要一个好用的"Agent 调度器"。
模式二:专业化分工
财务 Agent 做预算、医疗 Agent 看报告、法律 Agent 审合同——各司其职,通过 A2A 协作。
模式三:链式推理
用户问题 → 意图分类 Agent → 发现需要三方面信息
→ 调用财经 Agent 查数据
→ 调用分析 Agent 做判断
→ 调用写作 Agent 写报告
→ 综合返回
当前的局限
A2A 还很年轻(2025 年 4 月发布),有几块尚未完善:
- 服务发现机制:目前靠手动配置 Agent URL,还没有类似 DNS 的自动发现
- 安全认证:Agent 间互信机制还在草案阶段
- 生态规模:目前支持 A2A 的 Agent 框架有限,主要以 Google 自己的生态为主
- 长任务管理:跨数小时甚至数天的任务如何管理和恢复仍在探索
但方向是明确的——Agent 不会永远活在框架的围墙花园里。就像 90 年代的局域网最终连成了互联网,Agent 也需要一个共同的通信协议。