LOADING

OpenAI官方Prompt工程指南

AI干货2周前更新 AI宝贝
5.6K 0 0

获得更好结果的六项策略

一、写下清晰的指示

这些模型无法读懂你的想法。 如果输出太长,请要求简短答复。 如果输出太简单,请要求专家级别的写作。 如果您不喜欢这种格式,请演示您希望看到的格式。 模型猜测你想要什么的次数越少,你得到它的可能性就越大。
写出清晰指令的小技巧:
  1. 在查询中包含详细信息以获得更相关的答案( 提供详细的内容)

为了获得高度相关的响应,请确保请求提供任何重要的详细信息或上下文。不能让模型来猜测你的意思。
尽量多的提供任何重要的详细信息和上下文,添加更具体的信息,不要使用笼统的描述。
较差的提问
较好的提问
如何在 Excel 中添加数字?
如何在 Excel 中添加一行美元金额?我想对整张行自动执行此操作,所有总计都在右侧名为“总计”的列中结束。
谁是总统?
谁是 2021 年墨西哥总统?选举频率如何?
编写代码来计算斐波那契数列。
编写一个 TypeScript 函数来高效计算斐波那契数列。自由地注释代码以解释每部分的作用以及为什么这样编写。
总结会议记录。
用一个段落总结会议记录。然后写下演讲者的 Markdown 列表以及他们的每个要点。最后,列出发言人建议的后续步骤或行动项目(如果有)。
  1. 要求模特采用角色(让模型扮演某个角色)

你可以把GPT当作演员,你要告诉他让他演什么角色,他就会更符合角色的专业度。
假扮成一位旅行顾问,每当我需要旅行建议时,以有趣的方式介绍目的地,并添加一些有趣的当地传说或小故事。 扮演一位心理学家,每当我提出问题时,提供有关问题的专业见解。
  1. 使用分隔符清楚地指示输入的不同部分

三引号、XML 标签、节标题等分隔符可以帮助划分要区别对待的文本节。可以帮助大模型更好的理解文本内容。
"""在此插入文字""" <article> 在此插入第一篇文章 </article> <article> 在此插入第二篇文章 </article>
  1. 指定完成任务所需的步骤

有些任务最好指定为一系列步骤。明确地写出这些步骤可以使模型更容易遵循它们。
使用以下分步说明来响应用户输入。 第1步: - 用户将为您提供三引号中的文本。用一个句子总结这段文字,并加上前缀“Summary:”。 第2步: - 将步骤 1 中的摘要翻译成西班牙语,并添加前缀“翻译:”。
  1. 提供例子

即少样本提示,few-shot prompt,给大模型例子,让大模型按你的例子来输出。
  1. 指定所需的输出长度

可以要求模型生成给定目标长度的输出。目标输出长度可以根据单词、句子、段落、要点等的计数来指定。中文效果不明显,字数长度只能是个大概,但是像多少句、多少段这种效果就比较好。
用大约 50 个单词概括由三引号分隔的文本。"""在此插入文字""" 总结两段中用三引号分隔的文本。"""在此插入文字""" 将由三引号分隔的文本总结为 3 个要点。"""在此插入文字"""

二、提供参考文本

语言模型可以自信地发明假答案,特别是当被问及深奥的主题或引文和 URL 时。 为这些模型提供参考文本可以帮助减少模型胡说八道的概率。
  1. 让模型使用参考文本回答

如果我们可以为模型提供与当前查询相关的可信信息,那么我们可以指示模型使用提供的信息来组成其答案。
使用提供的由"""< 此处插入文章>"""三重引号引起来的文章来回答问题。如果在文章中找不到答案,请写“我找不到答案”。
  1. 让模型通过引用参考文本来回答

如果已经给了文本,则可以直接要求模型通过引用所提供文档中的段落来为其答案添加引用。可以提高正确性,增加可验证性。
您将获得一份由三重引号和一个问题分隔的文档。您的任务是仅使用提供的文档回答问题,并引用用于回答问题的文档段落。如果文档不包含回答此问题所需的信息,则只需写:“信息不足”。如果提供了问题的答案,则必须附有引文注释。使用以下格式引用相关段落({“引用”:…})。 """<在此插入文档>""" 问题:<在此插入问题>

