Prompt Engineering 高级篇

2.高级篇

2.1 Prompt框架

看完基础篇的各种场景介绍后,你应该对 Prompt 有较深的理解。

之前的章节我们讲的都是所谓的「术」,更多地集中讲如何用,但讲「道」的部分不多。高级篇除了会讲更高级的运用外,还会讲更多「道」的部分。

高级篇的开篇,我们来讲一下构成 prompt 的框架。

2.1.1 Prompt基础框架

查阅了非常多关于文心一言 prompt 的框架资料,我目前觉得写得最清晰的是 Elavis Saravia 总结的框架,他认为一个 prompt 里需包含以下几个元素:

  • Instruction(必须): 指令,即你希望模型执行的具体任务。
  • Context(选填): 背景信息,或者说是上下文信息,这可以引导模型做出更好的反应。
  • Input Data(选填): 输入数据,告知模型需要处理的数据。
  • Output Indicator(选填): 输出指示器,告知模型我们要输出的类型或格式。

只要你按照这个框架写 prompt ,模型返回的结果都不会差。当然,你在写 prompt 的时候,并不一定要包含所有4个元素,而是可以根据自己的需求排列组合。比如拿前面的几个场景作为例子:

  • 推理:Instruction + Context + Input Data
  • 信息提取:Instruction + Context + Input Data + Output Indicator

2.1.2 CRISPE Prompt框架

另一个我觉得很不错的 Framework 是 Matt Nigh 的 CRISPE Framework,这个 framework 更加复杂,但完备性会比较高,比较适合用于编写 prompt 模板。CRISPE 分别代表以下含义:

CR: Capacity and Role(能力与角色)。你希望 文心一言 扮演怎样的角色。

I: Insight(洞察力),背景信息和上下文(坦率说来我觉得用 Context 更好)。

S: Statement(指令),你希望 文心一言 做什么。

P: Personality(个性),你希望 文心一言 以什么风格或方式回答你。

E: Experiment(尝试),要求 文心一言 为你提供多个答案。

以下是这几个参数的例子:

Step

Example

Capacity and Role

把你想象成机器学习框架主题的软件开发专家,以及专业博客作者。

Insight

这个博客的读者主要是有兴趣了解机器学习最新进展技术的专业人士。

Statement

提供最流行的机器学习框架的全面概述,包括它们的优点和缺点。包括现实生活中的例子,和研究案例,以说明这些框架如何在各个行业中成功地被使用。

Personality

在回应时,混合使用 Andrej Karpathy、Francois Chollet、Jeremy Howard 和 Yann LeCun 的写作风格。

Experiment

给我多个不同的例子。

在文心一言中进行实验,会得到如下结果。

2.2 Zero-Shot Prompts

在基础篇里的推理场景,我提到了 Zero-Shot Prompting 的技术,本章会详细介绍它是什么,以及使用它的技巧。

2.2.1 介绍

Zero-Shot Prompting 是一种自然语言处理技术,可以让计算机模型根据提示或指令进行任务处理。各位常用的 文心一言 就用到这个技术。

传统的自然语言处理技术通常需要在大量标注数据上进行有监督的训练,以便模型可以对特定任务或领域进行准确的预测或生成输出。相比之下,Zero-Shot Prompting 的方法更为灵活和通用,因为它不需要针对每个新任务或领域都进行专门的训练。相反,它通过使用预先训练的语言模型和一些示例或提示,来帮助模型进行推理和生成输出。

举个例子,我们可以给 文心一言 一个简短的 prompt,比如 描述某部电影的故事情节,它就可以生成一个关于该情节的摘要,而不需要进行电影相关的专门训练。

2.2.2 缺点

但这个技术并不是没有缺点的:

1.Zero-Shot Prompting 技术依赖于预训练的语言模型,这些模型可能会受到训练数据集的限制和偏见。比如在使用 文心一言 的时候,它常常会在一些投资领域,使用男性的「他」,而不是女性的「她」。那是因为训练 文心一言 的数据里,提到金融投资领域的内容,多为男性。

2.尽管 Zero-Shot Prompting 技术不需要为每个任务训练单独的模型,但为了获得最佳性能,它需要大量的样本数据进行微调。像 文心一言 就是一个例子,它的样本数量是过千亿。

3.由于 Zero-Shot Prompting 技术的灵活性和通用性,它的输出有时可能不够准确,或不符合预期。这可能需要对模型进行进一步的微调或添加更多的提示文本来纠正。

