跳到主要内容

🟢 OpenAI官方提示功能指南

😀 前言:15号 OpenAI 更新了官方提示工程指南(Prompt engineering),指南里面提到了六大原则:

1. Write clear instructions(写出清晰的指令)

2. Provide reference text(提供参考文本)

3. Split complex tasks into simpler subtasks(将复杂的任务拆分为更简单的子任务)

4. Give the model time to "think"(给模型时间“思考”)

5. Use external tools(使用外部工具)

**6. Test changes systematically(系统地测试变更)

这些原则可以相互结合,以发挥更大的作用。按照这个框架,可以完成你的提示语的99%的优化**

一. 写出清晰的指令

模型不会读心术,无法猜到你的想法。

  • 如果模型的输出内容过长,你可以要求它简短回答。
  • 如果模型输出内容过于简单,你可以要求使用更专业的水平写作。
  • 如果你对输出格式不满意,可以直接展示你期望的格式

最好就是让模型不需要去猜你想要什么,这样你最有可能获得想要的结果。

OpenAI给出了6个核心技巧

1. 在问题中添加详细信息

确保你的提问中包含了所有重要的细节和背景信息。

🙅不要说:“总结一下会议记录”

🙆而是说:“请用一个段落总结会议记录。接着,用 markdown 列表的形式列出所有发言者及其关键观点。最后,如果有的话,列出发言者提出的下一步计划或建议的行动项”

2. 请求模型扮演特定角色

显著告诉模型应该充当什么角色,能够激活它的“扮演”能力。官方提供的例子不够经典,这里我换了一个:

我希望你扮演一名小说家。您将想出富有创意且引人入胜的故事,可以长时间吸引读者。你可以选择任何类型,如奇幻、浪漫、历史小说等,但目标是写出具有出色情节、引人入胜的人物和意想不到的高潮的作品。我的第一个要求是“我要写一部以未来为背景的科幻小说”。

3. 使用分隔符来清晰区分输入的不同部分