三、将复杂的任务拆分为更简单的子任务

复杂的任务往往比简单的任务具有更高的错误率。 把复杂的任务给拆给更为简单的子任务,大模型会有更好的表现。
  1. 使用意图分类来识别与用户查询最相关的指令

例如,假设对于客户服务应用程序,查询可以有效地分类如下: 我们将向您提供客户服务查询。 将每个查询分为主要类别和次要类别。 提供 json 格式的输出,其中包含以下键:主要和次要。 主要类别:计费、技术支持、帐户管理或一般查询。 计费二级类别: - 取消订阅或升级 - 添加付款方式 - 收费说明 - 费用争议 技术支持二级类别: - 故障排除 - 设备兼容性 - 软件更新 帐户管理二级类别: - 密码重置 - 更新个人信息 - 关闭帐户 -帐户安全一般查询二级类别: - 产品信息 - 定价 - 反馈 - 与人交谈
根据客户查询的分类,可以向模型提供一组更具体的指令,以供其处理后续步骤。 例如,假设客户需要“故障排除”方面的帮助。 您将收到需要在技术支持环境中进行故障排除的客户服务查询。 通过以下方式帮助用户: - 要求他们检查进出路由器的所有电缆是否已连接。 请注意,随着时间的推移,电缆松动是很常见的。 - 如果所有电缆均已连接并且问题仍然存在,请询问他们正在使用哪种路由器型号 - 现在您将建议他们如何重新启动其设备: - 如果型号是 MTD-327J,建议他们按红色按钮并按住 5 秒钟,然后等待 5 分钟后再测试连接。 -- 如果型号是 MTD-327S,建议他们拔下并重新插入,然后等待 5 分钟再测试连接。 - 如果客户的问题在重新启动设备并等待 5 分钟后仍然存在,请通过输出 {“IT 支持请求”} 将他们连接到 IT 支持。 - 如果用户开始询问与此主题无关的问题,请确认他们是否愿意结束当前有关故障排除的聊天,并根据以下方案对他们的请求进行分类:<在此处插入上面的主要/次要分类方案>
  1. 对于需要很长对话的对话应用,总结或过滤以前的对话

由于模型具有固定的上下文长度,因此用户和助手之间的对话(其中整个对话都包含在上下文窗口中)无法无限期地继续。
解决此问题有多种解决方法,其中之一是总结对话中的先前回合。 一旦输入的大小达到预定的阈值长度,这可能会触发总结部分对话的查询,并且先前对话的摘要可以作为系统消息的一部分包括在内。 或者,可以在整个对话过程中在后台异步总结之前的对话。
另一种解决方案是动态选择与当前查询最相关的对话的先前部分。 参见策略 “使用基于嵌入的搜索实现高效的知识检索”
  1. 分段总结长文档并递归构建完整摘要

由于模型具有固定的上下文长度,因此它们不能用于总结长于上下文长度减去单个查询中生成的摘要长度的文本。
要总结一个很长的文档(例如一本书),我们可以使用一系列查询来总结文档的每个部分。 章节摘要可以连接和总结,生成摘要的摘要。 这个过程可以递归地进行,直到总结整个文档。 如果有必要使用前面部分的信息来理解后面的部分,那么另一个有用的技巧是在总结该点的内容时,在书中任何给定点之前包含文本的运行摘要。 OpenAI在之前的 研究 中已经使用 GPT-3 的变体研究了这种总结书籍的过程的有效性。

四、给模型时间“思考”

think step by step
如果要求将 17 乘以 28,您可能不会立即知道,但随着时间的推移仍然可以算出来。 同样,模型在尝试立即回答而不是花时间找出答案时会犯更多推理错误。 在给出答案之前询问“思路链”可以帮助模型更可靠地推理出正确答案。
  1. 指示模型在急于得出结论之前找出自己的解决方案