2.2.3 Zero-Shot Chain of Thought

基于上述的第三点缺点,研究人员就找到了一个叫 Chain of Thought 的技巧。

这个技巧使用起来非常简单,只需要在问题的结尾里放一句 Let‘s think step by step (让我们一步步地思考),模型输出的答案会更加准确。

这个技巧来自于 Kojima 等人 2022 年的论文 Large Language Models are Zero-Shot Reasoners。在论文里提到,当我们向模型提一个逻辑推理问题时,模型返回了一个错误的答案,但如果我们在问题最后加入 Let‘s think step by step 这句话之后,模型就生成了正确的答案:

论文里有讲到原因,感兴趣的朋友可以去看看,我简单解释下为什么(🆘 如果你有更好的解释,不妨反馈给我):

1.首先各位要清楚像 文心一言 这类产品,它是一个统计语言模型,本质上是基于过去看到过的所有数据,用统计学意义上的预测结果进行下一步的输出(这也就是为什么你在使用 文心一言 的时候,它的答案是一个字一个字地吐出来,而不是直接给你的原因,因为答案是一个字一个字算出来的)。

2.当它拿到的数据里有逻辑,它就会通过统计学的方法将这些逻辑找出来,并将这些逻辑呈现给你,让你感觉到它的回答很有逻辑。

3.在计算的过程中,模型会进行很多假设运算(不过暂时不知道它是怎么算的)。比如解决某个问题是从 A 到 B 再到 C,中间有很多假设。

4.它第一次算出来的答案错误的原因,只是因为它在中间跳过了一些步骤(B)。而让模型一步步地思考,则有助于其按照完整的逻辑链(A > B > C)去运算,而不会跳过某些假设,最后算出正确的答案。 按照论文里的解释,零样本思维链涉及两个补全结果,左侧气泡表示基于提示输出的第一次的结果,右侧气泡表示其收到了第一次结果后,将最开始的提示一起拿去运算,最后得出了正确的答案:

这个技巧,除了用于解决复杂问题外,还适合生成一些连贯主题的内容,比如写长篇文章、电影剧本等。但需要注意其缺点,连贯不代表,它就一定不会算错,如果其中某一步骤算错了,错误会因为逻辑链,逐步将错误积累,导致生成的文本可能出现与预期不符的内容。另外,根据 Wei 等人在 2022 年的论文表明,它仅在大于等于 100B 参数的模型中使用才会有效。如果你使用的是小样本模型,这个方法不会生效。

2.3 Few-Shot Prompting

2.3.1 介绍

我们在1.4.2中,提到我们可以给模型一些示例,从而让模型返回更符合我们需求的答案。这个技巧其实使用了一个叫 Few-Shot 的方法。这个方法最早是 Brown 等人在 2020 年发现的,论文里有一个这样的例子,非常有意思,通过这个例子你应该更能体会,像 文心一言 这类统计语言模型,其实并不懂意思,只是懂概率。

我输入的内容是这样的(追云、断月和落红雨 其实只是王者荣耀里的英雄技能):

不过这并不代表,Few-Shot 就没有缺陷,我们试试下面这个例子:

实际应该是:把所有的奇数相加(15,5,13,7,1)是41。答案是假的。

2.3.2 Few-Shot Chain of Thought

要想解决这个问题,可以使用Few-Shot Chain of Thought这个技巧。

要解决这个缺陷,就要使用到新的技巧,Few-Shot Chain of Thought。根据 Wei 他们团队在 2022 年的研究表明:

通过向大语言模型展示一些少量的样例,并在样例中解释推理过程,大语言模型在回答提示时也会显示推理过程。这种推理的解释往往会引导出更准确的结果。下面是论文里的案例,使用方法很简单,在技巧2 的基础上,再将逻辑过程告知给模型即可。从下面这个案例里,你可以看到加入解释后,输出的结果就正确了。

聊完技巧,我们再结合前面的 Zero-Shot Chain of Thought,来聊聊 Chain of Thought 的关键知识。根据 Sewon Min 等人在 2022 年的研究 表明,思维链有以下特点:

  • "the label space and the distribution of the input text specified by the demonstrations are both key (regardless of whether the labels are correct for individual inputs)" 标签空间和输入文本的分布都是关键因素(无论这些标签是否正确)。
  • the format you use also plays a key role in performance, even if you just use random labels, this is much better than no labels at all. 即使只是使用随机标签,使用适当的格式也能提高性能。

