协议拆解 · Agent 基础设施

工具调用是怎么标准化的:从函数调用到 MCP

每一次标准化,都是把「不可靠的约定」换成「可验证的契约」。但契约解决了连接,没解决分寸。

2026-10-11协议拆解约 16 分钟

引言:模型很聪明,为什么「用个工具」这么难?

2022 年底,ChatGPT 刚火起来那阵,几乎所有人都想到同一个用法:能不能让它帮我查天气、下单、翻数据库?

很快就发现,模型真正难的地方不是「知道要干什么」。它早就知道要查天气。难的是另一件事——把想干的事,准确地告诉程序。

它只会吐字。

你让它查北京天气,它可能回一句「好的,我来帮你查一下北京的天气」;也可能回一段 JSON;还可能回半句话加一个表情符号。同样的请求,两次输出格式都可能不一样。程序读不懂这种东西。

于是那段时间,开发者在做同一件事:写正则、写 if-else,从模型的自由文本里把参数抠出来。抠错了就重试。有人后来回忆,那阵子有将近一半的代码,在处理「模型又没按格式说」。

这篇文章要讲的,就是这段历史:工具调用是怎么从「各写各的解析器」,一步步走到今天这个叫 MCP 的公开协议的。

沿着一条主线推进:标准化到底标准化了什么,又有什么东西始终没被标准化?想清楚后半句,比记住前半句更有用。

01标准出现之前,人们怎么让模型调工具?

答案很朴素:全靠提示词工程加文本解析。能跑,但脆得像玻璃。

先把时间拨到 2022 年 10 月。

那时候还没有任何厂商提供官方的函数调用能力。研究者 Yao 等人发了一篇论文,叫 ReAct(Reason + Act)。思路今天看依然漂亮:让模型交替生成「推理」和「行动」。

模型先想一步,输出一个动作,比如 Search[北京天气]。程序把这个动作解析出来,真的去搜,再把结果塞回去。模型看到结果,接着想下一步,或者给出答案。

这是「推理加行动」范式的奠基工作,后来几乎所有 Agent 都长这个样子。

但它有一个前提:模型必须严格按你规定的格式输出。而模型不是为这个格式训练出来的。

一个真实到有点好笑的细节

有人为了让模型稳定输出 JSON,在提示词里写满了各种强调:「你必须严格输出 JSON」「不要加任何解释」「不要说『好的』」。然后在代码里写正则去匹配。

跑几次就崩了。模型的输出是「这是结果:{"city":"北京"}」,多了一句「这是结果:」,正则匹配不上。于是加一层容错,再崩,再加。

这种做法能上生产吗?能。但它依赖一个很虚的东西——模型今天心情好,愿意按格式说话。换句话说,格式靠自觉,契约并不存在。

LangChain 这类框架后来把这套东西封装成了 Agent / Tool 抽象,看起来专业多了。但扒开看,底层还是提示词约定加文本解析。换汤没换药。

这一章的答案:在官方标准出现前,工具调用本质上是一次「赌运气」——赌模型这次会好好说话。整个行业都在给这个赌局打补丁。

02OpenAI 的 function calling 到底「标准化」了什么?

它把「希望模型这么做」,变成了「模型被训练成这么做」。这是从约定走向契约的第一步。

转折点在 2023 年 6 月 13 日。OpenAI 发布博文《Function calling and other API updates》,在 Chat Completions 接口里引入了 function calling,同时放出 gpt-3.5-turbo-0613 和 gpt-4-0613。

机制不复杂,四步:

  1. 开发者用 JSON Schema 描述函数的名字、用途、参数,塞进请求的 functions 参数里;
  2. 模型自己判断「要不要调、调哪个」,返回一个结构化的对象(function_call,含 name 和 arguments),而不是自由文本;
  3. 开发者拿到参数,执行真正的函数;
  4. 把结果以 role: "function" 回传,模型基于结果继续推理,或者给出最终回答。

一次完整的工具调用往返