使用三重引号、XML 标签、章节标题等作为分隔符,能够有效地区别并处理不同的文本内容。(通俗来说就是让模型清洗分辨出哪一部分是你的需求,哪一部分是需要处理文本

例如:

你将会接收到两篇关于相同主题的文章。首先分别总结这两篇文章的主要论点。接着评价哪篇文章的论据更具说服力,并说明理由。

“”“

文章内容

“”“

善用空行和“”“在代码领域常用于划分不同区域的符号非常有效且方便

4. 明确指出完成任务需要的步骤

对于复杂任务,最好将其分解成一系列明确的步骤。将步骤清晰地写出来,可以帮助模型更有效地遵循指令。

例如:

请按照以下步骤来回应用户的输入。

第 1 步 - 用户会给你提供带有三重引号的文本。请将这段文本总结为一句话,并以“摘要:”作为前缀。

第 2 步 - 将第 1 步中的摘要翻译成西班牙语,并以“翻译:”作为前缀。

"""输入文本""”

5. 提供实例作为参考

few-shot技巧:在某些情况下,通过提供具体示例来说明可能更直观。比如,你想让模型学习某种特定的回应方式。

例如:

whatpu是一种原产于坦桑尼亚的毛茸茸的小动物。

使用whatpu这个词的句子示例如下: 我们在非洲旅行,看到了这些非常可爱的 whatpus。

"farduddle "的意思是快速地上下跳跃。

使用该词的句子举例如下的句子是:

6. 明确指定希望输出的长度

请用两段话概括三引号内的文本。

"""insert text here"""

. 提供参考文本

语言模型可能会自信地编造出虚假答案,特别是当回应一些深奥主题或被要求提供引文和 URLs 时。为GPT提供参考文本也可减少其制造虚假信息的情况。

1. 使用参考文本来构建答案

例如:

当你被提供特定文章,并需要回答问题时,请依据这些文章中的内容来作答。如果这些文章中没有包含答案,你只需表明“无法找到答案”。

<插入文章内容,每篇文章之间用三个引号隔开>

问题:<插入问题>

💡 由于所有模型都受到上下文窗口大小的限制,我们需要一种方法来动态地查询与提出的问题相关的信息。可以使用 Embeddings(嵌入式技术)来实现有效的知识检索。

2. 指导模型用引用的文本回答问题

如果输入信息中已经包含了相关知识,就可以直接要求模型在回答问题时引用所提供的文件中的段落。值得注意的是,输出中的引用可以通过在所提供的文件中匹配字符串来进行验证。

例如:

你将会收到一个用三个引号标记的文档和一个问题。你的任务是仅使用所提供的文档来回答这个问题,并引用文档中用来回答问题的部分。如果文档中没有包含足够的信息来回答这个问题,就简单地写“信息不足”。如果提供了问题的答案,那么必须用引用标记。引用相关段落时,请使用以下格式({"citation": …})

"""<插入文档>"""

问题:<插入问题>

三. 将复杂任务分解成更简单的子任务

将一个庞大且复杂的任务划分成更小、更简单的子任务是一种有效的方法。这同样适用于大型模型。这种方法能够帮助它们更有效地处理复杂任务,从而展现出更优异的性能。

1. 利用意图分类确定与用户查询最相关的指令

当你有很多不同的任务要处理时,一个方法是先把这些任务分成几类。然后,根据每一类任务,你就可以决定需要用哪些特定的步骤来完成它。比如,你可以先设定几个主要的任务类型,然后对每种类型的任务设定一些固定的步骤。

这种方法的好处是,你不需要一次性处理所有的事情,而是可以一步步来,这样就减少了出错的机会。这样做不仅能减少错误,还可能节省成本,因为处理一大堆事情的成本通常比分步处理要高。

比如,对于客户服务应用来说,可以有效地把查询分为以下几类:

现在,大模型根据步骤1,知道“我断网了咋整”是属于技术支持中的故障排除了,我们就可以再继续步骤2:

2. 针对需要长时间对话的应用程序,应概括或过滤之前的对话内容

由于模型的上下文长度是固定的,用户与助手的对话不能无限延续,尤其是当整个对话内容都包含在上下文窗口中时。

解决这一问题的方法之一是概括之前的对话。当输入内容达到一定长度时,可以触发对部分对话内容进行概括的查询,这样的概括可以作为系统消息的一部分。或者,也可以在整个对话过程中不断后台概括之前的对话内容。

takeaways

💡 虽然这个偏开发场景,但是普通用户也能够用prompt主动让模型总结之前的对话历史 例如:

你的任务是总结人工智能角色与人类对话中之前的信息历史。 为您提供的对话来自一个固定的上下文窗口,可能并不完整。 从人工智能的角度总结对话中发生的事情(使用第一人称)。 摘要字数应少于 {WORD_LIMIT},切勿超过字数限制

WORD_LIMIT就是你希望输出的字数长度

另一种方法是动态地挑选对话中与当前问题最相关的部分。详情可见策略 “利用基于嵌入向量的搜索实现高效的知识检索”

3 逐段归纳长文档并递归地构建完整摘要

因为模型的上下文长度是固定的,所以它们无法一次性总结超过上下文长度减去所生成摘要长度的文本。

例如,要总结一本很长的书,我们可以使用一系列的查询来分别总结书中的每个章节。这些部分的摘要可以被连结并进一步总结,形成摘要的摘要。这个过程可以递归地进行,直至整本书被总结完毕。如果在理解书中后续部分时需要前面章节的信息,那么在总结当前部分内容时附加一个前面内容的连续摘要会是一个实用的技巧。

OpenAI 之前利用 GPT-3 的变种对这种总结书籍的方法进行了研究

Untitled

四. 给予模型“思考”的时间

1. 在模型急于得出结论之前,指导模型自己寻找解决方案

有时,在明确指导模型根据基本原理进行推理之前,我们可能会得到更好的结果。假设我们希望模型评估一个学生对数学问题的解答。最直观的方式是直接询问模型学生的解答是否正确。

Untitled

然而,学生的解答其实并不正确!我们可以通过引导模型首先产生它自己的解答,从而让它成功地发现这个问题。

Untitled

2. 运用内心独白或连续提问来隐藏模型的推理过程

先前的策略证明,在回答特定问题之前,模型有时需要深入地推理问题的过程。然而,在某些应用环境中,模型为得出最终答案的推理过程不宜与用户分享。比如,在教导应用里,我们或许希望鼓励学生自行思考答案,但模型对于学生解答的推理过程可能会无意间透露出答案。

内心独白就是能有效应对这种情况的策略。内心独白的主要概念是指导模型将那些需要被用户隐藏的输出部分以一种结构化的形式表现,从而容易进行解析。然后在将输出结果展示给用户之前,将其进行解析处理,最后只呈现部分的解析结果给用户看。

Untitled

另一种方式是通过一系列的查询来实现,除了最后一个外,所有查询的结果都不展示给用户。

首先,我们可以让模型独立解决这个问题。因为这个初始步骤不需要学生的答案,所以可以省略。这样可以确保模型的答案不会受到学生答案的影响。

Untitled

最后,让模型根据自己的分析以有帮助的家教身份给出回复。

Untitled

3. 询问模型是否有遗漏

比如我们在用模型列出与特定问题相关的摘录时,每列出一段后,模型需要决定是继续写下一个还是停止。如果原文很长,模型可能会过早结束,错过一些相关摘录。此时,通过后续查询来寻找之前遗漏的摘录,通常可以获得更好的效果。

Untitled

五. 使用外部工具

简单来说就是模型可以通过利用作为输入的一部分提供的外部信息,生成更加准确和及时的回应。(gpt的插件系统就是这个策略有效性的体验)

1. 使用基于嵌入的搜索实现高效知识检索

如果用户提问有关某部特定电影的问题,将该电影的高质量信息(如演员、导演等)添加到模型输入中可能很有帮助。嵌入技术可以用于高效地检索知识,因此可以在运行时动态地将相关信息添加到模型输入中。

takeaways

💡 文本嵌入是一种向量,能够衡量文本字符串之间的相关性。相关或相似的字符串在嵌入空间中会比不相关的字符串更靠近。这一事实,加上快速向量搜索算法的存在,意味着可以使用嵌入来实现高效的知识检索。具体而言,可以将文本语料库分割成多个块,对每个块进行嵌入处理并存储。然后,可以对特定查询进行嵌入处理,并进行向量搜索,以找到语料库中与查询最相关的嵌入文本块(即在嵌入空间中位置最接近的)。

在 OpenAI Cookbook 中,你可以找到一些实用的实现示例。

2. 利用代码执行进行精确计算或调用外部 API

仅凭语言模型自身,我们不能指望它准确完成算术或复杂计算。在需要精确计算的场合,我们可以让模型编写并运行代码,而不是自行计算。特别是,我们可以让模型将要执行的代码放在特定的格式里,比如三个反引号。代码运行后产生的输出可以被提取并执行。必要时,还可以将代码执行引擎(比如 Python 解释器)的输出作为下一步查询的输入。

例如:

你可以通过用三个反引号包裹 Python 代码来编写并执行代码,例如code goes here。这种方式适用于需要进行计算的情况。

求解以下多项式的所有实数解:3x**5 - 5x4 - 3*x3 - 7*x - 10。

3. 使模型能够访问特定功能

这是利用 OpenAI 模型来执行外部函数调用的推荐方法,偏开发侧

简单来说是Chat Completions API 允许在请求中传递函数的描述。这样,模型就可以生成符合这些描述的函数参数。这些参数以 JSON 格式由 API 返回,并可以用于执行函数调用。函数调用的结果可以再次输入到模型中,形成一个闭环。

function-calling

Untitled

5. 以标准答案为基准评估模型输出

假设我们已经知道对某个问题的正确回答应当涉及一组特定的已知事实。在这种情况下,我们可以通过模型查询来检查回答中包含了哪些必要的事实。

takeaways

💡 主要目的在于协助开发人员评估更改Prompt是否提升或降低了实际效果。通常情况下,样本数量有限,因此很难判断是真正的进步还是仅仅由于偶然因素。

主要思路是“追踪模型生成答案与标准答案之间的相似性,以及候选答案是否与标准答案有任何矛盾。”,这部分推荐看原文:

prompt-engineering

📎 参考文章