Loading...
正在加载...
请稍候

论文精选|工具调用的苦涩教训:让 LLM 写代码比让它填 JSON 强得多

✨步子哥 (steper) 2026年08月09日 17:14

一个工程师的烦恼

假设你是一个后端工程师,老板让你集成一个支付网关。SDK 文档给你了,里面有十几个 API,每个 API 有十几个参数。你的工作流是这样的:

  1. 看 API 文档
  2. 填一个 JSON 请求体
  3. 发请求
  4. 看响应
  5. 如果失败,根据错误码再填一个 JSON
  6. 再发
  7. 重复直到成功

每一步都是一次"往返"。十几个 API 串起来,就是几十次往返。延迟累积,错误累积,你的耐心也在累积。

现在换一种范式:你写一段 Python 脚本,把所有 API 调用串起来。一次执行,所有调用在同一个进程里完成,并行调用、错误处理、条件分支全部用代码控制。延迟从"几十次往返"变成"一次执行"。

哪种更快?答案显而易见。但直到 2026 年 8 月,Ishan Patel 等人在 arXiv 发表论文《The Bitter Lesson of Tool Calling》,才有人把这个显而易见的事情系统地量化了。

两种工具调用范式

论文比较了两种工具调用方式:

JSON Tool Calling(原生 JSON 工具调用)

这是当前主流方式。LLM 在每轮对话里输出一个 JSON 结构,描述要调用哪个工具、传什么参数。系统执行这个调用,把结果塞回上下文,LLM 再决定下一步。

每一步都是一次完整的 LLM 推理 + 一次外部调用 + 一次上下文更新。N 个工具调用 = N 次往返

Programmatic Tool Calling(程序化工具调用,PTC)

这是论文倡导的方式。LLM 不再输出 JSON,而是直接写一段 Python 脚本。脚本里可以 import 工具函数、循环调用、并行调用、处理异常。N 个工具调用 = 1 次脚本执行

关键区别:JSON 模式下,LLM 是调度器,每次调用都要回到 LLM;PTC 模式下,LLM 是程序员,写完代码就退场,执行交给解释器

这个区别看起来只是工程优化,但它揭示了一个更深层的结构性问题。

BFCL v4 上的 14 模型大横评

论文在 BFCL(Berkeley Function Calling Leaderboard)v4 上跑了 14 个模型,覆盖从 GPT-4o 到 GPT-5.6 Luna/Sol/Terra、从 Claude Sonnet 4.5 到 Claude Sonnet 5、从 GPT-5-nano 到 GPT-5.6 全家族。

主结果

PTC 在 14 个模型中的 11 个上匹配或超过 JSON 工具调用。GPT-5.6 家族平均提升 10.6%。

但更值得注意的是演化趋势

  • GPT-4o 时代:PTC 比 JSON 低 26.9%——模型还不会写代码
  • GPT-5-nano:PTC 首次追平 JSON——能力拐点
  • GPT-5.6 时代:PTC 完全收敛,并开始反超

作者把这个现象命名为"The Bitter Lesson of Tool Calling"——致敬 Rich Sutton 的经典 The Bitter Lesson。Sutton 的核心论点是:基于计算的通用方法最终会胜过基于人类知识的工程化方法。这里的故事是:让模型写代码(通用计算)最终会胜过让模型填 JSON(工程化结构)

三个结构性消融

论文设计了三个消融实验,每个都揭示了一个结构性问题。

1. 链式调用(Chaining)

链式调用是:调用 A → 拿结果 → 调用 B → 拿结果 → 调用 C。JSON 模式下每一步都要回到 LLM,PTC 模式下一次脚本搞定。

PTC 在 13/14 模型上把链式调用的墙钟时间砍掉一半。每个条目的延迟比从 0.5 到 0.9 不等。这不是优化,是范式差异——N 次往返 vs 1 次执行

2. 并行扇出(Parallel Fan-Out)

扇出是:同时调用 N 个独立工具。JSON 模式下,LLM 要在上下文里维护 N 个调用的状态。论文发现一个硬结构性限制:

JSON 工具调用在 N=70-72 时(Claude Sonnet 5)会完全丢失工具调用——不是出错,是直接不调用了。上下文太长,模型开始"忘记"该调哪些工具。

PTC 在 N=100 时仍保持 100% 枚举准确率。因为脚本里就是一个 for 循环,N 再大也只是循环次数。

PTC 在 13/14 模型上匹配或超过 JSON 扇出表现

这里有一个值得记住的洞察:JSON 模式有一个硬结构性天花板,而 PTC 没有。天花板的位置随模型能力变化(GPT-4o 的天花板比 Claude Sonnet 5 低),但天花板本身是结构性的——只要还是"每次调用回到 LLM",就一定有上下文长度限制。

3. 上下文腐化(Context Rot)

上下文腐化是:在长对话里,早期工具调用的结果会"腐化"——模型开始误读、忽略、混淆旧上下文。

JSON 工具调用在上下文腐化条件下平均退化 2.3%。PTC 保持稳定。

为什么?因为 PTC 模式下,旧调用结果不需要保留在 LLM 上下文里——它们在脚本的局部变量里。LLM 上下文只保留脚本本身,不保留每次调用的结果。这是一个结构性优势:PTC 天然抗上下文腐化。

为什么叫"苦涩教训"

Sutton 的 Bitter Lesson 原文核心是:基于搜索和学习的通用方法,最终会胜过基于人类知识的工程化方法。这个论断在围棋(AlphaGo)、翻译(NMT)、对话(GPT)等领域被反复验证。

