A2A 协议(Agent2Agent):Google 的 Agent 间协作标准
提出问题:Agent 之间的"巴别塔"
2025 年,AI Agent 从 Demo 阶段进入生产落地。但问题也随之而来:不同框架、不同厂商构建的 Agent 互不相通。你用 LangGraph 搭了一个数据分析 Agent,伙伴用 CrewAI 搭了一个报表生成 Agent,两者要协作只能靠硬编码 API 对接 — 每个 Agent 对都要写集成代码,M×N 的集成爆炸。
M×N 问题有多痛? 假设一个企业内部有 5 个不同框架的 Agent(LangGraph、CrewAI、AutoGen、Semantic Kernel、Dify),每个 Agent 需要跟其他 4 个通信。如果没有标准协议,需要写 5×4 = 20 个集成适配器。扩展到 10 个 Agent → 90 个集成点。这跟微服务没标准化之前,RPC 协议百花齐放是一个道理。
2025 年 4 月,Google 推出了 Agent2Agent(A2A)协议,一个开放标准,旨在让 Agent 之间像 HTTP 一样发现、通信和协作。A2A 要解决什么问题?它和 MCP 是什么关系?如果你正在搭多 Agent 系统,这值得仔细看。
核心架构:Client-Server 模式拆解
角色定义
A2A 采用 Client-Server 架构,但角色不是固定的 —— 同一个 Agent 在 Task A 中可能是 Client,在 Task B 中可能是 Remote:
- Client Agent:发起任务请求的 Agent,相当于"雇主"
- Remote Agent:执行任务的 Agent,相当于"外包方"
通信流程:Client Agent 通过 Agent Card 发现 Remote Agent 的能力 → 发起 Task → Remote Agent 返回任务状态和结果。整个传输基于 JSON-RPC 2.0,走 HTTP。
四个核心能力维度
| 维度 | 做什么 | 类比 HTTP 协议 |
|---|---|---|
| Agent Card | JSON 元数据,描述能力、身份、端点 | DNS 服务发现 |
| Task 生命周期 | 统一状态机,同步/异步支持 | HTTP 请求-响应 |
| 协作机制 | 上下文共享、多轮对话、暂停恢复 | WebSocket 长连接 |
| 用户体验协商 | Agent 指定偏好的内容类型和格式 | Content Negotiation |
Agent Card 深度解析
Agent Card 是 A2A 的"名片",每个 Agent 通过 HTTP 端点暴露一个 JSON 元数据文件。其他 Agent 通过解析它来决策是否合作:
{
"schemaVersion": "1.0",
"agentCard": {
"name": "report-agent",
"description": "生成数据分析报告,支持 PDF 和 HTML 格式",
"url": "https://a2a.example.com/agent",
"version": "2.1.0",
"capabilities": {
"streaming": true,
"pushNotifications": true,
"stateTransitionHistory": false
},
"skills": [
{
"id": "generate_report",
"name": "生成报告",
"description": "基于结构化数据生成可视化报告",
"tags": ["report", "visualization", "data"],
"input": {
"type": "object",
"properties": {
"data": { "type": "string", "description": "JSON 格式的原始数据" },
"format": { "type": "string", "enum": ["pdf", "html"], "default": "html" },
"template": { "type": "string", "enum": ["simple", "detailed", "executive"] }
},
"required": ["data"]
}
}
],
"authentication": {
"schemes": ["bearer"],
"credentials": "https://a2a.example.com/auth/token"
}
}
}需要注意的点:Agent Card 的 capabilities 字段里,streaming 和 pushNotifications 决定了 Remote Agent 支持哪种通信模式。如果 Client Agent 只支持 polling,但 Remote Agent 只支持 push,两者需要协商降到最低公共能力 —— 类似于 WebSocket 的协议协商。
面试追问:Agent Card 与 MCP 的 tools 有什么区别?
MCP 的 tools 定义的是"工具能做什么",关注的是输入输出 schema;A2A 的 Agent Card 定义的是"Agent 能做什么",除了能力描述,还包含通信偏好、认证方式、版本号。两者定位不同层级:MCP 是函数签名,A2A 是服务目录。
Task 生命周期:从提交到完成的完整状态机
A2A 把 Agent 之间的协作抽象为 Task 的生命周期管理。这是最核心的抽象 — 两个 Agent 之间就是围绕 Task 展开的。
状态转换图
submitted ──→ working ──→ completed
│
↓
input-required ──→ working ──→ completed
│ │
↓ ↓
working ──→ failed canceled状态说明:
| 状态 | 含义 | 典型场景 |
|---|---|---|
submitted | 任务已提交,等待处理 | Client 刚 POST 请求 |
working | 正在处理中 | Agent 正在查询数据库、调用 LLM |
input-required | 需要更多信息 | 需要用户确认、或需要其他 Agent 提供数据 |
completed | 执行成功,有结果 | 报表生成完成,返回 URL |
failed | 执行失败 | 第三方 API 超时、数据格式不对 |
canceled | 被主动取消 | Client 超时放弃或用户手动取消 |
同步 vs 异步:两种模式选择
同步模式 —— 简单任务,一步到位:
// Client 发起请求
POST /agent HTTP/1.1
Content-Type: application/json
Authorization: Bearer token_xxx
{
"jsonrpc": "2.0",
"method": "tasks.send",
"params": {
"id": "task-001",
"sessionId": "sess-abc",
"message": {
"role": "user",
"parts": [
{ "type": "text", "text": "计算 1+1 等于多少" }
]
}
}
}
// Remote 同步返回
{
"jsonrpc": "2.0",
"id": "task-001",
"result": {
"id": "task-001",
"status": "completed",
"artifacts": [
{
"parts": [
{ "type": "text", "text": "1+1=2" }
]
}
]
}
}异步模式 —— 复杂任务(数据查询、多步推理):
// Client 发起请求
{
"jsonrpc": "2.0",
"method": "tasks.send",
"params": {
"id": "task-002",
"sessionId": "sess-abc",
"message": {
"role": "user",
"parts": [
{ "type": "text", "text": "分析上季度销售数据,生成一份包含趋势分析和异常检测的报表" }
]
}
}
}
// Remote 立即返回:任务已接收,正在处理
{
"jsonrpc": "2.0",
"id": "task-002",
"result": {
"id": "task-002",
"status": "working",
"statusUpdate": "开始分析数据,预计需要 30 秒"
}
}
// Client 轮询进度
GET /agent?taskId=task-002 HTTP/1.1
// 如果 Remote 支持 push,Client 可以注册一个 webhook 回调
// 远程主动推送结果过来,减少轮询开销input-required 状态的设计妙处
这个状态是 A2A 区别于简单 RPC 的关键。当 Remote Agent 遇到信息不足的场景,不会直接失败,而是"暂停"等待输入:
时序流程:
Client Agent Remote Agent
│ │
│── tasks.send(分析销售数据) ──→│
│ │── 检查数据:缺少区域筛选条件
│←── status: input-required ──│
│ reason: "需要指定区域" │
│ │
│── tasks.send(补充: 华东区) ──→│
│ │── 继续分析
│←── status: completed ──────│
│ artifacts: 报表结果 │实战场景:数据分析 Agent 在跑报表时发现数据量太大(超过 1000 万行),需要用户确认是否继续。Agent 通过 input-required 状态"问"回来,而不是直接报错或全量执行。这在生产系统中比直接失败友好得多。
Artifact 输出:不止是文本
A2A 的任务结果(Artifact)支持多种格式:
{
"artifacts": [
{
"name": "季度销售报告",
"parts": [
{ "type": "text", "text": "华东区 Q2 销售额同比增长 23%..." },
{ "type": "file", "mimeType": "application/pdf", "url": "https://cdn.example.com/report/q2.pdf" },
{ "type": "data", "data": { "totalRevenue": 12500000, "growthRate": 0.23 } }
]
}
]
}一个 Task 可以产出多个 Artifact,每个 Artifact 可以包含多个 Part(文本、文件、结构化数据混排)。这跟 LLM 的 multi-modal 输出思路一致。
A2A 与 MCP 的分工:工具 vs 协作
这是面试高频题,也是实际架构设计中最容易搞混的地方。
对比表(面试版)
| 维度 | MCP (Model Context Protocol) | A2A (Agent2Agent) |
|---|---|---|
| 目的 | Agent 连工具/数据/API | Agent 连其他 Agent |
| 角色 | Client=Agent, Server=工具 | Client=雇主Agent, Remote=执行Agent |
| 传输层 | stdio / SSE(本地优先) | HTTP(JSON-RPC,网络优先) |
| 核心抽象 | Resources / Tools / Prompts | Agent Card / Task / Artifact |
| 状态管理 | 无状态,每次调用独立 | 有状态 Task 生命周期管理 |
| 认证 | 传输层自带 | Agent Card 声明 + Bearer/OAuth |
| 发布方 | Anthropic (2024.11) | Google (2025.04) |
| 生态规模 | 200+ 工具实现 | 50+ 合作伙伴(发布时) |
两者叠加使用的架构
┌──────────────────────────────┐
│ Orchestrator Agent │
│ (LangGraph / Custom) │
└──────┬───────────────┬────────┘
│ │
A2A │ │ A2A
┌───────▼──────┐ ┌──────▼───────┐
│ Data Agent │ │ Report Agent │
│ (CrewAI) │ │ (Custom) │
└───────┬──────┘ └──────┬───────┘
│ │
MCP │ MCP │ MCP
┌───────▼──────┐ ┌──────▼───────┐
│ SQLite DB │ │ PDF Renderer │
│ BigQuery API │ │ S3 Storage │
└──────────────┘ └──────────────┘真实场景串联:
- Orchestrator Agent 收到用户请求:"分析昨天销售数据,出一份 PDF 报告"
- Orchestrator 通过 A2A 向 Data Agent 发起 Task:「查询昨天销售数据」
- Data Agent 通过 MCP 调用 BigQuery API,拿到原始数据
- Data Agent 通过 A2A 返回结果(status: completed, artifacts: 数据)
- Orchestrator 通过 A2A 向 Report Agent 发起 Task:「生成 PDF 报告」
- Report Agent 通过 MCP 调用 PDF Renderer 和 S3 Storage
- Report Agent 通过 A2A 返回 PDF 下载链接
一个坑:Agent 间通信的超时怎么处理?
A2A 协议本身没有规定超时策略。实战中需要自己实现:
- Client 侧:设置
tasks.send调用超时(建议 30s),超时后根据 Task 状态决定是重试、放弃还是等待 - Remote 侧:长任务需要定期返回
status: working+ 进度更新,否则 Client 会认为 Agent 挂了 - 幂等:Task ID 由 Client 生成,Remote 侧需要去重。如果同一个 Task ID 收到两次,返回上次结果即可
企业级协作场景与生态
50+ 合作伙伴意味着什么?
A2A 发布时获得了超过 50 个合作伙伴的支持,包括 Atlassian、Salesforce、SAP、ServiceNow、LangChain 等。这份名单揭示了一个信号:这不是 Google 一家的标准,而是企业软件厂商集体需要的东西。
为什么?因为企业软件天然是"多系统"的。CRM、ERP、BI、HR 系统各自独立,之前靠集成中间件(MuleSoft、TIBCO)做数据打通。Agent 起来后,集成从"数据层"上升到了"智能层" —— 不只是数据互通,更是决策和行动的协作。
典型应用场景
场景一:跨系统自动化(CRM → ERP → BI)
客户下单 → CRM Agent 创建订单
→ A2A 调用 ERP Agent 检查库存 → 确认发货
→ A2A 调用 BI Agent 更新销售看板场景二:多框架协作
LangGraph 搭建的客服 Agent 处理用户咨询
→ A2A 调用 CrewAI 搭建的退换货 Agent 处理售后
→ A2A 调用 Semantic Kernel 搭建的质检 Agent 审核退款框架之间零耦合,只通过 A2A 协议通信。不同团队可以各自选技术栈,只要实现 A2A 端点就行。
场景三:人机协作的暂停恢复
Agent 在处理退款时发现金额超过 5000 元,需要人工审核。通过 input-required 状态暂停,等待审批后恢复执行。这个流程在 A2A 中天然支持,不用自己写状态机。
Google ADK 的定位
Google 提供了 ADK(Agent Development Kit),原生支持 A2A 协议。但 ADK 不是必须的 —— 任何框架只要实现 A2A 的 HTTP 端点,就能互通。ADK 的价值在于开箱即用 + 与 Google Cloud 生态(Gemini、Vertex AI、Cloud Run)的集成。
面试中怎么答 A2A 相关的问题
问题:"A2A 和 MCP 有什么区别?"
回答结构(30 秒版本):
A2A 和 MCP 是互补关系,不是竞争。MCP 解决的是 Agent 怎么调用工具和数据源,A2A 解决的是 Agent 之间怎么协作。类比微服务:MCP 是 RPC 调用,A2A 是服务间消息。MCP 的抽象是 Resources/Tools,A2A 的抽象是 Agent Card/Task。实际架构中两者叠加使用。
扩展版(1 分钟,适合技术面):
从设计目标看,MCP 是 Anthropic 为了让 Claude 能调用外部工具而设计的,定位是"Agent-工具"协议,传输层走 stdio(本地进程)或 SSE(远程);A2A 是 Google 为了让不同 Agent 协作而设计的,定位是"Agent-Agent"协议,传输层走 HTTP/JSON-RPC。MCP 是 stateless 的,每次调用独立;A2A 是有状态 Task 生命周期管理,支持暂停恢复。举一个叠加场景:我的数据分析 Agent 通过 MCP 调用 BigQuery 拿数据,再通过 A2A 把处理结果传给报表 Agent 生成 PDF。
问题:"A2A 协议的局限性是什么?"
关键点:
- 生态尚早:虽然有 50+ 合作伙伴,但实际生产落地案例还不多
- 延迟问题:Agent 间通信走 HTTP,每次调用都有网络开销。如果 Agent 链路过长(A→B→C→D),端到端延迟会显著增加
- 安全性:Agent 之间互相暴露能力,如果某个 Agent 被攻破,攻击面会扩大(类似 SSRF 攻击)
- 协议协商:当两个 Agent 能力不匹配时(比如一个只支持 streaming,另一个只支持 polling),协商机制还不够成熟
参考
参考:Google A2A 协议规范(2025.04);Google ADK 文档;MCP 协议规范(Anthropic,2024.11);LangChain A2A 集成文档