2023/12/15,OpenAI发布了官方的提示词编写说明OpenAI提到6条大的原则,分别是:
Write clear instructions(写出清晰的指令)
Provide reference text(提供参考文本)
Split complex tasks into simpler subtasks(将复杂的任务拆分为更简单的子任务)
Give the model time to "think"(给模型时间“思考”)
Use external tools(使用外部工具)
Test changes systematically(系统地测试变更)
接下来六个章节会结合我之前的项目经验拆解这六个原则,列举一些我的实践案例,最后会梳理一张脑图,方便大家查看。
相信理解了这六个原则,会比学会套用Prompt框架价值更高,更有助于我们写出来更有效的prompt。
大模型和人与人沟通一样,我们第一件事要做的就是把话说明白,如果话都说不明白(人都听不懂),怎么能期望大模型理解我们呢?
因此写出清晰的指令,是核心中的核心,借用PMP的沟通模型,我们需要在传递信息时尽量减少噪音,同时告诉对方我们期望他能提供的反馈信息是什么样子的。
如何写出清晰的指令,OpenAI给出了6条小技巧:
1.1 把话说详细(
尽量多的把话讲清楚说详细,选取官方的例子,我们感受一下需要讲到多详细。
如何在 Excel 中添加数字?如何在 Excel 中添加一行美元金额?我想对整张行自动执行此操作,所有总计都在右侧名为“总计”的列中结束。谁是总统?谁是 2021 年墨西哥总统?选举频率如何?编写代码来计算斐波那契数列。编写一个 TypeScript 函数来高效计算斐波那契数列。自由地注释代码以解释每部分的作用以及为什么这样编写。总结会议记录。用一个段落总结会议记录。然后写下演讲者的 Markdown 列表以及他们的每个要点。最后,列出发言人建议的后续步骤或行动项目(如果有)。
我们需要详细到任何一个人看到这段话后可以尽快理解这段话的意思,不会提出较大的疑问和分歧,虽然看起来啰嗦一些,但是极大程度上提升了‘效率’。
1.2 让模型充当某个角色(
大模型一定程度上可以理解为一个‘万能’的演员,你要告诉他让他演什么角色,他的表现就会更专业。
比如:我们希望大模型的回答更专业,就需要他充当一个思维严谨、逻辑清晰的XX领域专家,如果我们希望回答根据趣味性,我们需要他充当一个风趣幽默的XX人员。
1.3 使用分隔符清楚地指示输入的不同部分(
三引号、XML 标签、节标题等分隔符可以帮助划分要区别对待的文本节。可以帮助大模型更好的理解文本内容。
比如:
用50个字符总结由三引号分隔的文本。"""在此插入文字"""
你将获得两篇关于同一主题的文章(用 XML 标签分隔)。首先总结每篇文章的论点。然后指出哪一个提出了更好的论点并解释原因。
这里可以提一下,因为大多数prompt模板都是使用的markdown语法,可以让大模型更快的了解到重点(标题、子标题、内容),因此比我们之前输入一段文本效果会好一些。
在使用模板或分隔符时一定要保证上下文一致性,例如如果我们将分隔符定义为:{在这里放参数}、"在这里插入上下文"、<在这里放例子>,一定要保持一致性,不要混用,否则大模型就会理解不了我们的意思,出现幻视现象。
1.4 指定完成任务所需的步骤(
有些任务最好拆解为一系列步骤,而不是告诉大模型一个目标。达成一个任务可以有很多条路径,大模型还没有办法自动思考出最优路径,因此我们告诉他完成任务所需的步骤,可以提升完成目标的概览。
比如:使用以下分步说明来响应用户输入。
步骤1 - 用户将为您提供三引号中的文本。用一个句子总结这段文字,并加上前缀“Summary:”。
步骤2 - 将步骤1中的摘要翻译成西班牙语,并添加前缀“翻译:”。
1.5 提供例子(
为了让结果更符合我们的预期,我们需要告诉大模型,他的输出格式是什么样的。类似于我们要写周报,写总结。十个人可能有十个想法,格式也千差万别,为了让每个人的周报都保持一致,我们就需要给一个例子或模板,这样大家的周报才会一致。
例如,需要按照以下格式输出文章:
文章标题:[文章标题]
主要观点:[列举文章的主要观点,最多不超过3个]
论证方法:[描述作者使用的论证方法,如举例、引用权威等]
逻辑分析:[对文章的逻辑合理性进行分析]
证据支持:[评估文章的论点是否有足够的证据支持]
行为框架:[描述文章的行为框架,包括作者的写作方式、结构等]
具体大纲:[列出文章的具体大纲,包括各个章节或段落的主题和内容,最多不超过5个]
关键实例:[提炼出关键实例,用以支持作者观点的案例或例子,最多不超过3个]
总结:[总结文章的关键论点、行为框架和大纲]
评价:[提供对文章的评价,包括优点和不足]
1.6 指定输出长度**(
要求模型生成给定目标长度的输出。目标输出长度可以根据单词、句子、段落、要点等计数来指定。
但一定要注意,要求大模型无法精准输出指定的字数,因此最好我们可以给出一个输出范围,例如请总结上下文,字数在30-50字之间。
大语言模型可以自信的发明假答案,因此我们需要给大模型提供一些文本或文档输入,降低大模型胡说八道的概率。就像是开卷考试一样,遇到一道问题,可以先翻教材,寻找答案。
2.1 让模型使用参考文本作答
知识库的经典用法,让大模型使用我们提供的信息来组成其答案。
比如:从我提供的《提供的文档》来回答问题。如果在文章中找不到答案,请写“我找不到答案”。
2.2 让模型通过引用参考文本来回答
如果已经给了文本,也可以直接要求模型通过引用所提供文档中的段落来为其答案添加引用。可以提高正确性,增加可验证性。
比如:您将获得一份《提供的文档》。您的任务是仅使用提供的文档回答问题,并引用用于回答问题的文档段落。如果文档不包含回答此问题所需的信息,则只需写:“信息不足”。如果提供了问题的答案,则必须附有引文注释。使用以下格式引用相关段落({“引用”:…})。
和人一样,我们无法一次性去做一个非常大的事,出错的概率是很大的。所以我们在工作和生活中,都说的是要拆,拆各种细节、子任务、子目标等等。大模型也是同样的道理。
把复杂的任务给拆给更为简单的子任务,大模型会有更好的表现。
3.1 使用意图分类来识别与用户查询最相关的指令
比如在客服场景中,用户问了一个问题“我的快递到哪里了”,大模型是无法直接准确回答出答案的,这时候就需要拆解,将客服的问题分为几个大类在采取不同的策略,回答具体的问题。
比如还是“我的快递到哪里了”这个问题:
步骤1,先判断问题类别:
如果用户提出了问题,你需要确认问题属于以下哪个分类
售前问题
咨询产品价格
咨询产品参数
了解运输信息
... ...
售中问题
快递什么时候到
几号可以发货
... ...
售后问题
产品如何使用
产品出现问题如何修理
... ...
步骤2,确定问题详细信息
您在询问哪个快递的进度
您在询问哪个产品
... ...
步骤3,提供答案
您订单号XXXX的快递正在运输,已经到了XX,预计XXXX送达
3.2 对于需要很长对话的对话应用,总结或过滤之前的对话
因为大模型具有固定的上下文长度,因此用户和大模型之间的对话是无法无限期继续的。
所以我们的解决方案是定期总结历史对话,将其生成摘要信息,作为下一次对话的内容,让大模型在了解背景的前提下继续完成对话。
例如:
在程序中,定期总结上下文,生成摘要信息,按照你需要的格式,生成{背景摘要}
大模型的prompt可以编写为:你是一个逻辑严谨的数据分析专家,你正在和一个名为{用户}探讨问题,你们之前已经进行了几次沟通,沟通内容为{背景摘要},你们最近几次的聊天信息为{前后5次对话内容},现在{用户}提出了{用户最后一次问题},你需要结合你的专业知识为其提供解答。
3.3 分段总结长文档并递归构建完整总结
听起来比较复杂,实际上逻辑很简单。用一句话总结来说就是通过不断总结,了解整篇文档。
让大模型读取一本书的所有内容,肯定会超过Token上限,所以我们可以不断总结,先生成每篇文章的摘要,在将每篇文章汇总,生成每章节的摘要,将每个章节的摘要汇总,生成全书的摘要。再遇到问题后,先从章节中寻找最有可能的章节,再去这个章节中寻找每篇文章,最终找到最有可能解答问题的文章段落。
详细的可以看这篇文档:https://openai.com/research/summarizing-books
Let's think step by step(一步步思考),一个非常非常有用的策略。
相同的以人为例,如果限定在1秒内123456789*987654321等于多少你肯定回答不出来,但是我们给定充足的时间,让你可以一步步计算,相信我们都可以给出正确的答案。
4.1 让模型在急于得出结论之前找出自己的解决方案(
有时我们直接让模型输出结论,会发现结论有时候对有时候错,但是如果让模型自己输出解题过程,然后再判断,正确率就会大大提升。
例如:我们在客服场景内,可以先让大模型在知识库内找到最相似的几个问题及答案,然后再综合评估输出结果,就可以得到不错的答案。
4.2 使用内心独白来隐藏模型的推理过程(
刚刚提的到让模型在输出结论的时候先输出思考分析过程,但是存在一定的限制,有一些场景下我们是不希望用户看到这些过程的,我们只希望用户看到最终的答案。
所以我们这个时候可以使用内心独白这个技巧,我们可以让模型将思考过程(不想让用户看到的内容)放到结构化的格式(特殊的输出格式)中,在回答用户问题时,可以选择不展示此部分内容。
例如:
步骤1:你需要分析用户问题,在知识库寻找相关问题及答案,获取最多不超过3条,并将其放入{}中;
步骤2:分析{}中的内容,获取到问题的最佳回答并放入[]中;
步骤3:回答用户问题,先陈述用户问题,再给出[]中的答案,如果[]中没有内容,则回答用户,抱歉这个问题我还不知道;
特别注意:在进行步骤3之前,不要将{}及[]中的内容告诉用户;
4.3 询问模型在之前的过程中是否遗漏了什么内容(
这个技巧主要应用于,长文档的问题回答。即使我们让模型Let's think step by step,但是模型在执行时仍然无法在某一步骤执行很长时间。如文档搜索场景,模型通常会寻找到部分信息后就进入到下一步骤。在这种情况下我们可以让模型再次思考,通常情况下可以获得更好的答案。
例如:我们在获取到首次的答案后,可以在问模型一句:你的答案正确吗?是否存在遗漏?在检索更多的信息,给我一个更可靠的答案。
大模型本质上还是一个预测模型,因此有很多工作执行的并不好,如果我们知道哪些工具可以很好的解决问题,可以告诉大模型,让他使用工具去解决特定问题,如使用搜索获取最新的信息,使用计算器或python进行数学逻辑计算。
5.1 使用基于嵌入的搜索实现高效的知识检索
技巧一,如果我们要获取实时的信息(因为大模型的知识是有时间限制的),我们可以让大模型先去联网搜索,获取到一大堆网页,然后让大模型分析网页里面的内容,进行回答。
技巧二,如果我们要使用企业内部资料或特定的行业资料,可以采用知识库的模型,常见步骤:加载文件 -> 读取文本 -> 文本分割 -> 文本向量化 -> 问句向量化 -> 在文本向量中匹配出与问句向量最相似的top k个 -> 匹配出的文本作为上下文和问题一起添加到prompt中 -> 提交给大模型生成回答。
5.2 使用代码执行来进行更准确的计算或调用外部API
大模型的计算能力是很差的因此OpenAI官方建议,如果遇到需要计算的东西,可以让大模型写一段计算的Python代码(使用工具),然后执行这段代码。
例如:你现在求以下多项式的所有实值根:(1)48x-54y=-3186(2)24x+y=1080,你需要编写一段python代码,将其放入{}中,然后执行代码获取答案。
也可以把我们公司的API文档(公开途径无法获取到的)给它,让大模型编写代码调取我们的API。
5.3 给模型提供特定的功能
偏开发的一个技巧,可以让大模型充当翻译角色,生成代码或参数(如json文件、SQL语句等),然后执行API接口或者语句,再将获得的结果(如调取API获取的结果,SQL查询出来的数据)让大模型翻译为自然语言,方便用户查看。
如何衡量prompt的效果,OpenAI建议我们设计评分体系,设置不同问题,用来验证每次修改是让结果变好了还是变差了。此处建议进行多轮测试,偶尔一次回答准确并不能说明大模型已经变得很好了,持续稳定的保持同一水准回答,才能体现模型的水平。