Agent 日报

MCP vs Function Calling:工具集成该用哪个

Cover image for 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 CallingMCP
它是什么模型层机制工具打包协议
跨 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 开销。

猜你喜欢