大模型LLM之提示词Prompt系列教程(三)-技术

217 阅读20分钟

前两章系统介绍了Prompt的基本概念与设计原则。为进一步提升大语言模型的应用效能,本章将深入探讨Prompt的高级使用技巧。

本章我们将逐一解析LLM提示词的多种关键技术,助力您精准把握其核心要点与应用场景,切实提升应用能力。

1、零样本提示(Zero-Shot )

零样本提示是一种让模型在没有特定任务示例展示的情况下直接处理任务的技术。其原理在于模型经过大量数据训练和指令调整后,自身具备了一定的通用知识和任务理解能力。例如:

# 提示词:
prompt"判断此文本的情感倾向为积极、消极或中性:这部电影情节紧凑,特效惊人。情感:"
# 模型会依据自身预训练知识对这个提示进行处理并输出结果

#模型输出:
积极

模型能依据自身预训练知识输出“积极”。然而,由于缺乏具体示例引导,对于复杂任务,其效果可能受限。

2、少样本提示(Few-Shot Prompting)

虽然大型语言模型展示了惊人的零样本能力,但在使用零样本设置时,它们在更复杂的任务上仍然表现不佳。少样本提示可以作为一种技术,以启用上下文学习,我们在提示中提供演示以引导模型实现更好的性能。演示作为后续示例的条件,我们希望模型生成响应。

#提示词:
“whatpu”是坦桑尼亚的一种小型毛茸茸的动物。一个使用whatpu这个词的句子的例子是:
我们在非洲旅行时看到了这些非常可爱的whatpus。
“farduddle”是指快速跳上跳下。一个使用farduddle这个词的句子的例子是:

#模型的输出为:
小兔子在草地上兴奋地farduddle,看起来特别欢乐!

模型通过提供一个示例(即1-shot)已经学会了如何执行任务。对于更困难的任务,我们可以尝试增加演示(例如3-shot、5-shot、10-shot等)。

根据研究结果,以下是在进行少样本学习时关于演示/范例的一些额外提示

  • • “标签空间和演示指定的输入文本的分布都很重要(无论标签是否对单个输入正确)”
  • • 使用的格式也对性能起着关键作用,即使只是使用随机标签,这也比没有标签好得多。
  • • 其他结果表明,从真实标签分布(而不是均匀分布)中选择随机标签也有帮助。

让我们尝试一些例子。让我们首先尝试一个随机标签的例子(意味着将标签Negative和Positive随机分配给输入):

# 提示词:
这太棒了!// 消级
这太糟糕了!// 积极 
哇,那部电影太棒了!// 积极
多么可怕的节目!//

# 输出:

即使标签已经随机化,我们仍然得到了正确的答案。请注意,我们还保留了格式,这也有助于。实际上,通过进一步的实验,我们发现我们正在尝试的新GPT模型甚至对随机格式也变得更加稳健。

少样本提示的限制

提供示例对解决某些任务很有用。当零样本提示和少样本提示不足时,这可能意味着模型学到的东西不足以在任务上表现良好。从这里开始,建议开始考虑微调您的模型或尝试更高级的提示技术。接下来,我们将讨论一种流行的提示技术,称为思维链提示,它已经获得了很多关注。

3、思维链提示(Chain-of-Thought Prompting)

3.1 传统COT

提示通过中间推理步骤实现了复杂的推理能力。您可以将其与少样本提示相结合,以获得更好的结果,以便在回答之前进行推理的更复杂的任务。

# 提示词:
这组数中的奇数加起来是偶数:489151221。
A:将所有奇数相加(9151)得到25。答案为False。

这组数中的奇数加起来是偶数:171019481224。
A:将所有奇数相加(1719)得到36。答案为True。

这组数中的奇数加起来是偶数:161114481324。
A:将所有奇数相加(1113)得到24。答案为True。

这组数中的奇数加起来是偶数:17910121342。
A:将所有奇数相加(17913)得到39。答案为False。

这组数中的奇数加起来是偶数:15325138271。
A:

# 模型输出:
将所有奇数相加(1551371)得到41。答案为False

在这个例子中,甚至我们可以只需要写一个示例,大模型就能得到正确结果