理解起来有点难,我找一个 prompt 案例给大家解释(🆘 如果你有更好的解释,不妨反馈给我)。我给 文心一言 一些不一定准确的例子:

在上述的案例里,每一行,我都写了一句话和一个情感词,并用 情感分类 分开,但我给这些句子都标记了错误的答案,比如第一句其实应该是 积极的 才对。但:

1.即使我给内容打的标签是错误的(比如第一句话,其实应该是 积极的),对于模型来说,它仍然会知道需要输出什么东西。 换句话说,模型知道 情感分类: 后要输出一个衡量该句子表达何种感情的词(积极的 或 负面的)。这就是前面论文提到的,即使我给的标签是错误的,或者换句话说,是否基于事实,并不重要。标签和输入的文本,以及格式才是关键因素。

2.只要给了示例,即使随机的标签,对于模型生成结果来说,都是有帮助的。这就是前面论文里提到的内容。

最后,需要记住,思维链仅在使用大于等于 100B 参数的模型时,才会生效。

2.4 Self-Consistency

Self-Consistency 自洽是对 Chain of Thought 的一个补充,它能让模型生成多个思维链,然后取最多数答案的作为最终结果。

按照 Xuezhi Wang 等人在 2022 年发表的论文 https://arxiv.org/pdf/2203.11171.pdf 表明。当我们只用一个逻辑链进行优化时,模型依然有可能会算错,所以 XueZhi Wang 等人提出了一种新的方法,让模型进行多次运算,然后选取最多的答案作为最终结果:

就我目前使用下来,在 文心一言 上,其自洽性非常高,暂时没有遇到过出现多种答案的情况。查阅多份资料,我发现这个自洽性可能更多的用于评估模型的优劣,好的模型一般自洽性会比较高。

2.5 PAL Models

PAL Models,全称为 Program-Aided Language Models。需要各位注意,这个方法,真的非常高级,甚至我觉得有点 Hack。

但我在很多 PE 的教程里都有看到这个方法,所以我这里就简单介绍一下,这个方法来自于 2022 年,Luyu Gao 等人的研究 https://arxiv.org/pdf/2211.10435.pdf ,根据他们的研究,在 LLM 模型中,即使使用了前面提到的 Chain of Thought 的方法,也未必能拿到答案,论文中使用的 prompt 是这样的:

### 学习 Prompt Engineering 的资源 #### 资源概述 Prompt Engineering 是一门关于构建清晰、有效和具体的指令的艺术,这些指令可以引导像 ChatGPT 这样的大型语言模型生成期望的结果[^3]。以下是几种学习 Prompt Engineering 的资源: 1. **在线文章与博客** - 文章《Introduction to AI Prompt Engineering》提供了对提示工程的基础介绍以及一些工具推荐[^1]。 - 另外,《打工人转型之道:Prompt Engineering 基础》系列文章通过实际案例讲解了从基础到高级的技巧应用方法[^2]。 2. **学术论文** - SSRN 上的一研究论文探讨了更深层次的语言模型交互方式及其优化策略[^4]。这类学术资料适合希望深入理解理论背景的学习者。 3. **实践指南与教程视频** - 各大平台上的教学视频通常会展示具体的操作流程并分享实用的小窍门。例如,“10个 prompt engineering 技巧图解”就是一份图文并茂的手册,非常适合初学者快速上手。 4. **社区讨论与论坛交流** - 加入活跃的技术社群能够获取最新动态并与同行切磋经验。比如 Reddit 或 GitHub Discussions 中常有关于最佳 practices 和创新应用场景的话题。 5. **官方文档和支持材料** - OpenAI 官方网站不仅有详尽的产品说明还有专门针对开发者设计的工作坊内容可供参考(需自行查找链接)。 #### 示例代码片段演示如何编写高效 Prompts 下面是一个简单的 Python 函数用来自动化创建结构化 prompts: ```python def create_prompt(task_description, input_data=None): base_template = "You are an assistant tasked with solving {task}." if input_data: detailed_template = f"{base_template} Here's your data:{input_data}" else: detailed_template = base_template.format(task=task_description) return detailed_template example_task = "a classification problem involving fruits." data_sample = ["apple", "banana"] print(create_prompt(example_task, data_sample)) ``` 上述脚本定义了一个函数 `create_prompt` ,它接受任务描述作为参数,并可选地接收输入数据来定制个性化的请求语句给 LLMs 使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值