简介

Prompt(提示),最初是 NLP 研究者为下游任务设计出来的一种任务专属的输入形式或模板。在 ChatGPT 引发大语言模型新时代之后,Prompt 指与大模型交互输入的代称。 随着大模型的进展,Prompt Engineering是一个持久的探索过程。本文主要概括了我前段时间学习prompt的一些心得,和一些简单的大模型的入门知识。

我们一般将给大模型的输入称为 Prompt,将大模型返回的输出称为 Completion

大模型
大模型指的是那些比传统模型具有更多参数的机器学习模型,它们的训练需要大量的数据和强大的计算资源。由于模型的拟合能力强、复杂度高,它们通常具有更好的性能和更强的泛化能力。

大模型

大语言模型
大语言模型(Large language model,简称LLM)是指具有海量参数的神经网络语言模型,它通过大型的神经网络对人类的自然语言数据训练得到。ChatGPT 的出现,不仅证明了大型语言模型能近乎完美的处理和理解人类的自然语言,更让我们看到了实现通用人工智能(AGI)的希望。

大语言模型

或者从语言模型发展的角度,来看大语言模型的进展。

大语言模型

一些必要的知识点

生成式模型

大语言模型(LLM)是通过预测下一个词的监督学习方式进行训练的。具体来说,首先准备一个包含数百亿甚至更多词的大规模文本数据集。然后,可以从这些文本中提取句子或句子片段作为模型输入。模型会根据当前输入 Context 预测下一个词的概率分布。通过不断比较模型预测和实际的下一个词,并更新模型参数最小化两者差异,语言模型逐步掌握了语言的规律,学会了预测下一个词。 这里主要说明LLM如何对输入进行推理。

生成式模型

模型中的 token

到目前为止对 LLM 的描述中,我们将其描述为一次预测一个单词,但实际上还有一个更重要的技术细节。即 LLM 实际上并不是重复预测下一个单词,而是重复预测下一个 token 。对于一个句子,语言模型会先使用分词器将其拆分为一个个 token ,而不是原始的单词。对于生僻词,可能会拆分为多个 token 。这样可以大幅降低字典规模,提高模型训练和推断的效率。 token 是自然语言处理的最细粒度。简单点说就是,大语言模型的输入是一个个的 token,输出也是一个个的 token。 GPT4的词表token大小为100255,部分中文token如下表所示: “59795”: “中国” “73958”: " 中" “16325”: “中” “29504”: “国” 复杂的中文需要使用多个token表示,如上图的“全聚德”,在gpt中会转化为(包含起止符号):

gpt3的tokenizor

模型部署中的一些参数

这里是chatgpt的详细接口可调节参数 openai API

参数 释义 备注
max_tokens 完成时要生成的最大token数
temperature 使用什么样的采样温度,介于0和2之间。值越高(如0.8),输出越随机,而值越低(如0.2),输出就越集中和确定 和top-p不建议同时更改
top_k 每次采样的样本数量
top_p 一种替代温度采样的方法,称为核采样,其中模型考虑具有top_p概率质量的token的结果。因此,0.1意味着只考虑包含前10%概率质量的代币 和温度参数不建议同时更改

为了详细介绍不同的参数,了解不同解码方式的差别,我们通过下篇文章进行详细的探究。

Prompt 公式通常由三个主要元素组成

任务:对提示要求模型生成的内容进行清晰而简洁的陈述。

指令:在生成文本时模型应遵循的指令。

角色:模型在生成文本时应扮演的角色。

也可拆解为: prompt = 角色 + 任务 + 要求 + 提示【步骤拆解、范例说明,技巧点拨等】 即是谁?要做什么?要做成什么样?要怎么做?

一个简单的Prompt示例(只描述任务),目标为生成法律文件。

任务:生成法律文件
指令:文件应符合相关法律法规
提示公式:“按照以下指示生成符合相关法律法规的法律文件:文件应符合相关法律法规。”

角色提示技术是通过为ChatGPT指定一个特定的角色来引导其输出的一种方式。这种技术对于生成针对特定上下文或受众的文本非常有用。

要使用角色提示技术,您需要为模型提供一个清晰具体的角色。

任务:生成法律文件
角色:律师
提示公式:“作为律师,生成法律文件。”
种子词: 可以对任务的侧重点进行强调。

