MCP 解决”Agent 怎么连工具和数据源”,A2A 解决”Agent 怎么和其它 Agent 协作”——两条链路分工明确,组合起来才形成完整的智能体网络。在做一个多 Agent 数据分析平台时,我让所有 Agent 都用 MCP 接数据源、用 A2A 互相委派任务,既避免了每个 Agent 重写适配器(数据接入 N 个变成 1 个),又让复杂任务能被拆给专业 Agent 并行处理,整体吞吐翻了几倍。下文把这两条协议的协同架构、典型场景、关键设计点拆开讲清。
一、先把 MCP 和 A2A 摆清楚
MCP(Model Context Protocol)由 Anthropic 在 2024 年底提出,定位是”Agent 接入工具和数据的标准协议”。它定义了 Host、Client、Server 三方,Server 暴露工具(读数据库、调 API、读文件),Client 帮 Agent 调用,Host 跑 Agent 本身。
A2A(Agent-to-Agent Protocol)由 Google 在 2025 年提出,定位是”Agent 之间协作的标准协议”。它定义了 Agent Card(能力广告)、Task(有状态任务)、Artifact(交付产物)、Part(产物组成)几个核心概念,让 Agent 能发现彼此、委派任务、异步等待结果。
两者关系用一句话总结:MCP 解决”纵向”(Agent 武装到牙齿),A2A 解决”横向”(武装好的 Agent 组成队伍)。
二、一个完整的协同架构
下面是一个”研究助手”多 Agent 系统的典型架构,8 个 Agent 各自有专长,通过 MCP+A2A 协作:
┌──────────────────────────────────────┐
│ 用户(通过 Web/CLI 提交研究问题) │
└─────────────┬────────────────────────┘
│ A2A: 委派任务
▼
┌──────────────────────────────────────┐
│ Orchestrator Agent(编排 Agent) │
│ - 拆任务 / 调度子 Agent │
│ - 维护全局状态机 │
└────┬────────┬────────┬────────┬────────┘
│A2A │A2A │A2A │A2A
┌──────────▼──┐ ┌───▼──────┐ ┌▼────────┐ ┌▼──────────┐
│ Search Agent │ │ Analyst │ │ Writer │ │ Critic │
│ (查资料) │ │ Agent │ │ Agent │ │ Agent │
│ │ │ (做分析) │ │ (写文) │ │ (审校) │
└──────┬──────┘ └────┬─────┘ └────┬────┘ └─────┬─────┘
│MCP │MCP │MCP │MCP
┌──────▼──────┐ ┌───▼──────┐ ┌───▼─────┐ ┌────▼─────┐
│ Web Search │ │ Postgres │ │ Datasets│ │ Style │
│ MCP Server │ │ MCP │ │ MCP │ │ Guide │
│ │ │ Server │ │ Server │ │ MCP │
└─────────────┘ └──────────┘ └─────────┘ └──────────┘
Orchestrator 拿到用户的”研究 XX 公司 Q3 财报”任务,拆成 4 步:
- 调 Search Agent 查 XX 公司新闻和公告(用 Web Search MCP);
- 调 Analyst Agent 拉财务数据做同比环比(用 Postgres MCP + Datasets MCP);
- 调 Writer Agent 把分析写成 800 字摘要(用 Style Guide MCP);
- 调 Critic Agent 审校事实和风格,需要时回退到上一步。
每一步都是 A2A 委派,每步内部的工具调用都走 MCP。
三、关键设计点
把 MCP 和 A2A 组合起来用,有几个工程上的关键点:
- A2A 的发现机制要建在 MCP 之上:Agent Card 通常通过一个 “Agent Registry MCP Server” 暴露,Orchestrator 用 MCP 拉 Agent 列表,再用 A2A 发起任务。这样发现链路和工具调用链路同源,运维更简单。
- A2A 的 Task 状态要走持久化:Agent 之间可能跨小时甚至跨天协作,Task 状态必须落库(Postgres/Redis),不能只放内存。
- MCP Server 复用最大化:同一个 Postgres MCP Server,Analyst Agent 和 Critic Agent 都能用,避免每 Agent 写一套适配器。
- 权限边界按”层”切:MCP 层按”哪个 Agent 能访问哪个 Server”切,A2A 层按”哪个 Agent 能委派给哪个 Agent”切,两层叠加形成完整 ACL。
四、典型场景的协议选型
按场景对照协议,有助于避免错配:
| 场景 | 推荐协议 | 原因 |
|---|---|---|
| Agent 查数据库 | MCP | 单向、原子、无状态 |
| Agent 读文件 / 调 SaaS API | MCP | 工具语义 |
| Agent 调代码解释器 | MCP | 副作用短事务 |
| Agent 委派”审稿”给 Critic | A2A | 有状态、可中断、要交付 Artifact |
| Agent 发起”研究 XX 主题” | A2A | 长时任务、跨 Agent、需要状态机 |
| Agent 间共享”任务上下文” | A2A | 用 Artifact 传递 Part |
| 一次性查询 | MCP | 简单直接 |
| 异步协作 / 长时任务 | A2A | 状态可恢复 |
| 多 Agent 并行处理同一任务 | A2A | 委派多个 Task 并行 |
五、一段协同调用代码
下面这段代码展示 Orchestrator Agent 同时使用 MCP 和 A2A 的最小化实现:
import asyncio
from a2a_sdk import A2AClient, Task
from mcp_sdk import MCPClient
async def research_pipeline(question: str):
# 1) A2A: 委派"查资料"给 Search Agent
search_task = await A2AClient("search-agent").send_task(
Task(skill="web_search", input={"query": question})
)
search_result = await search_task.wait()
# 2) A2A: 委派"做分析"给 Analyst Agent(基于 search_result)
analyst_task = await A2AClient("analyst-agent").send_task(
Task(skill="financial_analysis", input={"sources": search_result.parts})
)
analysis = await analyst_task.wait()
# 3) MCP: Analyst 内部用 Postgres MCP 拉财务数据
# (这一步发生在 Analyst Agent 内部,这里展示其内部调用)
# data = await MCPClient("postgres").call("query",
# {"sql": "SELECT * FROM financials WHERE company = $1", "params": [...]})
# 4) A2A: 委派"写文"给 Writer Agent
writer_task = await A2AClient("writer-agent").send_task(
Task(skill="summarize", input={"analysis": analysis.parts})
)
article = await writer_task.wait()
return article
注意代码里”任务分解 → 委派 → 等待”的循环,正是 A2A 的核心动作;而每个 Agent 内部会用自己的 MCP 工具集去完成任务。
六、常见反模式
把 MCP 和 A2A 用错的几种典型情况:
- 用 A2A 调用工具:让 Agent A “委派” Agent B 去查数据库,Agent B 内部又用 MCP 查——这层间接完全多余,Agent A 自己用 MCP 查就行。
- 用 MCP 协同 Agent:让多个 Agent 都暴露成 “MCP Tool”,互相调用——这把有状态异步任务当无状态工具用,状态管理全乱。
- 不分场景地全用 A2A:连一次性查询也走 A2A,徒增几秒延迟和 token 成本。
实战里我还遇到过一种”双协议串台”的反模式:某 Agent 收到 A2A 任务后,在内部又把”调用 MCP 工具”这件事外包给另一个 Agent,导致 A2A Task 状态被反复嵌套,事后审计几乎查不清谁真正动了数据。规范的做法是:A2A 边界清晰,每个 Task 至少有一个人类可读的 skill 名(比如 “researchcompany” / “summarizedoc”),内部无论怎么调 MCP 都不再开 A2A 子任务,这样 A2A 的 Task 树和 MCP 的工具调用树是正交的,排查问题只需顺着 A2A Task 树往下钻。
常见问题(FAQ)
Q1:MCP 和 A2A 会不会合并成一个协议?
短期内不会,它们分别由不同组织定义,解决的问题域不重叠;但可能会有”统一网关”项目把它们一起管理。
Q2:Orchestrator Agent 是不是单点故障?
是的,生产环境要部署多实例 + Leader 选举;或者用无中心的 P2P 委派(每 Agent 都能接任务)。
Q3:小项目(2-3 个 Agent)用得着 A2A 吗?
用不着。直接函数调用即可,只有 Agent 数量超过 5 个、跨服务部署时才上 A2A。