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 与技能市场,所有内容均经过真实企业级工作流验证。没有噱头,只有真正有效的东西。

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

相关推荐
冬奇Lab1 小时前
每日一个开源项目(第159篇):Vibe-Trading - 用自然语言做量化研究,AI 驱动的个人交易 Agent
人工智能·开源·资讯
AI大模型-小雄1 小时前
2026 年 7 月国内怎么开通 ChatGPT Pro?5x / 20x 区别、适合人群与避坑指南
人工智能·gpt·chatgpt·ai编程·开发工具·codex·chatgpt pro
ctrl_v助手2 小时前
Halcon学习笔记2
人工智能·笔记·学习
彭军辉2 小时前
生命体AI和数字生命有什么区别
人工智能
Rauser Mack2 小时前
AI大模型测评:GPT-5.5翻车、Claude封神——大模型选型的真相
人工智能·gpt·prompt
2601_961946082 小时前
AI API 网关实战:从单 Key 管理到企业级多租户架构
大数据·人工智能·金融·架构·api·个人开发
AI-好学者2 小时前
GraphRAG与混合检索架构
人工智能·知识图谱
智写-AI3 小时前
真实有效的免费降英文AI工具服务商
人工智能·python