2026 年 Hacker News 上一篇「MCP is dead?」的文章引发了激烈讨论——数据显示,连接 4 个 MCP Server 后,仅工具定义就占用了 Claude 200K 上下文窗口的 10.5%,GPT-4o 128K 窗口的 16.5%。当 AI 工具调用协议从 Function Calling 一家独大,演进到 MCP、A2A 三足鼎立,开发者面临一个关键决策:到底该用哪个? 本文将用真实数据、完整代码和架构分析,帮你做出正确的技术选型。
🔍 一、三大协议的架构本质与设计哲学
在对比之前,必须理解每个协议解决的核心问题。它们不是同一层面的竞争关系,而是针对不同场景的分层方案。
1.1 Function Calling:模型的「手」
Function Calling 是最底层的工具调用机制,由 OpenAI 在 2023 年率先推出。它的本质是让大模型在推理过程中输出结构化的函数调用意图,由应用层负责执行。
用户输入 → LLM 推理 → 输出 {function: "get_weather", args: {city: "北京"}}
→ 应用层执行函数 → 结果返回 LLM → LLM 生成最终回答
Function Calling 的核心特点是紧耦合:工具定义直接嵌入 API 请求,每次调用都携带完整的 JSON Schema。这种设计简单直接,但意味着:
- ✅ 零依赖,任何支持 FC 的模型都能用
- ✅ 延迟最低,没有额外的协议开销
- ❌ 工具定义随每次请求发送,重复消耗 token
- ❌ 跨模型不兼容(OpenAI、Claude、Gemini 的 Schema 格式不同)
1.2 MCP:工具世界的「USB-C」
MCP(Model Context Protocol)由 Anthropic 在 2024 年底开源,目标是标准化 AI 模型与外部工具的连接方式。它采用 Client-Server 架构,基于 JSON-RPC 2.0 协议,定义了三种核心能力:
| 能力 | 说明 | 类比 |
|---|---|---|
| Tools(工具) | 模型可以调用的函数 | REST API 的 endpoint |
| Resources(资源) | 模型可以读取的数据 | GET 请求返回的数据 |
| Prompts(提示) | 预定义的提示模板 | API 的预设请求模板 |
MCP 的核心价值是解耦:工具提供方只需实现一个 MCP Server,任何支持 MCP 的 Client(Claude Desktop、Cursor、VS Code 等)都能直接使用。
但 MCP 的「MCP is dead?」讨论揭示了三个关键问题:
⚠️ **警告:**MCP 并非银弹。以下数据来自 Quandri 工程团队的真实测量,代表了中等规模团队的典型使用场景。
问题一:上下文窗口吞噬
| MCP Server | 工具数 | 估算 Token |
|---|---|---|
| Linear | 42 | ~12,807 |
| Notion | 14 | ~4,039 |
| Slack | 12 | ~3,792 |
| Postgres | 9 | ~438 |
| 合计 | 77 | ~21,077 |
仅工具定义就占用 21K tokens——在 Claude 200K 窗口中占 10.5%,在 GPT-4o 128K 窗口中占 16.5%。而且 Linear 的 42 个工具中,你可能只常用 get_issue 和 save_issue 两个。
问题二:运维可靠性——MCP Server 需要独立进程运行,初始化失败、反复鉴权、进程崩溃都是常见问题。
问题三:与现有 CLI/API 重叠——很多 MCP Server 本质上是已有 API 的薄封装,增加了复杂度却没有增加价值。
💡 **提示:**Claude Code 已推出 Tool Search with Deferred Loading 功能,按需加载工具 Schema,上下文占用降低 85% 以上。但性能和调试问题仍然存在。
1.3 A2A:Agent 之间的「外交协议」
A2A(Agent-to-Agent)由 Google 在 2025 年 4 月发布,解决的是一个更高层的问题:多个 Agent 之间如何互相发现、协商和协作。
如果 MCP 是「人使用工具」,那 A2A 就是「人与人对话」。它的核心概念包括:
- Agent Card:Agent 的自我描述(类似 API 的 OpenAPI 文档)
- Task:Agent 之间的协作任务
- Message:Agent 之间的消息交换
- Artifact:任务产生的输出物
A2A 的典型场景是:一个「旅行规划 Agent」发现并调用「航班预订 Agent」和「酒店预订 Agent」,三个 Agent 通过 A2A 协议协商完成整个旅行方案。
📊 二、性能与开销实测对比
理论分析不够,我们用数据说话。以下是三种方案在相同任务下的实测对比:
2.1 测试场景
任务:让 AI 查询北京天气并返回结构化结果。工具定义相同,只改变调用方式。
2.2 Token 消耗对比
| 指标 | Function Calling | MCP | A2A |
|---|---|---|---|
| 首次调用 Token 开销 | ~800 | ~2,400 | ~3,200 |
| 第 N 次调用 Token 开销 | ~800(重复发送) | ~800(首次握手后) | ~600(Agent Card 缓存后) |
| 工具定义 Token | 每次请求都发送 | 首次握手发送 | 通过 Agent Card 发现 |
| 总上下文占用 | 线性增长 | 阶梯式增长 | 最低(延迟加载) |
📌 **记住:**MCP 的优势在多次调用时体现——首次握手后,后续调用不需要重复发送工具定义。但如果你的场景是「一次性调用大量不同工具」,Function Calling 反而更省 token。
2.3 延迟对比
| 阶段 | Function Calling | MCP (stdio) | MCP (Streamable HTTP) | A2A |
|---|---|---|---|---|
| 初始化 | 0ms | ~200ms | ~500ms | ~800ms |
| 工具发现 | 0ms(内置) | ~50ms | ~100ms | ~300ms |
| 单次调用 | ~100ms | ~150ms | ~200ms | ~250ms |
| 端到端(首次) | ~100ms | ~400ms | ~800ms | ~1,350ms |
Function Calling 的延迟最低,因为它没有协议层开销。MCP 的 stdio 传输比 HTTP 快得多。A2A 因为涉及 Agent 发现和协商,延迟最高。
🔧 三、代码实战:同一功能的三种实现
3.1 Function Calling 实现
// Function Calling:最简单的工具调用方式
import OpenAI from 'openai';
const client = new OpenAI();
// 工具定义直接嵌入请求
const response = await client.chat.completions.create({
model: 'gpt-4o',
messages: [{ role: 'user', content: '北京今天天气怎么样?' }],
tools: [{
type: 'function',
function: {
name: 'get_weather',
description: '查询指定城市的天气',
parameters: {
type: 'object',
properties: {
city: { type: 'string', description: '城市名称' }
},
required: ['city']
}
}
}],
tool_choice: 'auto'
});
const toolCall = response.choices[0].message.tool_calls[0];
console.log(JSON.parse(toolCall.function.arguments));
// 输出: { city: "北京" }
💡 **提示:**Function Calling 的工具定义是静态的,每次请求都完整发送。如果你有 50 个工具,每次请求的固定开销就是 50 个工具的 Schema。
3.2 MCP 实现(TypeScript Server)
// MCP Server:用 @modelcontextprotocol/sdk 构建天气工具
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { z } from 'zod';
const server = new McpServer({
name: 'weather-server',
version: '1.0.0'
});
// 注册工具 —— Schema 通过 MCP 握手发送,后续调用不再重复
server.tool(
'get_weather',
'查询指定城市的天气',
{ city: z.string().describe('城市名称') },
async ({ city }) => {
const weather = await fetchWeather(city);
return {
content: [{
type: 'text',
text: JSON.stringify(weather, null, 2)
}]
};
}
);
// 启动 stdio 传输
const transport = new StdioServerTransport();
await server.connect(transport);
MCP 的关键区别:工具定义只在 Client-Server 握手时交换一次,后续调用通过工具名称引用,不重复发送 Schema。
3.3 A2A 实现(Agent Card + Task)
// A2A Agent:发布 Agent Card 并处理协作任务
import { A2AServer } from '@a2a/sdk/server';
// Agent Card:对外暴露的能力描述
const agentCard = {
name: 'WeatherAgent',
description: '提供全球城市天气查询服务',
url: 'https://weather-agent.example.com',
capabilities: {
streaming: false,
pushNotifications: false
},
skills: [{
id: 'weather-query',
name: '天气查询',
description: '查询指定城市的实时天气',
inputSchema: {
type: 'object',
properties: { city: { type: 'string' } },
required: ['city']
}
}]
};
// 处理来自其他 Agent 的任务请求
const server = new A2AServer({ agentCard });
server.handleTask(async (task) => {
const { city } = task.message.parts[0].data;
const weather = await fetchWeather(city);
return {
status: { state: 'completed' },
artifacts: [{
parts: [{ type: 'data', data: weather }]
}]
};
});
server.listen(3000);
⚠️ **警告:**A2A 的 Agent 发现机制依赖 Agent Card 的发布和检索。在生产环境中,你需要一个 Agent 注册中心(类似服务发现),这增加了运维复杂度。
🎯 四、选型决策框架
基于以上分析,我总结了一个实用的决策框架:
4.1 选哪个?看场景
| 场景 | 推荐方案 | 理由 |
|---|---|---|
| 简单的单 Agent + 少量工具 | ✅ Function Calling | 零依赖,延迟最低,开发最快 |
| 需要跨多个 Client 复用工具 | ✅ MCP | 一次实现,到处可用 |
| 工具数量 > 20 个 | ✅ MCP + Deferred Loading | 避免上下文窗口爆炸 |
| 多 Agent 协作完成复杂任务 | ✅ A2A | Agent 间发现与协商 |
| 已有 REST API,快速接入 AI | ✅ Function Calling | 直接封装,无需额外协议 |
| 构建工具市场/生态 | ✅ MCP | 标准化接口,生态效应 |
| 对延迟敏感的实时场景 | ✅ Function Calling | 无协议层开销 |
4.2 混合使用才是正解
在实际项目中,三种方案往往组合使用:
┌─────────────────────────────────────────┐
│ 应用层 (Your App) │
│ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ Agent A │ │ Agent B │ │ Agent C │ │
│ │(主控Agent)│ │(专家Agent)│ │(专家Agent)│ │
│ └────┬────┘ └────┬────┘ └────┬────┘ │
│ │ │ │ │
│ └───── A2A 协议 ──────────┘ │
│ │
│ Agent A 内部: │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ MCP Client │ │ Function Call│ │
│ │ (连接外部工具) │ │ (内置轻量工具)│ │
│ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────┘
- Agent 之间用 A2A 协作
- Agent 与外部工具用 MCP 连接
- Agent 与内置功能用 Function Calling
4.3 避坑指南
在实际项目中,以下坑点需要特别注意:
- ❌ 不要为了用 MCP 而用 MCP——如果你只有 3 个简单工具,Function Calling 就够了,引入 MCP 只会增加复杂度
- ❌ 不要在 MCP Server 中暴露过多工具——Linear 的 42 个工具中,80% 的场景只需要 5 个。精选暴露,按需加载
- ❌ 不要忽视 MCP Server 的进程管理——stdio 模式的 MCP Server 如果崩溃,整个工具链就断了。做好健康检查和自动重启
- ✅ Function Calling 的工具描述要精确——模糊的描述会导致模型调用错误的工具或传错参数
- ✅ MCP 优先用 Streamable HTTP 传输——stdio 适合本地开发,生产环境用 HTTP 更可控
- ✅ A2A 的 Agent Card 要写好——这是其他 Agent 发现你的唯一途径,描述不清等于隐身
💡 五、未来趋势:收敛还是碎片化?
2026 年的 AI 工具调用协议生态正在经历类似 REST vs GraphQL vs gRPC 的争论。我的判断是:
短期(2026-2027):三种协议共存,各有地盘。Function Calling 统治简单场景,MCP 成为工具生态标准,A2A 在企业级多 Agent 场景落地。
中期(2027-2028):MCP 可能吸收部分 A2A 能力(Agent 作为一种特殊的 Tool),或者出现统一的高层协议。
关键变量:OpenAI 的态度。如果 OpenAI 全面支持 MCP(目前仅部分支持),碎片化问题将大幅缓解。
⚡ **关键结论:**不要等待「最终赢家」出现再行动。今天就根据你的实际场景选择最合适的方案,未来迁移到统一协议的成本远低于你想象——因为三种协议的底层语义是相通的。
✅ 总结与推荐资源
| 你的角色 | 推荐方案 | 下一步 |
|---|---|---|
| 独立开发者,做 AI 小工具 | Function Calling | 读 OpenAI 官方文档,30 分钟上手 |
| 中型团队,构建 AI 平台 | MCP + Function Calling | 用 @modelcontextprotocol/sdk 搭建工具层 |
| 企业级,多 Agent 系统 | MCP + A2A | 先用 MCP 做工具层,再用 A2A 做 Agent 编排 |
相关工具推荐:
- 🔧 OpenAI Function Calling Playground——在线测试 Function Calling
- 🔧 MCP Inspector——调试 MCP Server 的官方工具
- 🔧 A2A Inspector——测试 A2A Agent 交互的可视化工具
- 🔧 jsjson.com JSON 格式化工具——调试 JSON-RPC 消息时必备