我对Prompt Engineering的理解

 

“提示工程(Prompt Engineering)” 这一概念源于语言模型的发展,它描述了如何有效地利用提示从语言模型中提取信息的过程,通常应用于现实世界的应用场景中。

许多声称正在进行提示工程的人实际上只是在盲目地给出提示。我用 “盲目提示(Blind Prompting)” 这个术语来描述这种创建提示的方法,这种方法采用了粗浅的尝试和错误方法,结合少量的测试,或者几乎没有测试,给出非常简单的提示知识。盲目提示不是提示工程。

关于提示工程究竟能否真正被称为 “工程”,还是只是炒作者们宣扬的 “魔法”,也存在很多质疑。我认为,在大多数情况下,质疑的根源在于我看到的很多推文和博客文章都声称是在进行提示工程,它们实际上最多只是盲目提示的一小部分。

在这篇博客文章中,我将阐述提示工程是一门可以基于真实实验方法培养的实用技能。通过一个现实的例子,我将向大家展示如何为一个有实际应用的问题进行提示工程,从而为该应用带来实际价值。

这篇文章主要关注文本输出,因为在使用语言模型时,文本输出是我遇到的主要应用场景。有些技巧,比如测试方法,不能直接应用于其他类型的输出,如图像。但是,本文中的所有内容对于多模态输入来说都非常有效。

            什么是提示(Prompting)?

如果你已经非常熟悉 “提示” 这个词或了解 “提示” 的含义,可以跳过本节。

在语言模型(如果你不熟悉该术语,可以将其理解为 ChatGPT)中,“提示” 是用户提供给模型的输入。在 ChatGPT 中,它可以理解为你输入文本框的文字。然后,语言模型根据你的提示 “推断” 出一个 “补全”。例如,如果你在 ChatGPT 中输入 “4 + 3 = ”,它可能会回应 “7”。在这个例子中,“4 + 3 = ” 是提示,“7” 是补全。

“提示工程” 是利用提示作为一种从模型中提取所需信息的方法。这种方法很有吸引力,因为你不需要大量的离线训练数据集,不需要离线访问模型,而且对于非工程师来说也很直观。提示只是调整模型的一种方式。最后,“提示工程” 是一种更严谨的领域(正如本文所展示的),旨在利用提示作为一种为实际应用构建可靠功能的方法。它与 ChatGPT 式的提示有所不同,因为通过提示工程生成的提示通常用于在高频、多样化的场景中反复使用,以便为应用程序可靠地解决特定问题。

问题

首先,你需要确定一个需要解决的问题。这个问题可以用来评估提示是否是最佳解决方案,还是可能存在其他更适合的解决方案。工程的初衷并非为了某种方法本身,而是基于相信它是正确的方法。

以这个例子为例,假设我们是一家开发日历客户端的公司。我们希望用户能够使用自然语言输入事件。例如:

晚餐:下周二与 Alice 在 Taco Bell 共进晚餐公司会议:11 月 4 日一对一会议:明天上午 10 点与 Bob 的会谈

语言模型或许是个很好的解决方案,它能够处理自然语言输入,并提取结构化输出以描述我们可以在应用程序中使用的事件。

当然,还存在其他潜在解决方案。我们可以利用一组正则表达式和字符串搜索来查找常见短语(如 < 星期几 >、明天、今天、下周等)。

语言模型有它们自己的优势:它们可能更好地处理其他语言,更好地处理拼写错误或语法错误,或者在正则表达式失败时充当一个有效的后备方案。总之,继续研究提示作为潜在解决方案是有前景的。

演示集

接下来,我们必须组装一个演示集。演示集包含预期输入和预期输出。这个集合将服务于多个目标:

  1. 它将用于衡量我们提示的准确性。通过使用单个示例的输入,我们可以断言我们得到了预期的输出。

  2. 它指定了我们期望提示输入和输出的样子,使我们作为工程师能够确定它是否适合我们的问题。

  3. 如果我们选择使用少量示例提示,我们可以将示例集的一部分作为范例。对于那些不熟悉术语 “few-shot” 的人,few-shot 是一种提示方式,除了提示之外还给出了示例。

了解 Few-Shot 与 Zero-Shot 可以参考:

https://www.promptingguide.ai/techniques/fewshot

Q:与 Alice 在 Taco Bell 共进晚餐A:下周二Q:公司会议A:11/4Q:明天上午 10 点和 Bob 一对一沟通A:明天

关于示例集大小的说明:在这篇博客文章中,我们只有三个示例。实际上,你可能至少需要十几个示例。示例越多,你可以进行的测试就越好,但同时也会因为 token 使用变得更加昂贵。在某种程度上,微调语言模型通常更具经济性。

上面的示例中,有两个重要的决策需要作出。对于任何提示问题,你必须作出类似的决策。

