AI原生应用开发:提示工程原理与实战
上QQ阅读APP看书,第一时间看更新

1.4 提示工程的本质

提示是什么?提示是用户向大语言模型提供的一段文字描述。用户通过这段文字描述对大语言模型进行引导,帮助大语言模型“回忆”它在预训练时学到的知识,使其根据文字描述所提供的信息,生成合适的、有针对性的回复。

因此,提示的质量直接影响大语言模型的输出效果。提示工程则专注于编写和优化提示的技术,通过这些技术,我们可以更有效地与大语言模型进行交互,使其更深入地理解任务要求,并生成高质量且符合预期的输出。提示工程显著提升了大语言模型在AI原生应用中的普适性和扩展性,成为AI原生应用开发者必须掌握的关键技能。本节将从开发者的角度,深入探讨提示工程的核心原理。

1.4.1 提示是引导生成的起点

大语言模型在训练时利用了大量无标注语料,通过自监督学习方法获得了根据给定部分前序文本序列,生成下一个文字符号的文本预测能力。因此,大语言模型内容生成可以粗略看概率生成,它会根据输入的文本,计算出后续每个词出现的可能性,并选择可能性最大的一个词作为输出。然后,它会把这个词和输入的文本拼接起来作为新的输入,重复上述过程,不断延长文本,直到它输出一个停止符号或达到最大长度为止。

大语言模型根据“到饭点了,你妈妈喊你”这个前序文本序列,逐步预测出后续文本“回家吃饭”,过程如图1-5所示。

图1-5 大语言模型内容生成过程

总体而言,大语言模型在训练过程中接触到了海量的数据,这使得它从中汲取了大量知识。训练完成后,它便成为一个具备丰富知识的文本预测工具。由于其基于自身的预测能力来生成后续内容,因此其输出并不完全可控和可预测。

既然这样,为什么在上述例子中大语言模型似乎能按照预期生成后续内容呢?原因在于我们为其提供的上下文文本——提示。

用户通过这些特定场景的上下文文本信息去引导大语言模型,使其初始的生成参数(即初始概率)得到优化,从而干预它后续生成内容的概率和方向,让它更好地发挥自己的潜力,输出预期的文本,而非简单地生成一些泛泛而谈的平庸的文本。这一技术的核心指导思想为上下文学习(in-context learning,ICL)。

上下文学习作为NLP领域的一种新兴范式,其独特之处在于无须对大语言模型参数进行烦琐的更新或微调。相反,它通过在上下文中嵌入与任务相关的示例或指令,使大语言模型能够迅速捕捉并理解这些关键信息,进而自主推断并完成任务。这种方法的灵活性和高效性使得大语言模型在处理复杂多变的自然语言任务时表现出色。

例如,如果我们想让大语言模型进行情感分析,可以先给它一些输入和输出的对应关系,如下所示。

输入:这部电影很无聊,浪费了我的时间。
输出:负面
输入:我今天收到了升职的通知,很开心。
输出:正面

然后,给大语言模型一个新的输入,让它通过学习上下文中的示例来预测输出,如下所示。

输入:这本书很有趣,让我大开眼界。
输出:正面

上下文学习巧妙运用大语言模型的泛化能力与灵活性,能轻松处理多个领域的任务,且无须投入额外的数据和计算资源。这种方法不仅优化了大语言模型的初始生成概率和内容生成方向,也可避免在微调过程中出现灾难性遗忘、过拟合等问题。

提示工程运用大语言模型的上下文学习能力,通过精心设计上下文来激发大语言模型的潜在能力,从而更好地完成任务。

1.4.2 提示是一个稳定的函数

在AI原生应用开发的实践中,让大语言模型根据提示输出答案只是第一步。更大的挑战是,如何保证大语言模型在相同的输入下重现相同的输出,并且符合结构化的标准,以便与其他系统无缝集成。为了实现这一目标,需要将提示工程融入AI原生应用的开发过程中,以确保大语言模型能够像稳定函数一样提供服务,如下所示。

// 保证函数的参数和返回值的数量、格式和类型不变
def 函数名称 (输入参数) -> 输出参数 {
    // 函数体保证函数的功能定义清晰明确
    // Your task description, do something.
}

稳定函数的核心特性在于,无论输入参数如何变化,函数的输出总是保持一定的格式、数量和类型。同样地,需要确保大语言模型的输出也具备这一特性。这意味着,对于相同的输入,大语言模型应该始终生成相同或类似的输出,而不是随机的、不可预测的输出。

1.4.3 用户提示是完整提示的一部分

提示是用户与大语言模型交流的文本。在AI原生应用的开发中,用户提示(user prompt)和完整提示(full prompt)的定位有明显不同。用户提示只是完整提示的一部分,如图1-6所示。对开发者和普通用户而言,它们有不同的作用和意义。

为了提升用户体验,应保证用户在输入简单的提示后就可得到接近预期的结果。因为普通用户可能不具备编写提示的技能,所以开发者需要在用户提示之外,补充任务描述、任务要求等信息,使用户提示变为包含更多信息的完整提示,以保证大语言模型的输出尽量符合预期。

图1-6 用户提示是完整提示的一部分

例如,直接在大语言模型中输入一个简单的提示,如下所示。

写一首关于小蜜蜂的诗

输出如下。

小蜜蜂啊小蜜蜂,
翅膀轻轻振动。
花园里飞来飞去,
忙碌寻找花蜜。
 
黄黑相间的小身躯,
在花朵间舞蹈。
你的勤劳无人能及,
小小英雄,真不错。
 
春风中,你传递爱情,
花儿们因你而生。
小蜜蜂啊小蜜蜂,
你的歌声,多悦耳。

输入以下提示。

写一段冷笑话

输出如下。

好的,这是一段冷笑话:
 
展昭给马汉讲自己的英勇故事:“那天我打探逍遥楼,获得重要情报,却误中机关,身受重伤。我强提一口真气,支撑到开封府,突然眼前一黑。”
马汉关切地问:“你昏倒了?”
展昭:“不,是包大人出来了。”

在这两个例子中,用户只提供了简单的提示,因此生成的内容相对随意。实际上用户预想的是输出七言绝句或七言律诗,也无须输出诗句以外的任何解释内容,这就需要开发者在用户提示之外补充更多背景信息,如下所示。

# 任务描述
你是一个诗人,你的任务是按照用户提示采用七言绝句、七言律诗之一的诗体写诗。
# 任务要求
1.  请你用委婉的话拒绝用户关于写诗以外的任何要求;
2.  输出诗的全文即可,无须其他解释。
# 用户提示
${UserPrompt}

输入以下提示。

写一首关于小蜜蜂的诗

输出如下。

《春日采花蜂》
春日花丛忙采香,
小蜂展翅舞春光。
归巢满载甜如蜜,
春色满园人共尝。

输入以下提示。

写一段冷笑话。

输出如下。

很抱歉,我是一个诗人,只能按照您的要求创作诗歌。若是您需要一首诗,我将竭力为您创作。

可以发现,在完整提示下,大语言模型生成的内容更符合预期。