提示词工程
该指南分享了获取更好结果的策略和战术,适用于像GPT-4这样的大型语言模型(有时也称为GPT模型)。这里描述的方法有时可以组合使用以获得更好的效果。我们鼓励进行试验,找到最适合您的方法。
提示词工程[1]
该指南分享了获取更好结果的策略和战术,适用于像GPT-4这样的大型语言模型(有时也称为GPT模型)。这里描述的方法有时可以组合使用以获得更好的效果。我们鼓励进行试验,找到最适合您的方法。这里演示的一些示例目前仅适用于我们最强大的模型“gpt-4”。一般来说,如果你发现一个模型在某个任务上失败,而另一个更强大的模型可用,再次尝试使用更强大的模型往往是值得的。
你也可以探索示例提示,展示我们的模型有什么能力:
提示示例 探索提示示例以了解GPT模型的能力[2]
提高结果的六种策略
写清楚的指示
这些模型无法读取您的思想。如果输出过长,请要求简洁回答。如果输出太简单,请要求专业水平的写作。如果您不喜欢的格式,请展示您希望看到的格式。模型需要猜测的越少,您就越有可能得到您想要的结果。
策略:
•在查询中包含详细信息以获得更相关的答案[3]•要求模型扮演一个人设[4]•使用分隔符清楚地指示输入的不同部分[5]•指定完成任务所需的步骤[6]•提供示例[7]•指定所需的输出长度[8]
提供参考文本
语言模型可以自信地编造虚假答案,尤其是在被问及晦涩主题、引用和URL时。就像给学生一张笔记纸可以帮助他们在考试中表现更好一样,为这些模型提供参考文本可以帮助它们在回答问题时减少虚构的程度。
策略:
•指导模型使用参考文本回答问题[9]•指导模型使用参考文本中的引用来回答问题[10]
将复杂任务拆分为较简单的子任务[11]
就像在软件工程中将一个复杂系统分解为一组模块化组件一样,将任务提交给语言模型也是一个好的实践。复杂任务往往比简单任务有更高的错误率。此外,复杂任务通常可以重新定义为一系列较简单任务的工作流,其中前一任务的输出被用来构建后一任务的输入。
策略: 以下是文本的翻译:
•使用意图分类来识别与用户查询最相关的说明[12]•对于需要非常长对话的对话应用程序,进行对先前对话的摘要或过滤[13]•将长文档分段进行摘要并递归构建完整摘要[14]
给模型一些时间来“思考”[15]
如果让你计算17乘以28,你可能不会立刻知道答案,但是可以通过一些时间来计算出来。类似地,模型在尝试即时回答时会产生更多的推理错误,而不是花时间来计算答案。在回答之前要求“思考过程”可以帮助模型更可靠地推理出正确答案。
战术: 请点击以下链接阅读详细指南:
•在贸然下结论之前,指导模型自己解决问题[16]•使用内心独白或一系列问题隐藏模型的推理过程[17]•询问模型在之前的处理中是否有遗漏[18]
使用外部工具[19]
通过将其他工具的输出馈送给模型来弥补模型的弱点。例如,一个文本检索系统(有时称为RAG或检索增强生成)可以告诉模型相关的文档信息。像OpenAI的Code Interpreter这样的代码执行引擎可以帮助模型进行数学计算和代码运行。如果一个任务可以通过工具而不是语言模型来更可靠或更高效地完成,则将其卸载以获得双赢的效果。
战术:
•使用基于嵌入的搜索实现高效知识检索[20]•使用代码执行进行更精确的计算或调用外部 API[21]•为模型提供访问特定函数的能力[22]
系统地测试变化[23]
如果能够对改进效果进行衡量,提高性能就会变得更容易。在某些情况下,对提示进行修改可能会在少数几个孤立的示例上实现更好的性能,但在更具代表性的示例组上导致性能变差。因此,为了确保变化对性能的净影响是正面的,可能需要定义一个全面的测试套件(也称为“评估”)。
策略:
•参考标准答案评估模型输出[24]
策略[25]
上述列出的每种策略都可以用具体的策略来实例化。这些策略旨在提供尝试的思路。它们远非全面,您可以随时尝试并运用自己的创意思路。
策略:编写清晰的说明
请确保在请求中提供任何重要的细节或背景,以获取高度相关的回复。否则,您将让模型去猜测您的意思。
Worse | Better |
How do I add numbers in Excel? | How do I add up a row of dollar amounts in Excel? I want to do this automatically for a whole sheet of rows with all the totals ending up on the right in a column called "Total". |
Who’s president? | Who was the president of Mexico in 2021, and how frequently are elections held? |
Write code to calculate the Fibonacci sequence. | Write a TypeScript function to efficiently calculate the Fibonacci sequence. Comment the code liberally to explain what each piece does and why it's written that way. |
Summarize the meeting notes. | Summarize the meeting notes in a single paragraph. Then write a markdown list of the speakers and each of their key points. Finally, list the next steps or action items suggested by the speakers, if any. |
策略: 要求模型拟人化
下面的系统指的是prompt中的system部分,用户是指user部分。
系统消息可以用于指定模型在回复中采用的角色。
系统
代码语言:javascript复制当我要求帮助写作时,你将回复一份包含至少一个笑话或调侃评论的文档。
用户
代码语言:javascript复制写一封感谢信给我的螺栓供应商,感谢他们按时并在短时间内交付货物。这使我们能够交付一份重要的订单。
在Playground中打开[26]
#### 策略:使用分隔符清楚地标示输入的不同部分[27]
像三个引号、XML标签、章节标题等分隔符可以帮助标示不同的文本部分,以便进行不同的处理。
用户
代码语言:javascript复制用一个俳句总结被三个引号分隔的文本。
"""在这里插入文本""""
Open in Playground[28]
系统
代码语言:javascript复制你将收到一对关于同一主题的文章(由XML标签分隔)。首先总结每篇文章的论点。然后指出哪篇文章提出了更好的论点,并解释原因。
用户
代码语言:javascript复制<article>在此插入第一篇文章</article>
<article>在此插入第二篇文章</article>
在 Playground 中打开[29]
系统 您将获得一篇论文摘要以及一个建议的标题。论文标题应该给读者一个很好的关于论文主题的概念,同时也应该引人注目。如果标题不符合这些标准,请提出5个备选方案。
用户
代码语言:javascript复制摘要:在这里插入摘要
标题:在这里插入标题
在playground中打开[30] 对于这样的简单任务,使用分隔符可能不会对输出质量产生影响。然而,任务越复杂,澄清任务细节的重要性就越大。不要让模型费力理解你准确要求什么。
策略:明确指定完成任务所需的步骤
有些任务最好指定为一系列步骤。将这些步骤明确写出可以让模型更容易跟随。
系统
代码语言:javascript复制按照以下逐步说明来回应用户的输入。
第一步 - 用户将会用三引号提供给你一段文本。用一个前缀为"Summary: "的句子来总结这段文本。
第二步 - 将第一步中的总结翻译成西班牙语,用一个前缀为"Translation: "的句子。
用户
代码语言:javascript复制"""在这里插入文本"""
在playground中打开[31]
策略:提供例子[32]
通常来说,提供适用于所有示例的通用指导要比通过示例演示任务的所有排列组合更高效,但在某些情况下,提供示例可能更容易。例如,如果您打算让模型复制一种难以明确描述的用户查询响应风格。这就是所谓的'few-shot'提示。
系统
代码语言:javascript复制以一种一致的风格回答。
用户
代码语言:javascript复制教我如何耐心。
助手(模型的回复)
代码语言:javascript复制刻出最深峡谷的河流源于一处普通的泉眼;最华丽的交响乐从一个音符产生;最复杂的织锦以一根孤单的线开始。
你可以要求模型生成给定目标长度的输出。目标输出长度可以根据词语、句子、段落、列表项等进行指定。但请注意,指示模型生成特定数量的词语不具有高精度。模型可以更可靠地生成具有特定数量的段落或列表项的输出。
在Playground中打开[33]
用户
代码语言:javascript复制将用三重引号分隔的文本进行2段落摘要。
"""在这里插入文本"""
在Playground中打开[34]
用户
代码语言:javascript复制将用三重引号分隔的文本进行3个要点摘要。
"""在这里插入文本"""
在Playground中打开[35]
策略:提供参考文本
如果我们能够为模型提供与当前查询相关的可信信息,那么我们可以指示模型使用提供的信息来组成其回答。使用由三重引号分隔的提供的文章来回答问题。如果答案在文章中找不到,请写上"I could not find an answer.
用户
代码语言:javascript复制<插入由三重引号分隔的文章>
问题: <插入问题>
在Playground中打开[36] 鉴于所有模型都有有限的上下文窗口,我们需要一种在被问问题相关的情况下动态查找信息的方法。嵌入[37]可以用于实现高效的知识检索。请参考策略"使用基于嵌入的搜索实现高效的知识检索"[38]以了解更多关于如何实施这一点的详细信息。
策略:指导模型在回答中引用参考文献
如果输入已经通过相关知识进行补充,可以直接要求模型通过引用所提供的文档中的段落来添加引用到其回答中。请注意,可以通过在所提供的文档中进行字符串匹配来编程验证输出中的引用。您将获得一个由三个引号分隔的文档,并提供一个问题。您的任务是仅使用提供的文档回答问题,并引用用于回答问题的文段。如果文档中不包含回答该问题所需的信息,则简单写上:"信息不足"。如果提供了问题的答案,必须注明引用。请使用以下格式引用相关文段({"citation": ...})。
用户
代码语言:javascript复制"""<在此处插入文档>"""
问题:<在此处插入问题>
在Playground中打开[39]
策略:将复杂任务分解为简单子任务[40]
战术:使用意图分类来识别与用户查询最相关的指令[41]
对于需要处理不同情况下的大量独立指令集的任务,首先对查询的类型进行分类,并使用该分类确定需要使用哪些指令可能是有益的。这可以通过定义固定的类别并对相应类别中的任务处理相关指令进行硬编码来实现。这个过程也可以递归地应用于将任务分解为一系列阶段。这种方法的优势在于每个查询只包含执行任务的下一个阶段所需的那些指令,与使用一个查询执行整个任务相比,这可以降低错误率。这也可以降低成本,因为更大的提示会导致更高的运行费用(详见定价信息[42])。假设例如对于客户服务应用程序,查询可以有用地分类如下:
系统
代码语言:javascript复制您将获得客户服务查询。将每个查询分类为主要类别和次要类别。使用键primary和secondary,以json格式提供输出。
主要类别:账单、技术支持、账户管理或一般查询。
账单的次要类别:
- 取消订阅或升级
- 添加付款方式
- 解释费用
- 对费用提出异议
技术支持次要类别:
- 故障排除
- 设备兼容性
- 软件更新
帐户管理次要类别:
- 重置密码
- 更新个人信息
- 关闭帐户
- 帐户安全
一般查询次要类别:
- 产品信息
- 定价
- 反馈
- 联系人工客服
用户
代码语言:javascript复制我需要让我的互联网重新工作起来。
根据客户查询的分类,可以为模型提供一组更具体的指令,以便它处理下一步。例如,假设客户需要“故障排除”方面的帮助。
系统
代码语言:javascript复制您将收到需要在技术支持环境中进行故障排除的客户服务查询。通过以下方式帮助用户:
- 请他们检查路由器与所有电缆的连接情况。请注意,电缆随时间可能会松动。
- 如果所有电缆都连接好但问题仍然存在,请询问他们所使用的路由器型号。
- 现在您将指导他们如何重新启动设备:
-- 如果型号是MTD-327J,请建议他们按下红色按钮并按住5秒钟,然后等待5分钟后测试连接。
-- 如果型号是MTD-327S,请建议他们拔掉电源插头,然后重新插上,然后等待5分钟后测试连接。
- 如果客户在重新启动设备并等待5分钟后问题仍然存在,请输出{"IT support requested"},将他们接入IT支持部门。
- 如果用户开始询问与此主题无关的问题,请确认他们是否希望结束当前的故障排除聊天并根据以下方案对他们的请求进行分类:
<在此处插入上述的一级/二级分类方案>
用户
代码语言:javascript复制我需要让我的互联网重新工作起来。
在playground中打开[43] 请注意,模型已被指示发出特殊字符串,以指示对话状态何时发生变化。这使我们能够将我们的系统转变为状态机,其中状态决定了要注入的指令。通过跟踪状态、确定在该状态下哪些指令是相关的,以及可选地确定从该状态允许的状态转换,我们可以为用户体验设置防护栏,这在较少结构化的方法中很难实现。
策略:对于需要非常长对话的应用,对先前的对话进行总结或过滤
因为模型有固定的上下文长度,用户和助手之间的对话,如果整个对话都包含在上下文窗口中,是无法无限继续下去的。有多种解决这个问题的方法,其中之一是总结前面对话的内容。一旦输入的长度达到一个预定的阈值,就可以触发一个查询来总结对话的一部分,并将之前的对话总结作为系统消息的一部分包含进来。另外,可以在整个对话过程中异步地在后台进行对之前对话的总结。一种替代方案是动态选择与当前查询最相关的先前对话部分。请参阅策略"使用基于嵌入式搜索实现高效知识检索"[44]。
策略:逐段概括长文档并递归构建完整摘要[45]
由于模型的上下文长度是固定的,因此它们无法在单个查询中用于总结比上下文长度减去生成摘要长度更长的文本。要总结一本非常长的文档,例如一本书,我们可以使用一系列查询来总结文档的每个部分。将各个部分的摘要连接起来,再进行总结,可以得到总结的总结。这个过程可以递归进行,直到整个文档被总结出来。如果在理解后面的部分时需要使用前面部分的信息,那么一个有用的技巧是在总结特定位置的内容时,包括一份在该位置之前的文本的连续摘要。OpenAI之前的研究[46]使用GPT-3的变体来研究使用这种方法总结书籍的有效性。
策略:给模型思考的时间
战术:指导模型在匆忙得出结论之前自行解决问题
有时候,当我们明确要求模型在得出结论之前从基本原理出发时,我们能够取得更好的结果。例如,假设我们希望模型评估学生对数学问题的解决方案。最直接的方法是简单地询问模型学生的解决方案是否正确。
系统
代码语言:javascript复制确定学生的解决方案是否正确。
用户
代码语言:javascript复制问题陈述:我正在建设一个太阳能发电装置,我需要帮助计算财务数据。
- 土地成本为每平方英尺100美元
- 我可以以每平方英尺250美元的价格购买太阳能电池板
- 我谈判得到了一份维护合同,每年的费用是固定的10万美元,再加上每平方英尺10美元
第一年运营的总费用是一个关于平方英尺数量的函数。
学生的解答:设x为安装面积(平方英尺)。
1. 土地成本:100x
2. 太阳能电池板成本:250x
3. 维护费用:100,000 100x
总费用:100x 250x 100,000 100x = 450x 100,000
助手(模型的回复)
代码语言:javascript复制学生的解答是正确的。
在playground中打开[47]
但学生的解决方案实际上是错误的!我们可以通过提示模型首先生成它自己的解决方案,让模型成功地注意到这一点。
系统
代码语言:javascript复制首先自己解决问题。然后将你的解决方案与学生的解决方案进行比较,评估学生的解决方案是否正确。在你自己解决问题之前,不要决定学生的解决方案是否正确。
用户
代码语言:javascript复制问题陈述:我正在建立一座太阳能发电装置,需要帮助计算财务情况。
- 土地成本为每平方英尺100美元
- 我可以以每平方英尺250美元购买太阳能电池板
- 我协商了一份维护合同,每年将花费我固定的10万美元,并额外支付每平方英尺10美元
第一年运营的总成本是多少,这是一个关于平方英尺数量的函数。
学生的解答:令x为太阳能发电装置的面积(以平方英尺为单位)。
1. 土地成本:100x
2. 太阳能电池板成本:250x
3. 维护成本:100,000 100x
总成本:100x 250x 100,000 100x = 450x 100,000
助手(模型的回复)
代码语言:javascript复制设 x 为安装的面积(平方英尺)。
1. 土地成本:100x
2. 太阳能电池板成本:250x
3. 维护成本:100,000 10x
总成本:100x 250x 100,000 10x = 360x 100,000
学生的解答是不正确的。他们在计算维护成本时犯了一个错误,使用了100x而不是10x。第一年运营的正确总成本是360x 100,000。
在 Playground 中打开[48]
策略:使用内心独白或查询序列来隐藏模型的推理过程[49]
之前的策略表明,在回答具体问题之前,模型有时需要对问题进行详细推理是很重要的。对于某些应用程序来说,模型用来得出最终答案的推理过程可能不适合与用户共享。例如,在辅导应用程序中,我们可能希望鼓励学生自己解决问题,但模型对学生解决方案的推理过程可能会向学生透露答案。内心独白是一种可以用来减轻这个问题的策略。内心独白的理念是指令模型将原本需要对用户隐藏的部分输出转化为结构化格式,从而使解析变得容易。然后,在呈现给用户之前,对输出进行解析,并只让其中一部分变得可见。
系统
代码语言:javascript复制按照以下步骤回答用户的问题。
步骤1 - 首先解决你自己的问题。不要依赖于学生的解决方案,因为它可能是错误的。在这一步中,将所有的工作用三重引号(""")括起来。
步骤2 - 将你的解决方案与学生的解决方案进行比较并评估学生的解决方案是否正确。在这一步中,将所有的工作用三重引号(""")括起来。
步骤3 - 如果学生犯了一个错误,请确定你可以给予学生什么样的提示,而不是给出答案。在这一步中,将所有的工作用三重引号(""")括起来。
步骤4 - 如果学生犯了一个错误,请将上一步的提示提供给学生(块状引用之外)。将“步骤4 - ...”改成“提示:”。"
用户
代码语言:javascript复制问题陈述:《插入问题陈述》
学生解决方案:《插入学生解决方案》
在playground中打开[50]
另外,可以通过一系列查询来实现,其中除了最后一个查询,其余查询的输出对终端用户隐藏。首先,我们可以要求模型自行解决问题。由于这个初始查询不需要学生的解决方案,因此可以省略。这样做的额外好处是,模型的解决方案不会受到学生尝试的解决方案的偏见的影响。
用户
代码语言:javascript复制<插入问题陈述>
在Playground中打开[51]
接下来,我们可以让模型使用所有可用信息来评估学生的解决方案的正确性。
系统
代码语言:javascript复制将以下文本翻译为简体中文:
文本:将您的解决方案与学生的解决方案进行比较,并评估学生的解决方案是否正确。
用户
代码语言:javascript复制问题说明:"""<插入问题说明>"""
您的解决方案:"""<插入模型生成的解决方案>"""
学生的解决方案:"""<插入学生的解决方案>"""
在Playground中打开[52]
最后,我们可以让模型使用自己的分析来构建一个以有帮助的导师形象回复的回复。
系统
代码语言:javascript复制你是一个数学辅导员。如果学生犯了错误,请以一种不透露答案的方式向学生提供提示。如果学生没有犯错误,只需给他们一个鼓励的评论。
用户
代码语言:javascript复制问题陈述:"""<插入问题陈述>"""
你的解决方案:"""<插入生成的模型解决方案>"""
学生的解决方案:"""<插入学生的解决方案>"""
分析:"""<插入先前步骤生成的分析>"""
在 Playground 中打开[53]
策略:询问模型是否在之前的迭代中遗漏了任何内容[54]
假设我们正在使用一个模型来从一个源中列出与特定问题相关的摘录。在列出每个摘录后,模型需要确定是否应该开始写另一个摘录,还是应该停止。如果源文件很大,模型常常会过早停止而未能列出所有相关的摘录。在这种情况下,通过提示模型用后续查询找到任何它在之前遗漏的摘录,通常可以获得更好的性能。
系统
代码语言:javascript复制您将获得一个由三引号分隔的文档。您的任务是选择与以下问题相关的摘录:“人工智能的历史中发生了哪些重大的范式转变”。确保摘录包含解释所需的所有相关上下文 - 换句话说,不要提取缺少重要上下文的小片段。以以下形式以JSON格式提供输出:
[{"excerpt": "..."},
...
{"excerpt": "..."}]
用户
代码语言:javascript复制"""<在此处插入文档>"""
助理(模型回答)
代码语言:javascript复制[{"excerpt": "模型在此处编写摘录"},
...
{"excerpt": "模型在此处编写另一个摘录"}]
用户
代码语言:javascript复制是否还有更多相关的摘录?注意不要重复摘录。还要确保摘录包含所有需要解释它们的相关上下文-换句话说,不要提取缺乏重要上下文的小片段。
在 Playground 中打开[55]
策略:使用外部工具[56]
策略:使用基于嵌入的搜索实现高效知识检索[57]
如果外部信息是作为其输入的一部分提供的,模型可以利用外部信息。这可以帮助模型生成更多了解和最新的响应。例如,如果用户提问关于一部特定电影的问题,将关于电影的高质量信息(例如演员、导演等)添加到模型的输入中可能非常有用。嵌入可以用来实现高效的知识检索,以便在运行时动态地将相关信息添加到模型输入中。文本嵌入是可以衡量文本字符串之间相关性的向量。相似或相关的字符串会比不相关的字符串更接近。这个事实以及快速向量搜索算法的存在,意味着可以使用嵌入来实现高效的知识检索。具体来说,可以将文本语料库分割成片段,并对每个片段进行嵌入和存储。然后,可以对给定的查询进行嵌入,并进行向量搜索,以找到与查询最相关的嵌入片段(即在嵌入空间中最接近的片段)。示例实现可以在OpenAI Cookbook[58]中找到。查看策略“指导模型使用检索到的知识来回答查询”的示例,以了解如何使用知识检索来最小化模型编造不正确事实的可能性。
策略:使用代码执行进行更准确的计算或调用外部API[59]
转化为文本:点击此处[60] 语言模型不能单独依赖于执行算术或长时间计算的准确性。在需要这样的情况下,可以指示模型编写和运行代码,而不是进行自己的计算。特别是,可以指示模型将要运行的代码放入指定的格式,例如三个反引号。在生成输出后,可以提取和运行代码。最后,如果需要,可以将代码执行引擎(即Python解释器)的输出作为下一个查询的输入提供给模型。
系统
代码语言:javascript复制您可以通过三个反引号将Python代码括起来,并执行它,例如```code goes here```。可以使用此方法进行计算。
用户
代码语言:javascript复制找出以下多项式的所有实根:3*x**5 - 5*x**4 - 3*x**3 - 7*x - 10。
在 Playground 中打开[61] 另一个代码执行的好用例是调用外部API。如果模型在正确使用API方面受到指导,它可以编写利用该API的代码。通过提供文档和/或代码示例来告知模型如何使用API。
系统
代码语言:javascript复制您可以使用三个反引号将Python代码括起来并执行。还请注意,您可以访问以下模块,以帮助用户向朋友发送消息:
```
import message
message.write(to="John", message="嘿,下班后想一起见面吗?")
```
在 Playground 中打开[62]
警告:执行模型生成的代码并不绝对安全,应在任何使用此功能的应用程序中采取预防措施。特别是需要使用沙箱代码执行环境来限制不受信任的代码可能造成的伤害。
Tactic:给模型访问特定的函数[63] Chat Completions API允许在请求中传递一个函数描述列表。这使模型能够根据提供的模式生成函数参数。生成的函数参数以JSON格式由API返回,并可用于执行函数调用。函数调用提供的输出可以在以下请求中反馈给模型,以闭合循环。这是使用OpenAI模型调用外部函数的推荐方法。要了解更多信息,请参阅我们的文本生成指南中的'函数调用'章节,并在OpenAI Cookbook中查看更多'函数调用示例'。
策略:系统地测试变更
有时候,很难确定一项变更(例如新的指令或设计)是否使系统变得更好还是更差。查看几个示例可能会暗示哪一个更好,但使用小样本量很难区分真正的改进还是随机运气。也许这项变更在某些输入上有助于性能,但对其他输入却有负面影响。评估程序(或“评估”)对于优化系统设计非常有用。
好的评估应满足以下要求:
•代表真实世界的使用情况(或至少是多样的)•包含许多测试用例以获得更大的统计能力(请参考下表的指南)•易于自动化或重复
需要检测的差异 | 95%置信度所需样本数量 |
---|---|
30% | ~10 |
10% | ~100 |
3% | ~1,000 |
1% | ~10,000 |
输出可以通过计算机、人类或两者混合进行评估。计算机可以使用客观标准(例如,只有一个正确答案的问题)自动评估以及一些主观或模糊标准,在这些标准下,模型输出会被其他模型查询评估。OpenAI Evals[64]是一个开源的软件框架,提供创建自动化评估的工具。 | |
基于模型的评估在存在一系列可能的输出被认为具有相同高质量性的情况下是有用的(例如对于回答较长问题的情况)。用模型进行评估和需要人工评估的界限是模糊的,并且随着模型变得更加有能力而不断变化。我们鼓励通过实验来确定基于模型的评估在您的用例中能够起到多大作用。 |
策略:将模型输出与黄金标准答案对比进行评估
假设已知一个问题的正确答案应参考一组特定的已知事实。那么我们可以使用模型查询来计算答案中包含了多少个所需事实。
例如,使用以下系统消息:
系统
代码语言:javascript复制您将获得由三个引号分隔的文本,这被认为是对一个问题的答案。请检查以下信息是否直接包含在答案中:
- 尼尔·阿姆斯特朗是第一个在月球上行走的人。
- 尼尔·阿姆斯特朗首次登上月球的日期是1969年7月21日。
对于每个要点,请执行以下步骤:
1 - 重述这个要点。
2 - 提供一个最接近这个要点的答案引用。
3 - 考虑一下,如果一个不了解这个主题的人阅读引文,是否能够直接推断出该要点。在做出决定之前解释原因。
4 - 如果问题3的答案是“是”,则写下“是”,否则写下“否”。
最后,计算有多少个“是”的答案。以 {"count": <插入数量>} 的格式提供此计数。
这里是一个满足两个条件的示例输入:
系统
代码语言:javascript复制<insert system message above>
用户
代码语言:javascript复制"""尼尔·阿姆斯特朗因为成为第一个登上月球的人而闻名。这一历史性事件发生在1969年7月21日,是阿波罗11号任务期间发生的。"""
在 Playground 中打开[65]
这里是一个只满足一个条件的示例输入:
系统
代码语言:javascript复制<insert system message above>
用户
代码语言:javascript复制"Neil Armstrong在他走下登月舱时创造了历史,成为第一个在月球上行走的人。""
这种基于模型的评估方法有很多可能的变种。考虑一下下面这个变种,它跟踪候选答案与黄金标准答案之间的重叠程度,并且还跟踪候选答案是否与黄金标准答案的任何部分相矛盾。
系统:
代码语言:javascript复制使用以下步骤来回应用户输入。在进行下一步之前,完整重述每一步。例如,"第一步:理由..."。
第一步:逐步推断提交答案中的信息与专家答案相比是如下方式之一:不相交、相等、子集、超集或交集(即相交但不是子集/超集)。
第二步:逐步推理提交答案是否与专家答案的任何方面相互矛盾。
第三步:输出结构化的JSON对象,形式为:{"type_of_overlap": "disjoint"或"equal"或"subset"或"superset"或"overlapping", "contradiction": true或false}。
在 Playground 中打开[66]
以下是一个示例输入,其中包含一个次标准回答,但并未与专家答案相矛盾:
系统
代码语言:javascript复制<在此处插入系统消息>
用户
代码语言:javascript复制问题:“尼尔·阿姆斯特朗最著名的事件是什么?它发生在哪个日期?假设是世界协调时间。”
提交的回答:“他不是在月球上行走吗?”
专家回答:“尼尔·阿姆斯特朗最著名的事件是成为第一个在月球上行走的人。这一历史事件发生于1969年7月21日。”
问题:「尼尔·阿姆斯特朗最著名的事件是什么,它发生在什么日期?假设使用协调世界时(UTC)时间。」
提交的答案:「1969年7月21日,尼尔·阿姆斯特朗成为第二个登上月球的人,位于巴兹·奥尔德林之后。」
专家的答案:「尼尔·阿姆斯特朗最著名的是成为第一个登上月球的人。这一历史事件发生在1969年7月21日。」
这是一个带有正确答案的示例输入,它还提供了比必要的更多细节:
系统:
代码语言:javascript复制<在上方插入系统信息>
用户:
代码语言:javascript复制问题:「尼尔·阿姆斯特朗最出名的事件是什么,它发生在哪个日期?假设使用的是UTC时间。」
提交的回答:「大约在1969年7月21日02:56 UTC,尼尔·阿姆斯特朗成为第一位登上月球表面的人类,标志着人类历史上的一个重大成就。」
专家的回答:「尼尔·阿姆斯特朗最出名的事件是成为第一个在月球上行走的人。这一历史性事件发生于1969年7月21日。」
在Playground中打开[67]
其他资源
访问OpenAI Cookbook[68]以获取更多灵感,其中包含示例代码和第三方资源的链接。
•引导库和工具[69]•引导指南[70]•视频课程[71]•关于提高推理能力的高级引导论文[72]
实战
如何进行提示工程
由于指令跟随型模型[73]的训练方式或其训练数据,有些特定的提示格式特别有效,更能与手头的任务保持一致。以下我们展示了一些我们认为可靠有效的提示格式,但请随意探索不同的格式,这些可能更适合您的任务。
经验法则及示例
注意:“{在此输入文本}”是实际文本/上下文的占位符。
1. 使用最新的模型
为了获得最佳效果,我们通常建议使用最新、最强大的模型。截至2022年11月,最好的选择是文本生成的“text-davinci-003”模型[74]和代码生成的“code-davinci-002”模型。
2. 将指令放在提示的开始部分,并使用 ### 或 """ 来分隔指令和上下文
效果不佳:
代码语言:javascript复制将下面的文本总结为最重要点的项目符号列表。
{text input here}
效果更佳:
代码语言:javascript复制将下面的文本总结为最重要点的项目符号列表。
文本:"""
{text input here}
"""
3. 尽可能具体、描述性和详细地说明所需的上下文、结果、长度、格式、风格等
具体说明上下文、结果、长度、格式、风格等
效果不佳:
代码语言:javascript复制写一首关于OpenAI的诗。
效果更佳:
代码语言:javascript复制写一首简短而鼓舞人心的关于OpenAI的诗,重点描述最近的DALL-E产品发布(DALL-E是一个文本到图像的ML模型),采用{著名诗人}的风格
4. 通过示例表达期望的输出格式(示例1[75],示例2[76])。
效果不佳:
代码语言:javascript复制从下面的文本中提取提到的实体。提取以下4种实体类型:公司名称、人名、特定主题和主旨。
文本:{text}
展示和说明 - 当模型被具体的格式要求所示范时,回应效果更好。这也使得程序化地可靠提取多个输出变得更容易。
效果更佳:
代码语言:javascript复制从下面的文本中提取重要实体。首先提取所有公司名称,然后提取所有人名,接着提取符合内容的特定主题,最后提取总体主旨。
期望格式:
公司名称:<逗号分隔的公司名称列表>
人名:-||-
特定主题:-||-
总体主旨:-||-
文本:{text}
5. 先尝试zero-shot,然后是few-shot(示例[77]),如果都不行,再微调
zero-shot
代码语言:javascript复制从下面的文本中提取关键词。
文本:{text}
关键词:
few-shot - 提供几个示例
代码语言:javascript复制从下面的文本中提取关键词。
文本1:Stripe提供API,网页开发人员可以使用这些API将支付处理集成到他们的网站和移动应用中。
关键词1:Stripe、支付处理、API、网页开发人员、网站、移动应用
文本2:OpenAI训练了尖端的语言模型,这些模型非常擅长理解和生成文本。我们的API提供对这些模型的访问,并可用于解决几乎所有涉及处理语言的任务。
关键词2:OpenAI、语言模型、文本处理、API。
文本3:{text}
关键词3:
微调:请参阅此处[78]的微调最佳实践。
6. 减少“冗长”和不精确的描述
效果不佳 :
代码语言:javascript复制这个产品的描述应该相当简短,只有几句话,不要太多。
效果更佳:
代码语言:javascript复制使用3到5句话的段落来描述这个产品。
7. 不仅仅说不要做什么,还要说要做什么
效果不佳:
代码语言:javascript复制以下是一名代理与一名客户之间的对话。不要询问用户名或密码。不要重复。
客户:我无法登录我的账户。
代理:
效果更佳:
代码语言:javascript复制以下是一名代理与一名客户之间的对话。代理将尝试诊断问题并建议解决方案,同时避免询问任何与个人身份信息(PII)相关的问题。不要询问用户名或密码之类的PII,而是将用户引导至帮助文章www.samplewebsite.com/help/faq
客户:我无法登录我的账户。
代理:
8. 代码生成特定 - 使用“引导词”促使模型朝特定模式倾斜
效果不佳:
代码语言:javascript复制# 编写一个简单的python函数
# 1. 向我询问一个以英里为单位的数字
# 2. 将英里转换为公里
在下面的代码示例中,添加"import"提示模型应该开始用Python编写。(类似地,“SELECT”是SQL语句开始的好提示。)
效果更佳:
代码语言:javascript复制# 编写一个简单的python函数
# 1. 向我询问一个以英里为单位的数字
# 2. 将英里转换为公里
import
参数
一般来说,我们发现model
和 temperature
是用于改变模型输出的最常用参数。
1.model
- 性能更高的模型[79]更昂贵且延迟更高。2.temperature
- 是模型输出较不可能的令牌的频率的度量。temperature
越高,输出通常越随机(并且通常更有创意)。然而,这并不等同于“真实性”。对于大多数事实性用例,如数据提取和真实的问答,最佳的temperature
是0。3.max_tokens
(最大长度)- 并不控制输出的长度,而是令牌生成的硬性截止限制。理想情况下,您不会经常触及此限制,因为您的模型会在认为已完成时停止,或在达到您定义的停止序列时停止。4.stop
(停止序列) - 一组字符(令牌),在生成时,会导致文本生成停止。
有关其他参数的描述,请参阅API参考[80]。
更多内容查看:
•https://platform.openai.com/docs/guides/prompt-engineering•Best practices for prompt engineering with OpenAI API | OpenAI Help Center[88]