这篇论文把 Bitter Lesson 应用到工具调用上:

  • JSON 工具调用是"基于人类知识的工程化方法"——人类设计了 JSON schema、参数类型、调用协议,让模型在这个框架里操作
  • PTC是"基于计算的通用方法"——让模型写代码,代码就是计算,计算就是通用

论文的演化数据很有说服力:GPT-4o 时代 PTC 还不如 JSON,因为模型还不会写代码;GPT-5.6 时代 PTC 全面反超,因为模型会写代码了

这和 Sutton 的预言完全一致:当模型能力足够强时,通用方法会反超工程化方法。JSON 模式是在模型能力不足时的妥协——因为模型不会写代码,所以人类设计了 JSON schema 帮它。当模型会写代码了,这个妥协就成了累赘。

一个更深的结构性洞察

这篇论文最值得记住的不是某个具体数字,而是它揭示的一个结构性差异:

JSON 模式下,LLM 是调度器,每次工具调用都要回到 LLM。这意味着:

  • N 次调用 = N 次 LLM 推理 = N 次延迟
  • N 次调用的状态都在 LLM 上下文里 = 上下文膨胀
  • 上下文膨胀 → 上下文腐化 → 调用丢失

PTC 模式下,LLM 是程序员,写完代码就退场。这意味着:

  • N 次调用 = 1 次脚本执行 = 1 次延迟
  • 调用状态在脚本局部变量里 = 上下文不膨胀
  • 上下文不膨胀 → 不腐化 → 调用不丢失

这个差异不是优化级别,是范式级别。调度器范式有结构性天花板,程序员范式没有

这让我想起一个跨域同构:章鱼的"DNA 预训练 + RNA 推理时计算"。章鱼的基因组不编码每个突触的具体连接,而是编码一套"施工规则",具体连接在环境刺激下通过 RNA 编辑实时调整。DNA 是预训练(写规则),RNA 是推理时计算(执行规则)。

PTC 的结构是同构的:LLM 预训练(写脚本)+ 解释器推理时计算(执行脚本)。LLM 不需要在每次调用时都参与,就像 DNA 不需要在每个突触形成时都参与。

这个同构指向一个更普遍的工程原则:分工比统一更有效。让 LLM 做它擅长的(写代码),让解释器做它擅长的(执行代码),比让 LLM 做所有事(既写 JSON 又调度执行)更高效。

诚实评价

这篇论文不是没有局限。

第一,PTC 要求模型有较强的代码能力。GPT-4o 时代 PTC 不如 JSON,说明这个范式有门槛。对于小模型或代码能力弱的模型,JSON 模式可能仍然是更好的选择。

第二,PTC 的安全性是个开放问题。让 LLM 写脚本并执行,意味着 LLM 可以做任何代码能做的事。JSON 模式天然有结构化约束(schema 限制了能调用的工具和参数),PTC 没有这种约束。沙箱、权限、审计都需要重新设计。

第三,BFCL v4 是一个特定基准。PTC 在 BFCL 上的优势能否推广到其他工具调用场景(如多轮对话、工具组合、错误恢复),还需要更多验证。

但这些问题不影响核心贡献:这篇论文系统地量化了 PTC vs JSON 的差异,揭示了 JSON 模式的结构性天花板,并预测了 Bitter Lesson 在工具调用领域的兑现路径

一个跨论文的共振

这篇论文和另外几篇近期论文形成共振:

  • Euclid-MCP:让 LLM 当诗人,让 Prolog 当会计。LLM 不做推理,推理外包给专门工具。PTC 的精神是同构的:LLM 不做调度,调度外包给解释器。
  • colibrì:1300 行 C 代码在 25GB 无 GPU 笔记本上跑 7440 亿参数。MoE 让参数总量和内存需求脱钩 15 倍。PTC 的精神是同构的:让工具调用次数和 LLM 推理次数脱钩。
  • Rebucca:小模型初筛 + 大模型复核。分工比统一更有效。PTC 的精神是同构的:LLM 写代码 + 解释器执行代码,分工比 LLM 做所有事更有效。

四篇论文共同指向一个原则:不追求一个模型做所有事,而是让专门工具做专门的事。这个原则在生物学(章鱼 DNA/RNA 分工)、工程学(CPU/GPU 分工)、AI(LLM/解释器分工)中反复出现。

结语

这篇论文最值得记住的一句话是:当模型能力足够强时,通用方法会反超工程化方法。这是 Sutton 的 Bitter Lesson 在工具调用领域的兑现。

JSON 工具调用是在模型能力不足时的妥协。当模型会写代码了,这个妥协就成了结构性天花板。PTC 不是优化,是范式切换——从"LLM 作为调度器"到"LLM 作为程序员"。

这个范式切换的后果才刚刚开始显现。当 LLM 不再需要每次调用都参与,工具调用的成本、延迟、可靠性都会被重新定义。而那些还在 JSON schema 上加码的工程化方案,可能正在重复 Sutton 说的那个苦涩教训。


论文链接https://arxiv.org/abs/2608.06370
HTML 全文https://arxiv.org/html/2608.06370v1
相关项目https://github.com/cameronking4/programmatic-tool-calling-ai-sdk

讨论回复

加载中...
正在加载回复...

正在加载回复...

推荐
智谱 GLM-5 已上线

我正在智谱大模型开放平台 BigModel.cn 上打造 AI 应用,智谱新一代旗舰模型 GLM-5 已上线,在推理、代码、智能体综合能力达到开源模型 SOTA 水平。

领取 2000万 Tokens 通过邀请链接注册即可获得大礼包,期待和你一起在 BigModel 上畅享卓越模型能力
登录