3.2 零样本 COT

只需要在提示词后面加上:让我们逐步思考。是不是很神奇!

我去市场买了10个苹果。我给了邻居2个苹果和修理工2个苹果。然后我去买了5个苹果并吃了1个。我还剩下多少苹果?

让我们逐步思考。

3.3 自动思维链(Auto-CoT)

当使用思维链提示时,这个过程需要手工制作有效且多样化的例子。这种手动工作可能会导致次优解决方案。Zhang et al. (2022) 提出了一种消除人工的方法,即利用 LLMs “让我们一步一步地思考” 提示来生成一个接一个的推理链。这种自动过程仍然可能在生成的链中出现错误。为了减轻错误的影响,演示的多样性很重要。这项工作提出了Auto-CoT,它对具有多样性的问题进行采样,并生成推理链来构建演示。

Auto-CoT 主要由两个阶段组成:

  • • 阶段1:问题聚类:将给定问题划分为几个聚类
  • • 阶段2:演示抽样:从每组数组中选择一个具有代表性的问题,并使用带有简单启发式的 Zero-Shot-CoT 生成其推理链

简单的启发式方法可以是问题的长度(例如,60 个 tokens)和理由的步骤数(例如,5 个推理步骤)。这鼓励模型使用简单而准确的演示。

www.promptingguide.ai/_next/image…

Auto-CoT 的代码可在这里找到:github.com/amazon-scie…

3.4 自我一致性(Self-Consistency)

也许在提示工程中更高级的技术之一是自我一致性。由 Wang等人(2022) 提出,自我一致性旨在“替换链式思维提示中使用的天真贪婪解码方法”。其想法是通过少样本 CoT 采样多个不同的推理路径,并使用生成结果选择最一致的答案。这有助于提高 CoT 提示在涉及算术和常识推理的任务中的性能。

让我们尝试以下算术推理示例:

提示:
当我6岁时,我的妹妹是我的一半年龄。现在我70岁了,我的妹妹多大?

输出:
35

输出是错误的!我们如何通过自我一致性来改进这个问题?让我们试试。我们将使用 Wang 等人 2022 年的少量样本范例(表 17 ):

提示:

Q:林中有15棵树。林业工人今天将在林中种树。完成后,将有21棵树。林业工人今天种了多少棵树?
A:我们从15棵树开始。后来我们有21棵树。差异必须是他们种树的数量。因此,他们必须种了21-15 = 6棵树。答案是6Q:停车场有3辆汽车,又来了2辆汽车,停车场有多少辆汽车?
A:停车场已经有3辆汽车。又来了2辆。现在有3 + 2 = 5辆汽车。答案是5Q:Leah有32块巧克力,她的姐姐有42块。如果他们吃了35块,他们总共还剩多少块?
A:Leah有32块巧克力,Leah的姐姐有42块。这意味着最初有32 + 42 = 74块巧克力。已经吃了35块。因此,他们总共还剩74-35 = 39块巧克力。答案是39Q:Jason有20个棒棒糖。他给Denny一些棒棒糖。现在Jason只有12个棒棒糖。Jason给Denny多少棒棒糖?
A:Jason有20个棒棒糖。因为他现在只有12个,所以他必须把剩下的给Denny。他给Denny的棒棒糖数量必须是20-12 = 8个棒棒糖。答案是8Q:Shawn有五个玩具。圣诞节,他从他的父母那里得到了两个玩具。他现在有多少个玩具?
A:他有5个玩具。他从妈妈那里得到了2个,所以在那之后他有5 + 2 = 7个玩具。然后他从爸爸那里得到了2个,所以总共他有7 + 2 = 9个玩具。答案是9Q:服务器房间里有9台计算机。从周一到周四,每天都会安装5台计算机。现在服务器房间里有多少台计算机?
A:从周一到周四有4天。每天都添加了5台计算机。这意味着总共添加了4 * 5 =
20台计算机。一开始有9台计算机,所以现在有9 + 20 = 29台计算机。答案是29Q:Michael有58个高尔夫球。星期二,他丢失了23个高尔夫球。星期三,他又丢失了2个。星期三结束时他还剩多少个高尔夫球?
A:Michael最初有58个球。星期二他丢失了23个,所以在那之后他有58-23 = 35个球。星期三他又丢失了2个,所以现在他有35-2 = 33个球。答案是33Q:Olivia有23美元。她用每个3美元的价格买了五个百吉饼。她还剩多少钱?
A:她用每个3美元的价格买了5个百吉饼。这意味着她花了15美元。她还剩8美元。
Q:当我6岁时,我的妹妹是我的一半年龄。现在我70岁了,我的妹妹多大?
A

