II · 提示工程

提示工程基础

微软《Generative AI for Beginners》 · 第 04 课 · 中文翻译 · 本地镜像

提示工程基础

介绍

本模块涵盖了在生成式 AI 模型中创建有效提示的基本概念和技术。向大型语言模型(LLM)编写提示的方式也很重要。精心设计的提示可以获得更高质量的回应。但“提示”和“提示工程”这些术语具体是什么意思?我如何改进发送给 LLM 的提示输入?这些是我们将在本章和下一章中尝试回答的问题。

生成式 AI 能够响应用户请求生成新内容(例如文本、图像、音频、代码等)。它通过使用像 OpenAI 的 GPT(“生成式预训练变换器”)系列这样的大型语言模型实现,这些模型经过针对自然语言和代码的训练。

用户现在可以使用熟悉的聊天等交互范式与这些模型互动,无需任何技术专长或培训。模型是 基于提示 的——用户发送文本输入(提示),并获得 AI 的回应(补全)。然后他们可以通过多轮对话迭代“与 AI 聊天”,不断优化提示,直到回应符合预期。

“提示”现已成为生成式 AI 应用的主要_编程接口_,告诉模型要做什么并影响返回回应的质量。“提示工程”是一个快速发展的研究领域,专注于设计和优化提示,以实现规模化的一致且高质量回应。

学习目标

在本课中,我们将学习什么是提示工程、它为何重要,以及如何针对特定模型和应用目标设计更有效的提示。我们将了解提示工程的核心概念和最佳实践,并学习一个交互式 Jupyter 笔记本“沙盒”环境,在其中可以将这些概念应用于实际示例。

本课结束后,我们将能够:

  1. 解释什么是提示工程以及其重要性。
  2. 描述提示的组成部分及其用途。
  3. 学习提示工程的最佳实践和技巧。
  4. 使用 OpenAI 端点将学到的技巧应用于实际示例。

关键词

提示工程:设计和优化输入,引导 AI 模型生成期望输出的实践。 分词(Tokenization):将文本转换为模型能理解和处理的小单元(称为“标记”)的过程。 指令调优 LLM(Instruction-Tuned LLMs):经过特定指令微调以提升反应准确性和相关性的大型语言模型。

学习沙盒

提示工程目前更多是一门艺术而非科学。提升直觉的最好方式是_多加练习_,采用试错方法,将应用领域专业知识与推荐技术及模型特定的优化结合起来。

本课配套的 Jupyter 笔记本提供了一个_沙盒_环境,您可以边学边尝试——或在课程末尾的代码挑战中使用。要执行练习,您需要:

  1. Azure OpenAI API 密钥——一个已部署的 LLM 服务端点。
  2. Python 运行环境——用于执行笔记本。
  3. 本地环境变量——请现在完成安装设置步骤以准备

笔记本中附带了_初学者_练习——同时鼓励您添加自己的_Markdown_(描述)和_代码_(提示请求)部分,尝试更多示例或创意,培养提示设计的直觉。

图解指南

想在深入之前先了解本课的整体内容吗?看看这份图解指南,它帮助您了解主要主题和各主题的关键收获。课程路线图引导您从理解核心概念和挑战,到采用相关的提示工程技巧和最佳实践解决问题。请注意,本指南中的“高级技巧”部分涉及课程_下一章_的内容。

提示工程图解指南

我们的初创公司

现在,让我们谈谈_本主题_如何与我们的初创公司使命 —— 将 AI 创新带入教育 —— 相关。我们希望构建基于 AI 的 个性化学习 应用——因此让我们思考不同用户如何在我们的应用中“设计”提示:

这仅仅是冰山一角。请查看 教育提示库 —— 由教育专家策划的开源提示库 —— 以更广泛了解可能性!尝试在沙盒或 OpenAI Playground 中运行这些提示,看看会发生什么!

什么是提示工程?

我们在本课开始时定义了提示工程,即为特定应用目标和模型_设计和优化_文本输入(提示),以实现一致且高质量响应(补全)的过程。我们可以将其视为一个两步过程:

这必然是试错过程,需要用户的直觉和努力以达最佳效果。那么为什么它重要?为回答这个问题,我们首先要理解三大概念:

分词

LLM 将提示视为_标记序列_,不同模型或模型版本可对同一提示采用不同的分词方式。由于 LLM 训练基于标记(而非原始文本),提示的分词方式直接影响生成回应的质量。

