模型发出特殊字符串来指示对话状态何时发生变化,这使我们能够将我们的系统变成一个状态机,其中状态决定注入哪些指令,通过跟踪状态、哪些指令与该状态相关,可选地允许从该状态进行哪些状态转换,我们可以为用户体验设置护栏,而使用不太结构化的方法很难实现这一点。
2.对于需要很长对话的应用,总结过滤对话
由于模型具有固定的上下文长度,因此用户和助手之间的对话(其中整个对话都包含在上下文窗口中)不会无限期继续,解决此类问题有多种方法,系统给出了2种。
一种是总结对话中的先前回合。一旦输入的大小达到预定的阈值长度,这可能会触发总结部分对话的查询,并且先前对话的摘要可以作为系统消息的一部分包括在内。或者,可以在整个对话过程中在后台异步总结之前的对话。
另一种解决方案是动态选择与当前查询最相关的对话的先前部分。参见策略OpenAI的官方文档:“使用基于嵌入的搜索实现高效的知识检索”。
由于模型具有固定的上下文长度,因此它们不能用于总结长于上下文长度减去单个查询中生成的摘要长度的文本。
要总结一个很长的文档(例如一本书),我们可以使用一系列查询来总结文档的每个部分。章节摘要可以连接和总结,生成摘要的摘要。这个过程可以递归地进行,直到总结整个文档。如果有必要使用前面部分的信息来理解后面的部分,那么另一个有用的技巧是在总结该点的内容时,在书中任何给定点之前包含文本的运行摘要。OpenAI在之前的研究中已经使用 GPT-3 的变体研究了这种总结书籍的过程的有效性。
1.指示模型在得出结论之前,找出自己的解决方案
当我们明确指示模型在得出结论之前从第一原理推理时,我们会得到更好的结果。假设我们想要一个模型来评估学生对数学问题的解决方案。解决这个问题最明显的方法是简单地询问模型学生的解决方案是否正确。
系统 | 确定学生的解决方案是否正确。 |
用户 | 问题陈述:我正在建造一个太阳能发电装置,我需要帮助解决财务问题。 - 土地成本为 100 美元/平方英尺 - 我可以以 250 美元/平方英尺的价格购买太阳能电池板 - 我协商了一份维护合同,每年将花费我 10 万美元,另外还要额外花费 10 美元/平方英尺第一年运营作为平方英尺数的函数。学生的解决方案:设 x 为装置的尺寸(以平方英尺为单位)。 1. 土地成本:100x 2. 太阳能电池板成本:250x 3. 维护成本:100,000 + 100x 总成本:100x + 250x + 100,000 + 100x = 450x + 100,000 |
助手 | 该学生的解决方案是正确的。 |
这位同学的解法其实不正确,我们通过模型,生成自己的解决方案,提示模型注意到这一点。
系统 | 首先制定自己的问题解决方案。然后将你的解决方案与学生的解决方案进行比较,并评估学生的解决方案是否正确。在你自己完成问题之前,不要决定学生的解决方案是否正确。 |
用户 | 问题陈述:我正在建造一个太阳能发电装置,我需要帮助解决财务问题。 - 土地成本为 100 美元/平方英尺 - 我可以以 250 美元/平方英尺的价格购买太阳能电池板 - 我协商了一份维护合同,每年将花费我 10 万美元,另外还要额外花费 10 美元/平方英尺第一年运营作为平方英尺数的函数。学生的解决方案:设 x 为装置的尺寸(以平方英尺为单位)。 1. 土地成本:100x 2. 太阳能电池板成本:250x 3. 维护成本:100,000 + 100x 总成本:100x + 250x + 100,000 + 100x = 450x + 100,000 |
助手 | 设 x 为安装尺寸(以平方英尺为单位)。 1. 土地成本:100x 2. 太阳能电池板成本:250x 3. 维护成本:100,000 + 10x 总成本:100x + 250x + 100,000 + 10x = 360x + 100,000 学生的解决方案不正确。他们在维护成本计算中犯了一个错误,使用了 100x 而不是 10x。第一年运营的正确总成本是 360x + 100,000。 |
前面的策略表明,模型有时在回答特定问题之前详细推理问题很重要。对于某些应用程序,模型用于得出最终答案的推理过程不适合与用户共享。例如,在辅导应用程序中,我们可能希望鼓励学生得出自己的答案,但模型关于学生解决方案的推理过程可能会向学生揭示答案。
内心独白是一种可以用来缓解这种情况的策略。内心独白的想法是指示模型将原本对用户隐藏的部分输出放入结构化格式中,以便于解析它们。然后,在向用户呈现输出之前,将解析输出并且仅使部分输出可见。
系统 | 请按照以下步骤回答用户的疑问。步骤 1 - 首先找出你自己的问题解决方案。不要依赖学生的解决方案,因为它可能是不正确的。将您此步骤的所有工作用三引号 (""") 括起来。第 2 步 - 将您的解决方案与学生的解决方案进行比较,并评估学生的解决方案是否正确。将您此步骤的所有工作用三引号 ("") 括起来”)。第 3 步 - 如果学生犯了错误,请确定在不泄露答案的情况下可以给学生什么提示。将这一步的所有工作用三引号 (""") 括起来。步骤 4 - 如果学生犯了错误,请向学生提供上一步的提示(在三引号之外)。而不是写“步骤 4 - ...”写“提示:”。 |
用户 | 问题陈述:<插入问题陈述> 学生解决方案:<插入学生解决方案> |
或者,这可以通过一系列查询来实现,其中除了最后一个查询之外,所有查询的输出都对最终用户隐藏。
首先,我们可以要求模型自己解决问题。由于这个初始查询不需要学生的解决方案,因此可以省略。这提供了额外的优势,即模型的解决方案不会因学生尝试的解决方案而产生偏差。
接下来,我们可以让模型使用所有可用信息来评估学生解决方案的正确性。
系统 | 将您的解决方案与学生的解决方案进行比较,并评估学生的解决方案是否正确。 |
用户 | 问题陈述:"""<插入问题陈述>""" 您的解决方案:"""<插入模型生成的解决方案>""" 学生的解决方案:"""<插入学生的解决方案>""" |
最后,我们可以让模型使用自己的分析来以乐于助人的导师的角色构建回复。
系统 | 你是一名数学导师。如果学生犯了错误,请以不透露答案的方式向学生提供提示。如果学生没有犯错,只需给他们一个鼓励性的评论。 |
用户 | 问题陈述:"""<插入问题陈述>""" 您的解决方案:"""<插入模型生成的解决方案>""" 学生的解决方案:"""<插入学生的解决方案>""" 分析:"""<插入模型从上一步生成的分析>""" |
3.询问模型在之前的过程中是否遗漏了任何内容
假设我们使用一个模型来列出与特定问题相关的来源的摘录。列出每个摘录后,模型需要确定是否应该开始编写另一个摘录或者是否应该停止。如果源文档很大,模型通常会过早停止并且无法列出所有相关摘录。在这种情况下,通过使用后续查询提示模型查找之前传递中错过的任何摘录,通常可以获得更好的性能。
系统 | 您将获得一份由三重引号分隔的文档。你的任务是选择与以下问题相关的摘录:“人工智能历史上发生了哪些重大的范式转变。”确保摘录包含解释它们所需的所有相关上下文 - 换句话说,不要提取缺少重要上下文的小片段。提供 JSON 格式的输出,如下所示: [{"excerpt": "..."}, ... {"excerpt": "..."}] |
用户 | """<在此插入文档>""" |
助手 | [{"excerpt": "模型在这里写一个摘录"}, ... {"excerpt": "模型在这里写另一个摘录"}] |
用户 |
还有更多相关摘录吗?注意不要重复摘录。还要确保摘录包含解释它们所需的所有相关上下文 - 换句话说,不要提取缺少重要上下文的小片段。
|
通过向模型提供其他工具的输出来弥补模型的弱点。例如,文本检索系统(有时称为 RAG 或检索增强生成)可以告诉模型相关文档。像 OpenAI 的代码解释器这样的代码执行引擎可以帮助模型进行数学运算并运行代码。如果一项任务可以通过工具而不是语言模型更可靠或更有效地完成,那么可以卸载它以充分利用两者。
具体使用方法:
- 使用基于嵌入的搜索实现高效的知识检索
- 使用代码执行来进行更准确的计算或调用外部API
- 授予模型访问特定功能的权限
使用示例:
1.使用基于嵌入的搜索实现高效的知识检索
示例实现可以在
OpenAI Cookbook中找到。请参阅策略
“指示模型使用检索到的知识来回答查询”,了解如何使用知识检索来最大程度地减少模型编造不正确事实的可能性的示例。
2.使用代码执行来进行更准确的计算或调用外部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,想在下班后见面吗?")`` ` |
警告:执行模型生成的代码本质上并不安全,任何试图执行此操作的应用程序都应采取预防措施。特别是,需要沙盒代码执行环境来限制不受信任的代码可能造成的危害。
3.授予模型访问特定功能的权限
聊天完成 API 允许在请求中传递功能描述列表,这使模型能够根据提供的模式生成函数参数,生成函数参数由 API 以 JSON 格式返回,可用于执行函数调用。然后,可以将函数调用提供的输出反馈到以下请求中的模型中以关闭循环。这是使用OpenAI模型调用外部函数的推荐方式。
具体请参阅我们的介绍性文本生成指南中的
函数调用部分以及OpenAI Cookbook 中的更多
函数调用示例。
如果您可以衡量性能,那么提高性能就会更容易。在某些情况下,对提示的修改将在一些孤立的示例上实现更好的性能,但会导致在一组更具代表性的示例上整体性能变差。因此,为了确保更改对性能产生净积极影响,可能有必要定义一个全面的测试套件(也称为“评估”)。
具体使用方法:
具体示例:
假设已知问题的正确答案应参考一组特定的已知事实。然后我们可以使用模型查询来计算答案中包含多少必需的事实。
例如,使用以下系统消息:
系统 |
您将获得由三引号分隔的文本,该文本应该是问题的答案。检查答案中是否直接包含以下信息: - 尼尔·阿姆斯特朗是第一个登上月球的人。 - 尼尔·阿姆斯特朗 (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 日,尼尔·阿姆斯特朗成为第二个在上面行走的人继巴兹·奥尔德林之后登上月球。"""专家解答:"""尼尔·阿姆斯特朗最著名的是第一个登上月球的人。这一历史性事件发生在 1969 年 7 月 21 日。""" |
下面是一个带有正确答案的示例输入,它还提供了比必要的更多的细节:
系统 | <在上面插入系统消息> |
用户 | 问题:“”“尼尔·阿姆斯特朗最著名的事件是什么?它发生在哪一天?假设 UTC 时间。”“”提交的答案:“”“1969 年 7 月 21 日大约 02:56 UTC,尼尔·阿姆斯特朗成为第一个人类踏上月球表面,标志着人类历史上的一项里程碑式的成就。”“”专家解答:“”“尼尔·阿姆斯特朗最著名的是第一个登上月球的人。这一历史性事件发生在7月21日, 1969年。 |
特别提示:本信息由相关用户自行提供,真实性未证实,仅供参考。请谨慎采用,风险自负。