MCP 系列(06):MCP vs Function Calling——用数据说话的选型指南
两个问题MCP 的架构优势在第 01 篇已经讲清楚了:工具标准化复用。工程师在实际选型时会追问两个更具体的问题:MCP 的进程通信开销有多大,会影响用户体验吗?代码量上,MCP 什么时候比 Function Calling 更划算?下面用真实基准测试数据回答。基准测试设计测试对象:同一个"搜索 Issues"功能方案 A(Function Calling):工具定义和执行逻辑写在 Agent 代码里,直接 Python 函数调用方案 B(MCP):工具在独立 Server 进程中,通过 stdio 子进程通信每种方案各跑 20 次调用(5 次热身不计),记录 P50/P90/均值。延迟测量结果Method Mean P50 P90 Min ──────────────────────────── ──────── ──────── ──────── ──────── Direct function call 0.01ms 0.01ms 0.01ms 0.005ms MCP stdio call 2.09ms 2.05ms 2.37ms 2.00ms MCP overhead per call: +2.08ms (283x slower than direct) MCP server startup (one-time): 570ms Calls to amortize startup cost: ~274283x 听起来很吓人。换个角度看:每次 LLM 推理需要 5-30 秒,工具调用只是其中一环。在这个时间尺度上,2ms 的协议开销完全不可感知。2ms 开销什么时候才有影响:Agent 任务:LLM 推理 15s + 工具调用 2ms → 开销占比 0.01% → 忽略不计 实时聊天机器人:目标响应 200ms,工具调用在关键路径上 → 需要评估 高频自动化:每秒调用 100 次工具 → 2ms × 100 = 200ms 额外延迟/秒 → 需要评估MCP Server 是子进程,每次会话启动时初始化一次,之后所有工具调用共用这个进程。调用超过 274 次(570ms / 2.08ms),总延迟与 Function Calling 持平。普通 Agent 任务的工具调用次数远超 274,启动成本很快摊销。代码规模测量结果Function Calling(工具定义 + handler + Agent 循环):43 行 MCP Server(独立进程,含完整 Server): 32 行 MCP Agent 代码(无工具代码): 0 行单项目差异不大(43 vs 32 行),随项目数量增长差距拉开:共享同一工具的项目数 Function Calling 总行数 MCP 总行数 MCP 节省 ────────────────────────────────────────────────────────────────────── N=1 43 32 11 行 N=2 86 32 54 行 N=3 129 32 97 行 N=5 215 32 183 行Function Calling 的代码量线性增长,每个 Agent 独立维护工具代码。MCP Server 只写一次,代码量不随项目数量变化。为什么 283x 不是选型的主要依据原始倍数容易误导决策。工具调用的实际成本由三部分组成:总延迟 = LLM 推理时间 + 工具执行时间 + 协议开销 典型场景: LLM 推理: 8,000ms 工具执行(Jira): 200ms MCP 协议开销: 2ms ───────────────────────── 总计: 8,202ms Function Calling:8,200ms(无协议开销) MCP: 8,202ms(+2ms) 差异:0.024%协议开销在 LLM 推理面前几乎不存在。选 MCP 还是 Function Calling,延迟不是决定因素。决策框架核心问题:这个工具会被多少个项目使用?使用项目数 = 1,且: 工具逻辑 30 行 Agent 快速原型,不确定是否长期用 → Function Calling 使用项目数 = 2,或: 工具需要状态管理(连接池、认证 Session) 非工程师需要能安装配置这个工具(Claude Desktop 生态) 团队想统一维护工具标准 → MCP Server 不适合 MCP 的场景: 每次调用 10ms 的实时性要求(API 网关、实时推荐) 工具与 Agent 逻辑高度耦合,分离没有意义 Agent 生命周期极短( 100 次工具调用)且对启动时间敏感一张图总结选型逻辑:工具复用次数(N个项目 × M次调用) │ ├── 单项目、低频 ────────────→ Function Calling(代码简单) │ ├── 多项目共享 ─────────────→ MCP Server(复用收益明显) │ ├── 需要状态 ───────────────→ MCP Server(进程管理状态) │ └── 实时性 10ms ──────────→ Function Calling(无协议开销)两种写法并排对比同一个"搜索 Issues"功能,完整实现代码:Function Calling(43 行,工具逻辑在 Agent 里):