想感受分词工作原理,可尝试如下工具,如下所示的 OpenAI Tokenizer。复制粘贴你的提示,观察如何转成标记,注意空白字符和标点符号的处理。注意,此例显示的是较早版本 LLM(GPT-3),对新模型尝试可能产生不同结果。

分词

概念:基础模型

一旦提示被分词,"基础 LLM"(或基础模型)的主要功能就是预测序列中的下一个标记。因为 LLM 训练于海量文本数据,它们对标记间统计关系有很好的把握,能相对自信地进行预测。注意,它们并不“理解”提示或标记中的_意义_,只是识别一个能通过下一个预测“完成”的模式。它们可持续预测序列,直至用户中断或预设条件满足。

想看看基于提示的补全如何工作?将上述提示输入Microsoft Foundry playground(默认设置),系统将把提示视为信息请求——您应看到符合该上下文的补全结果。

但如果用户想获得满足某些标准或任务目标的特定内容呢?这时,指令调优 LLM 应运而生。

基础 LLM 聊天补全

概念:指令调优 LLM

指令调优 LLM 基于基础模型,通过示例或输入/输出对(例如多轮“消息”)进行微调,这些示例带有明确指令,AI 的回应尝试遵循这些指令。

这使用了人类反馈强化学习(RLHF)等技术,可以训练模型_遵循指令_并_从反馈中学习_,从而产生更适合实际应用且更贴合用户目标的回应。

让我们试试 —— 重访上面的提示,但现在修改_系统消息_,提供以下指令作为上下文:

为小学二年级学生总结所提供内容。结果保持为一段话,包含 3-5 个要点。

看到结果现在已调整为反映期望的目标和格式了吗?教育者可以直接在课堂幻灯片中使用此回应。

指令调优 LLM 聊天补全

为什么需要提示工程?

既然知道提示如何被 LLM 处理,让我们谈谈_为什么_需要提示工程。答案在于当前 LLM 具有许多挑战,若不花力气构建和优化提示,就很难实现_可靠且一致的补全_。例如:

  1. 模型回应具有随机性。相同的提示_在不同模型或不同版本的模型中很可能产出不同的回应。甚至同一个模型在不同时间也可能产生不同结果。_提示工程技巧能帮助最小化这些差异,提供更好的规则

  2. 模型可能捏造回应。模型通过_大但有限_的训练数据预训练,意味着它们不具备训练范围外的知识。因此,可能生成不准确的、虚构的,或与已知事实直接矛盾的补全。提示工程技巧帮助用户识别并缓解此类捏造,例如通过要求 AI 提供引用或推理

  3. 模型能力各异。新模型或新一代模型能力更丰富,但也带来成本和复杂性的独特权衡。提示工程有助于制定最佳实践和工作流程,抽象化差异并以规模化、无缝的方式适应模型特定需求

让我们在 OpenAI 或 Azure OpenAI Playground 中实际看一下:

虚构示例

在本课程中,我们使用“虚构”一词指代 LLM 有时因训练限制或其他约束而生成事实不正确信息的现象。您可能在热门文章或研究中听说过“幻觉”这一说法。但是我们强烈建议使用“虚构”一词,以避免将机器产生的结果误赋予人类特质。这也从用词角度加强了负责任 AI 指南,去除在某些情况下可能被视为冒犯或不包容的词汇。

想了解虚构是如何运作的吗?设想一个指示 AI 就不存在的话题生成内容的提示(以确保其不包含在训练数据集中)。例如——我尝试了这个提示:

提示: 生成关于 2076 年火星战争的课程计划。

网络搜索显示有关于火星战争的虚构作品(如电视剧或书籍)——但并非发生在 2076 年。常识告诉我们 2076 年是_未来_,因此不可能与真实事件关联。

那当我们用不同的LLM供应商运行这个提示时会发生什么?

回复 1:OpenAI Playground (GPT-35)

回复 1

回复 2:Azure OpenAI Playground (GPT-35)

回复 2

回复 3:Hugging Face Chat Playground (LLama-2)

回复 3

正如预期的那样,每个模型(或模型版本)由于随机行为和模型能力的不同,产生了略有不同的回复。例如,一个模型面向八年级受众,另一个则假设是高中生。但这三个模型都生成了能够让不了解情况的用户相信事件真实发生的回复。