首先,我们只提取一条信息。尝试让模型提取我们的整个事件(例如事件名称、与会者、时间、地点等)并将其输出为一些漂亮的即用型 JSON 或其他诱人的格式。该模型可能能够做到这一点。但是在处理新问题时,我建议将其分解为单个问题。这使问题更易于解决,并且最终会给你一个基线精度,你可以用它来衡量多输出方法是否真的值得投入。

第二,我们的输出没有经过转换。我们不是试图将所有内容都转换为日期,也不是试图确保所有的内容都是正确,等等。我们正在进行文本提取。有很多出色的确定性库可以将字符串(如 “下周二”)准确地转换为时间戳。这不是我们需要语言模型为我们做的事情。所以,让我们拿出粗略的日期格式(“下周二”、“11/4”、“明天”),并使用传统的编程方法解决将其转换为时间戳的问题,因为这是一个简单的问题。输出越简单,精度就越高。

最后,关于输出解码的简要说明。LLM 将以多种方式完成你的提示:它可能是一个完整的句子,可能会添加句点,可能是被大写的,等等。你应该确定你希望 LLM 的输出有多完美,以及在验证演示集之前要对多少内容进行规范化。

例如,如果我正在进行文本提取,我通常会发现删除空格和句号并将整个输出全部小写是合理的。如果我正在做一些更高级的事情,比如 JSON 生成,我可能会以某种确定的顺序和样式解析和重新编码 JSON,因此这是比较确定的。

我的建议:使 LLM 的输出尽可能简单灵活,并在你的应用程序中执行一些规范化操作。不要试图强制 LLM 从一开始就输出完美的格式。在 LLM 中进行太多的 “输出形状” 很难将 LLM 执行核心任务(本例中是信息提取)的能力与其结构输出的能力分开。

提示候选

(Prompt Candidates)

现在,我们提出一些提示候选。提示候选是一个提示,我们认为可能会引发语言模型所希望的行为。我们提出多个候选选项,是因为我们不太可能一开始就选择最佳提示。

为了成为初级水平的文本,我们会手动给出提示。为了有效,在构建提示时,提示工程师应该使用一些基本知识。例如,断言比防御更好。清晰简洁往往比重复冗长要好。在构建少数提示时,标签的均衡分配很重要,展示完整的标签集合很重要等。在选择示例时,LLM 可能出错的示例通常表现最好,示例已被证明在从短到长的顺序排列时通常表现最佳等。

很抱歉!我没有引用实验研究来支持这些建议。老实说,我懒得去查阅我读过的关于它们的论文(通常每个点都有多篇)。如果你不相信我,没关系,重要的是,关于提示技巧及其有效性的实验研究确实存在。但是,我保证我没有编造,尽管有些可能已经过时了,需要根据现代模型进行更新。

这是一篇专门阐述这些技术的单独帖子,它不是这篇帖子的目标。这篇帖子的目标是展示高层次的端到端流程,并展示有一种工程方法可以从 LLM 中提取价值。

目前,目标是想出一些不错的 Zero-Shot Prompting。Zero-Shot Prompting 可以转化为 Few-Shot Prompting,进一步转化为思维链。每一个都可以进一步变成批处理提示等。因此,由于 Zero-Shot Prompting 是尝试的基本要求,我们专注于此。

以下是我想出的三个提示候选:

  • 识别给定文本中提到的日期或时间,并将其作为输出提供。

  • 确定给定事件描述中提到的日期或时间。

  • 根据每个输入确定日期或时间,并相应地以单个短语或日期的形式提供输出。

这些提示都是合理的。对于任何受过教育的人来说,每个提示都可能产生非常高的准确性。但是,语言模型并非人类,因此我们不能自动期望获得相同的结果。我之前已经展示过,即使是非常合理的提示,也可能表现得非常糟糕。所以,我们接下来要做的是通过进行一些测试和测量来为我们的决策提供依据。

即时测试

(Prompt Testing)

拥有一组候选提示和演示集后,我们现在可以测试准确性了。到目前为止,我发现最好的方法是使用像 LangChain 这样的库构建一个简单的 Python 脚本。在我的测试中,我通常会运行每个演示,并执行以下提示模板:

Zero-Shot

Few-Shot

……

Prompt 1

64

68

……

Prompt……

44

52

……

Prompt N

23

22

……

此表格以 Y 轴展示了提示候选,使用这些提示的 X 轴是提示类型。数值表示正确答案的百分比准确率。

以日历应用为例,“prompt 1” 作为一个 zero-shot 提示和一个示例可能如下所示:

识别给定文本中提到的日期或时间,并将其作为输出提供。

Q:11 月 4 日的 CorpConf,A:我们期待 “11/4” 作为答案。

few-shot 版本可能如下所示:

识别给定文本中提到的日期或时间,并将其作为输出提供。