你的应用 定义工具 schema 模型 判断并返回调用 真实函数 查库 / 调 API tools tool_calls 执行结果回传 模型据此生成最终回答 参数由 schema 约束,不再是自由文本

schema 就是那份契约:模型知道要往哪个格式里填,程序知道该去哪儿取参数。之前那堆正则,全都可以扔了。

关键转变在于,模型被专门微调过,知道什么时候该输出结构化的调用。格式从「我希望它这么做」,变成了「它被训练成会这么做」。这是从约定走向契约的第一步。

「函数」怎么变成了「工具」

2023 年 11 月 6 日的 DevDay,OpenAI 又推了一把:GPT-4 Turbo 上线,带来 并行函数调用(parallel function calling)。一句话里说「打开车窗并关掉空调」,模型可以在单条消息里返回多个调用,不用来回好几轮。

同一天,参数名也换了:functions 变成 tools,function_call 变成 tool_choice(微软 Azure OpenAI 文档记载,随 2023-12-01-preview 版本弃用旧参数)。这个改名不只是字面功夫——概念从「函数」泛化成了「工具」,为后面接检索、代码执行这些非函数能力留了口子。

同日发布的还有 Assistants API。官方第一次明确把它定位成「构建类智能体体验的第一步」。也就是说,从这一天起,function calling 被正式当成了 Agent 的核心组件。

把「最后一点不确定性」也拿掉

还剩一个问题。模型大部分时候会按 schema 输出,但偶尔会漏一个字段、多一个逗号。

2024 年 8 月 6 日,OpenAI 发布 Structured Outputs。在工具定义里加上 strict: true,模型输出会被受限解码(constrained decoding)约束,严格符合你给的 schema。

效果有多硬?复杂 JSON schema 的遵循评测里,gpt-4o-2024-08-06 做到 100% 可靠;而一年前的 gpt-4-0613,得分低于 40%。

这一章的答案:function calling 标准化了「模型怎么把意图翻译成程序能执行的结构」。schema 是契约,结构化返回是履约,执行回传是闭环。工具调用从此不再是赌运气。

03标准有了,为什么还是碎片化?

因为这是「每家自己的标准」。三套契约,互不相通。

Anthropic 也有 tool use,Google 也有 function calling。听起来皆大欢喜,实际上开发者更累了。

因为每一家定义的「契约格式」都不一样。看这张表就明白:

厂商怎么描述工具模型怎么返回调用谁执行
OpenAItools 数组 + JSON Schematool_calls(name + arguments)客户端执行
Anthropictools + input_schemastop_reason=tool_use,返回 tool_use 内容块区分 client tools / server tools
Google Geminifunction declarations(OpenAPI 风格)functionCall客户端执行

差别不止字段名。Anthropic 用的是内容块机制:模型返回一个或多个 tool_use 块,你把 tool_result 块传回去。而且它明确区分两类工具——client tools 跑在应用侧,server tools(比如 web_search、code_execution)跑在 Anthropic 自己的基础设施上。这套划分,OpenAI 那边没有。

为什么 M 个工具 × N 个模型,会变成一场噩梦

没有统一协议:M×N 份适配 有了 MCP:M+N 工具 模型 MCP 工具 模型

每个工具都想接进每个模型,就要为每一种组合写一份适配代码。M 乘 N,随规模爆炸。中间加一层统一协议,成本降到 M 加 N。

你今天写了一个查 Postgres 的工具,想同时接进三个模型。对不起,得写三份适配代码。三个模型 × 十个工具,就是三十份胶水代码。维护起来是一场灾难。

Anthropic 发布 MCP 时,把这个痛点说得很直白:数据被锁在信息孤岛和遗留系统里,每接一个新数据源,都要做一次定制实现。真正连通的系统,难以规模化。

这就像 USB 出现之前——每个外设一个专属接口,键盘一个口、鼠标一个口、打印机又一个口。直到有人站出来说:我们定一个所有人都认的接口形状吧。