提示工程技术如_元提示_和_温度配置_可以在一定程度上减少模型的虚构内容。新的提示工程_架构_也将新工具和新技术无缝地融入提示流程,以减轻或减少这类影响。

案例研究:GitHub Copilot

让我们通过查看一个案例研究来总结这一部分,了解提示工程如何在实际解决方案中应用:GitHub Copilot

GitHub Copilot 是你的“AI编程助手”——它将文本提示转化为代码补全,并集成在你的开发环境(例如 Visual Studio Code)中,带来无缝的用户体验。正如下面一系列博客所记录,最早版本基于 OpenAI Codex 模型,工程师们很快意识到需要微调模型并开发更好的提示工程技术来提升代码质量。今年七月,他们推出了超越 Codex 的改进 AI 模型,实现更快速的建议。

按顺序阅读这些帖子,追踪他们的学习历程。

你也可以浏览他们的工程博客,阅读更多像这篇这样的帖子,展示了这些模型和技术如何_应用_于推动现实世界的应用开发。


提示构造

我们已经了解为什么提示工程很重要——现在让我们理解提示是如何_构造_的,从而评估不同的技术以实现更有效的提示设计。

基础提示

先来看基础提示:发送给模型的纯文本输入,没有其他上下文。举个例子——当我们将美国国歌的开头几句话发送给 OpenAI 的Completion API时,它会立即根据下一几行进行_补全_,展示了基本的预测行为。

提示(输入) 补全(输出)
Oh say can you see 看起来你在开始唱“星条旗永不落”(美国国歌)的歌词。完整歌词是……

复杂提示

现在我们给基础提示增添上下文和指令。Chat Completion API让我们把复杂提示构造成一组_消息_,包括:

请求现在采用如下形式,_分词_有效地从上下文和对话中捕捉相关信息。现在,改变系统上下文对回复质量的影响可能和提供的用户输入一样大。

response = client.responses.create(
    model="gpt-4o-mini",
    input=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "Who won the world series in 2020?"},
        {"role": "assistant", "content": "The Los Angeles Dodgers won the World Series in 2020."},
        {"role": "user", "content": "Where was it played?"}
    ]
)

指令提示

在上例中,用户提示是简单的文本查询,可以理解为信息请求。用_指令_提示,我们可以用文本更详细地指定任务,给AI提供更好的指导。示例如下:

提示(输入) 补全(输出) 指令类型
写一段关于内战的描述 返回了一段简单的段落 简单
写一段关于内战的描述。提供关键日期和事件并描述其意义 返回一段文字,后跟关键事件日期及描述的列表 复杂
用一段文字写内战的描述。提供3个关键日期和其意义的要点。再提供3个与历史人物及其贡献相关的要点。返回格式为JSON文件。 返回更详细的文本,格式为JSON,你可以复制粘贴到文件并根据需要验证 复杂。格式化

主内容

在上例中,提示仍较开放,让LLM决定其预训练数据中哪部分是相关的。使用_主内容_设计模式时,输入文本分为两部分:

例如,指令是“用两句话总结以下内容”。

提示(输入) 补全(输出)
木星是距离太阳第五颗行星,也是太阳系中最大的一颗。它是一颗气态巨行星,质量是太阳的千分之一,但却是太阳系所有其他行星质量总和的两倍半。木星是夜空中用肉眼可见的最明亮天体之一,自人类有史以来的古文明就已经知道它的存在。它以罗马神朱庇特命名。[19] 从地球看,木星的亮度足以让其反射光产生可见的阴影,[20] 并且平均而言是夜空中第三亮的自然天体,仅次于月亮和金星。
用两句话总结这段内容
木星是距离太阳第五颗行星,也是太阳系中最大的行星,因其是夜空中最亮的天体之一而闻名。 它以罗马神朱庇特命名,是一个气态巨行星,质量是太阳系其他所有行星质量总和的两倍半。

主内容部分可以用多种方式来推动更有效的指令设计:

让我们来实际探索这些方法。

使用示例

这种方法通过主内容“喂给模型”一些期望输出的示例,让它推断出期望输出的模式。根据提供示例数量不同,可以分为零样本提示、一次样本提示、多样本提示等。

提示现在包含三个部分:

学习类型 提示(输入) 补全(输出)
零样本 "The Sun is Shining". 翻译成西班牙语 "El Sol está brillando".
一样本 "The Sun is Shining" => ""El Sol está brillando".
"It's a Cold and Windy Day" =>
"Es un día frío y ventoso".
多样本 The player ran the bases => Baseball
The player hit an ace => Tennis
The player hit a six => Cricket
The player made a slam-dunk =>
Basketball

