Prompt工程

Prompt工程

这个指南分享了从大型语言模型(有时称为GPT模型)如GPT-4 中获得更好结果的策略和技巧。这里描述的方法有时可以结合使用以达到更好的效果。我们鼓励进行实验,找到最适合您的方法。

这里演示的一些示例目前仅适用于我们最强大的模型gpt-4。一般来说,如果您发现一个模型在某项任务上失败了,并且有一个更强大的模型可用,那么值得尝试使用更强大的模型再次尝试。

您还可以探索一些示例提示,展示了我们的模型的能力:

获得更好结果的六种策略

编写清晰的指导说明

这些模型无法读取您的思维。如果输出太长,请要求简洁的回复。如果输出太简单,请要求专家级的写作。如果您不喜欢格式,请演示您希望看到的格式。模型需要猜测您的意图越少,您获得所需结果的可能性就越大。

策略:

  • 在查询中包含详细信息以获得更相关的答案
  • 要求模型采用某种角色扮演
  • 使用定界符清楚地指示输入的不同部分
  • 指定完成任务所需的步骤
  • 提供示例
  • 指定输出的期望长度

提供参考文本

语言模型在被问及神秘主题、引用和URL等内容时,往往会自信地创造虚假答案。就像一张笔记纸可以帮助学生在考试中表现更好一样,为这些模型提供参考文本可以帮助它们以较少的虚构内容进行回答。

策略:

  • 指示模型使用参考文本进行回答
  • 指示模型从参考文本中引用引文进行回答

将复杂任务分解为简单子任务

就像在软件工程中将复杂系统分解为一组模块化组件是良好的实践一样,提交给语言模型的任务也是如此。复杂任务往往具有比简单任务更高的错误率。此外,复杂任务通常可以重新定义为一系列简单任务的工作流,其中早期任务的输出用于构造后续任务的输入。

策略:

  • 使用意图分类来识别用户查询的最相关指令
  • 对于需要非常长对话的对话应用程序,对之前的对话进行总结或过滤
  • 逐段对长文档进行总结,并递归构造完整的摘要

给模型一些时间来“思考”

如果被要求计算17乘以28,你可能不会立即知道答案,但是可以花时间算出来。同样,模型在试图立即回答问题时会出现更多的推理错误,而不是花时间计算出一个答案。在回答之前要求一个“思维链条”可以帮助模型更可靠地推理出正确答案。

策略:

  • 指示模型在匆忙得出结论之前自己计算出解决方案
  • 使用内心独白或一系列查询来隐藏模型的推理过程
  • 询问模型是否在之前的尝试中遗漏了任何东西

使用外部工具

通过将其他工具的输出提供给模型来弥补模型的弱点。例如,文本检索系统(有时称为RAG或检索增强生成)可以告诉模型相关文档的信息。像OpenAI的代码解释器这样的代码执行引擎可以帮助模型进行数学计算和代码运行。如果一个任务可以通过工具而不是语言模型更可靠或更有效地完成,那么将其卸载以获得最佳效果。

策略:

  • 使用基于嵌入的搜索实现高效的知识检索
  • 使用代码执行来执行更准确的计算或调用外部API
  • 给模型访问特定功能

系统地测试变化

如果能够衡量改进的性能,那么改进性能就会更容易。在某些情况下,对提示的修改可能会在一些孤立的示例上实现更好的性能,但在更具代表性的示例集上导致整体性能更差。因此,为了确保改变对性能的净影响是正面的,可能需要定义一个全面的测试套件(也称为“评估”)。

策略:

  • 使用与黄金标准答案相比较来评估模型输出

策略

上面列出的每个策略都可以通过特定的战术实例化。这些战术旨在提供尝试的想法。它们绝不是全面的,您应该随意尝试这里未涉及的创造性想法。

策略:编写清晰的指导说明

战术:在查询中包含详细信息以获得更相关的答案

为了获得高度相关的响应,请确保请求提供任何重要的细节或背景信息。否则,您就是让模型去猜测您的意思。