这一章的答案:厂商的 function calling 是「私有标准」。它解决了单个模型内部的一致性问题,却制造了模型与模型之间的新墙。

04MCP 是怎么把「接工具」这件事标准化的?

它定的不是「怎么调用」,而是「怎么把你的能力,描述成一个任何客户端都能读懂的接口」。

2024 年 11 月 25 日,Anthropic 开源了 MCP(Model Context Protocol)。发布当天不只是一篇公告,还给了完整规范、SDK、Claude Desktop 的本地 server 支持,以及一批预构建的 server——Google Drive、Slack、GitHub、Git、Postgres、Puppeteer。由 David Soria Parra 和 Justin Spahr-Summers 主导。

目标是六个字:一次编写,到处集成(write once, integrate everywhere)。

三层架构:谁管谁

MCP 用的是 Host / Client / Server 三层模型:

这里有个克制的设计原则:server 不该能读整段对话,也不能「看进」其他 server。能力通过初始化时协商,可以渐进式添加。

三大原语:server 能给出什么

数据层跑在 JSON-RPC 2.0 上。传输层支持 Stdio(本地进程走标准输入输出)和 Streamable HTTP(远程)。Server 暴露三种核心原语:

Tools(工具)
AI 可调用的可执行函数。查库、调 API、操作文件都算。对应 tools/list 和 tools/call。
Resources(资源)
给模型当上下文的数据源——文件内容、数据库记录、API 响应。这是给模型「读」的,不是「调」的。
Prompts(提示模板)
可复用的结构化交互模板,比如一段 system prompt 或 few-shot 示例。

客户端那边也保留了几个原语。最有意思的是 Sampling:server 可以通过 sampling/createMessage,反过来请求宿主的 LLM 做一次补全。这样一来,一个 server 不必内置任何模型 SDK,就能保持模型无关。

还有 Elicitation(向用户要额外信息或确认)和 Logging(发调试日志)。

「模型再聪明,也被与数据的隔离困住。每接一个数据源,就要做一次定制实现。」 — Anthropic 发布 MCP 时的核心论证
这一章的答案:MCP 标准化的是「能力的描述方式」和「连接的握手方式」。工具怎么实现还是你自己的事,但它长什么样、怎么被任何客户端发现和调用,被统一了。

05MCP 这几年怎么一路演进的?

一个协议定下来不就完了?不。它在真实使用里被发现问题,然后选择改,甚至做减法。

MCP 从 2024 年底到现在,经历了好几轮大改。值得关注的是,改动方向很明显:越来越像一套正经的工程协议——无状态、可授权、可扩展。

版本关键变化
2024-11-05初始规范。本地 Stdio + HTTP/SSE 两种传输。
2025-03-26引入 OAuth 2.1 授权框架;用 Streamable HTTP 替换 HTTP+SSE;加 JSON-RPC 批处理;加 tool annotations(标注工具是否只读、是否有破坏性)。
2025-06-18去掉批处理;加结构化工具输出;把 server 归为 OAuth Resource Server,引入 RFC 8707 Resource Indicators 防恶意 server 骗 token;加 elicitation 和 resource links。
2025-11-25一周年版。引入 Tasks(长时任务)与官方 Extensions 框架;简化授权流程;治理结构成型(58 名 maintainer、9 名核心)。
2026-07-28目前最大一次修订。走向无状态核心——移除 initialize 握手和 Mcp-Session-Id,协议版本改由每次请求的 _meta 携带,可以在普通负载均衡器后面跑,不再依赖 sticky session。Extensions 升级为一等公民。

协议也会做减法

2026-07-28 这一版里,有个容易被忽略但意味深长的动作:Roots、Sampling、Logging 三项核心特性被弃用(标注为 deprecated,一年内仍可用)。

尤其是 Sampling。它当年是 MCP 设计里的一个亮点——让 server 不用内置模型 SDK,就能借用宿主的模型。但到了 2026 年,官方建议:改为直接集成 LLM provider 的 API。