注意,零样本提示中需要显式指令(“翻译成西班牙语”),但一样本示例中这条指令被隐含推断出来。多样本示例展示了添加更多示例能让模型更准确地推断,无需额外说明。

提示线索

另一种使用主内容的技巧是提供_线索_而非示例。在这种方法中,我们通过_起始片段_给模型一个方向,让它了解想要的回应格式,模型从线索中“接力”,沿着该方向继续生成内容。

线索数量 提示(输入) 补全(输出)
0 木星是距离太阳第五颗行星,也是太阳系中最大的一颗。它是一颗气态巨行星,质量是太阳的千分之一,但却是太阳系所有其他行星质量总和的两倍半。木星是夜空中用肉眼可见的最明亮天体之一,自人类有史以来的古文明就已经知道它的存在。
总结这段内容
木星是太阳系中最大的行星,排名第五,是一颗气态巨行星,质量为太阳的千分之一,但比其它所有行星质量总和还重。古代文明早已知晓木星,它在夜空中非常明亮。
1 木星是距离太阳第五颗行星,也是太阳系中最大的一颗。它是一颗气态巨行星,质量是太阳的千分之一,但却是太阳系所有其他行星质量总和的两倍半。木星是夜空中用肉眼可见的最明亮天体之一,自人类有史以来的古文明就已经知道它的存在。
总结这段内容
我们了解到木星
是距离太阳第五颗行星,也是太阳系中最大的一颗。它是一颗气态巨行星,质量是太阳的千分之一,但却是所有其他行星质量总和的两倍半。它用肉眼即可见,并自古代以来就为人所知。
2 木星是距离太阳的第五颗行星,也是太阳系中最大的行星。它是一颗气态巨星,质量约为太阳的千分之一,但比太阳系中所有其他行星质量总和的两倍半还要大。木星是夜空中肉眼可见的最亮天体之一,自有记载的历史之前就已为古代文明所熟知。
总结如下
我们学到的前三个事实:
1. 木星是距离太阳的第五颗行星,也是太阳系中最大的行星。
2. 它是一颗气态巨星,质量约为太阳的千分之一……
3. 自古以来,木星就肉眼可见……

提示模板

提示模板是一个_预定义的提示配方_,可以存储并根据需要重复使用,以实现规模化的更一致用户体验。它最简单的形式,就是像OpenAI的这个示例那样的提示示例集合,既提供交互式的提示组件(用户和系统消息),也提供通过API驱动的请求格式——支持重复使用。

更复杂的形式,如LangChain的这个示例,包含_占位符_,可以用来自各种来源(用户输入、系统上下文、外部数据源等)的数据替换,以动态生成提示。这允许我们创建一个可重复使用的提示库,能程序化地在大规模中驱动一致的用户体验。

最终,模板的真正价值在于能够为垂直应用领域创建并发布_提示库_,在此基础上提示模板被_优化_以反映应用特定的背景或示例,使响应对目标用户群更加相关和准确。Prompts For Edu仓库就是这种方法的好例子,它为教育领域策划了一个提示库,重点关注课程规划、课程设计、学生辅导等关键目标。

支持内容

如果我们将提示结构看作是包含指令(任务)和目标(主要内容),那么_次要内容_就像是我们提供的额外背景,用于以某种方式影响输出。它可以是调优参数、格式说明、主题分类等,帮助模型_定制_其响应,以满足期望的用户目标或预期。

例如:假定我们有一个具有丰富元数据(名称、描述、级别、元数据标签、讲师等)的课程目录,涵盖课程表中所有可用课程:

现在,模型可以按照这些示例提供的格式给出总结——但如果结果涉及多个标签,它可以优先考虑次要内容中识别的5个标签。


提示工程最佳实践

既然我们知道提示是如何_构造_的,就可以开始思考如何_设计_提示,以体现最佳实践。我们可以从两个方面思考——拥有正确的_心态_和应用正确的_技术_。

提示工程心态

