MCP 系列(06):MCP vs Function Calling——用数据说话的选型指南

两个问题

MCP 的架构优势在第 01 篇已经讲清楚了:工具标准化复用。工程师在实际选型时会追问两个更具体的问题:

  1. MCP 的进程通信开销有多大,会影响用户体验吗?
  2. 代码量上,MCP 什么时候比 Function Calling 更划算?

下面用真实基准测试数据回答。


基准测试设计

测试对象:同一个"搜索 Issues"功能

  • 方案 A(Function Calling):工具定义和执行逻辑写在 Agent 代码里,直接 Python 函数调用
  • 方案 B(MCP):工具在独立 Server 进程中,通过 stdio 子进程通信

每种方案各跑 20 次调用(5 次热身不计),记录 P50/P90/均值。


延迟测量结果

sql 复制代码
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: ~274

283x 听起来很吓人。换个角度看:每次 LLM 推理需要 5-30 秒,工具调用只是其中一环。在这个时间尺度上,2ms 的协议开销完全不可感知。

2ms 开销什么时候才有影响:

markdown 复制代码
Agent 任务:LLM 推理 15s + 工具调用 2ms → 开销占比 0.01%
                                         → 忽略不计

实时聊天机器人:目标响应 < 200ms,工具调用在关键路径上
                                         → 需要评估

高频自动化:每秒调用 100 次工具 → 2ms × 100 = 200ms 额外延迟/秒
                                         → 需要评估

MCP Server 是子进程,每次会话启动时初始化一次,之后所有工具调用共用这个进程。调用超过 274 次(570ms / 2.08ms),总延迟与 Function Calling 持平。普通 Agent 任务的工具调用次数远超 274,启动成本很快摊销。


代码规模测量结果

vbscript 复制代码
Function Calling(工具定义 + handler + Agent 循环):43 行
MCP Server(独立进程,含完整 Server):               32 行
MCP Agent 代码(无工具代码):                         0 行

单项目差异不大(43 vs 32 行),随项目数量增长差距拉开:

ini 复制代码
共享同一工具的项目数    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 不是选型的主要依据

原始倍数容易误导决策。工具调用的实际成本由三部分组成:

javascript 复制代码
总延迟 = LLM 推理时间 + 工具执行时间 + 协议开销

典型场景:
  LLM 推理:        8,000ms
  工具执行(Jira):  200ms
  MCP 协议开销:       2ms
  ─────────────────────────
  总计:           8,202ms

Function Calling:8,200ms(无协议开销)
MCP:            8,202ms(+2ms)

差异:0.024%

协议开销在 LLM 推理面前几乎不存在。选 MCP 还是 Function Calling,延迟不是决定因素。


决策框架

核心问题:这个工具会被多少个项目使用?

vbscript 复制代码
使用项目数 = 1,且:
  工具逻辑 < 30 行
  Agent 快速原型,不确定是否长期用
  → Function Calling

使用项目数 >= 2,或:
  工具需要状态管理(连接池、认证 Session)
  非工程师需要能安装配置这个工具(Claude Desktop 生态)
  团队想统一维护工具标准
  → MCP Server

不适合 MCP 的场景:
  每次调用 < 10ms 的实时性要求(API 网关、实时推荐)
  工具与 Agent 逻辑高度耦合,分离没有意义
  Agent 生命周期极短(< 100 次工具调用)且对启动时间敏感

一张图总结选型逻辑:

vbscript 复制代码
工具复用次数(N个项目 × M次调用)
        │
        ├── 单项目、低频 ────────────→ Function Calling(代码简单)
        │
        ├── 多项目共享 ─────────────→ MCP Server(复用收益明显)
        │
        ├── 需要状态 ───────────────→ MCP Server(进程管理状态)
        │
        └── 实时性 < 10ms ──────────→ Function Calling(无协议开销)

两种写法并排对比

同一个"搜索 Issues"功能,完整实现代码:

Function Calling(43 行,工具逻辑在 Agent 里):