更差 更好
如何在Excel中添加数字? 如何在Excel中将一行美元金额相加?我想要自动为整个表中的所有行进行此操作,所有总数都会出现在右边,放在一个名为“Total”的列中。
谁是总统? 谁是2021年的墨西哥总统,选举频率是多少?
编写代码来计算斐波那契数列。 编写一个高效计算斐波那契数列的TypeScript函数。在代码中大量使用注释来解释每个部分的作用及其为何以这种方式编写。
总结会议记录。 用一段话总结会议记录。然后写一个Markdown列表,列出发言者和他们每个的要点。最后,列出发言者建议的下一步行动或行动项(如果有的话)。

战术:要求模型采用特定角色

系统消息可以用来指定模型在回复中所采用的角色。

战术:使用定界符清晰地指示输入的不同部分

像三重引号、XML标记、章节标题等定界符可以帮助标明要以不同方式处理的文本部分。

对于像这样直接的任务,使用定界符可能不会在输出质量上产生影响。然而,任务越复杂,澄清任务细节的重要性就越大。不要让模型费力去理解您究竟要求什么。

战术:明确完成任务所需的步骤。

某些任务最适合以一系列步骤的形式进行说明。明确地写出这些步骤可以使模型更容易遵循。

战术:提供示例

通常,提供适用于所有示例的一般指导比通过示例展示任务的所有排列组合更有效,但在某些情况下,提供示例可能更容易。例如,如果您打算让模型复制一种难以明确描述的对用户查询做出响应的特定风格。这被称为“少样本”提示。

战术:指定输出的期望长度

您可以要求模型生成具有特定目标长度的输出。目标输出长度可以根据单词、句子、段落、项目符号等数量来指定。但请注意,指示模型生成特定数量的单词不具有高精度。模型可以更可靠地生成具有特定数量段落或项目符号的输出。

策略:提供参考文本

战术:指示模型使用参考文本进行回答

如果我们可以向模型提供与当前查询相关的可信信息,那么我们可以指示模型使用提供的信息来构建其答案。

考虑到所有模型都有限的上下文窗口,我们需要一种动态查找与所提问的问题相关信息的方法。嵌入可以用来实现高效的知识检索。有关如何实现此功能的更多详细信息,请参见策略“使用基于嵌入的搜索来实现高效的知识检索”。

战术:指示模型使用参考文本中的引文进行回答

如果输入已经被补充了相关知识,那么很容易请求模型通过引用提供的文档中的段落来给其答案添加引文。请注意,输出中的引文可以通过在提供的文档中进行字符串匹配来进行程序验证。

策略:将复杂任务分解为简单子任务

战术:使用意图分类来识别用户查询的最相关指令

对于需要处理不同情况的大量独立指令集的任务,首先对查询的类型进行分类并使用该分类确定需要的指令可能会有益。这可以通过定义固定的类别并硬编码与处理给定类别任务相关的指令来实现。这个过程也可以递归地应用于将任务分解为一系列阶段。这种方法的优点是,每个查询仅包含执行任务下一阶段所需的指令,这可能导致与使用单个查询执行整个任务相比更低的错误率。这也可能导致更低的成本,因为更大的提示费用更高(请参阅定价信息)。

例如,假设对于客户服务应用程序,查询可以有以下有用的分类:

根据客户查询的分类,可以向模型提供一组更具体的指令,以便它处理下一步。例如,假设客户需要“故障排除”帮助。

请注意,已经指示模型发出特殊字符串以指示对话状态的变化。这使我们能够将我们的系统转变为状态机,其中状态确定了要注入的指令。通过跟踪状态、在该状态下哪些指令是相关的,以及可选地允许从该状态进行的状态转换,我们可以在用户体验周围设置护栏,这在使用结构化程度较低的方法时很难实现。

战术:对于需要非常长对话的对话应用程序,总结或过滤之前的对话

由于模型具有固定的上下文长度,用户和助手之间的对话中如果整个对话都包含在上下文窗口中,则对话无法无限期地进行下去。