有时,当我们明确指示模型在得出结论之前从第一原理进行推理时,我们会得到更好的结果。 假设我们想要一个模型来评估学生对数学问题的解决方案。 解决这个问题最明显的方法是简单地询问模型学生的解决方案是否正确。
问题陈述:我正在建造一个太阳能发电装置,我需要帮助解决财务问题。 - 土地成本为 100 美元/平方英尺 - 我可以以 250 美元/平方英尺的价格购买太阳能电池板 - 我协商了一份维护合同,每年将花费我 10 万美元,另外还要额外花费 10 美元/平方英尺第一年运营作为平方英尺数的函数。 学生的解决方案:设 x 为装置的尺寸(以平方英尺为单位)。 1. 土地成本:100x 2. 太阳能电池板成本:250x 3. 维护成本:100,000 + 100x 总成本:100x + 250x + 100,000 + 100x = 450x + 100,000
  1. 使用内心独白或一系列查询来隐藏模型的推理过程

前面的策略表明,模型有时在回答特定问题之前详细推理问题很重要。 对于某些应用程序,模型用于得出最终答案的推理过程不适合与用户共享。 例如,在辅导应用程序中,我们可能希望鼓励学生得出自己的答案,但模型关于学生解决方案的推理过程可能会向学生揭示答案。
内心独白是一种可以用来缓解这种情况的策略。 内心独白的想法是指示模型将原本对用户隐藏的部分输出放入结构化格式中,以便于解析它们。 然后,在向用户呈现输出之前,将解析输出并且仅使部分输出可见。
请按照以下步骤回答用户的疑问。 步骤 1 - 首先找出你自己的问题解决方案。 不要依赖学生的解决方案,因为它可能是不正确的。 将您此步骤的所有工作用三引号 (""") 括起来。 步骤 2 - 将您的解决方案与学生的解决方案进行比较,并评估学生的解决方案是否正确。将您此步骤的所有工作用三引号 ("") 括起来”)。 步骤 3 - 如果学生犯了错误,请确定在不泄露答案的情况下可以给学生什么提示。 将这一步的所有工作用三引号 (""") 括起来。 步骤 4 - 如果学生犯了错误,请向学生提供上一步的提示(在三引号之外)。而不是写“步骤 4 - ...”写“提示:”。 问题陈述:<插入问题陈述> 学生解决方案:<插入学生解决方案>
或者,这可以通过一系列查询来实现,其中除了最后一个查询之外,所有查询的输出都对最终用户隐藏。
首先,我们可以要求模型自己解决问题。 由于这个初始查询不需要学生的解决方案,因此可以省略。这提供了额外的优势,即模型的解决方案不会因学生尝试的解决方案而产生偏差。 接下来,我们可以让模型使用所有可用信息来评估学生解决方案的正确性。 将您的解决方案与学生的解决方案进行比较,并评估学生的解决方案是否正确。 问题陈述:"""<插入问题陈述>""" 您的解决方案:"""<插入模型生成的解决方案>""" 学生的解决方案:"""<插入学生的解决方案>"""
最后,我们可以让模型使用自己的分析来以乐于助人的导师的角色构建回复。
你是一名数学导师。 如果学生犯了错误,请以不透露答案的方式向学生提供提示。 如果学生没有犯错,只需给他们一个鼓励性的评论。 问题陈述:"""<插入问题陈述>""" 您的解决方案:"""<插入模型生成的解决方案>""" 学生的解决方案:"""<插入学生的解决方案>""" 分析:"""<插入模型从上一步生成的分析>"""
  1. 询问模型在之前的过程中是否遗漏了任何内容

假设我们正在使用一个模型来列出与特定问题相关的来源的摘录。 列出每个摘录后,模型需要确定是否应该开始编写另一个摘录或者是否应该停止。 如果源文档很大,模型通常会过早停止并且无法列出所有相关摘录。 在这种情况下,通过使用后续查询提示模型查找之前传递中错过的任何摘录,通常可以获得更好的性能。
您将获得一份由三重引号分隔的文档。 你的任务是选择与以下问题相关的摘录:“人工智能历史上发生了哪些重大的范式转变。” 确保摘录包含解释它们所需的所有相关上下文 - 换句话说,不要提取缺少重要上下文的小片段。 提供 JSON 格式的输出,如下所示: [{"excerpt": "..."}, ... {"excerpt": "..."}] [{"excerpt": "模型在这里写一个摘录"}, ... {"excerpt": "模型在这里写另一个摘录"}] 还有更多相关摘录吗? 注意不要重复摘录。 还要确保摘录包含解释它们所需的所有相关上下文 - 换句话说,不要提取缺少重要上下文的小片段。