python 复制代码
# 工具定义
SEARCH_TOOL = {
    "name": "search_issues",
    "description": "Search Jira issues by keyword",
    "input_schema": {
        "type": "object",
        "properties": {"query": {"type": "string"}},
        "required": ["query"]
    }
}

# 工具实现
def search_issues(query: str) -> str:
    results = [i for i in ISSUES if query.lower() in i["summary"].lower()]
    return "\n".join(f"[{i['key']}] {i['summary']}" for i in results)

# Agent 循环(每个 Agent 都要写这段)
def run_agent(user_input: str):
    client = anthropic.Anthropic()
    messages = [{"role": "user", "content": user_input}]
    while True:
        response = client.messages.create(model="claude-sonnet-4-6",
                                          tools=[SEARCH_TOOL], messages=messages)
        if response.stop_reason != "tool_use":
            return response.content[0].text
        tc = next(b for b in response.content if b.type == "tool_use")
        result = search_issues(tc.input["query"])
        messages.extend([...])  # 添加工具结果

MCP Server(32 行 Server,Agent 代码 0 行工具代码):

python 复制代码
# jira_server.py(一次性写,所有 Agent 复用)
server = Server("jira-tools")

@server.list_tools()
async def list_tools():
    return [Tool(name="search_issues", description="Search issues",
                 inputSchema={"type": "object",
                              "properties": {"query": {"type": "string"}},
                              "required": ["query"]})]

@server.call_tool()
async def call_tool(name, arguments):
    query = arguments["query"].lower()
    results = [i for i in ISSUES if query in i["summary"].lower()]
    text = "\n".join(f"[{i['key']}] {i['summary']}" for i in results)
    return [TextContent(type="text", text=text)]

async def main():
    async with stdio_server() as (r, w):
        await server.run(r, w, server.create_initialization_options())

asyncio.run(main())

# Agent 配置(在 settings.json 里加一行,Agent 代码里不需要任何工具代码)

总结

三条结论来自真实数字:

  1. 2ms 开销在 Agent 场景里可以忽略:LLM 推理是 8000ms,协议开销是 2ms,占比 0.024%。"283x 更慢"是技术上正确但实践上误导的描述
  2. 570ms 启动成本需要预热设计:如果 Agent 需要快速响应第一个工具调用,在会话开始时提前初始化 MCP Server(懒加载 vs 预加载的工程选择)
  3. 代码复用是选 MCP 的核心原因:单项目差异有限(43 vs 32 行),3 个项目共用时 FC 需要 129 行而 MCP 保持 32 行------工具越多、项目越多,差距越大

参考资料


欢迎访问 PrimeSkills ------ 一个精心策划的 AI Agent 与技能市场,所有内容均经过真实企业级工作流验证。没有噱头,只有真正有效的东西。

更多实用知识和有趣产品,欢迎访问我的个人主页

相关推荐
IT_陈寒12 小时前
SpringBoot自动配置的坑,这次真踩疼我了
前端·人工智能·后端
Mac的实验室12 小时前
谷歌邮箱注册教程|为什么注册谷歌邮箱账号需要扫码发短信验证,最新申请谷歌账号注册风控原理分享
人工智能
甲维斯12 小时前
Claude和Kimi消耗60亿,价值2.6万,收入0蛋!
人工智能
子兮曰12 小时前
AI 浏览器 Agent 的安全困局:当自动化工具可以偷走你的登录态
前端·人工智能·后端
FBI HackerHarry浩12 小时前
AI大模型开发V2第四阶段线性回归
人工智能·算法·线性回归
71777712 小时前
国产 DevOps 新路径:解析 Gitee 软件工厂本土化、信创、AI 核心优势
人工智能·gitee·devops
小白说大模型13 小时前
人工智能:深度学习中的卷积神经网络(CNN)实战应用
人工智能·深度学习·cnn
众人皆醒我独醉13 小时前
Triton Inference Server:NVIDIA 的推理"瑞士军刀"——LLM 只是它的一种负载
人工智能·面试·ai编程
Vince的修炼之路13 小时前
大模型推理框架SGLang的源码分析
人工智能·架构
码途潇潇13 小时前
Codex Rules 与 Skills:项目级和全局级配置一览
人工智能