引言
如今,提示词是与大语言模型(LLM)交互的主要方式。提示词需要根据用户需求进行调整,为大语言模型提供正确的上下文和指引,以最大程度提高获得 “正确” 响应的几率。
这促使提示词工程 [1] 作为一门专业学科兴起,提示词工程师系统地进行试验,记录他们的发现,以得出能引出 “最佳” 响应的 “正确” 提示词。然后,这些成功的提示词会以库的形式整理起来,以便能高效复用,这就是所谓的提示词库。
不幸的是,策划和维护高质量的提示词库仍然充满挑战。提示词库的首要目标是能够为给定任务检索到最优提示词,而无需重复整个实验过程。然而,由于提示词的重叠性,这种检索说起来容易做起来难。
问题陈述
让我们借助内容写作领域(如今生成式人工智能应用最广泛的领域之一)的几个提示词,来尝试理解提示词重叠的问题:
提示词1:为一篇宣布一家80年代主题咖啡馆开业的博客文章生成引人入胜的摘要。突出氛围和菜单。使用友好的语气吸引老年顾客群体。
提示词2:为一篇宣布一家现代主题咖啡馆开业的报纸文章生成不超过200字的引人入胜的摘要。突出装饰和菜单。使用友好的语气吸引年轻顾客群体。
假设这两个提示词都能生成经(人类)评审认可的 “良好” 响应(甚至不考虑基于 “大语言模型作为评判者” 的技术),那么问题就来了,该将哪个提示词添加到提示词库中呢?至少有以下四种选择:
- 两个都添加,但它们如此相似,在检索时会不会很难区分?
- 添加其中一个,但这样我们可能会丢失每个提示词特有的一些上下文,例如,两个提示词分别对应的报纸与博客文章、老年与年轻顾客群体等;以及响应过滤器,例如,像第二个提示词那样将响应限制在n个字以内。
- 都不添加,因为提示词库中可能已经存在涵盖类似范围的提示词。(同样的挑战也适用于大语言模型缓存。)
- 添加一个捕捉这两个提示词通用特征的模板,为特定变量设置占位符,并列出这些变量允许的值(术语表)。例如,涵盖上述提示词的通用提示词模板可能如下:
为关于以下事件的文章生成引人入胜的摘要。突出主题。使用指定的语气,并将响应限制在一定字数内。
文章类型:[报纸、博客、文章,…]
事件:[咖啡馆开业、餐厅开业、小餐馆开业,…]
主题:[氛围、装饰、菜单,…]
语气:[友好、正式、信息丰富,…]
这是推荐的方法,在下一节中,我们将展示像LangChain这样的框架如何使用提示词模板来组织提示词,以及它们支持的模板类型。
提示词模板
LangChain提供了以下预定义的提示词模板类 [2]:
- PromptTemplate是默认模板。
- ChatPromptTemplate用于对聊天消息进行建模。
- FewShotPromptTemplate用于应用少样本学习技术。
可以合并模板,例如,将ChatPromptTemplate与FewShotPromptTemplate合并,以适应具体的用例。
让我们从基本的PromptTemplate开始:
from langchain_core.prompts import PromptTemplate
prompt_template = PromptTemplate.from_template(
"Generate an engaging abstract for a {post} on the following {event}."
)
prompt_template.format(post="blog", event="opening of cafe")
它基本上适用于建模为带有变量(占位符)的字符串(句子)的提示词,就像我们在上一节中考虑的示例提示词那样。
如果你使用过早期的聊天机器人(ChatGPT之前),比如利用IBM Watson Assistant、AWS Lex、Google Dialogflow等,这些概念可能会让你联想到意图、话语和实体。这类引导式聊天机器人需要首先通过提供一组提示词、提示词变体及其相应的响应来进行训练。提示词可以分组为意图。提示词变体,在聊天机器人术语中称为话语,指的是不同用户可能提出相同提示词的示例变体。最后,实体指的是特定领域的术语表,基本上就是变量允许的值列表。
接下来,我们考虑ChatPromptTemplate,它允许对用户与人工智能系统之间的多步对话进行建模。可以指定用户、助手、系统等角色。允许的角色取决于底层大语言模型所允许的角色。例如,OpenAI Chat Completions API允许指定以下角色:人工智能助手、人类或系统。这些角色为对话提供了额外的上下文,并有助于大语言模型更深入地理解对话。
from langchain_core.prompts import ChatPromptTemplate
chat_template = ChatPromptTemplate.from_messages(
[
("system", "You are a knoweldgeable AI bot. You are called {name}."),
("human", "Hi, how are you today?"),
("ai", "I'm doing great, thanks! How can I help you?"),
("human", "{user_input}"),
]
)
messages = chat_template.format_messages(name="Emily",
user_input="How should I call you?")
最后,让我们考虑FewShotPromptTemplate类,它允许在提出实际问题之前,先在示例问答字典上对大语言模型进行训练,从而执行少样本学习。
from langchain_core.prompts.few_shot import FewShotPromptTemplate
from langchain_core.prompts.prompt import PromptTemplate
examples = [
{"question": "What is the second largest ocean on Earth?", "answer": "Atlantc Ocean"},
{"question": "What is the tallest mountain in Asia?", "answer": "Mount Everest"},
]
example_prompt = PromptTemplate(
input_variables=["question", "answer"], template="Question: {question}\n{answer}"
)
prompt = FewShotPromptTemplate(
examples=examples,
example_prompt=example_prompt,
suffix="Question: {input}",
input_variables=["input"],
)
print(prompt.format(input="What is the tallest mountain in Africa?"))
基于强化学习的提示词库整理
LangChain的提示词模板是将提示词模板化和组织起来的绝佳解决方案。然而,当处理拥有100多个提示词(模板)的企业提示词库时,很快就会发现手动管理它们极具挑战性。对于每个新的(已批准并推荐的)提示词:
- 提取提示词模板和实体值。
- 确定与现有提示词模板的重叠部分。
- 如果不存在涵盖该提示词的模板,则将该模板添加到提示词库中。
- 如果存在涵盖该提示词的模板,但覆盖率低于(某个阈值),比如70%,则可能需要根据缺失的实体和计数值来调整模板。
提示词库整理过程如下图所示:
例如,给定以下(现有)提示词模板:
为关于以下事件的文章生成引人入胜的摘要。突出主题。使用指定的语气。
文章类型:[报纸、博客、文章,…]
事件:[咖啡馆开业、餐厅开业、小餐馆开业,…]
主题:[氛围、菜单]
语气:[信息丰富、正式]
以及新的提示词:
为一篇宣布一家现代主题咖啡馆开业的报纸文章生成不超过200字的引人入胜的摘要。突出装饰和菜单。使用友好的语气吸引年轻顾客群体。
则需要通过添加(200字)字数限定符以及以下实体值来调整现有提示词模板:
主题:[氛围、装饰、菜单]
语气:[友好、信息丰富、正式]
接下来,我们概述一种基于用户反馈的强化学习方法,以实现提示词库整理的自动化。
强化学习模型并非旨在从头构建提示词库,而是利用带有用户反馈的提示词来实现提示词库整理的自动化。
我们方法的核心是一个评分模型,该模型经过训练,根据用户反馈对提示词 - 响应元组进行评分。此模型预测的分数用作强化学习智能体的奖励。由于有一个用户模拟器,策略学习可以离线进行,该模拟器输入从提示词库中的提示词模板实例化得到的提示词。策略学习使用带有ε - 贪婪探索的深度Q网络(DQN)智能体来实现,该智能体经过调整,能有效地为超出范围的提示词提供回退响应。
强化学习模型
强化学习模型架构如下图所示:
强化学习模型的关键组件包括:自然语言理解(NLU)单元,用于在预热阶段初步训练强化学习智能体;用户模拟器,从提示词数据库中随机提取候选提示词,以添加新的用例、场景等;根据用户对提示词的反馈进行训练的评分模型;以及基于深度Q网络(DQN)的强化学习智能体。
自然语言理解(NLU)
自然语言理解单元是一个意图识别自然语言理解模块,使用提示词库中现有的(已批准的)提示词模板进行训练。为简单起见,在这项工作中,我们仅考虑(来自LangChain的)基本PromptTemplate,并使用来自Rasa的开源自然语言理解模块以及TensorFlow管道。然而,强化学习方法与所选择的自然语言理解模块无关,并且可以轻松扩展到诸如Google DialogFlow、IBM Watson或Amazon LEX等自然语言理解引擎。
用户反馈
我们使用在实际内部聊天机器人开发过程中获得的用户反馈来开展工作。该聊天机器人的作用是回答员工有关办公设施、人力资源政策和福利等方面的问题。
参与反馈过程的所有十位用户都被告知,他们的反馈将用于提高提示词的质量。用户对提示词 - 响应元组提供二元反馈评级。因此,历史数据包含以下格式的四元组:(提示词、响应、自然语言理解置信度和用户反馈)。
强化学习奖励函数
评估自然语言理解性能是计算语言学中一个长期存在的问题。从机器翻译借鉴而来的评估指标 [4] 在短句子上表现不佳 [5],例如我们案例中的响应(模板)。另一方面,目前,对提示词 - 响应的用户(人工)评审被视为评估质量、准确性、可靠性等的事实上的标准,尽管这些评分往往难以收集且成本高昂。
为了以离线强化学习的方式应用用户反馈,我们使用了一个评分模型,该模型能够对新的(未见过的)提示词 - 响应元组的二元反馈进行建模。句子的向量表示使用通过TensorFlow Hub提供的通用句子编码器来计算。
在此基础上,评分模型学习将提示词和响应的向量表示投影到一个线性变换空间中,使得相似的向量表示获得高分。
为了训练强化学习奖励模型,通过带有L2正则化的均方误差(模型预测与人工反馈之间的误差)损失进行优化。为了评估模型,将预测分数转换为二元结果,并与目标(用户反馈)进行比较。对于那些具有已识别模板且同时获得正面反馈和自然语言理解置信度接近1的提示词对,我们进行数据增强,为提示词与回退意图的组合分配低分。
基于DQN的强化学习智能体策略学习
强化学习智能体使用带有DQN架构的Q学习算法来学习策略。我们遵循 [6] 中提出的方法,使用一个全连接网络,由一个经验回放池缓冲区提供输入,该缓冲区包含提示词和响应的独热编码表示以及相应的奖励。
在预热阶段,DQN使用自然语言理解置信度在自然语言理解模块上进行训练。每当状态 - 动作元组的置信度值高于某个阈值时,通过为给定状态和所有其他可用动作分配零权重来扩充DQN训练集。因此,在强化学习训练开始时,强化学习智能体的表现与自然语言理解单元类似。
在强化学习训练期间,我们使用ε - 贪婪探索,其中根据概率ε探索随机动作。我们使用随时间变化的ε,在训练开始时ε_t0 = 0.2,在最后一个epoch时ε_t = 0.05。
在一个epoch中,我们模拟一批大小为n - 个episode(在我们的实验中范围为10 - 30)的对话,并使用元组(s_t,a_t,r_t)填充经验回放缓冲区。缓冲区大小固定,当强化学习智能体的性能提高到指定阈值以上时,首次清空缓冲区。在那些状态 - 动作元组获得奖励大于50%的episode中,我们通过为当前状态分配任何其他动作时赋予零奖励来进行数据增强。
结论
在本文中,我们重点关注了构建企业提示词库所面临的挑战。不幸的是,由于提示词的重叠性,策划和维护提示词库仍然是一项具有挑战性的任务。基本上,对于每个新的候选提示词(要添加到提示词库中),我们需要回答以下问题:
- 我们应该直接将其添加到提示词库中吗?但这样提示词库的检索过程会变得复杂。
- 我们如何解决与提示词库中已有提示词的重叠 / 冲突问题?在这些情况下,我们如何调整现有提示词,以涵盖新候选提示词的范围?
我们详细讨论了这个问题,强调了一种以提示词模板的形式组织提示词的结构化方法。我们给出了LangChain支持的提示词模板类型的具体示例。最后,我们展示了如何使用基于用户反馈的强化学习来半自动化提示词库的整理过程。
展望未来,需要更好的工具和策略来解决提示词范围冲突,特别是在多领域提示词库的情况下,不同的用户群体(业务部门)对同一提示词的效用可能有不同的看法。
参考文献
- Open AI. Prompt Engineering. https://platform.openai.com/docs/guides/prompt-engineering
- LangChain. Prompt Templates Quick Reference. https://python.langchain.com/v0.1/docs/modules/model_io/prompts/quick_start/
- D. Biswas. Chatbots & Natural Language Search. In Towards Data Science, https://towardsdatascience.com/chatbots-natural-language-search-cc097f671b2b
- K. Papineni, et al. Bleu: A Method for Automatic Evaluation of Machine Translation. In 40th Annual Meeting on Association for Computational Linguistics, ACL ’02, pages 311–318, 2002. https://aclanthology.org/P02-1040.pdf
- R. Lowe, et al. Towards an Automatic Turing test: Learning to Evaluate Dialogue Responses. In 55th Annual Meeting of the ACL (Volume 1: Long Papers), pages 1116–1126. Association for Computational Linguistics, 2017. https://aclanthology.org/P17-1103.pdf
- X. Li, et al. End-to-end Task-completion Neural Dialogue Systems. In 8th International Joint Conference on Natural Language Processing, 2017. https://arxiv.org/abs/1703.01008