计算器从不算错,搜索引擎什么都查得到。
模型缺的不是工具,是知道什么时候该用、该怎么用。
Toolformer 让模型自己往文章里插工具调用,只留下真正帮上忙的那些,再拿来训练自己。整个过程不需要人工标注。
原文:Toolformer: Language Models Can Teach Themselves to Use Tools
2023 年 2 月发布,NeurIPS 2023。作者是 Timo Schick 等 8 人,来自 Meta AI。
先看看人是怎么用工具的
写数学作业时,你大概是这样做的:
- 「3 + 5」,心算就行。
- 「400 ÷ 1400 是百分之几」,心算没把握,拿计算器。
- 碰到一个不认识的外语词,翻词典。
- 作文里要写今天几号,看一眼日历。
没人在每个字前面都拿起计算器,也没人什么都硬算。
什么时候该用、什么时候不用,没人一条条教过你。你是在一次次「用了果然省事」「用了也白用」里,自己摸出来的。
Toolformer 想让模型也这样学:自己试着用,用了有帮助的记住,没帮助的扔掉。
一、模型的短板,工具的长处
语言模型很会写字,却常在几件「简单」的事上栽跟头:
- 算术。 论文用的 GPT-J 有 67 亿参数,在一套小学数学应用题(ASDiv)上只答对 7.5%。
- 冷门事实。 常见的记得住,冷门的容易记错,还答得很肯定。RAG 那篇讲过,这就是幻觉。
- 今天几号。 模型的知识停在训练那一刻,它不知道「现在」是什么时候。
- 小语种。 训练数据里少见的语言,它读不太懂。
这些事,对工具来说都是小菜一碟:计算器不会算错,搜索引擎查得到冷门事实,日历永远知道今天几号。
模型为什么算不对?前面讲过,模型做的事是预测下一个 token。「400 ÷ 1400 ≈ 0.29」这样具体的算式,训练数据里几乎没见过原样的,它只能凭「看起来像」去猜。
那就让模型学会用工具。问题是怎么学。在 Toolformer 之前,主要有两条路:
- 靠人教。 找人大量标注「这里该调用什么工具」,再拿来训练。WebGPT、LaMDA 都这么做过。贵,而且人觉得有用的地方,不一定是模型真需要帮忙的地方。
- 靠提示词。 在提示词里给几个示范,让模型照着用工具。上一篇的 ReAct 就是这样,论文也把它归在这一类。示范要按任务来写,模型只在写好示范的那类任务里会用工具。
论文给自己定了两个目标:
- 自己学:不靠大量人工标注。
- 不丢本事:模型原来的语言能力一点不能少;什么时候用、用哪个工具,由它自己决定,不限定在某个任务上。
二、工具调用长什么样
Toolformer 的一次工具调用,就是夹在正文里的一小段文字:
[工具名(输入) → 结果]论文开头给了四个例子(示例改写自论文图 1,原文为英文,这里做了意译):
《新英格兰医学杂志》是 [QA("谁出版了《新英格兰医学杂志》?") → 马萨诸塞州医学会] MMS 的注册商标。
1400 名参加者中,有 400 人(约 [Calculator(400 / 1400) → 0.29] 29%)通过了考试。
这个名字来自 "la tortuga",也就是西班牙语里的 [MT("tortuga") → turtle] 乌龟。
《布朗法》是加州的一部法律,[WikiSearch("Brown Act") → 《拉尔夫·M·布朗法》是加州议会通过的一项法案……] 要求市议会这类机构公开开会。方括号里是一次调用:QA 是问答工具,括号里是问的问题,箭头后面是工具返回的结果。方括号外面,是原来的句子。
留意调用插的位置:总在答案出现之前。「29%」前面先算出 0.29,「乌龟」前面先查到 turtle。有了结果,后面的字就好写了。
这个「好写了」,就是后面挑数据的标准。
为什么是方括号和箭头?论文原本设计了三个特殊符号 <API>、</API>、→,实际换成了普通的「[」「]」「->」。
这样不用往词表里加新 token。前面讲过,词表里每个 token 对应词嵌入表里的一行。加一个新 token,就多出一行没训练过的数字,模型得从头认识它。用现成的符号,就省掉了这一步。
五个工具
| 工具 | 是什么 | 输入 | 输出 |
|---|---|---|---|
| 问答(QA) | Atlas,一个先检索再回答的模型 | 一个问题 | 简短的答案 |
| 计算器(Calculator) | 几行 Python,只会加减乘除,结果保留两位小数 | 一个算式 | 一个数 |
| 维基百科搜索(WikiSearch) | 用 BM25 在维基百科里搜 | 一个搜索词 | 几句原文 |
| 翻译(MT) | NLLB,6 亿参数,能把 200 种语言译成英文 | 一段外语 | 英文 |
| 日历(Calendar) | 直接返回今天的日期 | 不用输入 | 日期 |
有两个是熟面孔。Atlas 和 RAG 那篇是一类,先查资料再回答;BM25 就是 RAG 那篇提到的按字面匹配的老办法。
五个工具有一个共同点:输入是一段文字,输出也是一段文字。
对模型来说,工具就是一个黑盒:写进去一句话,吐出来一句话。里面是计算器还是另一个大模型,它不用管。只要满足这一点,换成别的工具也行。
三、模型怎么自己教自己
核心想法一句话:让模型自己到处试着插调用,真的去调用,只留下让后文更好猜的那些,再拿来训练自己。
论文用一句话演示整个过程:「Pittsburgh is also known as the Steel City」,意思是「匹兹堡又被称为钢铁之城」。

下面一步一步看。
第 1 步:模型自己提议「这里可以调用」
先给 GPT-J 写一段提示词,讲清楚怎么插调用,再附两个示范。问答工具的提示词大意是这样(示意,改写自论文附录,原文为英文):
你的任务是往一段文字里插入对问答 API 的调用。
问的问题要能帮你补全这段文字。写法是 [QA(问题)]。
输入:拜登出生在斯克兰顿,那里属于宾夕法尼亚州。
输出:拜登出生在 [QA("拜登出生在哪里?")] 斯克兰顿,那里属于 [QA("斯克兰顿在哪个州?")] 宾夕法尼亚州。
(再放一个示范)
输入:(要标注的文字)
输出:提示词最后是「输出:」,模型就会照着示范,把原文重写一遍,顺手插几个调用。ReAct 那篇讲过,模型很会「照着前面的样子写」。
不过论文没让模型从头抄一遍了事,而是分两步,挑得更细:
先挑位置。 原文的每一个位置都算一下:模型在这里写下「[」的概率有多大?超过 5% 的位置才留下;留下的太多,就只要最高的 5 个。
再挑问题。 在每个留下的位置,让模型从「[」开始往下写,写出一个完整的调用,写到「]」为止。每个位置最多写 5 个。
所以一段文字,最多冒出 5 × 5 = 25 个候选调用。
匹兹堡那句,模型在「the Steel City」前面提了两个问题:
- QA("What other name is Pittsburgh known by?"):匹兹堡还被叫作什么?
- QA("Which country is Pittsburgh in?"):匹兹堡在哪个国家?
第一个问到了点子上。第二个也不算错,但和后文没关系。现在还分不出来,要等第 3 步。