输出 1:

当我6岁时,我的妹妹是我的一半年龄,也就是3岁。现在我70岁了,所以她是70-3 = 67岁。答案是67

输出 2:

当叙述者6岁时,他的妹妹是他年龄的一半,也就是3岁。现在叙述者70岁了,他的妹妹应该是70-3 = 67岁。答案是67

输出 3:

当我6岁时,我的妹妹是我的一半年龄,也就是3岁。现在我70岁了,所以她是70/2 = 35岁。答案是35

计算最终答案涉及几个步骤(详见论文),但为了简单起见,我们可以看到已经出现了大多数答案,因此这基本上将成为最终答案。

3.5 生成知识提示

生成知识提示主要用于解决模型在处理需要额外知识的任务时出现的局限性。它的操作方式是先让模型生成与任务相关的知识,再整合这些知识得出准确答案。比如:

prompt"""输入:高尔夫球的一部分是试图获得比其他人更高的得分。
知识:高尔夫球的目标是以最少的杆数打完一组洞。一轮高尔夫球比赛通常包括 18 个洞。每个洞在标准高尔夫球场上一轮只打一次。每个杆计为一分,总杆数用于确定比赛的获胜者。
解释和答案:"""
# 模型根据生成的知识对问题进行回答

像这样先生成相关知识,再整合知识得出准确答案“不是,高尔夫球的目标是以最少杆数完成比赛,而非追求更高得分”,有效提升模型在常识推理任务的准确性。

3.6 链式提示

链式提示可以完成很复杂的任务。LLM 可能无法仅用一个非常详细的提示完成这些任务。在链式提示中,提示链对生成的回应执行转换或其他处理,直到达到期望结果。

除了提高性能,链式提示还有助于提高 LLM 应用的透明度,增加控制性和可靠性。这意味着您可以更容易地定位模型中的问题,分析并改进需要提高的不同阶段的性能。

链式提示在构建 LLM 驱动的对话助手和提高应用程序的个性化用户体验方面非常有用。

文档问答中的链式提示

提示链可以用于不同的场景,这些场景可能涉及多个操作或转换。例如,LLM 的一个常见用途是根据大型文本文档回答问题。想要更好阅读大文本文档,可以设计两个不同的提示,第一个提示负责提取相关引文以回答问题,第二个提示则以引文和原始文档为输入来回答给定的问题。换句话说,可以创建两个不同的提示来执行根据文档回答问题的任务。

下面的第一个提示根据问题从文档中提取相关引文。请注意,为了简化,我们为文档添加了一个占位符{{文档}}。要测试此提示,您可以从维基百科复制并粘贴一篇文章,例如这个关于提示工程的页面。由于此任务使用了较长的上下文,因此要使用了支持长token 的模型。您也可以将此提示与其他长上下文 LLM(如 Claude)一起使用。

提示 1:

你是一个很有帮助的助手。你的任务是根据文档回答问题。第一步是从文档中提取与问题相关的引文,由####分隔。请使用<quotes></quotes>输出引文列表。如果没有找到相关引文,请回应“未找到相关引文!”。
####
{{文档}}
####

提示 2:

