MCP vs A2A 实战对比:一篇文章讲透 AI Agent 两大通信协议的设计哲学与生产落地
2026 年,AI Agent 的竞争已经从"谁的模型更强"转向了"谁的智能体更能协作"。在这场协作革命中,两个看似低调却极其关键的协议正在重塑 AI 工程师的工作方式——MCP(Model Context Protocol)和 A2A(Agent2Agent)。
网上关于这两个协议的对比已经太多:大都停留在"一句话版本"的层面。要么告诉你"MCP 是 AI 的 USB,A2A 是 AI 的 HTTP",要么丢给你一张分层图表然后就没有下文。作为一个真正写过生产级 Agent 的工程师,我花了整整两周时间,把两个协议都撸了一个遍,从协议栈设计理念到实际代码落地,写了一堆 Demo 才敢下笔写这篇文章。
这篇文章不讲正确的废话,只讲我实际踩过的坑、趟过的雷、以及最终形成的认知。
背景:为什么我们需要标准协议?
在 MCP 和 A2A 出现之前,AI 智能体的开发是一场"野蛮生长"。
2024 年那会儿,如果你让 Claude 调用一个飞书机器人,你需要:
第一步,去翻飞书开放平台的 API 文档,找到 Webhook 的格式
第二步,手写一个 Python 函数,封装成 JSON 格式
第三步,配置到 Claude Code 的 settings 里面
第四步,祈祷别出 bug,因为下次换模型又要重来一遍
同一个项目,Austin 给 OpenAI 写了 Tool Use,给 Anthropic 写了 Function Call——互不兼容,每个模型都要单独适配。更恐怖的是,当你的系统里有三五个模型、七八个工具,一旦换模型,整个工具链都要重写。这不叫 AI Agent,这叫"体力活 Agent"。
MCP 要解决的,就是这种"每次都从零开始"的困境。它的核心思路是:定义一套标准的通信协议,让 AI 模型和外部工具之间的交互方式统一化——就像 USB-C 让不同设备之间的物理连接标准化一样。
A2A 的野心更大。它解决的不是工具调用的问题,而是"Agent 和 Agent 怎么聊天"的问题。想象你有一个研究 Agent、一个写代码 Agent、一个代码审查 Agent,它们三个怎么分工?怎么协作?谁负责调度谁?出现的错误怎么传递?A2A 就是来解决这个问题的。
一、MCP 协议深度解析
1.1 MCP 是什么
MCP(Model Context Protocol)最初由 Anthropic 在 2025 年底推出,核心使命是:让 AI 模型能以统一的方式连接外部工具和数据源。
你可以把 MCP 理解为 AI 世界的"驱动程序"。以前模型要调用工具,需要针对每个工具分别写适配代码;有了 MCP 之后,只要工具实现了 MCP 接口,模型就能自动发现和使用这些工具。
1.2 MCP 的核心架构
MCP 的架构非常简单,三层结构:
Server(服务端):暴露三类能力——Tools(工具)、Resources(资源)、Prompts(提示词模板)。通过 stdio 或 HTTP+SSE 与客户端通信,实现具体的工具逻辑。
Client(客户端):连接到 Server,发起工具调用请求。可以是 Claude Code、Cursor,或者是任何实现了 MCP 客户端的 AI 应用。
Transport Layer(传输层):两种通信方式——stdio(本地进程通信,最常用、安全隔离)和 HTTP+SSE(网络通信、远程服务器、多客户端)。
来看一个最简单的 MCP Server 实现(Python):
from mcp.server import Server
from mcp.server.models import Tool, Resource
import json
# 创建 MCP Server 实例
server = Server("my-weather-server")
# 注册一个工具:查询天气
@server.tool()
async def get_weather(city: str) -> str:
"""查询指定城市的天气"""
# 这里可以调用真实的天气 API
weather_data = {
"北京": "晴,22°C",
"上海": "多云,25°C",
"深圳": "雷阵雨,28°C"
}
return weather_data.get(city, "未找到该城市天气数据")
# 运行 Server
if __name__ == "__main__":
server.run()
这就是一个完整的 MCP Server。客户端连接上来之后,AI 模型会自动发现这个 get_weather 工具,不需要你手写任何调用代码。
1.3 MCP 的消息格式
MCP 使用 JSON-RPC 2.0 作为消息格式。这是一个被广泛验证的协议规范,很多地方都能看到它的影子:
// 客户端请求工具列表
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list"
}
// 服务器响应
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"tools": [
{
"name": "get_weather",
"description": "查询指定城市的天气",
"inputSchema": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称"
}
}
}
}
]
}
}
// 客户端调用工具
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "get_weather",
"arguments": {
"city": "北京"
}
}
}
简洁、清晰、易于调试。这是 MCP 为什么能在短期内获得大量生态支持的原因之一——协议规范本身就是成熟的。
1.4 MCP 的安全性设计
MCP 在设计上考虑了安全性,但这反而成了争议点。
MCP 服务器可以访问用户系统上的各种资源——文件系统、浏览器、数据库。这意味着,如果一个恶意的 MCP Server 被安装了,它可以做的事情就多了。
2026 年 5 月披露的 CVE-2026-33032(又称 MCPwn)漏洞就是一个例子:
# 漏洞在于路由注册不对称
func InitRouter(r *gin.Engine) {
// /mcp 有两层保护
r.Any("/mcp", middleware.IPWhiteList(), middleware.AuthRequired())
// /mcp_message 只有一层保护!
r.Any("/mcp_message", middleware.IPWhiteList()) # 缺少 AuthRequired()
# 问题:IP 白名单默认为空,空列表 = 允许所有
# 结果:攻击者可以通过 /mcp_message 绕过身份验证!
}
这是一个经典的身份验证绕过漏洞。两个端点调用同一个 MCP Handler,但因为其中一个缺少认证保护,攻击者可以绕过身份验证直接调用高权限操作。
MCP 安全最佳实践:
永远不要直接暴露 MCP Server 到公网:MCP 的设计初衷是本地进程通信,不是远程 RPC。如果需要远程访问,通过 VPN 或者专门的认证代理。
仔细审查 MCP Server 的权限:安装新的 MCP Server 时,明确它需要什么权限。文件访问?网络访问?Shell 执行?不给不必要的权限。
定期审计已安装的 MCP Server:用工具定期扫描,看看有没有可疑的 MCP Server 在运行。
关注 MCP 官方安全公告:MCP 生态还在快速发展,新的安全漏洞会被发现。关注官方 GitHub 和安全邮件列表。
二、A2A 协议深度解析
2.1 A2A 是什么
A2A(Agent2Agent)协议由 Google 在 2026 年正式推出,联合了 50+ 合作伙伴(Salesforce、SAP、Atlassian 等),目标是成为 AI Agent 世界的"HTTP 协议"。
如果说 MCP 解决的是"Agent 怎么调用工具"的问题,那 A2A 要解决的就是"Agent ���么��其他 Agent 协作"的问题。
A2A 的核心愿景是:不同团队开发的 Agent,不需要关心对方的内部实现,只需要遵循协议,就能互相调用。
2.2 A2A 的核心概念
A2A 协议有三个核心实体:
Client Agent(客户端 Agent):发起请求的一方,负责协调和调用其他 Agent。
Remote Agent(服务端 Agent):接收请求的一方,真正干活的 Agent。Client Agent 不需要知道 Remote Agent 用的是什么框架、什么模型,只需要通过 A2A 协议发送请求。
Agent Card(元数据卡片):这是 A2A 最创新的设计。每个 A2A Agent 必须在 /.well-known/agent.json 暴露自己的能力描述卡片,包括:支持的技能(Skills)、认证方式、流式传输能力等。
来看一个 Agent Card 的例子:
{
"name": "Research Agent",
"description": "专业的AI研究助手,能搜索和分析互联网信息",
"version": "1.0.0",
"capabilities": {
"streaming": true,
"pushNotifications": true
},
"skills": [
{
"id": "web-research",
"name": "Web Research",
"description": "在互联网上搜索和研究任意主题"
},
{
"id": "fact-check",
"name": "Fact Checking",
"description": "验证事实声明的准确性"
}
],
"authentication": {
"schemes": ["bearer", "oauth2"]
},
"endpoint": "https://agent.example.com/a2a"
}
这个设计太重要了——它让 Agent 变成了"可发现的"。以前你需要手动配置另一个 Agent 的 API 地址,现在只需要知道对方的域名,Agent Card 会自动告诉你它能做什么、怎么认证、支持什么能力。
2.3 A2A 的通信模式
A2A 定义了三种核心交互模式:
Request-Response(请求-响应):最简单,发送请求,等待结果,同步调用。
Task Push(任务推送):适合长时间运行的任务。提交任务后,服务端返回一个 Task ID,客户端可以通过这个 ID 查询任务状态或者接收推送通知。
Streaming(流式响应):适合需要实时反馈的场景,比如 Agent 正在搜索、正在分析,需要一步一步给你看进度。
来看一个 A2A Server 的实现(TypeScript):
import { A2AServer, AgentCard, TaskContext } from '@anthropic/a2a';
// 定义 Agent Card
const agentCard: AgentCard = {
name: 'Writer Agent',
description: '专业的技术写作助手',
version: '1.0.0',
endpoint: 'https://writer-agent.example.com/a2a',
skills: [
{
id: 'tech-writing',
name: 'Technical Writing',
description: '撰写技术文档和博客文章'
},
{
id: 'code-documentation',
name: 'Code Documentation',
description: '为代码生成文档注释'
}
]
};
// 创建 A2A Server
const server = new A2AServer({
agentCard,
// 实现具体的技能处理逻辑
async handleSkill(skillId: string, context: TaskContext) {
switch (skillId) {
case 'tech-writing':
return await this.writeTechArticle(context);
case 'code-documentation':
return await this.generateDocComments(context);
default:
throw new Error(`Unknown skill: ${skillId}`);
}
}
});
// 启动 Server
await server.start();
这段代码展示了 A2A 的核心模式:定义 Agent Card 和技能处理逻辑,启动 Server,就可以被其他 Agent 调用了。
2.4 A2A 与 MCP 的关系
很多人把 A2A 和 MCP 混为一谈,其实它们解决的是完全不同的层次:
| 维度 | MCP | A2A |
|---|---|---|
| 解决什么 | AI 模型 ↔ 工具/数据源 | Agent ↔ Agent |
| 通信方向 | 单���:模型调用工具 | 双向:Agent 间平等协作 |
| 类比 | 函数调用(Function Call) | 微服务间通信(gRPC/HTTP) |
| 设计目标 | 让模型能使用工具 | 让 Agent 能互相调用 |
| 地位层级 | 接口层(Lower) | 应用层(Higher) |
核心理解:MCP 是"Agent 的工具箱",A2A 是"Agent 的社交网络"。
它们不是竞争关系,而是互补关系。MCP 负责 Agent 与外部世界(工具、数据)的连接;A2A 负责 Agent 与其他 Agent 的协作。
一个实用的对比:
# 用 MCP 调用工具
result = await mcp_client.call_tool("search_web", {"query": "最新AI新闻"})
# 模型自己在后台完成了工具发现和调用
# 用 A2A 调用其他 Agent
# 假设有一个研究 Agent,我可以这样调用:
a2a_client = A2ARemoteClient("https://research-agent.example.com")
result = await a2a_client.send_task(
skill="web_research",
input={"query": "最新AI新闻", "max_results": 5}
)
2.5 A2A 的安全考量
A2A 因为是 Agent 间的通信,安全考量也很重要:
认证和授权:A2A 支持多种认证方式,包括 Bearer Token、OAuth2。部署时要用强认证,不要用 API Key 这种静态凭证。
Agent Card 的可信度:Agent Card 描述了 Agent 的能力和端点。如果 Agent Card 被篡改,可能会把请求导向恶意的 Agent。使用 HTTPS + 证书校验来保证不被篡改。
任务数据的隔离:不同 Client 发来的任务数据要严格隔离,防止数据泄露。
三、生产环境实战:MCP + A2A 联合架构
3.1 什么时候选 MCP,什么时候选 A2A
我的经验法则:
用 MCP 当:
- 你需要让模型调用外部工具——搜索、数据库、文件、API
- 工具数量不多,需要集中管理
- 单个模型需要使用多个工具
用 A2A 当:
- 你需要多个 Agent 分工协作
- 每个 Agent 有独立的职责,可能来自不同团队
- 需要任务的持久化和状态追踪
- 任务可能需要很长时间,阶段性反馈
两者都用当:
- 大型多 Agent 系统,每个 Agent 可能需要调用外部工具
- A2A 负责 Agent 间的协作,MCP 负责 Agent 与工具的连接
3.2 实际架构示例
让我展示一个我实际用过的架构:
┌─────────────────────────────────────────────────────┐
│ User Interface │
└─────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ Host Agent(主控 Agent,负责任务分发) │
│ 使用 A2A 协议与其他 Agent 通信 │
└─────────────────────────────────────────────────────┘
│ │ │
┌──────┴──────┐ ┌────┴────┐ ┌──────┴──────┐
▼ ▼ ▼ ▼ ▼ ▼
┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐
│Research│ │ Writer │ │Coder │ │Reviewer│ │Deployer│
│ Agent │ │ Agent │ │ Agent │ │ Agent │ │ Agent │
└────────┘ └────────┘ └────────┘ └────────┘ └────────┘
│ │ │ │ │
│ │ │ │ │
▼ ▼ ▼ ▼ ▼
┌─────────────────────────────────────────────┐
│ MCP Tool Layer │
│ 所有 Agent 通过 MCP 连接外部工具和服务 │
└─────────────────────────────────────────────┘
这个架构的工作流程是:
- 用户通过聊天界面发送任务,比如"帮我研究最新的 AI Agent 框架发展趋势,然后写一篇技术博客"
- Host Agent 接收到任务,用 A2A 协议调度 Research Agent 进行研究
- Research Agent 通过 MCP 搜索互联网、整理信息,然后把结果返回给 Host Agent
- Host Agent 再把研究结果发送给 Writer Agent
- Writer Agent 调用 MCP 撰写博客文章
- 如果需要代码示例,Host Agent 会调度 Coder Agent,然后 Reviewer Agent 审核
- 最后 Deployer Agent 负责发布
整个过程中,A2A 负责 Agent 间的任务调度,MCP 负责每个 Agent 与外部世界的连接。清晰的职责划分,让系统更容易维护和扩展。
3.3 避坑指南:我踩过的血泪教训
在实际生产中,我踩过的坑:
坑 1:MCP Server 的响应超时
MCP 的请求有时会超时,尤其是在网络调用、外部 API 不稳定的情况下。解决方案:给每次调用设置合理的超时,配合重试机制。我一般设置 30 秒超时,最多重试 3 次。
坑 2:A2A 任务的长时间阻塞
A2A 的任务是异步的,任务可能需要很长时间。我一开始没处理好状态的追踪,后来学会了:任务的每个状态变化都用回调函数处理,不要假定任务一定会成功完成。需要保存 Task ID,定期查询状态。
坑 3:Agent 之间的数据传递格式不统一
不同的 Agent 对数据格式的期望不一样。研究 Agent 返回的是 Markdown,Writer Agent 期望的是结构化 JSON。解决方案:在 Host Agent 这一层做数据格式的转换,每两个 Agent 之间的数据传递都是清晰的、有明确 schema 的。
坑 4:MCP Server 的权限过度
很多 MCP Server 默认给了太多权限。我现在的做法是:最小权限原则,只给 Agent 必要的权限,其他的一律不给。
四、协议的未来:从竞争到融合
4.1 当前生态现状
截止到 2026 年 6 月,MCP 和 A2A 的生态都在快速发展:
MCP 生态:
- Anthropic、OpenAI、Claude Code 都原生支持 MCP
- 官方维护的 MCP Servers 仓库有数百个社区贡献的 Server
- VS Code 的 Cursor、Warp 等主流 IDE 都开始支持 MCP
A2A 生态:
- Google 牵头,50+ 合作伙伴
- Salesforce、SAP、Atlassian 等企业软件巨头都在支持
- 逐渐有更多的 Agent 开发框架开始支持 A2A
4.2 我的判断
我认为两三年内,两者不会是竞争关系,而是会融合:
MCP 负责底层工具的标准化,A2A 负责上层协作的标准化。就像 TCP/IP 和 HTTP 一样,各自在自己的层级发挥作用。
对于工程师的建议是:两个协议都要学,不用纠结选哪个。在实际项目中,你会同时用到它们。学好两个协议,在不同的场景用合适的那个。
结语
写到最后,我想用一句话总结这篇文章的核心:
MCP 是让 Agent 能用工具,A2A 是让 Agent 能找同事。两者不冲突,都是 AI Agent 技术栈中不可或缺的一环。
作为一个写了多年后端的工程师,我对这种标准化的协议是非常乐观的。以前每次接入新的 API 都要从头写适配代码,后来有了 OpenAPI���Swagger)规范,全球的 API 都能被统一描述和管理。我相信 MCP 和 A2A 也一样,它们的普及会让 AI Agent 的开发变得更加标准、高效。
技术浪潮一波接一波,作为工程师,我们要做的是保持学习,然后做出有用的东西。