当初想得很美的设计,不一定活得下来。协议是会长出赘肉然后被修剪的。

从 Anthropic 的项目,变成中立的行业项目

更重要的变化在治理层。2025 年 12 月 9 日,Anthropic 把 MCP 捐给了 Linux Foundation 旗下的 Agentic AI Foundation(AAIF)。

这个基金会由 Anthropic、Block、OpenAI 联合创立,Google、微软、AWS、Cloudflare、Bloomberg 支持。三个创始项目是:Anthropic 的 MCP、Block 的 goose、OpenAI 的 AGENTS.md。

关键安排是:技术方向仍由原 maintainer 团队自治,Linux Foundation 提供中立基础设施,不干预技术路线。这套路子很眼熟——Kubernetes、PyTorch、Node.js 都是这么走的。

数据上看,它确实成了事实标准

这一章的答案:MCP 用一年半时间,从一个公司的开源项目,变成了有治理、有注册表、有多个大厂接入的行业协议。它成熟的标志,不是加了多少功能,而是开始敢于删掉功能。

06成了事实标准,新的问题是什么?

标准化解决了「能不能连上」,没解决「连上之后安不安全、划不划算」。

假设现在全世界都用 MCP 了。工具都能连上了。那还有问题吗?

有,而且不小。问题从「接口格式」转移到了「接口之外」。

问题一:安全。协议本身有洞

最刺眼的一个,是 STDIO 命令注入。2026 年 4 月,安全厂商 OX Security 披露:MCP 的 STDIO 传输会无条件执行传入的 command 字段。这个默认行为顺着官方实现,传导进了所有主流语言绑定(Python、TypeScript、Java、Rust)和下游项目,波及 7000 多个公开 server 与包、1.5 亿多次下载。Cloud Security Alliance 给它的定性很狠——「设计即 RCE(远程代码执行)」。

另一类风险是提示注入与上下文投毒。MCP 会把工具描述全量注入模型上下文。如果某个工具的描述里藏了恶意指令,它就能借「工具元数据」污染模型的推理。Palo Alto 的研究还指出,Sampling 机制带来了资源盗用、对话劫持、隐蔽工具调用这几类新攻击面。

权限方面也松。第三方一项覆盖 210 名安全从业者的调研显示,64.8% 的企业 MCP 集成存在过度授权,或使用了 root 级工具权限。而 IETF 的一份草案进一步指出:MCP 的 JSON-RPC 消息没有签名,客户端与 server 无法用密码学验证对端身份,理论上可以被冒充和篡改。

问题二:Token。工具定义是「全量预加载」的

这是工程上最日常的痛。

大多数 MCP 客户端,会把所有工具定义预先塞进上下文。你连了上千个工具?那模型还没读到你的问题,上下文里已经躺着几十万 token 的工具描述了。

而且成本是持续的。每个工具 schema 的每个字节,每一轮对话都要重新进一次上下文。有研究审计了 1862 个公共 server,发现连良性 server 的冗长描述,也会抬高 token 成本、拖慢 agent 表现。

中间结果也重复流转。Anthropic 举过一个例子:处理两小时的会议纪要,可能因为结果反复经过模型,额外多烧掉 5 万 token。

问题三:规模。工具一多,模型会「断崖式」失效

这一条最反直觉。

工具数量 vs 任务成功率:不是下滑,是断崖

100% 50% 0 10 个 20 个 50 个 107 个 完美完成 全线失败

一个受控实验的结果:10 个工具时任务完美完成,20 个时 20 次里对 19 次,到了 107 个,大小模型全部失败。不是慢慢变差,是一脚踩空。数据来自二手汇总,仅供参考。

模型选工具的准确率,并不随工具数量平滑下降。它在某个点之后,会突然崩掉。这背后的直觉是:工具越多,名字越像、描述越重叠,模型挑错的概率就越高,而错一次,整条链路就废了。

