跟人聊 agent 的时候,我发现一个很有意思的现象:很多人用 Claude Code、Cursor 用得很熟,但要 ta 解释”工具调用到底是怎么发生的”,就会卡。
这其实不奇怪——工具调用这个事,从 2022 年到 2024 年经历了三代完全不同的机制,但因为每一代都对用户透明,所以日常使用感受不到差异。但你做 agent 系统、写 prompt、调试失败案例的时候,这三代的差别就是天和地。
这篇梳理这三代演进的逻辑:每一代解决了什么问题、留下了什么坑、催生出下一代。
第一代:ReAct(2022)—— 把 LLM 装上”思考-行动”循环
Yao et al. 2022, ReAct: Synergizing Reasoning and Acting in Language Models
ReAct 之前的 LLM 要么只能”思考”(Chain-of-Thought 输出推理过程),要么只能”答题”(直接给结果)。ReAct 的核心贡献是把两者强制交替:
Thought: 我需要查找东京人口Action: search("Tokyo population")Observation: Tokyo has 13.96 millionThought: 现在我知道了,可以回答用户Action: finish("东京人口是 1396 万")(详细解读待补)
1.1 ReAct 解决的根本问题
1.2 为什么纯 prompt 实现不稳
1.3 历史地位
第二代:Function Calling(2023)—— 结构化的工具调用
(详细解读待补)
2.1 OpenAI 2023.6 的范式转变
2.2 JSON Schema 驱动的参数定义
2.3 留下的坑
- 跨厂商格式不兼容
- 工具定义每次重发
- 没有标准化”工具发现”
- 重复造轮子
第三代:MCP(2024)—— Agent 时代的 USB-C
Model Context Protocol, Anthropic 2024.11
(详细解读待补)
3.1 Server / Client 架构
3.2 stdio vs HTTP
3.3 跟 Function Calling 的核心区别
| Function Calling | MCP | |
|---|---|---|
| 工具定义位置 | agent 应用代码内 | 独立 server |
| 跨应用复用 | 不行 | 天然支持 |
| 工具发现 | 写死在请求里 | 协议级 list_tools |
| 数据资源 | 没有概念 | resources / prompts |
| 厂商生态 | OpenAI / Anthropic / Google 各自一套 | 跨厂商共识 |
3.4 MCP 没解决的事
一句话总结
- ReAct:让 LLM 学会”思考-行动”循环(理论奠基)
- Function Calling:让工具调用变得结构化(工程实现)
- MCP:让工具调用变得跨平台、可复用(生态标准)
每一代都是对前一代的升级,但前一代并没有过时——MCP 协议底层用的是 function calling 范式,function calling 底层服务的是 ReAct 心智模型。
理解这一层,你做 agent 项目的时候才不会在错误的层面调试错误的问题。
草稿。这篇是结构化梳理,正在补每一节的具体内容和我自己的踩坑经验。