提示工程是一个反复试验的过程,记住这三条广泛的指导原则:

  1. 领域理解很重要。 响应的准确性和相关性取决于应用或用户所处的_领域_。运用你的直觉和领域专业知识进一步定制技术。例如,在系统提示中定义_领域特定的个性_,或在用户提示中使用_领域特定的模板_。提供反映领域特定场景的次要内容,或用_领域特定的提示和示例_引导模型走向熟悉的使用模式。

  2. 模型理解很重要。 我们知道模型本质上具有随机性。但模型实现也可能因其训练数据集(预训练知识)、提供的能力(如通过API或SDK)以及优化的内容类型(如代码、图像、文本)而异。理解你使用的模型的优缺点,并利用这些知识_优先安排任务_或构建_为模型能力优化的定制模板_。

  3. 迭代与验证很重要。 模型和提示工程技术都在快速发展。作为领域专家,你可能有其他适用于你具体应用的上下文或标准,而这些可能不适用于更广泛的社区。使用提示工程工具和技术“快速启动”提示构建,然后用你自己的直觉和领域专业知识反复迭代和验证结果。记录你的见解,创建一个知识库(如提示库),可以被他人作为新的基线用以未来更快的迭代。

最佳实践

现在让我们看看OpenAIAzure OpenAI的实践者推荐的常见最佳实践。

内容 原因
评估最新模型 新一代模型通常具备改进的功能和质量,但可能成本更高。评估它们的影响后再做迁移决定。
分离指令与上下文 检查你的模型或提供者是否定义了_分隔符_以更清楚地区分指令、主要内容和次要内容。这有助于模型更准确地为标记赋权重。
具体且清晰 提供关于期望的上下文、结果、长度、格式、风格等的更多细节。这将提升响应的质量和一致性。在可复用模板中记录这些配方。
详尽说明,使用示例 模型可能对“示范加讲解”的方式反应更好。先尝试零样本方式(给出指令但无示例),然后再用少样本方式精炼,提供几个期望输出的示例。使用类比。
使用提示启动完成 通过提供一些引导词或短语,推动模型朝预期结果开展响应。
多次强调 有时你可能需要重复指令给模型。在主要内容前后给指令,使用指令和提示等。不断迭代和验证看何种方法有效。
顺序很重要 你呈现给模型信息的顺序可能影响输出,即使是学习示例,也因近因偏差而影响结果。尝试不同选项找出最佳方案。
给模型“退路” 给模型一个_备选_的完成响应,如果它因任何原因无法完成任务,可以使用。这能减少模型生成错误或虚假响应的可能性。

正如任何最佳实践一样,记住_实际效果可能因模型、任务和领域而异_。将这些作为起点,反复迭代找到最适合你的方法。随着新模型和工具的不断出现,持续重新评估你的提示工程流程,重点关注流程可扩展性和响应质量。

任务

恭喜你!你已经完成了本课的学习!现在是时候用真实示例来测试其中一些概念和技术了!

在我们的任务中,将使用一个Jupyter Notebook,其中包含可以交互完成的练习。你还可以用你自己的Markdown和代码单元来扩展该Notebook,自主探索想法和技术。

开始前,请先fork该仓库,然后

接下来,配置你的环境变量

然后,打开Jupyter Notebook

你已准备好运行练习。注意这里没有“正确与错误”答案 —— 只是通过反复试验探讨不同选项,建立对给定模型和应用领域有效方法的直觉。

因此本课没有代码解决方案部分。Notebook中将有题为“我的解决方案:”的Markdown单元,展示一个示例输出以供参考。

知识检测

下列哪个是符合合理最佳实践的良好提示?

  1. 给我一张红色汽车的图片
  2. 给我一张红色沃尔沃XC90汽车停在悬崖边夕阳下的图片
  3. 给我一张红色沃尔沃XC90汽车的图片

答案:2,因为它是最佳提示,具体说明了“什么”且细节丰富(不仅仅是汽车,还明确了品牌和型号)并描述了整体场景。3紧随其后也包含了很多描述内容。

🚀 挑战

试试看利用“提示”技术,完成句子“给我一张红色沃尔沃汽车的图片,型号为”。看它如何回应,你会如何改进?

干得好!继续学习

想了解更多不同的提示工程概念?访问继续学习页面,寻找该主题的其他优质资源。

前往第5课,我们将探讨高级提示技术


免责声明: 本文件由 AI 翻译服务 Co-op Translator 翻译完成。尽管我们力求准确,但请注意,自动翻译可能包含错误或不准确之处。原始语言版文件应视为权威来源。对于重要信息,建议使用专业人工翻译。我们对因使用本翻译而产生的任何误解或误释不承担责任。