一句话概括这三道坎:MCP 把「接口」标准化了,但没有标准化「如何组织成百上千个工具」,也没有标准化「如何约束一个工具的能力边界」。前者是工程问题,后者是安全问题,协议层面都还没有答案。

07那「标准化」的下一步往哪走?

一条路是换掉调用方式,一条路是让协议分层。它们其实在回答两个不同的问题。

路线一:别让模型「调」工具,让它「写代码」

这是目前最有意思的一场范式之争。

Anthropic 在 2025 年 11 月的工程博客里提了个方案:不把 MCP 工具直接暴露给模型,而是把它们呈现成「代码 API」,让 agent 写代码去调用。

这样做的好处很实在。模型按需加载工具定义,而不是全量预加载;它可以在执行环境里先过滤、聚合数据,只把真正需要的结果回传。博客里给了一个案例:token 从 150,000 降到 2,000,省了 98.7%。顺带还有隐私收益——中间数据默认留在执行环境,敏感信息「流经但不进入模型上下文」。

Cloudflare 走了同一条路,叫 Code Mode。它把 MCP 工具转成 TypeScript API,理由很朴素:LLM 见过海量真实的 TypeScript 代码,却只见过少量「合成」的工具调用样例。所以它写代码调用,比直接做结构化调用更擅长,多步串联时优势尤其明显。

代价也清楚:要跑模型生成的代码,就得有安全沙箱、资源限制、监控。Cloudflare 的做法是用 V8 isolate,沙箱默认没有公网访问,只能碰那些以 binding 形式注入的已授权接口,API key 由 supervisor 持有,模型写不出会泄露 key 的代码。

这场争论的本质是一句话:要不要把「结构化函数调用」当成模型的头等交互界面?

路线二:协议分层,各管一段

另一条路是承认:没有哪个协议能包办一切。于是它们分层。

VERTICAL

MCP:Agent ↔ 工具

  • 管垂直关系:agent 怎么连工具、数据源、API
  • 已捐给 Linux Foundation 旗下 AAIF
HORIZONTAL

A2A:Agent ↔ Agent

  • 管水平关系:自主 agent 如何跨组织发现、通信、协作
  • Google 2025 年 4 月发布,后捐给 Linux Foundation;v1.0 引入 Signed Agent Cards
CONTEXT

AGENTS.md:项目上下文

  • 放在仓库根目录的 Markdown,「给 agent 看的 README」
  • 就近原则:越靠近被编辑文件的优先级越高
EDITOR

ACP(Zed):编辑器 ↔ Agent

  • 标准化编辑器与 agent 之间的通信
  • 补上 MCP 和 A2A 都没覆盖的边界

Linux Foundation 把 A2A 的定位说得很明确:与 MCP 互补,而非替代。A2A 发布一年后,支持组织从 50 多家涨到 150 多家,AWS、思科、IBM、微软、Salesforce、SAP、ServiceNow 都在内。

一个典型的组合是这样的:A2A 先负责把任务委派给另一个 agent,接手的那个 agent,再用 MCP 去调它自己的工具。

这一章的答案:互操作层的「标准之争」,基本收敛成了「分层共存」。真正还没定论的争论,转移到了 MCP 内部——是继续做结构化调用,还是让模型写代码。前者简单可控,后者省 token 但要多养一个沙箱。

收束:标准化了什么,又没能标准化什么

回到开头那个问题。

从「让模型稳定吐个 JSON 都费劲」,到今天一个 server 任何客户端都能接,工具调用确实被标准化了。这条路走了三年:ReAct 的提示词约定,到 function calling 的私有契约,再到 MCP 的公开协议。

但仔细看,MCP 标准化的是接口的形状——schema 长什么样、怎么握手、怎么授权、怎么发现。

它没有标准化的是分寸——一个 agent 面前摆着上千个工具时该怎么选,一段工具描述里藏了恶意指令该如何防,一个中间结果到底该不该进上下文。

