MCP vs Function Calling:工具集成该用哪个
讲清 AI Agent 的 MCP vs function calling:它们解决的是同一问题的不同层。各自何时用、怎么组合,以及大多数团队忽略的 token 成本取舍。
TL;DR — Function calling 是模型请求工具的方式。MCP 是工具被打包、跨 Agent 共享的方式。它们不是竞争对手,是不同的层。单个应用的私有工具用裸 function calling。同一批工具服务多个 Agent 或客户端时用 MCP。大多数真实系统是在 function calling 之上用 MCP,因为底层 MCP 工具最终还是变成 function-call 定义。
问题本身就错了
“MCP vs function calling” 被反复问,这是个分类错误。就像问”REST vs HTTP”。Function calling 是模型层机制:LLM 输出一个结构化请求,去调用一个带参数的具名函数。MCP(Model Context Protocol)是更高层的标准,规定工具服务器如何向任意客户端暴露能力。
有件事能把它讲清:当你把 MCP 服务器连到 Claude 或 GPT-4o,MCP 工具在抵达模型前会被翻译成 function-call 定义。模型仍然在做 function calling。MCP 只是标准化了这些定义从哪来、结果怎么流回去。
所以真正的问题不是”用哪个”,而是”我需不需要在 function calling 之上加 MCP 这一层”。
Function Calling:机制
每个主流模型 API 都支持 function calling。你在请求里传工具定义;模型用一个结构化调用回应。(标准规范见 OpenAI 的 function-calling 文档。)
from openai import OpenAI
client = OpenAI(base_url="https://api.sandbase.ai/v1", api_key="sk-...")
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get current weather for a city",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "City name"}
},
"required": ["city"]
}
}
}]
response = client.chat.completions.create(
model="anthropic/claude-sonnet-4",
messages=[{"role": "user", "content": "What's the weather in Tokyo?"}],
tools=tools
)
# 模型用 tool_call 回应。你执行它,追加结果,再调一次。
tool_call = response.choices[0].message.tool_calls[0]
print(tool_call.function.name) # "get_weather"
print(tool_call.function.arguments) # '{"city": "Tokyo"}'
你定义工具,模型请求调用它,你跑实际的函数,再把结果喂回去。模型从不执行任何东西,它只发出意图。这就是全部机制,MCP 不替代它。
优势: 零额外基础设施。最低延迟。完全控制。对只有一个应用用的工具完美。
弱点: 工具定义和执行逻辑住在你的应用里。想在另一个 Agent 里用同一个 get_weather?复制粘贴。五个 Agent,五份拷贝,五个地方修同一个 bug。
MCP:打包层
MCP 解决复用问题。你写一次工具服务器;它通过标准协议暴露工具、资源和 prompt。任何 MCP 兼容客户端连上来就能用。
// 一个暴露同样天气工具的最小 MCP 服务器
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";
const server = new McpServer({ name: "weather", version: "1.0.0" });
server.tool(
"get_weather",
"Get current weather for a city",
{ city: z.string().describe("City name") },
async ({ city }) => {
const data = await fetchWeather(city); // 你的真实实现
return { content: [{ type: "text", text: JSON.stringify(data) }] };
}
);
现在 Claude Desktop、Cursor、你的 CLI Agent、你的生产应用全连到这一个服务器。修一次 bug,每个客户端都拿到。这就是全部卖点。动手搭一个见我们的数据分析自定义 MCP 服务器实战;把服务器接进 Agent 见把 MCP 服务器接进 Agent。
优势: 写一次,到处用。一个不断增长的预制服务器生态(GitHub、Postgres、Slack、文件系统)。标准化的认证和 transport。
弱点: 更多活动部件。每个工具 schema 都会被注入 context window,而 MCP 服务器往往暴露很多工具,token 开销累积得很快。
真正有用的对比
| 维度 | 裸 Function Calling | MCP |
|---|---|---|
| 它是什么 | 模型层机制 | 工具打包协议 |
| 跨 Agent 复用 | 复制粘贴 | 连同一个服务器 |
| 基础设施 | 无 | 跑一个服务器(stdio 或 HTTP) |
| 延迟 | 最低 | +1 跳(通常可忽略) |
| Token 开销 | 你精确控制发什么 | 所有服务器工具被注入 |
| 认证/transport | 你自己造 | 标准化 |
| 最适合 | 单个应用的私有工具 | 跨客户端共享的工具 |
| 生态 | 无(全自己写) | 有预制服务器可用 |
没人提的 Token 成本
陷阱在这。MCP 服务器经常暴露 10-30 个工具。连三个服务器,模型在每一次调用都看到 60+ 个工具定义——schema、描述、参数文档。这可能是 5,000-15,000 token 的开销,用户的问题还没开始处理。
裸 function calling,你只发当前任务相关的工具。MCP,你常常拿到连上的服务器提供的一切,不管需不需要。
解法:别盲目连每个 MCP 服务器。要么只连某个 Agent 需要的,要么在前面放一个路由层,按相关性过滤工具再喂给模型。这跟 Agent 记忆架构里的 token 纪律是同一个——加载正确的上下文,不是全部。
到底怎么决定
用裸 function calling,当:
- 工具只属于一个应用
- 你需要绝对最低的延迟和 token 数
- 你想紧控到底哪些 schema 抵达模型
- 你在做原型,不想立一个服务器
用 MCP,当:
- 同一个能力被多个 Agent、应用或客户端用(Claude Desktop、Cursor、你的后端)
- 你想用预制的社区服务器而不是自己写集成
- 你需要跨大量工具的标准化认证和 transport
- 你在做一个平台,各团队独立贡献工具
两个都用(常见情况): 大多数生产系统用 MCP 处理共享、可复用的能力(数据库访问、GitHub、内部 API),用裸 function calling 处理应用特定的胶水逻辑。既然 MCP 反正会编译成 function call,混用很自然。
FAQ
MCP 替代 function calling 吗?
不。MCP 坐在 function calling 之上。当 MCP 客户端连到模型,它把服务器的工具转成 function-call 定义。模型仍然做普通 function calling。MCP 标准化的是这些定义怎么产生、怎么共享。
MCP 比 function calling 慢吗?
略慢。多一跳到 MCP 服务器(stdio 是一个进程边界)。本地服务器是几毫秒。更大的成本是注入大量工具 schema 的 token 开销,不是延迟。
MCP 工具能配任何模型吗?
任何支持 function calling 的模型,也就是所有主流的(Claude、GPT-4o、Gemini,以及大多数开源模型通过其 API)。MCP 客户端负责把工具转成每个模型的 function-calling 格式。通过 SandBase 这样的网关你能换模型不动工具代码。
什么时候 MCP 是杀鸡用牛刀?
对一个只有几个私有工具、其他客户端永远不会用的单应用。立一个 MCP 服务器加了基础设施却零收益。裸 function calling 在那里更简单更快。一旦有第二个客户端需要同样的工具,MCP 就值回票价。
MCP 服务器更费 token 吗?
会,因为服务器往往暴露很多工具,所有这些 schema 每次调用都被注入上下文。只连 Agent 真正需要的服务器,或按相关性过滤工具,把开销压下去。
关键要点
- Function calling 是模型机制;MCP 是它之上的打包和共享层。是不同的层,不是对手。
- MCP 工具在抵达模型前变成 function-call 定义,所以两种方式模型都在做 function calling。
- 裸 function calling 在单应用的私有工具上赢:最低延迟、最低 token、零基础设施。
- MCP 在跨多个 Agent 或客户端共享的工具上赢,有不断增长的预制服务器生态,代价是你必须管理的 token 开销。