有各种解决这个问题的方法,其中之一是总结以前对话中的内容。一旦输入的大小达到预定的阈值长度,这可能会触发一个查询,总结对话的部分内容,并将先前对话的摘要作为系统消息的一部分包含在内。或者,可以在整个对话过程中异步地对先前的对话进行总结。

另一种解决方案是动态选择与当前查询最相关的先前对话部分。请参见战术“使用基于嵌入的搜索来实现高效的知识检索”。

战术:逐段总结长文档并递归构建完整摘要

由于模型具有固定的上下文长度,它们无法在单个查询中用于总结长于上下文长度减去生成摘要长度的文本。

为了总结非常长的文档,例如一本书,我们可以使用一系列查询来总结文档的每个部分。可以将部分摘要连接起来并进行总结,从而产生摘要。这个过程可以递归进行,直到整个文档被总结。如果需要使用较早部分的信息来理解较晚部分,那么可以进一步使用的一个有用的技巧是,在总结某一点的内容时,包含在该点之前的文本的运行摘要。这个程序用于总结书籍的效果已经被OpenAI以GPT-3的变体进行了研究。

策略:给模型时间“思考”

战术:指示模型在匆忙得出结论之前自己解决问题

有时,我们通过明确指示模型首先从基本原理出发进行推理,然后再得出结论,可以获得更好的结果。例如,假设我们想要模型评估学生对数学问题的解决方案。最直接的方法是简单地询问模型学生的解决方案是否正确。

但学生的解决方案实际上是不正确的!我们可以通过提示模型首先生成自己的解决方案来成功地让模型注意到这一点。

战术:使用内心独白或一系列查询来隐藏模型的推理过程

前面的战术表明,有时候模型在回答特定问题之前详细思考问题是很重要的。对于某些应用程序,模型用于得出最终答案的推理过程可能不适合与用户分享。例如,在辅导应用程序中,我们可能希望鼓励学生自行解决问题,但模型关于学生解决方案的推理过程可能会向学生透露答案。

内心独白是一种可以用来缓解这个问题的战术。内心独白的想法是指示模型将意图隐藏用户的部分输出放入结构化格式中,以便于解析。然后,在将输出呈现给用户之前,将输出进行解析,只有一部分输出是可见的。

另外,这可以通过一系列查询来实现,在这些查询中,除了最后一个查询外,所有的输出都对最终用户隐藏起来。

首先,我们可以要求模型独立解决问题。由于这个初始查询不需要学生的解决方案,所以可以省略。这提供了另一个优势,即模型的解决方案不会受到学生尝试的解决方案的影响。

接下来,我们可以让模型利用所有可用信息来评估学生的解决方案的正确性。

最后,我们可以让模型利用自己的分析,在友好辅导员的人设下构建回复。

战术:询问模型是否错过了之前的内容

假设我们正在使用一个模型来列出与特定问题相关的源文件摘录。在列出每个摘录之后,模型需要确定是否应该开始撰写另一个摘录,还是应该停止。如果源文件很大,模型常常会提前停止,未能列出所有相关的摘录。在这种情况下,通常可以通过提示模型进行后续查询,找到之前错过的任何摘录,从而获得更好的性能。

策略:使用外部工具

战术:使用基于嵌入的搜索来实现高效的知识检索

如果作为其输入的一部分提供,模型可以利用外部信息源。这可以帮助模型生成更具见解和最新的回答。例如,如果用户询问有关特定电影的问题,将关于该电影的高质量信息(例如演员、导演等)添加到模型的输入中可能会很有用。嵌入可以用来实现高效的知识检索,因此在运行时可以动态地将相关信息添加到模型输入中。

文本嵌入是一个可以衡量文本字符串之间关联性的向量。相似或相关的字符串将比不相关的字符串更接近。这个事实,加上快速向量搜索算法的存在,意味着嵌入可以用来实现高效的知识检索。特别是,一个文本语料库可以被分割成块,每个块可以被嵌入和存储。然后,给定的查询可以被嵌入,并进行向量搜索以找到与查询最相关的文本块(即在嵌入空间中最接近的文本块)。

