提示工程是一门相对较新的学科,旨在开发和优化提示词(Prompt),以便高效地应用和构建大语言模型(LLMs),以满足各种应用和使用场景的需求。
提示工程技能有助于更好地了解大语言模型(LLMs)的能力和局限性。研究人员通过提示工程来提升大语言模型(LLMs)在广泛的常见和复杂任务(如问答和算术推理)上的安全性和能力。开发人员可通过提示工程设计健壮且有效的提示技术,来与大语言模型(LLMs)和其他工具进行交互(interface)。
这份全面的指南涵盖了提示工程的理论和实践方面,以及如何利用最佳的提示技术,和大型语言模型进行之间进行交互与使用其构建(build)。
除非另有说明,本指南默认所有示例都是在 OpenAI 的 Playground 上使用 gpt-3.5-turbo
进行测试。模型使用默认配置,即 temperature=1 和 top_p=1 。这些提示也应适用于具有类似功能的其他模型,如gpt-3.5-turbo,但模型响应可能会有所不同。
使用提示词时,你通常会通过 API 或直接与大语言模型进行交互。你可以通过配置一些参数以获得不同的提示结果。调整这些设置对于提高响应的可靠性非常重要,你可能需要进行一些实验才能找出适合你的用例的正确设置。以下是使用不同LLM提供程序时会遇到的常见设置:
Temperature:简单来说,temperature
的参数值越小,模型就会返回越确定的一个结果。如果调高该参数值,大语言模型可能会返回更随机的结果,也就是说这可能会带来更多样化或更具创造性的产出。(调小temperature
)实质上,你是在增加其他可能的 token 的权重。在实际应用方面,对于质量保障(QA)等任务,我们可以设置更低的 temperature
值,以促使模型基于事实返回更真实和简洁的结果。 对于诗歌生成或其他创造性任务,适度地调高 temperature
参数值可能会更好。
Top_p:同样,使用 top_p
(与 temperature
一起称为核采样(nucleus sampling)的技术),可以用来控制模型返回结果的确定性。如果你需要准确和事实的答案,就把参数值调低。如果你在寻找更多样化的响应,可以将其值调高点。
使用Top P意味着只有词元集合(tokens)中包含top_p
概率质量的才会被考虑用于响应,因此较低的top_p
值会选择最有信心的响应。这意味着较高的top_p
值将使模型考虑更多可能的词语,包括不太可能的词语,从而导致更多样化的输出。
一般建议是改变 Temperature 和 Top P 其中一个参数就行,不用两个都调整。
Max Length:你可以通过调整 max length
来控制大模型生成的 token 数。指定 Max Length 有助于防止大模型生成冗长或不相关的响应并控制成本
Stop Sequences:stop sequence
是一个字符串,可以阻止模型生成 token,指定 stop sequences
是控制大模型响应长度和结构的另一种方法。例如,你可以通过添加 “11” 作为 stop sequence
来告诉模型生成不超过 10 个项的列表。
Frequency Penalty:frequency penalty
是对下一个生成的 token 进行惩罚,这个惩罚和 token 在响应和提示中已出现的次数成比例, frequency penalty
越高,某个词再次出现的可能性就越小,这个设置通过给重复数量多的 Token 设置更高的惩罚来减少响应中单词的重复。
Presence Penalty:presence penalty
也是对重复的 token 施加惩罚,但与 frequency penalty
不同的是,惩罚对于所有重复 token 都是相同的。出现两次的 token 和出现 10 次的 token 会受到相同的惩罚。 此设置可防止模型在响应中过于频繁地生成重复的词。 如果你希望模型生成多样化或创造性的文本,你可以设置更高的 presence penalty
,如果你希望模型生成更专注的内容,你可以设置更低的 presence penalty
。
与 temperature
和 top_p
一样,一般建议是改变 frequency penalty
和 presence penalty
其中一个参数就行,不要同时调整两个。
在我们开始一些基础示例之前,请记住最终生成的结果可能会和使用的大语言模型的版本而异。
你可以通过简单的提示词(Prompts)获得大量结果,但结果的质量与你提供的信息数量和完善度有关。一个提示词可以包含你传递到模型的指令或问题等信息,也可以包含其他详细信息,如上下文、输入或示例等。你可以通过这些元素来更好地指导模型,并因此获得更好的结果。
看下面一个简单的示例:
提示词:
The sky is
输出:
blue.
如果你正在使用OpenAI Playground或其他任何LLM Playground,你可以按照以下屏幕截图中的方式提示模型:
需要注意的是,当使用 OpenAI 的 gpt-4
或者 gpt-3.5-turbo
等聊天模型时,你可以使用三个不同的角色来构建 prompt: system
、user
和 assistant
。其中 system
不是必需的,但有助于设定 assistant
的整体行为,帮助模型了解用户的需求,并根据这些需求提供相应的响应。上面的示例仅包含一条 user
消息,你可以使用 user
消息直接作为 prompt。为简单起见,本指南所有示例(除非明确提及)将仅使用 user
消息来作为 gpt-3.5-turbo
模型的 prompt。上面示例中 assistant
的消息是模型的响应。你还可以定义 assistant
消息来传递模型所需行为的示例。你可以在此处了解有关使用聊天模型的更多信息。
从上面的提示示例中可以看出,语言模型能够基于我们给出的上下文内容 "The sky is"
完成续写。输出可能是出乎意料的,或者与你想要完成的任务相去甚远。实际上,这个基本示例突出了提供更多上下文或明确指示你想要实现什么的必要性。这正是提示工程的核心所在。
让我们试着改进一下:
提示词:
Complete the sentence:
The sky is
输出:
blue during the day and dark at night.
结果是不是要好一些了?本例中,我们告知模型去完善句子,因此输出结果看起来要好得多,因为它完全按照你告诉它要做的(“完善句子”)去做。在本指南中,这种设计有效的提示词以指导模型执行期望任务的方法被称为提示工程。
以上示例基本说明了现阶段的大语言模型能够发挥的功能作用。它们可以用于执行各种高级任务,如文本概括、数学推理、代码生成等。
前文中我们还是采取的比较简单的提示词。 标准提示词应该遵循以下格式:
<问题>?
或
<指令>
你可以将其格式化为问答(QA)格式,这在许多问答数据集中是标准格式,如下所示:
Q: <问题>?
A:
当像上面那样提示时,这也被称为零样本提示,即你直接提示模型给出一个回答,而没有提供任何关于你希望它完成的任务的示例或示范。一些大型语言模型具备进行零样本提示的能力,但这取决于手头任务的复杂性和知识,以及模型被训练以在其上表现良好的任务。
具体的零样本提示示例如下:
提示:
Q: What is prompt engineering?
对于一些较新的模型,你可以省略“Q:”部分,因为模型会根据序列(译注:输入的提示词)的构成将其理解为问答任务。换句话说,提示可以简化如下:
提示词
What is prompt engineering?
基于以上标准格式(format),一种流行且有效的提示技术被称为少样本提示,其中你提供示例(即示范)。你可以按照以下格式组织少样本提示:
<问题>?
<答案>
<问题>?
<答案>
<问题>?
<答案>
<问题>?
问答格式的版本看起来像这样:
Q: <问题>?
A: <答案>
Q: <问题>?
A: <答案>
Q: <问题>?
A: <答案>
Q: <问题>?
A:
请记住,使用问答格式并非必须。提示格式取决于手头的任务。例如,你可以执行一个简单的分类任务,并给出如下所示的示例来给任务示范:
提示词:
This is awesome! // Positive
This is bad! // Negative
Wow that movie was rad! // Positive
What a horrible show! //
输出:
Negative
语言模型可以基于一些说明了解和学习某些任务,而小样本提示正好可以赋能上下文学习能力。我们将在接下来的章节中更广泛的讨论如何使用零样本提示和小样本提示。
随着我们接触越来越多的提示工程的示例和应用,你会注意到提示词是由一些要素组成的。
一个提示词包含以下任何元素:
指令(Instruction):想要模型执行的特定任务或指令。
上下文(Context):包含外部信息或额外的上下文信息,引导语言模型更好地响应。
输入数据(Input Data):用户输入的内容或问题。
输出指示(Output Indicator):指定输出的类型或格式。
为了更好地演示提示词要素,下面是一个简单的提示,旨在完成文本分类任务:
提示:
请将文本分为中性、否定或肯定
文本:我觉得食物还可以。
情绪:
在上面的提示示例中,指令是“将文本分类为中性、否定或肯定”。输入数据是“我认为食物还可以”部分,使用的输出指示是“情绪:”。请注意,这个基本示例没有使用上下文,但上下文也可以作为提示的一部分提供。例如,此文本分类提示的上下文可以是作为提示的一部分提供的其他示例,以帮助模型更好地理解任务并引导预期的输出类型。
注意,提示词所需的格式取决于你想要语言模型完成的任务类型,并非所有以上要素都是必须的。我们会在后续的指南中提供更多更具体的示例。
以下是设计提示时需要记住的一些技巧:
在开始设计提示时,你应该记住,这实际上是一个迭代过程,需要大量的实验才能获得最佳结果。使用来自OpenAI或Cohere的简单的 playground 是一个很好的起点。
你可以从简单的提示词开始,并逐渐添加更多元素和上下文(因为你想要更好的结果)。因此,在这个过程中不断迭代你的提示词是至关重要的。阅读本指南时,你会看到许多示例,其中具体性、简洁性和简明性通常会带来更好的结果。
当你有一个涉及许多不同子任务的大任务时,可以尝试将任务分解为更简单的子任务,并随着结果的改善逐步构建。这避免了在提示设计过程中一开始就添加过多的复杂性。
你可以使用命令来指示模型执行各种简单任务,例如“写入”、“分类”、“总结”、“翻译”、“排序”等,从而为各种简单任务设计有效的提示。
请记住,你还需要进行大量实验以找出最有效的方法。以不同的关键词(keywords),上下文(contexts)和数据(data)试验不同的指令(instruction),看看什么样是最适合你特定用例和任务的。通常,上下文越具体和跟任务越相关则效果越好。在接下来的指南中,我们将讨论样例和添加更多上下文的重要性。
有些人建议将指令放在提示的开头。另有人则建议是使用像“###”这样的清晰分隔符来分隔指令和上下文。
例如:
提示:
### 指令 ###
将以下文本翻译成西班牙语:
文本:“hello!”
输出:
¡Hola!
要非常具体地说明你希望模型执行的指令和任务。提示越具描述性和详细,结果越好。特别是当你对生成的结果或风格有要求时,这一点尤为重要。不存在什么特定的词元(tokens)或关键词(tokens)能确定带来更好的结果。更重要的是要有一个具有良好格式和描述性的提示词。事实上,在提示中提供示例对于获得特定格式的期望输出非常有效。
在设计提示时,还应注意提示的长度,因为提示的长度是有限制的。想一想你需要多么的具体和详细。包含太多不必要的细节不一定是好的方法。这些细节应该是相关的,并有助于完成手头的任务。这是你需要进行大量实验的事情。我们鼓励大量实验和迭代,以优化适用于你应用的提示。
例如,让我们尝试从一段文本中提取特定信息的简单提示。
提示:
提取以下文本中的地名。
所需格式:
地点:<逗号分隔的公司名称列表>
输入:“虽然这些发展对研究人员来说是令人鼓舞的,但仍有许多谜团。里斯本未知的香帕利莫德中心的神经免疫学家 Henrique Veiga-Fernandes 说:“我们经常在大脑和我们在周围看到的效果之间有一个黑匣子。”“如果我们想在治疗背景下使用它,我们实际上需要了解机制。””
输出:
地点:里斯本,香帕利莫德中心
输入文本来自这篇 Nature 文章。
给定上述关于详细描述和改进格式的建议,很容易陷入陷阱:想要在提示上过于聪明,从而可能创造出不明确的描述。通常来说,具体和直接会更好。这里的类比非常类似于有效沟通——越直接,信息传达得越有效。
例如,你可能有兴趣了解提示工程的概念。你可以尝试这样做:
解释提示工程的概念。保持解释简短,只有几句话,不要过于描述。
从上面的提示中不清楚要使用多少句子以及什么风格。尽管你可能仍会从上述提示中得到较好的响应,但更好的提示应当是非常具体、简洁并且切中要点的。例如:
使用 2-3 句话向高中学生解释提示工程的概念。
设计提示时的另一个常见技巧是避免说不要做什么,而应该说要做什么。这样(说要做什么)更加的具体,并且聚焦于(有利于模型生成良好回复的)细节上。
以下是一个电影推荐聊天机器人的示例,因为我写的指令——关注于不要做什么,而失败了。
提示:
以下是向客户推荐电影的代理程序。不要询问兴趣。不要询问个人信息。
客户:请根据我的兴趣推荐电影。
代理:
输出:
当然,我可以根据你的兴趣推荐电影。你想看什么类型的电影?你喜欢动作片、喜剧片、爱情片还是其他类型的电影?
以下是更好的提示:
提示:
以下是向客户推荐电影的代理程序。代理负责从全球热门电影中推荐电影。它应该避免询问用户的偏好并避免询问个人信息。如果代理没有电影推荐,它应该回答“抱歉,今天找不到电影推荐。”。
```顾客:请根据我的兴趣推荐一部电影。
客服:
输出:
抱歉,我没有关于你兴趣的任何信息。不过,这是目前全球热门的电影列表:[电影列表]。希望你能找到喜欢的电影!
上述示例中的一些内容摘自 "Best practices for prompt engineering with OpenAI API" article.
上一节介绍了如何提示大语言模型的基本示例。
在本节中,我们会提供更多示例,介绍如何使用提示词来完成不同的任务,并介绍其中涉及的重要概念。通常,学习概念的最佳方式是通过例子。下面几个例子展示了如何使用精心制作的提示词来执行不同类型的任务。
自然语言生成中的一个标准任务是文本摘要。文本摘要可以涵盖许多不同的风格和领域。事实上,语言模型最有前景的应用之一就是将文章和概念概括成简洁易读的摘要。让我们尝试使用提示进行一个基本的摘要任务。
提示词:
Explain antibiotics
A:
输出:
Antibiotics are a type of medication used to treat bacterial infections. They work by either killing the bacteria or preventing them from reproducing, allowing the body’s immune system to fight off the infection. Antibiotics are usually taken orally in the form of pills, capsules, or liquid solutions, or sometimes administered intravenously. They are not effective against viral infections, and using them inappropriately can lead to antibiotic resistance.
"A:" 是一种在问答中使用的显式提示格式,你在这里使用它是为了告诉模型接下来你期望有一个答案。在这个例子中,我们可能还不清楚使用它是否有用,我们会在之后的示例中探讨这一点。现在假设我们感觉模型给了太多的信息,想要进一步提炼它。 我们可以指导模型帮我们用一句话总结相关内容:
提示词:
Antibiotics are a type of medication used to treat bacterial infections. They work by either killing the bacteria or preventing them from reproducing, allowing the body’s immune system to fight off the infection. Antibiotics are usually taken orally in the form of pills, capsules, or liquid solutions, or sometimes administered intravenously. They are not effective against viral infections, and using them inappropriately can lead to antibiotic resistance.
Explain the above in one sentence:
译注:
Explain the above in one sentence
可翻译为用一句话解释上面的信息:
输出:
Antibiotics are medications used to treat bacterial infections by either killing the bacteria or stopping them from reproducing, but they are not effective against viruses and overuse can lead to antibiotic resistance.
在不过多关注上面输出的准确性的情况下(这是我们将在后续指南中讨论的内容),模型尝试将段落总结成一句话。你可以对指令进行巧妙的设计,但我们将留到后面的章节再讨论。你可以暂时停住并进行实验,看看是否能获得更好的结果。
虽然语言模型是被训练用于执行自然语言生成及相关任务,但它同样非常擅长执行分类和一系列其他自然语言处理(NLP)任务。
这是一个从给定段落中提取信息的提示词示例。
提示词:
Author-contribution statements and acknowledgements in research papers should state clearly and specifically whether, and to what extent, the authors used AI technologies such as ChatGPT in the preparation of their manuscript and analysis. They should also indicate which LLMs were used. This will alert editors and reviewers to scrutinize manuscripts more carefully for potential biases, inaccuracies and improper source crediting. Likewise, scientific journals should be transparent about their use of LLMs, for example when selecting submitted manuscripts.
Mention the large language model based product mentioned in the paragraph above:
输出:
The large language model based product mentioned in the paragraph above is ChatGPT.
你可以通过许多方法来改进上述结果,但这已经非常有用了。
现在应该很明显,你可以通过简单地指示模型做什么来让它执行不同的任务。这是一个强大的能力,AI产品开发人员已经在利用它来构建强大的产品和体验。
段落来源: ChatGPT: five priorities for research
让模型给出具体回答的最佳方法之一是改善提示的格式。如前所述,一个提示可以结合指令、上下文、输入和输出指示(output indicators)来获得更好的结果。虽然这些组成部分不是必需的,但随着你给出的指令越具体,你将获得越好的结果,这成为了一种良好的实践。下面是一个例子,展示了按照更结构化的提示词来会是什么样子的。
提示词:
Answer the question based on the context below. Keep the answer short and concise. Respond "Unsure about answer" if not sure about the answer.
Context: Teplizumab traces its roots to a New Jersey drug company called Ortho Pharmaceutical. There, scientists generated an early version of the antibody, dubbed OKT3. Originally sourced from mice, the molecule was able to bind to the surface of T cells and limit their cell-killing potential. In 1986, it was approved to help prevent organ rejection after kidney transplants, making it the first therapeutic antibody allowed for human use.
Question: What was OKT3 originally sourced from?
Answer:
输出:
Mice.
上下文获取自 Nature。
到目前为止,你已经使用了简单的指令来执行任务。作为提示词工程师,你需要更擅长提供更好的指令。但这还不是全部!你还会发现,在更困难的用例中,仅仅提供指令是不够的。这就是你需要更多考虑上下文和其他元素(在提示词中使用)的地方。你可以提供的其他元素包括输入数据
或示例
。
让我们通过一个文本分类的示例来演示这一点。
提示词:
Classify the text into neutral, negative or positive.
Text: I think the food was okay.
Sentiment:
输出:
Neutral
你给出了对文本进行分类的指令,模型以'Neutral'
回应,这是正确的。这没有问题,但假设你真正需要的是让模型以你希望的确切格式给出标签。因此,你希望它返回的是neutral
而不是Neutral
。你如何实现这一点呢?有几种不同的方法可以做到这一点。在这里,你关心的是具体性,所以你给提示词提供的信息越多,结果就越好。你可以尝试提供示例来指定正确的行为。让我们再试一次:
提示词:
Classify the text into neutral, negative or positive.
Text: I think the vacation is okay.
Sentiment: neutral
Text: I think the food was okay.
Sentiment:
输出:
neutral
完美!这次模型返回了neutral
,这是你所寻找的具体标签。看起来,提示中提供的示例帮助模型在其输出中保持了具体性。
为了强调有时具体性为什么很重要,请查看下面的例子并找出问题所在:
提示词:
Classify the text into nutral, negative or positive.
Text: I think the vacation is okay.
Sentiment:
输出:
Neutral
这里的问题是什么?作为提示,模型完全忽略了虚构的nutral
标签。相反,模型输出了Neutral
,因为它对这个标签有一定的偏好。但假设你真正想要的是nutral
。你怎么解决这个问题?也许你可以尝试为标签添加描述或在提示中增加更多示例?如果你不确定,我们将在接下来的部分讨论一些想法。
你可以通过提示工程进行更有趣的实验,比如指导大语言模型系统如何表现,指定它的行为意图和身份。 当你在构建对话系统,如客户服务聊天机器人时,这尤其有用。
比如,可以通过以下示例创建一个对话系统,该系统能够基于问题给出技术性和科学的回答。 你可以关注我们是如何通过指令明确地告诉模型应该如何表现。 这种应用场景有时也被称为角色提示(Role Prompting)。
提示词:
The following is a conversation with an AI research assistant. The assistant tone is technical and scientific.
Human: Hello, who are you?
AI: Greeting! I am an AI research assistant. How can I help you today?
Human: Can you tell me about the creation of blackholes?
AI:
输出:
Sure! Black holes are regions of spacetime where the gravitational force is so strong that nothing, not even light, can escape from it. They are created when a very massive star dies and its core collapses in on itself, forming a singularity of infinite density. The intense gravity of the singularity pulls in all the matter and radiation around it, creating the black hole.
我们的AI研究助手听起来有点太技术性了,对吗?好的,让我们改变这种行为,并指示系统给出更易于理解的回答。
提示词:
The following is a conversation with an AI research assistant. The assistant answers should be easy to understand even by primary school students.
Human: Hello, who are you?
AI: Greeting! I am an AI research assistant. How can I help you today?
Human: Can you tell me about the creation of black holes?
AI:
输出:
Sure! Black holes are created when a very massive star runs out of fuel and collapses in on itself. The gravity of the star is so strong that nothing, not even light, can escape its pull. This creates a point in space-time with an intense gravitational force called a black hole.
我想我们应该取得了一些进展, 你也可以继续改进它。 如果你再添加更多的示例,可能会得到更好的结果。
大语言模型(LLMs)在代码生成方面非常有效。 在此方面,Copilot 就是一个很好的示例。通过巧妙的提示,你可以执行大量的代码生成任务。下面我们来看几个示例。
我们先用它写个简单的用户欢迎程序:
提示词:
/*
Ask the user for their name and say "Hello"
*/
输出:
let name = prompt("What is your name?");
console.log(`Hello, ${name}!`);
你看,我们甚至都不需要指定要使用的编程语言。
来,我们再稍微升级一下。 下面的示例展示了通过稍微多一点的提示词设计工作,LLMs可以变得多么强大。
提示词:
"""
Table departments, columns = [DepartmentId, DepartmentName]
Table students, columns = [DepartmentId, StudentId, StudentName]
Create a MySQL query for all students in the Computer Science Department
"""
输出:
SELECT StudentId, StudentName
FROM students
WHERE DepartmentId IN (SELECT DepartmentId FROM departments WHERE DepartmentName = 'Computer Science');
这非常令人印象深刻。在这种情况下,你提供了关于数据库模式的数据,并要求它生成一个有效的 MySQL 查询。
也许,当今大型语言模型(LLM)面临的最困难任务之一是需要某种形式的推理的任务。推理是最具吸引力的领域之一,因为有了推理,就可以从LLM中涌现出各种复杂的应用类型。
目前,涉及数学能力的推理任务已经有了一些改进。 对于当前的大型语言模型来说,执行推理任务可能会有一些难度,因此就需要更高级的提示词工程技术。 我们会在后面的指南中介绍这些高级技术。 现在,我们将介绍几个基本示例来展示算术功能。
提示词:
What is 9,000 * 9,000?
输出:
81,000,000
来,我们加大难度:
提示词:
The odd numbers in this group add up to an even number: 15, 32, 5, 13, 82, 7, 1.
A:
输出:
No, the odd numbers in this group add up to an odd number: 119.
这不对! 我们试着用提示词去改进它:
提示词:
The odd numbers in this group add up to an even number: 15, 32, 5, 13, 82, 7, 1.
Solve by breaking the problem into steps. First, identify the odd numbers, add them, and indicate whether the result is odd or even.
输出:
Odd numbers: 15, 5, 13, 7, 1
Sum: 41
41 is an odd number.
效果好多了,对吧?顺便提一下,我们尝试了几次这个任务,模型有时会失败。如果你提供更好的指令并结合示例,这可能有助于获得更准确的结果。
在后面的章节,我们将介绍更高级的提示工程概念和技术,以完成更困难任务。
如果您想使用 Python 练习上述提示,我们准备了一个 Notebook 来测试使用 OpenAI 模型的一些提示。
https://github.com/dair-ai/Prompt-Engineering-Guide/blob/main/notebooks/pe-lecture.ipynb