五、使用外部工具

通过向模型提供其他工具的输出来弥补模型的弱点。 例如,文本检索系统(有时称为 RAG 或检索增强生成)可以告诉模型相关文档。 像 OpenAI 的代码解释器这样的代码执行引擎可以帮助模型进行数学运算并运行代码。 如果一项任务可以通过工具而不是语言模型更可靠或更有效地完成,那么可以卸载它以充分利用两者。
策略:
  1. 使用基于嵌入的搜索实现高效的知识检索

如果作为输入的一部分提供,模型可以利用外部信息源。 这可以帮助模型生成更明智和最新的响应。 例如,如果用户询问有关特定电影的问题,则将有关电影的高质量信息(例如演员、导演等)添加到模型的输入中可能会很有用。 嵌入可用于实现高效的知识检索,从而可以在运行时动态地将相关信息添加到模型输入中。
文本嵌入是一个可以衡量文本字符串之间相关性的向量。 相似或相关的字符串比不相关的字符串更接近。 这一事实以及快速向量搜索算法的存在意味着嵌入可以用于实现高效的知识检索。 特别地,文本语料库可以被分割成块,并且每个块可以被嵌入和存储。 然后可以嵌入给定的查询,并且可以执行矢量搜索以从语料库中找到与查询最相关的嵌入文本块(即在嵌入空间中最接近的文本块)。
示例实现可以在OpenAI Cookbook 中找到 。 请参阅策略 “指示模型使用检索到的知识来回答查询”, 了解如何使用知识检索来最大程度地减少模型编造不正确事实的可能性的示例。
  1. 使用代码执行来执行更准确的计算或调用外部API

不能依赖语言模型自行准确地执行算术或长时间计算。 在需要的情况下,可以指示模型编写和运行代码,而不是进行自己的计算。 特别是,可以指示模型将要运行的代码放入指定的格式,例如三重反引号。 产生输出后,可以提取代码并运行。 最后,如果有必要,可以将代码执行引擎(即Python解释器)的输出作为下一个查询的模型的输入。
您可以通过将Python 代码括在三个反引号中来编写和执行Python 代码,例如“此处代码为”。 用它来执行计算。 求以下多项式的所有实值根:3*x**5 - 5*x**4 - 3*x**3 - 7*x - 10。
代码执行的另一个很好的用例是调用外部 API。 如果模型接受了如何正确使用 API 的指导,它就可以编写使用该 API 的代码。 通过向模型提供展示如何使用 API 的文档和/或代码示例,可以指导模型如何使用 API。
您可以通过将 Python 代码括在三个反引号中来编写和执行它。 另请注意,您可以访问以下模块来帮助用户向朋友发送消息: ```python import message message.write(to="John", message="Hey,想在下班后见面吗?")`` `
  1. 授予模型访问特定功能的权限

六、系统地测试变更

如果您可以衡量性能,那么提高性能就会更容易。 在某些情况下,对提示的修改将在几个孤立的示例上实现更好的性能,但会导致在一组更具代表性的示例上整体性能变差。 因此,为了确保更改对性能产生净积极影响,可能有必要定义一个全面的测试套件(也称为“评估”)。
有时很难判断更改(例如新指令或新设计)是否使您的系统变得更好或更差。 看几个例子可能会暗示哪个更好,但由于样本量较小,很难区分真正的改进或随机运气。 也许这种变化有助于某些输入的性能,但会损害其他输入的性能。
评估程序(或“evals”)对于优化系统设计非常有用。 好的评估是:
  • 代表现实世界的使用情况(或至少是多样化的)
  • 包含许多测试用例以获得更大的统计能力(有关指南,请参阅下表)
  • 易于自动化或重复
检测差异
95% 置信度所需的样本量
30%
〜10
10%
〜100
3%
〜1,000
1%
〜10,000
输出的评估可以由计算机、人类或两者混合来完成。 计算机可以使用客观标准(例如,具有单个正确答案的问题)以及一些主观或模糊标准自动进行评估,其中模型输出由其他模型查询进行评估。 OpenAI Evals 是一个开源软件框架,提供用于创建自动化评估的工具。
当存在一系列可能的输出被认为质量同样高时(例如,对于答案很长的问题),基于模型的评估会很有用。 通过基于模型的评估可以实际评估的内容与需要人类评估的内容之间的界限是模糊的,并且随着模型变得更加强大而不断变化。 我们鼓励进行实验,以确定基于模型的评估对您的用例的效果如何。