在OpenAI Cookbook中可以找到示例实现。参见战术“指示模型使用检索到的知识来回答查询”以了解如何使用知识检索来最小化模型捏造不正确事实的可能性的示例。

战术:使用代码执行来执行更准确的计算或调用外部API

语言模型不能单独准确执行算术或长时间计算。在需要这样做的情况下,可以指示模型编写和运行代码,而不是进行自己的计算。特别地,可以指示模型将要运行的代码放入指定的格式中,例如三重反引号。生成输出后,可以提取并运行代码。最后,如果需要,代码执行引擎(例如Python解释器)的输出可以作为模型下一个查询的输入提供。

另一个代码执行的良好应用案例是调用外部API。如果正确指示模型如何使用API,它可以编写使用该API的代码。可以通过提供文档和/或代码示例来指示模型如何使用API。

警告:执行模型生成的代码并不是绝对安全的,在任何试图执行此操作的应用程序中都应采取预防措施。特别是,需要一个沙盒式代码执行环境来限制不受信任的代码可能造成的危害。

战术:为模型提供特定函数的访问权限

Chat Completions API允许在请求中传递函数描述列表。这使得模型能够根据提供的模式生成函数参数。生成的函数参数以JSON格式由API返回,可以用于执行函数调用。函数调用提供的输出可以在下一个请求中反馈到模型中,以完成循环。这是使用OpenAI模型调用外部函数的推荐方法。要了解更多信息,请参阅我们的介绍性文本生成指南中的函数调用部分以及OpenAI Cookbook中的更多函数调用示例。

策略:系统地测试更改

有时候,很难确定一个改变——例如,新的指令或新的设计——是使系统变得更好还是更糟。查看几个示例可能会暗示哪个更好,但是对于小样本量来说,很难区分是真正的改进还是随机的运气。也许这个改变在某些输入上提高了性能,但在其他输入上降低了性能。

评估程序(或“评估”)对于优化系统设计很有用。良好的评估是:

  • 代表真实世界的使用情况(或至少是多样化的)
  • 包含许多测试案例,以增加统计功效(请参阅下表的指南)
  • 易于自动化或重复
待检测的差异 95% 置信水平所需的样本量
30% 约 10
10% 约 100
3% 约 1,000
1% 约 10,000

输出的评估可以由计算机、人类或二者混合进行。计算机可以利用客观标准(例如,具有单一正确答案的问题)自动化评估,也可以利用一些主观或模糊的标准,在这些标准中,模型输出由其他模型查询进行评估。OpenAI Evals 是一个开源软件框架,提供了创建自动化评估的工具。

当存在一系列可能的输出被认为在质量上都相当高(例如,对于长答案的问题)时,基于模型的评估就非常有用。基于模型的评估与需要人类评估的界限模糊不清,并且随着模型变得更加强大,这个界限不断变化。我们鼓励尝试以弄清楚基于模型的评估在您的用例中能够起到多大作用。

战术:根据黄金标准答案评估模型输出

假设已知问题的正确答案应该涉及到一组特定的已知事实。那么我们可以使用一个模型查询来计算答案中包含了多少个必需的事实。

例如,使用以下系统消息:

这是一个示例输入,其中两个要点都得到了满足:

这是一个示例输入,其中只有一个要点得到了满足:

这是一个示例输入,其中没有任何要点得到满足:

这种基于模型的评估有许多可能的变体。考虑以下变体,它跟踪候选答案和黄金标准答案之间的重叠程度,并且还跟踪候选答案是否与黄金标准答案的任何部分相矛盾。

这里是一个示例输入,其中包含一个次优的答案,但它并没有与专家答案相矛盾:

这里是一个示例输入,其中包含一个直接与专家答案相矛盾的答案:

这里是一个示例输入,其中包含一个正确的答案,而且提供了比必要更多的细节:

其他资源

为了获得更多灵感,可以访问OpenAI Cookbook,它包含了示例代码以及链接到第三方资源,例如:

  • 提示库和工具
  • 提示指南
  • 视频课程
  • 关于高级提示以提高推理能力的论文