LLM Agent 指令微调与搜索代理方案
上一章我们介绍了基于 Prompt 范式的工具调用方案,这一章介绍基于模型微调,支持任意多工具组合调用、复杂调用的方案。多工具调用核心需要解决 3 个问题:在哪个位置进行工具调用 (Where),从众多工具中选择哪一个 (Which),工具的输入是什么 (What)。Where + Which + What,我称之为 3W 原则。
其实如何教大模型使用工具,和教人类使用工具没啥区别。就像学习使用电钻的途径无非有三种:
- 基于历史经验:凭借自信直接上手。对应到 LLM 就是本章要提到的工具微调,让模型先学习在不同的场景使用什么工具、如何使用,再利用大模型的迁移泛化能力泛化到更多的场景。
- 从工具说明书中学习:对应到 LLM 简单版就是上一章的 zero-shot prompt 方案,告诉大模型工具的使用场景和用法;升级版是动态召回工具的完整说明书和使用范例作为上文输入模型。
- 通过观察他人使用工具来学习:对应到 LLM 简单版就是上一章介绍的 few-shot prompt 方案,让 LLM 看到在其他场景它是如何使用工具的;升级版是动态 few-shot prompt 的方案。
下面我们看下通过微调为模型注入工具使用经验的两个方案:Toolformer 和 Gorilla。
Toolformer
背景
Toolformer: Language Models Can Teach Themselves to Use Tools。这是工具调用领域的前辈,使用 LM 监督微调得到可以进行 Inline 工具调用的模型。解码时,模型会在恰当的位置生成 API 调用的请求,并中止解码,去调用 API 得到返回值,把返回值拼接到 "->" 字符之后,再继续模型解码。
样本构造
Toolformer 的创新主要在 API 调用的样本构造,主要包含以下 3 个步骤:
1. Sampling API
以 QA API 为例,作者会先编写几个样本作为 In-Context,得到以下的 FewShot 指令样本。然后针对新的长度为 N 的输入文本,计算每个位置得到 <API> 前缀的条件解码概率,并保留超过阈值的 TopK 个最优可能出现 <API> 的位置。每个位置基于上文,让模型随机解码 m 次生成 m 个候选的 API 调用请求。这样我们就得到了候选样本集,每一段文本最多有 K 个可能进行工具调用的位置,且每个位置有至多 m 个候选请求 {c1,...,cm}。
2. Executing API Calls
执行以上得到的候选请求,每个请求得到一个对应的返回值 {r1,...,rm}。可以是计算器的结果,维基百科的搜索返回等等。
3. Filtering API Calls
最后是过滤筛选,原理是好的工具调用样本,应该会让工具调用位置后面的文本解码概率提高,Perplexity 降低。因此作者计算了在工具调用位置之后,所有 token 的加权条件解码概率。离工具调用位置越远权重越小。
条件解码概率的条件 Z,分别是 [工具调用 + 返回值],[工具调用 + 无返回值],[无工具调用],这三者中 Loss 较小的一个。过滤方案是 [工具调用 + 工具返回值] 的 Loss 降幅超过阈值,则保留该样本。
整体量级上,1 个 API 生成了 25K 左右的样本用于微调,样本长度 1024。
微调
使用以上样本生成方案得到多 API 调用的样本集混合后得到增强训练样本。样本的构建方式是在原始文本中直接插入 API 调用的语句。例如:
The Nile has an approximate length of QA(What is the approximate length of the Nile?)->6,853 km 6,853 kilometers, the White Nile being its main source
这样通过微调,模型会学习到在什么位置使用什么样的工具,以及工具的请求输入。同时和解码的格式保持一致,后文会依赖 API 调用结果进行解码。微调使用了 GPT-J 模型,Batch=128,lr=1e-5,warmup=10%,训练了 2K step,常规的 LM Loss。