Q:下周二在 Taco Bell 与爱丽丝共进晚餐。A:下周二Q:明天上午 10 点与 Bob 进行一对一对话。A:明天Q:11 月 4 日的公司会议。A:

关于有经验的提示的注意事项:few-shot 示例中并没有写类似 “模仿下面的例子” 的话。实验研究表明,这并不能可靠地提高准确性,因此我喜欢在限制令牌的情况下先进行测试。其次,few-shot 示例中的示范并没有展示 “MM/DD” 提取作为一个例子,这种做法并不好。在真实的 few-shot 示例环境中,展示所有提取样式是很重要的。对于某些类型的问题,例如分类问题,你可以使用混淆矩阵(Strobelt 等)来可视化其他标签的概率,并据此判断你的标签集是否可以进一步优化。除了准确性之外,你还需要衡量所用的标记、所用的请求等。在选择最终提示时,必须考虑所有这些因素。

学习选择提示

最后,你根据所使用的模型、所需的 tokens 和展示的准确性,在应用中选择了一个候选提示。这个提示并不一定是最精确的。这是一个基于成本与准确性的权衡分析。

例如,你可能发现 few-shot 示例的变体表现最好,但在测试集上仅提高了 4% 的准确性,同时需要多使用 200% 的 tokens(对于当前基于 API 的模型,实际上成本翻倍)。对于你的业务而言,你可能认为以一半的成本换取准确性降低 4% 是值得的。或者,你可以选择返回并尝试其他方法来提高准确性。例如,你可以尝试在较低成本的模型上使用自我一致性解码策略,看看是否能够提高准确性。有时,在较低成本模型上使用更多的 tokens 会比在高成本模型上使用少量 tokens 节省大量资金。例如,GPT-4 的成本约为 GPT-3.5 的 15 倍。这意味着你实际上有 15 倍的 tokens 预算来提高 GPT-3.5 的提示准确性(注意有关速率限制的注意事项)。在本博客文章的示例中,我们可能会选择在表格中使用 zero-shot 版本的 Prompt 1,因为它具有 64% 的准确性,并且很可能使用的 tokens 更少。也许我们觉得 64% 的准确性足够填充我们日历应用程序的事件模板。对于这个特定问题,我认为我们可以比 64% 做得更好,但这只是我在这篇文章中使用的数字。最重要的是,你拥有做出明智决策所需的数据。

信任,但是需要验证和持续改进

由于生成式 AI 的概率性质,你的提示可能存在一些问题。即使你在测试集上的准确率达到 100%,仍可能有未知输入产生错误输出。因此,你应该在信任的基础上进行核实,并将核实失败的案例添加到示例集中,以开发新的提示并提高准确性。

验证在很大程度上取决于问题本身。以我们的日历应用为例,我们可能需要明确地询问用户:“这个事件是否正确?” 如果他们回答 “不”,那么将自然语言输入记录下来供人工审查。或者,我们可以在自动信息提取之后,更好地自动追踪用户手动修改的任何事件。以另一个例子来说,如果我们的提示是生成代码(例如正则表达式或编程语言文本),我们至少可以尝试对其进行解析。解析永远不应该成为安全隐患,至少可以进行最基本的验证,以确保语法正确。同样,如果这种验证失败了,我们可以记录输入和输出,扩大示例集,并开发更好的提示。验证还有助于防止对抗性提示。对抗性提示本身就是一个独立的主题,我在这篇文章中不会详细讨论。

总结

这篇博客文章展示了如何将提示开发 —— 在我看来 —— 视为一种工程实践。它描述了一种系统性方法来识别问题、形成解决方案、验证这些解决方案,并通过持续改进来完善这些解决方案。

将本文的方法与 “盲目提示” 进行比较,“盲目提示” 依赖于轶事经验和普遍的试错方法来得出某种可能的解决方案,但通常不会建立起适当的系统性基础设施,以便随着时间的推移可靠地迭代提示。

我想指出这篇博客文章非常基础。在这篇文章中有很多地方可以使用已知的更高级技巧加以改进。此外,我没有涉及对抗性提示等重要主题。举一个具体例子,有更科学的方法来为 few-shot 提示选择最佳示例,但我希望尽可能让这篇文章保持基础。

如果你想学习一些更高级的技巧,可以阅读 Lilian Weng 的《提示工程》:

https://lilianweng.github.io/posts/2023-03-15-prompt-engineering/

除此之外,人人都在迅速地转向更高层次的 LLM 集成:如提示链接、代理等。一些人认为,诸如此类以及更多的未来创新将使人类提示过时。无论这是否成真,我始终坚信从 “第一原理(First principle)” 学习的价值,而我认为学习这样的提示技巧只会提高我运用更高阶语言模型技巧的能力。我还认为,即使是基本的提示技巧,也能使更高阶概念的表现更出色。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值