Few-shot prompting
概述
提高模型性能的最有效方法之一是给模型提供你希望它做什么的示例。将示例输入和预期输出添加到模型提示中的技术被称为“少样本提示”。该技术基于语言模型是少样本学习者的论文。在进行少样本提示时,有几件事情需要考虑:
- 示例是如何生成的?
- 每个提示中有多少个示例?
- 在运行时如何选择示例?
- 提示中的示例是如何格式化的?
以下是每个的考虑因素。
1. 生成示例
少样本提示的第一步也是最重要的一步是提出一个好的示例数据集。好的示例应该在运行时相关、清晰、信息丰富,并提供模型尚未知道的信息。
从高层次来看,生成示例的基本方法有:
- 手动:一个人/人们生成他们认为有用的示例。
- 更好的模型:一个更好的(可能更昂贵/更慢)模型的响应被用作一个更差(可能更便宜/更快)模型的示例。
- 用户反馈:用户(或标注者)留下与应用程序交互的反馈,并根据该反馈生成示例(例如,所有获得正面反馈的交互都可以转化为示例)。
- LLM反馈:与用户反馈相同,但过程是通过让模型自我评估来自动化的。
哪种方法最好取决于你的任务。对于需要深入理解少量核心原则的任务,手工制作一些非常好的示例可能非常有价值。 对于正确行为空间更广泛且更细微的任务,以更自动化的方式生成许多示例可能很有用,这样对于任何运行时输入,存在一些高度相关的示例的可能性更高。
单轮对话 vs. 多轮对话示例
在生成示例时,另一个需要考虑的维度是示例实际展示的内容。
最简单的示例类型仅包含用户输入和预期的模型输出。这些是单轮示例。
另一个复杂的类型示例是,示例是一个完整的对话,通常是模型最初回答错误,然后用户告诉模型如何纠正其答案。 这被称为多轮示例。多轮示例对于更微妙的任务非常有用,在这些任务中,展示常见错误并明确指出它们为什么是错误的以及应该采取什么措施是很有帮助的。
2. 示例数量
一旦我们有了一个示例数据集,我们需要考虑每个提示中应该包含多少个示例。 关键权衡在于,更多的示例通常会提高性能,但更大的提示会增加成本和延迟。 超过某个阈值后,过多的示例可能会开始混淆模型。 找到合适的示例数量高度依赖于模型、任务、示例的质量以及您的成本和延迟限制。 根据经验,模型越好,它需要的示例就越少,而且添加更多示例的收益递减速度越快。 但是,可靠地回答这个问题的唯一方法是使用不同数量的示例进行一些实验。
3. 选择示例
假设我们没有将整个示例数据集添加到每个提示中,我们需要有一种方法根据给定的输入从我们的数据集中选择示例。我们可以这样做:
- 随机
- 通过输入的(语义或基于关键字的)相似性
- 基于一些其他约束,如令牌大小
LangChain 有许多 ExampleSelectors
,使得使用这些技术变得非常容易。
通常,通过语义相似性选择会带来最佳的模型性能。但这一点的重要性再次取决于模型和任务的具体情况,值得进行实验。
4. 格式化示例
目前大多数最先进的模型都是聊天模型,因此我们将重点放在这些模型的格式化示例上。我们的基本选项是插入示例:
- 在系统提示中作为字符串
- 作为他们自己的消息
如果我们将示例作为字符串插入系统提示中,我们需要确保模型清楚每个示例的开始位置以及哪些部分是输入与输出。不同的模型对不同的语法响应更好,比如ChatML、XML、TypeScript等。
如果我们将示例作为消息插入,其中每个示例表示为一系列人类、AI消息,我们可能还希望为我们的消息分配名称,如"example_user"
和"example_assistant"
,以明确这些消息对应于与最新输入消息不同的角色。
格式化工具调用示例
在将示例格式化为消息时,一个棘手的领域是当我们的示例输出包含工具调用时。这是因为不同的模型在生成任何工具调用时,对允许的消息序列类型有不同的限制。
- 某些模型要求任何带有工具调用的AIMessage必须立即跟随每个工具调用的ToolMessages,
- 一些模型还要求在任何ToolMessage之后立即跟随一个AIMessage,然后再是下一个HumanMessage,
- 某些模型要求,如果聊天历史中有任何工具调用/ToolMessages,则需要将工具传递给模型。
这些要求是特定于模型的,应检查您正在使用的模型。如果您的模型在工具调用后需要ToolMessages和/或在ToolMessages后需要AIMessages,而您的示例仅包括预期的工具调用而不是实际的工具输出,您可以尝试在每个示例的末尾添加具有通用内容的虚拟ToolMessages / AIMessages,以满足API约束。 在这些情况下,特别值得尝试将您的示例作为字符串与消息插入,因为拥有虚拟消息可能会对某些模型产生不利影响。
你可以看到一个案例研究,关于Anthropic和OpenAI如何响应两种不同的工具调用基准上的少样本提示技术这里。