将角色提示技术与指令提示和种子词提示结合使用可以增强ChatGPT的输出。 下面是一个示例,展示了如何将指令提示、角色提示和种子词提示技术结合使用 。

任务:为新智能手机生成产品描述
指令:描述应该是有信息量的,具有说服力,并突出智能手机的独特功能
角色:市场代表
种子词:创新的
提示公式:“作为市场代表,生成一个有信息量的、有说服力的产品描述,突出新智能手机的创新功能。该智能手机具有以下功能[插入您的功能]”

在这个示例中,指令提示用于确保产品描述具有信息量和说服力。角色提示用于确保描述是从市场代表的角度书写的。而种子词提示则用于确保描述侧重于智能手机的创新功能。

任务:为一台新笔记本电脑撰写产品评论
说明:评论应客观、信息丰富,强调笔记本电脑的独特特点
角色:技术专家 种子词:“强大的”
提示公式:“作为一名技术专家,生成一个客观而且信息丰富的产品评论,强调新笔记本电脑的强大特点。”

在这个示例中,标准提示技术用于确保模型生成产品评论。角色提示用于确保评论是从技术专家的角度写的。而种子词提示用于确保评论侧重于笔记本电脑的强大特点。

编写清晰、具体的指令

在许多情况下,更长、更复杂的 Prompt 反而会让语言模型更容易抓住关键点,给出符合预期的回复。原因在于,复杂的 Prompt 提供了更丰富的上下文和细节,让模型可以更准确地把握所需的操作和响应方式。

使用分隔符清晰地表示输入的不同部分