这些,协议解决不了。得靠沙箱、靠工程取舍、靠对整个链路负责的人。

所以下次有人问你「要不要上 MCP」,也许可以先把问题换一下:我要解决的,是「连不上」的问题,还是「用不好」的问题?

这两个问题的答案,往往不一样。

总结

  • 前史(2022):ReAct 确立「推理+行动」范式,但工具调用依赖提示词约定与文本解析,脆弱不可靠。
  • 私有契约(2023-2024):OpenAI function calling(2023-06-13)用 JSON Schema 把调用结构化;DevDay 更名 tool calling、支持并行调用;Structured Outputs(2024-08)用受限解码做到 100% 遵循 schema。
  • 碎片化:三家 API 格式各异(tool_calls / tool_use 内容块 / functionCall),M 个工具 × N 个模型 = M×N 份适配代码。
  • 公开协议(2024-11-25):MCP 用 Host/Client/Server 三层 + JSON-RPC 2.0,定义 Tools/Resources/Prompts 三大原语,目标是「一次编写,到处集成」。
  • 演进:2025-03 加 OAuth 2.1 与 Streamable HTTP;2026-07-28 转向无状态核心并弃用 Sampling/Roots/Logging;2025-12 捐给 Linux Foundation 旗下 AAIF。
  • 新问题:安全(STDIO 命令注入「设计即 RCE」、提示注入、64.8% 企业过度授权)、token 消耗(工具定义每轮全量进上下文)、规模(工具一多准确率断崖式下跌)。
  • 下一步:范式之争——直接 tool calling vs 让模型写代码(code execution / Code Mode,可省 98.7% token);协议分层——MCP(Agent↔工具)、A2A(Agent↔Agent)、AGENTS.md(项目上下文)、ACP(编辑器↔Agent)各管一段。

参考资料

  1. ReAct: Synergizing Reasoning and Acting in Language Models — arXiv:2210.03629
  2. Function calling and other API updates — OpenAI(2023-06-13)— openai.com
  3. New models and developer products announced at DevDay — OpenAI(2023-11-06)— openai.com
  4. Introducing Structured Outputs in the API — OpenAI(2024-08-06)— openai.com
  5. How to use function calling with Azure OpenAI Service — Microsoft Learn — learn.microsoft.com
  6. Tool use with Claude — Anthropic Docs — docs.anthropic.com
  7. Function calling with the Gemini API — Google AI — ai.google.dev
  8. Introducing the Model Context Protocol — Anthropic(2024-11-25)— anthropic.com
  9. MCP 架构总览 — modelcontextprotocol.io
  10. MCP Key Changes 2025-03-26 / 2025-06-18 — modelcontextprotocol.io
  11. One Year of MCP: November 2025 Spec Release — blog.modelcontextprotocol.io
  12. The 2026-07-28 MCP Specification Release Candidate — blog.modelcontextprotocol.io
  13. Introducing the MCP Registry(2025-09-08)— blog.modelcontextprotocol.io
  14. MCP joins the Agentic AI Foundation(2025-12-09)— blog.modelcontextprotocol.io
  15. Code execution with MCP: Building more efficient agents — Anthropic(2025-11-04)— anthropic.com
  16. Code Mode: the better way to use MCP — Cloudflare — blog.cloudflare.com
  17. A2A Protocol Surpasses 150 Organizations — Linux Foundation(2026-04-09)— linuxfoundation.org
  18. MCP by Design: RCE Across the AI Agent Ecosystem — Cloud Security Alliance(2026-04)— labs.cloudsecurityalliance.org
  19. New Prompt Injection Attack Vectors Through MCP Sampling — Palo Alto Unit42 — unit42.paloaltonetworks.com
  20. Security Considerations for MCP — IETF draft — datatracker.ietf.org
  21. RAG-MCP: Mitigating Prompt Bloat in LLM Tool Selection — arXiv:2505.03275
  22. AGENTS.md — agents.md
  23. Agent Client Protocol — Zed — zed.dev