提示词(Prompt)是指它通过向模型输入特定的指令或问题,来增强模型的表现,而无需对模型结构本身进行调整。这一概念随着大型语言模型的发展而流行,并催生了一个新兴的领域——提示词工程(Prompt Engineering)。这一领域目前还处于早期探索阶段,依赖于实践和试错来发现有效的提示词策略,属于经验科学的一种。
经验科学:在研究方法上,以归纳法为主,带有较多盲目性的观测和实验。一般科学的早期阶段属经验科学,化学尤甚。在恩格斯《自然辩证法》中,专指十八世纪以前搜集材料阶段的科学。(百度百科)
我对提示词的看法:
- 提示词的确有用
- 提示词本质上是一种“引导”,引导大模型说出他本来会的内容。因为它本身不会对模型性能进行任何修改。所以本质上来讲不应该叫“性能提升”,而是提升其“回答质量”。
- Prompt调优的效果因模型而异(甚至因版本而异),需要大量的实验。意味着同一套Prompt在迁移到其他模型的时候并不能保证它的效果。
- 提示词的脆弱性: 由于自然语言的复杂性,提示词往往是离散的,难以精确优化。这种脆弱性意味着很难为提示词找到一个明确的最佳结构,通常需要通过大量实验和迭代来探索。
- 不要指望一个方法一劳永逸。网上的各种Prompt教程/大模型使用教程鱼龙混杂,很多都缺乏基本的科学素质,即“开局一张嘴,内容全靠编。”,缺乏科学得证明“A方法就是比B方法好”。适合他的不代表适合你,他的最优解更不可能是你的最优解。理性看待,多做尝试。适合自己的才是好的。
- 推荐一下DSPy。这是我觉得为数不多“科学”的Prompt调优方式,还有xAI的PromptIDE看着也不错。
为什么要写这个系列?
作为一个一直在关注工程实现而没有深入研究提示词的产品经理,前一段时间的产品空窗期我重新研究了一下提示词。然后深感提示词领域的混乱。我意识到提示词领域存在许多混乱,各种术语和框架层出不穷,我相信许多人可能也有同样的困惑。因此,我希望通过一系列文章来整理和分享我的知识体系,希望能对大家有所帮助。
这个系列会引用很多论文,主要是两个原因,首先,部分章节会介绍一些专业知识(例如聚类算法),引用原论文可以提供权威参考;其次,许多结论源自论文,引用论文既是对原作者工作的尊重,也为我的论点提供了依据。我将努力确保每个观点都有充分的论据支持。
曾经有一个问题是AI产品经理到底要不要看论文,我的看法是不用看,但了解总是有益的。学术论文的方法相比网上的文章往往具备以下特征:
- 专业性(论文由科研工作者撰写,其研究方法和结论通常在相关数据集上经过验证)
- 严谨性(相比网上的文章,学术论文的研究和论证过程更为严谨。)
但是它对普通人不易读,所以做出一些解读还是很有必要的,提取一些关键点进行分析。
整个系列的行文结构参考今年6月份出的技术报告(Schulhoff, Sander, et al., 2024)。做了一些补充并加入了一些自己的理解。这篇论文很好,它对很多混乱概念进行了梳理并重新定义。比如说Few Shot,在深度学习中通常是指少样本学习(Few-Shot Learning)。Prompt工程中是指Few-Shot Prompting。两者最大的差别就在于前者是会对模型进行永久性修改(比如模型的参数)而后者仅限于在一次对话中,重启上下文后即会失效,对模型本身不会造成任何影响。
文章内容还会参考网上的一些资料,由于参考过多无法一一引用。在此向所有研究Prompt领域的工作者致敬🫡,你们是大模型时代的先驱者。
适用读者范围
下面几种人都可以在文章中各取所需
- AI产品经理
- 对提示词感兴趣的普通人,希望能够提升大模型的回答质量。或者构建属于自己的大模型。会讲解一些普通人通用的简单的设计技巧。
[[正文开始]]
提示词的组成
一个完整的提示词通常可以由指令、示例、输出格式、风格、角色约定几部分组成,它们并不需要同时存在,也并非所有场景都必须使用它们。
指令
指令即用户直接下达给大模型的命令。通常分为显式指令以及隐式指令两种。
显式指令:直接提出问题
告诉我历史上是谁统一了六国?
模型回答:
秦始皇。
隐式指令:给大模型一些示例,让其自动判断该输出什么。隐式指令更像“找规律”,让模型来自动判断如何输出。例如下面是一个将英语翻译成西班牙语的场景
用户输入:
Night:Noche
Morning:
模型回答:
Morning:Mañana
示例(Examples)
通常会使用*-Shot来表示,即提供给大模型的完成任务的示例,帮助其更好理解你的任务。上面的示例就属于一个One-Shot场景(即提供一个事例)。当场景足够简单、事例充分的情况下,大模型不需要你为他提供明确的指令,就可以得到你想要的答案。(参考上面的隐式指令场景)。*-Shot通常分为如下几种情况:
- Many-Shot:多实例上下文学习,指提供多个(没有具体的标准)示例来辅助大模型理解
- Few-Shot:提供少量示例,比如1-3个辅助大模型理解。
- Zero-Shot:不提供示例,让模型直接回答问题。
这一部分也通常称为ICL(In-Context Learning)上下文学习
通常来讲Zero-Shot场景是对模型性能要求最高的,也是各家大模型的优化重点。GPT4相比GPT3.5很明显的能力提升就在于它在Zero-Shot场景下的性能,这往往也代表着其语义理解能力更强。
输出格式约定
这一部分通常是指定模型的输出格式,例如
...,请以MarkDown的形式输出回答。
这么想的话你倒是可以拿大模型做为一个格式刷:)
风格约定
风格即指定大模型的输出风格,是一种非常常用的模型输出优化方式。
请以通俗易懂,略带风趣的方式来解释地球为什么围绕太阳旋转。
模型回答:
让我们来聊聊太阳和地球这对宇宙中的好基友。想象一下,你手里拿着一个网球,然后你用绳子把它系住,开始旋转。网球因为绳子的牵引,不得不跟着你转圈圈。这其实和地球围绕太阳转是一个道理。
角色约定
为大模型设置一个角色,这点与上一部分的风格约定通常都被用来改善模型输出的风格。
你是一个经验丰富的家庭教师,正在教一个二年级的小学生。请解释一下地球为什么围绕太阳旋转。
模型回答:
好的,想象一下你在公园里玩陀螺。你用绳子把陀螺绕起来,然后快速一拉,陀螺就会在地面上旋转起来,对吧?地球围绕太阳转的原理和这个有点像。首先,地球和太阳都非常非常重,太阳比地球重好多好多。很久以前,当太阳系形成的时候,地球和其他行星都是围绕着太阳旋转的。这就像你把陀螺的绳子一拉,它就开始转起来一样.....
少样本提示(Few-Shot Prompting)
大模型的记忆是有限的,它的记忆容量被称为上下文窗口(Context Window),决定了模型能够捕捉信息的范围。例如,GPT-4 Turbo拥有128k个Token的上下文窗口,相当于超过300页的文本,这使得它能够生成更符合对话语境的回复。而上下文学习(In-Context Learning,ICL)是指一种不需要对模型进行训练,在Prompt中通过给予示例以及说明来让模型提高模型的预测性能。但是这种性能提升其实并非“学习到的”,更像是一种激活。激活模型原有的记忆。
少样本提示(Few-Shot Prompting)参考上面的*-Shot介绍。尤其需要注意这里和深度学习中的Few-Shot Learning存在本质区别,FSP并不会对模型参数进行调整,它的提升仅限于当前的上下文窗口中。
通用的示例设计/选取原则
为大模型提供或构建示例的方式对其性能有显著影响。不当的示例可能会导致模型产生严重的误解。以下是六个关键因素。
- 示例数量
通常我们直觉上认为给大模型更多的示例,可以让其性能更好。但是考虑到客观条件,一方面大模型受到上下文长度限制。另一方面,不好的示例会成为噪音,从而将会降低大模型的性能。此外,在部分场景下过多的示例对性能提升并无帮助(Zhao et al., 2024)。 - 示例顺序
顺序可能会影响模型的表现,在某些极端场景下,不同的顺序甚至会使模型回答准确率从低于50%到90%+不等(Lu et al. , 2024)。这个地方可以使用人工排列组合,也可以采用下一小节样本自动构建技术中的一些方法。注意:该顺序也可能是不具有泛用能力的,迁移到另一个大模型可能会导致性能下降。 - 标签的分布
标签(label)类似于传统的机器学习中的概念。当我们训练机器学习模型时,我们通常会给模型提供很多示例,每个示例都有一个标签,告诉模型这个示例属于哪个类别。如果我们提供给大模型的示例中,某个类别的样本数量很多,而另一个类别的样本数量很少,那么大模型的回答将会更偏向于第一个类别。所以在进行示例采样时应该综合考虑。 - 标签的准确性
这点的影响目前还不确定,但是可以确定的点在于较大的模型通常更擅长处理不正确或不相关的标签。能不错还是不要错。 - 示例格式
示例的格式会对模型的回答质量造成影响,常用的格式例如“Q:{input},A:{label}"并没有所谓的“最佳格式”,需要去根据具体场景进行实验。 - 示例相似性
提供的示例的相似性也会对模型回答质量造成影响,但是具体的影响目前也不确定。有的场景下选择更多相似的示例可能会提升回答质量,而有的场景下多样化的示例则表现更好。一般来讲认为多样化的示例会使得模型表现更好。
样本自动构建技术(普通用户可以跳过)
目前,手动构建样本的方法还处于相对原始的阶段,类似于“刀耕火种”,主要依赖于人的主观判断。为了提高样本的质量,可以参考前面提到的几个关键因素,并进行多次测试以优化样本。此外,目前也有一些研究致力于开发自动化构建Few-Shot样本的技术。
如果我们有一个示例库,并希望从中动态构建有效的提示词(Prompt),这是一个非常实际且常见的应用场景。例如,在法律文书编写领域,我们需要为大模型提供与当前案件相似的文书示例,以辅助模型进行更准确的分析。这要求我们能够从示例库中智能地选择和构建相关的样本,以提高模型的理解和预测能力。
这里介绍几个常用的样本自动构建技术。
- K-NN(K-近邻算法)
非常经典的聚类算法,每次在特征空间中选取k个与输入样本最接近的训练样本。但其对计算资源的消耗以及时间需求都很高,如果在提升生成阶段使用将会一定程度影响使用体验。 - Vote-K (Su et al., 2022)
在第一阶段通过嵌入模型(SBert)来构建一个有向图。其中每个节点都指向其k最近邻。然后从一组选定的样本开始计算评分。在第二阶段对第一阶段对结果进行人工标注,在进行Prompt Retrieval时计算所有标注样本和测试样本的余弦相似度即可。 - SG-ICL(Kim et al., 2022)
自生成上下文学习 (Self-Generated In-Context Learning,SG-ICL)利用大模型本身来自动生成示例,效果嘛....不好说。考虑到大模型对指令的理解偏差,可能会进一步放大误差。让我想到了前段时间Nature发的那篇论文,利用AI生成的数据继续训练大模型会导致模型的迅速退化(Shumailov et al., 2024)。
其他还有基于Q-Learning、基于对比学习以及基于主动学习的样本构建技术。这些方法目前研究性仍然不足,暂不列举出来。
简单总结一下,Few-Shot是一种常见的提示词调优技术。一般来说,示例选取最好保持多样化,同时应该具有较强的随机性(顺序,内容...)以避免大模型发现了“规律”从而影响回答质量。
参考文献
Schulhoff, Sander, et al. "The Prompt Report: A Systematic Survey of Prompting Techniques." arXiv preprint arXiv:2406.06608 (2024).https://arxiv.org/abs/2406.06608
Zhao, Hao, et al. "Is In-Context Learning Sufficient for Instruction Following in LLMs?." arXiv preprint arXiv:2405.19874 (2024).https://arxiv.org/abs/2405.19874
Lu, Yao, et al. "Fantastically ordered prompts and where to find them: Overcoming few-shot prompt order sensitivity." arXiv preprint arXiv:2104.08786 (2021).https://arxiv.org/abs/2104.08786
Su, Hongjin, et al. "Selective annotation makes language models better few-shot learners." arXiv preprint arXiv:2209.01975 (2022).https://arxiv.org/abs/2209.01975
Kim, Hyuhng Joon, et al. "Self-generated in-context learning: Leveraging auto-regressive language models as a demonstration generator." arXiv preprint arXiv:2206.08082 (2022).https://arxiv.org/abs/2206.08082
Shumailov, Ilia, et al. "AI models collapse when trained on recursively generated data." Nature 631.8022 (2024): 755-759.https://www.nature.com/articles/s41586-024-07566-y