在编写 Prompt 时,使用各种标点符号作为“分隔符”,将不同的文本部分区分开来。可以选择用 ```,""",< >, ,: 等做分隔符,只要能明确起到隔断作用即可。 使用分隔符的重要作用是: 可以防止 提示词注入(Prompt Rejection) 提示词注入: 用户输入的文本可能包含与你的预设 Prompt 相冲突的内容,如果不加分隔,这些输入就可能“注入”并操纵语言模型,导致模型产生毫无关联的乱七八糟的输出。 下面示例演示使用ChatGpt(3.5版本)与llama2 13b及文心一言的模型做效果的展示

3个模型的效果

可以看到我们的prompt目的是翻译translate text to french (hello), 但模型将hello翻译为了法语。 加入分隔符后,可以正确的将整句进行翻译。

结构化的输出

这种输出非常适合在代码中进一步解析和处理 如下面示例,使用json格式进行输出:

要求模型检查是否满足条件

如果任务包含不一定能满足的假设(条件),我们可以告诉模型先检查这些假设,如果不满足,则会指出并停止执行后续的完整流程。还可以考虑可能出现的边缘情况及模型的应对,以避免意外的结果或错误发生。

prompt1

prompt2

prompt3

提供少量示例

这个非常重要,可以有效的提升模型的精度。

给予模型充足思考时间

语言模型与人类一样,需要时间来思考并解决复杂问题。如果让语言模型匆忙给出结论,其结果很可能不准确。例如,若要语言模型推断一本书的主题,仅提供简单的书名和一句简介是不足够的。 我们应通过 Prompt 指引语言模型进行深入思考。可以要求其先列出对问题的各种看法,说明推理依据,然后再得出最终结论。在 Prompt 中添加逐步推理的要求,能让语言模型投入更多时间逻辑思维,输出结果也将更可靠准确。 这里我们详细看一篇使用顺序Prompt链的文本分类的文章,其中也涉及一些设计prompt的消融实验。 Text Classification via Large Language Models

Few-shot 的样本质量对 LLMs 的 in-context learning (ICL) 很重要,这里也有很多文章针对这个问题做研究。例如,利用主动学习对标注样本做筛选Active Learning Principles for In-Context Learning with Large Language Models 标签设置对预测结果影响的论文:IN-CONTEXT LEARNING IN LARGE LANGUAGE MODELS LEARNS LABEL RELATIONSHIPS BUT IS NOT CONVENTIONAL LEARNING 目前in-context或者prompt是研究的热点方向。

指导模型在下结论之前找出一个自己的解法

在设计 Prompt 时,我们还可以通过明确指导语言模型进行自主思考,来获得更好的效果。 举个例子,假设我们要语言模型判断一个数学问题的解答是否正确。仅仅提供问题和解答是不够的,语言模型可能会匆忙做出错误判断。 相反,我们可以在 Prompt 中先要求语言模型自己尝试解决这个问题,思考出自己的解法,然后再与提供的解答进行对比,判断正确性。这种先让语言模型自主思考的方式,能帮助它更深入理解问题,做出更准确的判断。

迭代优化

在开发大语言模型应用时,很难通过第一次尝试就得到完美适用的 Prompt。但关键是要有一个良好的迭代优化过程,以不断改进 Prompt。 有了任务想法后,可以先编写初版 Prompt,注意清晰明确并给模型充足思考时间。运行后检查结果,如果不理想,则分析 Prompt 不够清楚或思考时间不够等原因,做出改进,再次运行。如此循环多次,终将找到适合应用的 Prompt。

一些关于Prompt的网站推荐

  1. AI Short:https://www.aishort.top/ ,提供多种 prompt 模板,热度高,简单修改可直接使用。
  2. promptport:https://promptport.ai/ ,聚合市场上大部分优质 Prompt 词库,适合快速查找。右上角可选中文语言。
  3. FLOWGPT:https://flowgpt.com/ ,国外最大的 Prompt 网站。
  4. snackprompt:https://snackprompt.com/
  5. Prompt Extend:https://huggingface.co/spaces/daspartho/prompt-extend ,自动拓提示词。
  6. PromptPerfect:https://promptperfect.jinaai.cn/prompts,提示词优化。
  7. awesome-chatgpt-prompts:https://github.com/f/awesome-chatgpt-prompts#act-as-a-stand-up-comedian, ChatGPT 的提示技巧汇总

链式Prompt

当面对复杂任务的时,单一的Prompt是不够的,我们需要将Prompt链接在一起才能完成。

主要是因为链式提示它具有以下优点:

  1. 分解复杂度,每个 Prompt 仅处理一个具体子任务,避免过于宽泛的要求,提高成功率。这类似于分阶段烹饪,而不是试图一次完成全部。
  2. 降低单次计算成本。过长的 Prompt 使用更多 tokens ,增加成本。拆分 Prompt 可以避免不必要的计算。
  3. 更容易测试和调试。可以逐步分析每个环节的性能。
  4. 融入外部工具。不同 Prompt 可以调用 API 、数据库等外部资源。
  5. 更灵活的工作流程。根据不同情况可以进行不同操作。

综上,链式提示通过将复杂任务进行科学拆分,实现了更高效、可靠的提示设计。它使语言模型集中处理单一子任务,减少认知负荷,同时保留了多步骤任务的能力。随着经验增长,开发者可以逐渐掌握运用链式提示的精髓。

顺序Prompt

当单个提示中提供的任务变得太长或太复杂并且包含许多不同的指令,则响应可能无法捕获所需的细节和粒度。在这种情况下,可以将该任务分解为多个子任务。一个子任务的响应会成为另外一个子任务的Prompt,按照顺序走下去直到任务完成。

假设你要用一个语言模型来解决一个法律问题

你可能会先问:“什么是这个问题的法律背景?”得到答案后,你可能会进一步问:“在这个背景下,有哪些相关的法律条款或案例?”再之后,你可能会问:“这些法律条款或案例如何应用于我的具体问题?”最后,你可能会问:“根据这些信息,最可能的解决方案是什么?”通过这一系列的问题和答案,你就能更全面、更准确地解决你面临的复杂问题。

这样的Chain of Thought不仅能帮助模型更好地理解问题,还能帮助使用者更清晰地看到问题解决的全过程,就像我们人类解决问题时会做的那样。

第一步:了解背景Prompt:“请简要描述这个法律问题的背景和主要矛盾点。”
第二步:相关法律和案例Prompt:“在这个法律背景下,有哪些相关的法律条款或先例案例?”
第三步:应用法律到具体问题Prompt:“这些法律条款或案例如何应用于我的具体问题?有没有可能的解释或者争议点?”
第四步:可能的解决方案Prompt:“根据以上的信息,最可能的解决方案或建议是什么

下面是一个关于故事生成的示例。在这里想要生成一个长故事,其中包含由一组信息(人物、故事节奏和地点)引导的对话。 现在,可以将所有这些信息填充到一个提示中,但这可能会淡化我们希望对话框包含的关键细节。

此外,一开始的时候我们不想编写所有的细节,而是希望模型替我们生成。 我们想要提供的只是我们想要的故事内容的简短摘要,这也是我们唯一的Prompt。下图总结了生成最终对话框所涉及的链。 首先,人类输入故事摘要,该摘要将成为生成角色列表的提示,然后该列表将成为生成故事节拍的提示,依此类推,直到我们进入对话生成阶段。

并行Prompt

假设我们正在构建一个应用程序,该应用程序可以生成一周的创意食谱,然后生成供用户购买的食材购物清单。 在这种情况下,给定用户输入,例如进餐次数或天数,我们可以并行运行食谱生成步骤。 提示可能类似于以下内容:

Prompt={“帮我生成一份快捷简单的7天菜谱,并以Json的形式输出,其中key为“食材成分”和“制作说明””}

接下来,将在所有菜谱中重复生成食谱。一旦完成,我们可以将每顿饭的食材合并成一个用户可以立即使用的购物清单。

Prompt={“根据“食材成分”将食材合并成一个单一的购物清单,不要重复。”}

循环Prompt链

在某些应用程序中,考虑到后续步骤中发生的情况,我们可能需要重新运行生成步骤。 一个例子是,后续步骤用于检查生成的响应是否满足特定标准,例如质量和格式。这就是循环模式有用的地方。

翻译任务:

抽样Prompt方法

思维链提示与预先训练的大型语言模型相结合,在复杂的推理任务中取得了令人鼓舞的结果。在本文中,我们提出了一种新的解码策略,自一致性,以取代思维链提示中使用的天真贪婪解码。它首先对一组不同的推理路径进行采样,而不是只采用贪婪的推理路径,然后通过边缘化采样的推理路径来选择最一致的答案。自我一致性利用了一种直觉,即复杂的推理问题通常允许多种不同的思维方式,从而得出独特的正确答案。我们广泛的实证评估表明,在一系列流行的算术和常识推理基准上,自我一致性以惊人的优势提高了思维链提示的性能。

参考:SELF-CONSISTENCY IMPROVES CHAIN OF THOUGHT REASONING IN LANGUAGE MODELS

树状Prompt链

在每一步,模型都会生成几个不同的解决方案。 然后使用单独的提示来评估这些解决方案并投票选出最佳解决方案。重复该过程直到完成最后一步。 参考:Tree of Thoughts: Deliberate Problem Solving with Large Language Models

下图显示了初始输入,其中包含四个看似不相关的句子的列表 - 每个句子都讨论倒立、空间的气味、手语和人们的感知。 任务是将它们编织成一个连贯的段落。 它必须包含四个短段落,每个段落都以给定的句子结尾。

在此示例中,由于任务相当具有挑战性,因此将任务分为两部分是有意义的:编写计划和根据获胜计划编写实际段落。每一步,模型都会生成一些解决方案,然后使用另一个提示来评估和投票选出最佳解决方案,指导下一步的方向。上面屏幕截图中显示了几个写作计划选项,获胜的选项建议以自助为主题,将句子编织成连贯的段落。

总结

在设计提示链时,我们并不需要也不建议将所有可能相关信息一次性全加载到模型中,而是采取动态、按需提供信息的策略,原因如下:

  1. 过多无关信息会使模型处理上下文时更加困惑。尤其是低级模型,处理大量数据会表现衰减。
  2. 模型本身对上下文长度有限制,无法一次加载过多信息。
  3. 包含过多信息容易导致模型过拟合,处理新查询时效果较差。
  4. 动态加载信息可以降低计算成本。
  5. 允许模型主动决定何时需要更多信息,可以增强其推理能力。
  6. 我们可以使用更智能的检索机制,而不仅是精确匹配,例如文本 Embedding 实现语义搜索。

因此,合理设计提示链的信息提供策略,既考虑模型的能力限制,也兼顾提升其主动学习能力,是提示工程中需要着重考虑的点。

参考:

吴恩达《ChatGPT Prompt Engineering for Developers》教程

datawhale的总结课程

The Art of Asking ChatGPT for High-Quality Answers: A complete

如何向 ChatGPT 提问以获得高质量答案:提示技巧工程完全指南