Toolformer: Language Models Can Teach Themselves to Use Tools
Schick et al. (Meta AI) · NeurIPS 2023 · 2023
阅读原文让 6.7B 模型自学「何时、如何插入 API 调用」:用自举数据过滤把工具使用内化到语言建模目标里。
核心要点
- 数据构造的天才设计:让模型自己采样 API 调用插入点,执行后用「调用结果是否降低困惑度」过滤——工具使用信号完全自举,无需人工标注。
- 学到的行为是「内化的」:工具调用出现在生成过程中而非对话协议里,模型在需要计算时自发调用,GPT-J 级小模型借此在数学、检索任务上大幅跃升。
- 实验覆盖计算器、检索、日历、QA、翻译五种工具,证明方法的通用性——这是后来 function calling 的学术先声。
- 局限同样前瞻性:工具集固定且互不组合、无多步链式调用、无错误恢复——这些正是今天 Agent 工程的未竟课题。
背景
2022 年底 GPT-3.5 已经展示了语言模型的知识广度,也暴露了它的三个硬伤:算术(数字运算是 token 级模式补全,11 位以上乘法靠猜)、时效(权重冻结在预训练截止日)、精确检索(闭卷问答靠「回忆」而非「查证」)。当时业界的工具使用方案分两派:外挂 controller(MRKL、ReAct)——用 prompt 让模型输出调用指令,由外部框架执行——问题是调用决策不在权重里,模型行为与工具协议「两张皮」,小模型根本玩不转;端到端微调——需要人工标注「何时调用、怎么调用」的数据,每个工具都要标,成本随工具数线性增长。
Meta AI(Schick 等,也就是后来 Llama 2/3 系列的作者班底)想问:模型能不能自己生产这些训练数据?
动机
核心赌注:工具调用可以成为语言建模的一部分——如果「算式 → 计算器结果」像「主语 → 谓语」一样在语料里高频共现,模型就会像学语法一样学会用工具。缺的只是数据:普通语料里没有 API 调用的痕迹。解法是自举(bootstrap):让模型自己猜测哪里该插 API、执行后用模型自身的困惑度当裁判筛选——保留「调用结果让后续文本更好预测」的样本作为训练数据。如果这招成立,工具集可以任意扩展而不需要人工标注——「教会模型教自己用工具」。
方法
三步自举管线:
第一步:采样候选。给 GPT-J 6.7B 一个 few-shot prompt(演示 API 的调用格式),让它在普通语料(CC100 的子集)上采样「在哪里、插什么 API 调用」——模型在每个位置可以提议形如 [计算器(11×34) → 374] 的插入。允许每个位置采样多个候选(不同 API、不同参数)。
第二步:执行 + 困惑度过滤。真实执行 API(计算器就算、搜索引擎就搜、日历就查),把结果插回原文。然后以另一个(冻结的)GPT-J 的困惑度为裁判:比较「有调用结果的文本」与「无调用的原文」在插入点之后一小段的困惑度——只有当 API 结果让模型觉得后面的文本「更好预测」时才保留这条样本。这个过滤有两个妙处:(1) 完全自动,无人工;(2) 天然剔除「模型乱插调用」的噪声——插入无关 API 会增加困惑度,直接被丢。
第三步:微调。过滤后的语料(约几万条有效样本量级)微调 GPT-J。推理时:模型生成到某个 token,若它输出 [计算器(...),系统执行 API、把结果按训练时的格式喂回,模型继续生成——调用是生成过程的一部分,不是对话协议。
五种工具:计算器(QA 数学)、问答系统(闭卷知识)、搜索引擎(CC 网页检索,用 Atlas)、翻译系统(NLLB)、日历(当前日期)。API 失败/超时也被显式建模——模型学会「调用失败就当没调过」。
实验设置
- 基座:GPT-J 6.7B(自举与微调都在这个规模——刻意证明「小模型也能自学工具」)
- 数据:CC100 子集采样;few-shot 演示每个 API 手写 3 条
- 评测任务:LAMBADA(完形,用计算器)、TemporalQuestions(时间敏感 QA,用日历+搜索)、Web Questions(搜索)、MLQA(跨语言 QA,用翻译)、数学题(计算器);对比基线:GPT-J zero/few-shot、GPT-3(175B,few-shot,无工具)、带工具的更大模型
- 消融:去掉困惑度过滤(用全部采样数据)、只用人工模板数据、不同 API 组合
结果
- 数学(LAMBADA 数字部分):Toolformer 从基线的个位数准确率跃升到 70%+ 量级——6.7B + 计算器超过 175B 裸 GPT-3 的 few-shot;这是全文最锋利的一条结论
- 时间敏感 QA:靠日历 API 从低分升到可比肩更大模型;跨语言 QA 用翻译 API 同样显著提升
- 泛化证据:模型在未见过的任务上自发调用工具(如在文本生成里主动查日期),且会忽略无关工具——自举数据里「保留标准 = 对预测有用」教会了它克制
- 消融:去掉困惑度过滤,性能崩(采样噪声毁掉训练);只用人工模板,泛化差
- 每个 API 只需 3 条演示 + 全自动管线——「新工具的接入成本 ≈ 写一段格式说明」
有趣的洞见
「困惑度过滤」是弱监督数据工程的通用范式。用模型自身信号(或更强模型的信号)为训练数据打分,几乎不需要人工——这个思想后来铺开成一整条脉络:self-instruct(用模型生成指令数据)、RLAIF(用模型当标注员)、拒绝采样微调(RFT,用模型采样+验证器筛)、以及 R1 时代「用可验证奖励筛 CoT」。当标注昂贵时,让执行结果说话——Toolformer 是这个范式的最早完整示范之一。
「调用在权重里」 vs 「调用在协议里」是两种世界观。Toolformer 的调用是内化的(模型在续写文本时自然想用工具);今天主流 function calling 是协议化的(系统 prompt 定义工具、模型按 JSON 格式应答、框架执行)。协议路线赢了产业(灵活、可控、免训练、工具可随时增删),但代价是:调用判断力永远停在提示层,长工具列表挤占上下文,模型对「该不该调用」的直觉依赖通用能力而非专门训练。MCP 时代的「工具爆炸 vs 上下文极限」矛盾,正在把「内化路线」重新拉回议程(工具使用预训练)。
小模型 + 正确的接口 > 大模型硬算。6.7B 带计算器打赢 175B 裸模型,这个结果的结构(能力靠接口补,不靠参数堆)后来在 Agent 领域反复出现——它其实是「神经符号结合」老思想的第一次产品级验证。
批判性评价
最弱的一环:设定过于乌托邦。五种工具全部是「单轮、结构化输出、结果可靠」的理想 API;没有链式调用(查完再算)、没有并行调用、没有错误恢复策略(除了「当没发生」)、工具集在训练后固定——真实工具生态的动态性(API 演化、权限、组合爆炸)远超设定。而且困惑度过滤的裁判本身有偏差:结果「有趣」≠ 结果「正确」(搜索引擎返回的噪声也可能降低困惑度)。6.7B 的规模也留下悬念:更强的模型还需要这种数据自举吗?(后续实践表明:更强模型靠指令遵循就能学会格式,自举的相对价值下降。)
依然重要的理由:它重新表述了工具使用的问题——不是「外挂框架」而是「语言建模目标的自然扩展」,这个视角在 MCP 时代依然锋利。它对「判断力能否进入权重」的回答(能,且只需要几万条自举数据)为今天的工具使用预训练提供了方法论起点;其困惑度过滤更是被整个 RFT/RLAIF 生态继承的通用技术。