策略:参考黄金标准答案评估模型输出

假设已知问题的正确答案应参考一组特定的已知事实。 然后我们可以使用模型查询来计算答案中包含多少必需的事实。例如,使用以下系统消息:
您将获得由三引号分隔的文本,该文本应该是问题的答案。 检查答案中是否直接包含以下信息: - 尼尔·阿姆斯特朗是第一个登上月球的人。 - 尼尔·阿姆斯特朗 (Neil Armstrong) 首次登上月球的日期是 1969 年 7 月 21 日。对于每个点,请执行以下步骤: 1 - 重述该点。 2 - 提供最接近这一点的答案的引文。 3 - 考虑不知道主题的阅读引文的人是否可以直接推断出该点。 在做出决定之前解释一下原因或原因。 4 - 如果 3 的答案是“是”,则写“是”,否则写“否”。 最后,计算有多少个“是”答案。 将此计数提供为 {"count": <在此处插入计数>}。
这是一个满足这两点的示例输入:
"""尼尔·阿姆斯特朗因成为第一个踏上月球的人类而闻名。这一历史性事件发生在 1969 年 7 月 21 日,阿波罗 11 号任务期间。"""
以下是仅满足一个点的示例输入:
“”“尼尔·阿姆斯特朗走下登月舱时创造了历史,成为第一个在月球上行走的人。”“”
这是一个不满足任何条件的示例输入:
“69 年夏天,一次伟大的航行,阿波罗 11 号,像传奇之手一样大胆。阿姆斯特朗迈出一步,历史展开,“一小步,”他说,为了一个新世界。”“”
这种基于模型的评估有许多可能的变体。 考虑以下变体,它跟踪候选答案和黄金标准答案之间的重叠类型,并且还跟踪候选答案是否与黄金标准答案的任何部分相矛盾。
使用以下步骤响应用户输入。 在继续之前充分重申每个步骤。 即“第一步:原因...”。 步骤 1:逐步推理所提交答案中的信息与专家答案相比是否是:不相交、相等、子集、超集或重叠(即存在交集,但不是子集/超集)。 第2步:逐步推理提交的答案是否与专家答案的任何方面相矛盾。 步骤 3:输出一个 JSON 对象,结构如下:{"type_of_overlap": "disjoint" or "equal" or "subset" or "superset" or "overlapping", "contradiction": true or false}
这是一个示例输入,其答案不合格,但与专家答案并不矛盾:
问题:“”“尼尔·阿姆斯特朗最著名的事件是什么?它发生在哪一天?假设 UTC 时间。”“”提交的答案:“”“他没有在月球上行走过吗?”“”专家解答: """尼尔·阿姆斯特朗最著名的是第一个登上月球的人。这一历史性事件发生在 1969 年 7 月 21 日。"""
这是一个示例输入,其答案与专家答案直接矛盾:
问题:“”“尼尔·阿姆斯特朗最著名的事件是什么?它发生在哪一天?假设 UTC 时间。”“”提交的答案:“”“1969 年 7 月 21 日,尼尔·阿姆斯特朗成为第二个在上面行走的人继巴兹·奥尔德林之后登上月球。"""专家解答:"""尼尔·阿姆斯特朗最著名的是第一个登上月球的人。这一历史性事件发生在 1969 年 7 月 21 日。"""
下面是一个带有正确答案的示例输入,它还提供了比必要的更多的细节:
问题:“”“尼尔·阿姆斯特朗最著名的事件是什么?它发生在哪一天?假设 UTC 时间。”“”提交的答案:“”“1969 年 7 月 21 日大约 02:56 UTC,尼尔·阿姆斯特朗成为第一个人类踏上月球表面,标志着人类历史上的一项里程碑式的成就。”“”专家解答:“”“尼尔·阿姆斯特朗最著名的是第一个登上月球的人。这一历史性事件发生在7月21日, 1969年。

其他资源

如需更多灵感,请访问 OpenAI Cookbook ,其中包含示例代码以及第三方资源的链接,例如:
© 版权声明

相关文章