年份与会议
2023 · NeurIPS
让语言模型通过自监督方式学习何时调用搜索、计算器、翻译等外部工具,把“会说”进一步推进到“会在合适时机借力外部系统”。
年份与会议
2023 · NeurIPS
作者
Timo Schick、Jane Dwivedi-Yu、Roberto Dessì、Roberta Raileanu、et al.
主题
工具调用
阅读时长
约 3 分钟
收录时间
2023/02/09
当大模型开始进入真实应用后,大家很快意识到一个根本问题:
例如:
这就引出一个重要问题:
模型到底该如何学会在合适时机调用工具,而不是靠人工把所有规则都硬编码进 prompt?
Toolformer 的关键贡献,就是尝试让语言模型自己学会这件事。它不只关心“工具能不能接进去”,更关心“模型如何知道什么时候该用、在哪里插入、调用后怎么继续写下去”。
这也是为什么 Toolformer 在工具调用和 Agent 路线中非常有代表性。
很多早期系统已经知道可以给 LLM 接搜索、计算器、翻译器、知识库 API。但实际效果常常不稳定,原因在于:
也就是说,工具调用的难点不只是“系统集成”,而是“调用决策本身”。如果完全靠人工写规则,系统很快会变得:
Toolformer 试图解决的,正是这个自动化问题。
从本质上说,工具调用是一个策略问题。模型需要隐式回答:
Toolformer 的高明之处在于,它没有把这个问题完全当成强化学习或复杂规划来做,而是把它转回语言模型最熟悉的框架:
通过训练数据,让模型在序列生成中学会把工具调用当成一种特殊 token 行为。
这会让工具使用能力可以自然融进语言建模过程,而不是额外挂一个非常硬的外部控制器。
Toolformer 的方法论非常漂亮。它大致分成三步:
先提供少量演示,告诉模型某类工具一般长什么样、在什么位置插入调用比较合理。
模型会在文本里候选一些可能调用工具的位置,并尝试把调用结果插进去。
并不是所有调用都保留,只有那些真正提升后续 token 预测效果的调用,才会进入训练数据。
这一步非常关键。因为它相当于给“是否应该调用工具”一个可训练的判断标准:如果工具结果真的让语言模型更容易预测后文,那么这个调用就是有价值的。
这也是 Toolformer 最有启发性的地方:它把工具调用决策和语言建模目标重新连在了一起。
如果把这套方法画成一条训练流水线,Toolformer 的新意就会很清楚:它不是只“接工具”,而是在自监督阶段筛出真正有价值的调用位置。
<g>
<rect x="34" y="116" width="164" height="82" rx="18" fill="#ede9fe" stroke="#b7a8ea" />
<text x="116" y="148" text-anchor="middle" font-size="19" font-weight="700">少量人工示例</text>
<text x="116" y="172" text-anchor="middle" font-size="13" fill="#4b5563">先示范工具格式</text>
</g>
<g>
<rect x="222" y="104" width="184" height="106" rx="20" fill="#e8f1ff" stroke="#98b7e1" />
<text x="314" y="138" text-anchor="middle" font-size="19" font-weight="700">候选插入位置</text>
<text x="314" y="162" text-anchor="middle" font-size="13" fill="#4b5563">在大规模文本里猜测</text>
<text x="314" y="183" text-anchor="middle" font-size="13" fill="#4b5563">“这里要不要查工具”</text>
</g>
<g>
<rect x="430" y="104" width="170" height="106" rx="20" fill="#eef6e8" stroke="#a8c48e" />
<text x="515" y="138" text-anchor="middle" font-size="19" font-weight="700">执行工具调用</text>
<text x="515" y="162" text-anchor="middle" font-size="13" fill="#4b5563">搜索 / 计算器 / 翻译</text>
<text x="515" y="183" text-anchor="middle" font-size="13" fill="#4b5563">把结果插回序列</text>
</g>
<g>
<rect x="624" y="94" width="190" height="126" rx="22" fill="#fff4dc" stroke="#e2c36f" />
<text x="719" y="128" text-anchor="middle" font-size="19" font-weight="700">收益筛选</text>
<text x="719" y="152" text-anchor="middle" font-size="13" fill="#4b5563">看调用后是否更利于</text>
<text x="719" y="173" text-anchor="middle" font-size="13" fill="#4b5563">预测后续 token</text>
<text x="719" y="194" text-anchor="middle" font-size="13" fill="#4b5563">无收益调用直接丢弃</text>
</g>
<g>
<rect x="838" y="116" width="108" height="82" rx="18" fill="#dff4f0" stroke="#8dc7bd" />
<text x="892" y="148" text-anchor="middle" font-size="19" font-weight="700">训练</text>
<text x="892" y="172" text-anchor="middle" font-size="13" fill="#4b5563">Tool-aware LM</text>
</g>
<line x1="198" y1="157" x2="222" y2="157" stroke="#5b6b7f" stroke-width="3" marker-end="url(#toolformer-arrow)" />
<line x1="406" y1="157" x2="430" y2="157" stroke="#5b6b7f" stroke-width="3" marker-end="url(#toolformer-arrow)" />
<line x1="600" y1="157" x2="624" y2="157" stroke="#5b6b7f" stroke-width="3" marker-end="url(#toolformer-arrow)" />
<line x1="814" y1="157" x2="838" y2="157" stroke="#5b6b7f" stroke-width="3" marker-end="url(#toolformer-arrow)" />
<rect x="154" y="264" width="676" height="70" rx="20" fill="#f9fafb" stroke="#d7e2f1" />
<text x="492" y="292" text-anchor="middle" font-size="18" font-weight="700">核心判断标准</text>
<text x="492" y="316" text-anchor="middle" font-size="14" fill="#4b5563">不是“这个工具能不能用”,而是“这个调用是否真的改善了后续生成”</text>
</g>
Toolformer 的方法之所以漂亮,是因为它避免了两个常见难题:
如果每种工具都靠人手工标“这里应该调用”,成本会非常高,也难以扩展。
它不是先上强化学习,而是先利用语言模型自身的预测目标,构造一个更自然的训练信号。
换句话说,Toolformer 做的不是“教模型一堆死规则”,而是让模型通过自监督方式逐步体会:
这为后来的工具学习和 Agent 训练都提供了非常重要的思路。
很多人第一次看 Toolformer,会以为它主要是在展示“接很多工具很酷”。其实它真正解决的是更底层的一层:
工具调用应该被当作语言模型序列决策的一部分,而不是完全外置的补丁逻辑。
也就是说,它的意义不只是工程接线,而是能力建模:
这些问题如果不能进入模型的决策过程,那么工具再多也只是外部装饰。
这也是 Toolformer 与 ReAct 可以互补的地方:
今天很多产品里的函数调用、tool calling、MCP、agent workflow 看起来和 Toolformer 的实验设定不完全一样,但底层问题高度一致:
Toolformer 的启发在于,它提醒我们不要把这件事只当系统工程,而要把它看作模型行为学习问题。
换句话说,现代函数调用系统常常有两层:
Toolformer 正是在第二层上非常有代表性的早期工作。
Toolformer 的实验最想说明的,并不是“某个 benchmark 提升了多少”,而是下面这个更本质的结论:
语言模型并非只能在封闭上下文里续写,它可以学会在生成过程中有选择地借助外部系统。
这个结论很重要,因为它改变了大家对“模型能力边界”的理解:
从这个角度看,Toolformer 实际上在推动一种更模块化的 AI 观:模型不需要自己会一切,但要会决定什么时候借力。
虽然 Toolformer 很有启发,但它也有明显局限:
论文里的工具接口相对干净,而真实世界里常常有权限、失败重试、网络波动、参数 schema 等复杂问题。
有些工具调用也许对最终任务很重要,但未必在局部 token 预测上立刻体现出巨大收益。
单次调用已经不易,多个工具串联、参数依赖、状态共享会让问题复杂得多。
模型会调工具,并不自动意味着它会规划、反思、纠错和长期追踪目标。
因此,Toolformer 更像工具学习路线的开端,而不是完整 Agent 终局。
Toolformer 最重要的遗产,是它把“工具调用”从纯系统工程问题推进成了模型学习问题。它告诉我们:
这三点对今天的函数调用、Browser Agent、代码执行 Agent、企业工作流系统都很有影响。很多现代系统虽然实现路径不同,但都在延续这个观念。
如果你只想抓住主线,请记住:
理解这三点后,你再看今天各种 tool calling 框架时,就不会只把它们理解成接口协议,而会更关心模型到底有没有学会好的调用决策。
沿着相近主题继续阅读,加深对方法边界与实践场景的理解。
用“先写中间推理步骤”的提示方式显著提升复杂推理任务表现,让 prompt 从输入模板升级为推理激活器。
把显式推理链和外部行动结合起来,让模型不只“想”,还会在需要时查资料、调工具、再继续推理,成为 Agent 设计的经典起点。
从任务定义、消息分层、few-shot、结构化输出到工具调用与评测回归,建立一套可复用的提示词工程方法。
从工具 schema 设计、调用循环、失败处理到评测闭环,建立一套可落地的 Agent 与工具调用实践框架。