根据从文档中提取的相关引文(由<quotes></quotes>分隔)和原始文档(由####分隔),请构建对问题的回答。请确保答案准确、语气友好且有帮助。
####
{{文档}}
####
<quotes>
- Chain-of-thought (CoT) prompting[27]
- Generated knowledge prompting[37]
- Least-to-most prompting[38]
- Self-consistency decoding[39]
- Complexity-based prompting[41]
- Self-refine[42]
- Tree-of-thought prompting[43]
- Maieutic prompting[45]
- Directional-stimulus prompting[46]
- Textual inversion and embeddings[59]
- Using gradient descent to search for prompts[61][62][63][64]
- Prompt injection[65][66][67]
</quotes>

这种方式提高了任务处理的准确性与可靠性,使得模型能够逐步深入地处理复杂问题。

3.7 思维树(TOT)

思维树框架是为了帮助模型应对复杂的探索性任务而设计的。它通过维护一棵思维树,让模型在解决问题时能够生成和评估中间思维步骤,并结合搜索算法进行系统性探索。示例如下:

# 假设给定数字为 4、9、10、13
prompt = """输入: 4 9 10 13
4 + 9 = 13 (left 10 13 13)
10 - 4 = 6 (left 6 9 13)
13 - 6 = 7 13 - 9 = 4
4 + 6 = 10 (left 7 9 4 * 6 = 24 (left 4 6)
评估是否能得到 24: sure

# 模型按照思维树的步骤进行推理和计算,并根据评估结果继续搜索或得出答案
"""

Hulbert (2023) 提出了思维树(ToT)提示法,将 ToT 框架的主要概念概括成了一段简短的提示词,指导 LLM 在一次提示中对中间思维做出评估。ToT 提示词的例子如下:

假设三位不同的专家来回答这个问题。
所有专家都写下他们思考这个问题的第一个步骤,然后与大家分享。
然后,所有专家都写下他们思考的下一个步骤并分享。
以此类推,直到所有专家写完他们思考的所有步骤。
只要大家发现有专家的步骤出错了,就让这位专家离开。
请问...

3.8 检索增强生成(RAG)

检索增强生成(RAG)技术将信息检索与文本生成相结合,专门用于处理知识密集型任务。它通过检索相关文档来为模型提供额外的知识支持,从而缓解模型的“幻觉”问题。例如:

# 假设这里有一个检索函数 retrieve_documents 和一个生成答案的函数 generate_answer
question"谁是首次登上月球的人?"
documents = retrieve_documents(question)
prompt"根据以下文档回答问题:" + str(documents) + " 问题是:" + question
answer = generate_answer(prompt)
# 最终得到的 answer 即为模型结合检索结果生成的答案

这有效确保答案基于可靠知识源,在自然问题、事实验证等基准测试中表现卓越。

3.9 自动推理并使用工具(ART)

自动推理并使用工具(ART)技术使模型能够自动生成包含推理步骤的程序,并在需要时调用外部工具。例如:

prompt"""计算 16 个苹果平均分给 4 个人,每人几个,再加上 3 是多少?
请生成解决这个问题的程序步骤。"""
# 模型会生成类似下面的程序步骤
# result = (16 / 4) + 3
# 然后可以在代码中执行这个程序步骤得到最终答案

在 BigBench 和 MMLU 基准测试中,ART 在多种任务上表现突出,显著超越少样本提示和自动 CoT 等方法,提升了模型解决问题的能力和效率。

3.10 自动提示工程师(APE)

自动提示工程师(APE)技术能够自动生成和筛选任务指令。它通过利用大型语言模型生成指令候选项,再依据评估分数选择最佳指令,从而提升提示生成的效率与效果。比如:

# 假设这里有一个生成指令候选项的函数 generate_candidates 和一个选择最佳指令的函数 select_best_instruction
article = "这里是一篇新闻文章的内容"
candidates = generate_candidates(article)
prompt = select_best_instruction(candidates) + " " + article
# 模型根据最终的 prompt 生成文章总结

例如总结新闻文章时,它先利用大型语言模型生成如“提取文章关键人物、事件和时间”“概括文章主要内容并突出重点”等指令候选项,再依据评估分数选择最佳指令,指导模型生成高质量总结。

3.11 Active-Prompt

Active-Prompt 技术主要用于解决思维链示例有效性的问题。它通过先查询模型生成多个答案,计算不确定度后挑选最不确定的问题由人类注释示例,再用新示例推断其他问题,从而优化模型对不同任务的适应性。比如:

# 假设这里有一个查询模型生成答案的函数 query_model 和一个计算不确定度的函数 calculate_uncertainty
prompt"对以下文本进行分类:这是一篇科技类文章。"
answers = query_model(prompt, num_answers=5)  # 生成 5 个答案
uncertainty = calculate_uncertainty(answers)
if uncertainty > threshold:  # 如果不确定度大于设定阈值
    # 选择最不确定的问题由人类注释示例,然后更新提示并重新查询模型
    new_prompt = update_prompt_with_annotated_example(prompt)
    final_answer = query_model(new_prompt)
else:
    final_answer = select_most_consistent_answer(answers)
# 最终得到的 final_answer 即为经过 Active-Prompt 处理后的答案

通过这种方式,能够提高模型在文本分类等任务中的准确性。

3.12 方向性刺激提示(Directional Stimulus Prompting)

方向性刺激提示通过训练策略 LM 生成引导提示,增强对模型生成结果的掌控力。例如文本摘要任务:

article = "这里是一篇文章的内容"
prompt"请根据文章内容生成一个引导提示,重点关注文章的主要事件和结果。"
# 策略 LM 会根据这个提示生成如“重点提取文章中事件的主体、发生的时间和最终结果”的引导提示
# 然后可以将这个引导提示用于后续的文本摘要任务中

在文本摘要任务中,策略 LM 依据文章主题、关键信息等生成引导提示,指导模型生成符合需求的摘要,提升摘要质量。

3.13 PAL(程序辅助语言模型)

PAL(程序辅助语言模型)技术让模型生成程序来解决问题,借助编程运行时提升解决复杂问题的能力。以日期计算问题为例:

question"今天是 2023 年 2 月 27 日,我出生于 25 年前,我的出生日期是多少?"
prompt = """
import datetime
from dateutil.relativedelta import relativedelta

# Q: 2015 年在 36 小时后到来。从今天起一周后的日期是多少(格式为 MM/DD/YYYY)?
# 如果 2015 年在 36 小时后到来,那么今天是 36 小时前。
today = datetime(2015, 1, 1) - relativedelta(hours=36)
# 从今天起一周后,
one_week_from_today = today + relativedelta(weeks=1)
# 格式化后的答案
one_week_from_today.strftime('%m/%d/%Y')

# Q: 今天是 2023 年 2 月 27 日,我出生于 25 年前,我的出生日期是多少?
"""
# 模型会生成类似下面的代码
# today = datetime(2023, 2 27)
# born = today - relativedelta(years=25)
# born.strftime('%m/%d/%Y')
# 然后可以在代码中执行模型生成的代码得到最终答案

3.14 ReAct 框架

ReAct 框架使模型交错生成推理轨迹和操作,提升答案的可靠性与可解释性。以回答问题为例:

question"除苹果遥控器外,哪些设备可控制其设计交互的程序?"
prompt"""问题:除苹果遥控器外,哪些设备可控制其设计交互的程序?
思考 1:我需要搜索苹果遥控器相关程序及可替代控制设备。
操作 1:搜索 [苹果遥控器 可替代控制设备]
观察 1:搜索结果为……
思考 2:根据搜索结果,分析哪些设备符合要求。
操作 2:筛选 [符合要求的设备]
观察 2:筛选结果为……
思考 3:整理最终答案。
操作 3:整理 [最终答案]
"""
# 模型会按照提示中的推理轨迹和操作步骤进行处理,并最终得出答案

在知识密集型和决策任务中表现良好,通过与外部环境交互获取信息来辅助推理。

3.15 自我反思(Reflexion)

自我反思框架包含参与者、评估者和自我反思三个模型,旨在帮助模型从错误中学习并提升性能。模拟编程任务的示例如下:

# 假设这里有参与者模型 actor、评估者模型 evaluator 和自我反思模型 reflexion
code = "这里是一段初始代码"
# 参与者模型生成尝试解决问题的代码和动作
result = actor(code)
# 评估者模型评价输出
score = evaluator(result)
# 自我反思模型根据评价结果生成改进建议
reflection = reflexion(score, result)
# 将改进建议应用到下一次的代码生成中,实现自我学习和提升
如代码出现语法错误,自我反思模型会提示可能错误原因及修正方向,帮助模型快速学习。

原文地址:https://mp.weixin.qq.com/s/-octkIoCRExnmzVCWnkIkg