提示工程
为什么要有提示工程?
- 为了让模型生成结构化的输出。
- 为了让模型更准确地理解任务要求,从而生成更准确的输出。
- 帮助模型生成与输入提示更相关的输出。
提示的结构
指令: 指令是提示工程的起点,它为用户或系统提供了一个明确的行动指南,告诉模型需要执行什么任务。在LangChain中,指令通常是通过提示模板(Prompt Template)来实现的。这些模板为用户提供了一组指令或输入,用于指导模型的响应。这些指令有助于模型理解上下文,并生成相关且连贯的基于语言的输出,例如回答问题、完成句子或参与某项活动、对话等。
上下文: 上下文是理解指令和提示输入所必需的信息背景。在LangChain中,上下文可以通过多种方式提供,例如直接在提示模板中嵌入相关信息,或者通过链式处理(Chains)等方式在模型调用前提供额外的上下文信息。上下文信息有助于模型更好地理解指令和提示输入,从而生成更准确的输出。
提示输入: 提示输入是用户或系统向模型提供的具体信息,用于触发模型的响应。在LangChain中,提示输入通常是通过动态填充提示模板中的占位符来实现的。这些占位符可以根据实际需求进行调整和变化,以适应不同的任务和应用场景。通过动态填充提示模板,用户可以灵活地构建各种提示输入,并将其传递给模型以获取所需的输出。
输出指示器: 输出指示器是标志着即将生成的文本的开头或格式的信息。在LangChain中,输出指示器可以通过在提示模板中指定特定的格式或标记来实现。例如,如果希望模型生成Python代码,可以使用“import”来告诉模型提示它必须开始编写Python代码。
LangChain 提示模板的类型
详细的使用方法可以参考langchain官方:prompts — 🦜🔗 LangChain documentation
示例选择器
如果我们的示例很多,那么一次性把所有示例发送给模型是不现实而且低效的。另外,每次都包含太多的Token也会浪费流量(OpenAI是按照Token数来收取费用)。
LangChain给我们提供了示例选择器,来选择最合适的样本。(注意,因为示例选择器使用向量相似度比较的功能,此处需要安装向量数据库,这里使用的是Chroma,你也可以选择Qdrant。)
from langchain.prompts.example_selector import SemanticSimilarityExampleSelector
from langchain.vectorstores import Chroma
from langchain.embeddings import OpenAIEmbeddings
# 初始化示例选择器
example_selector = SemanticSimilarityExampleSelector.from_examples(
samples,
OpenAIEmbeddings(),
Chroma,
k=1
)
# 创建一个使用示例选择器的FewShotPromptTemplate对象
prompt = FewShotPromptTemplate(
example_selector=example_selector,
example_prompt=prompt_sample,
suffix="鲜花类型: {flower_type}\n场合: {occasion}",
input_variables=["flower_type", "occasion"]
)
print(prompt.format(flower_type="红玫瑰", occasion="爱情"))
输出:
场合: 爱情
文案: 玫瑰,浪漫的象征,是你向心爱的人表达爱意的最佳选择。
鲜花类型: 红玫瑰
场合: 爱情
什么是 Chain of Thought
CoT这个概念来源于学术界,是谷歌大脑的Jason Wei等人于2022年在论文《Chain-of-Thought Prompting Elicits Reasoning in Large Language Models(自我一致性提升了语言模型中的思维链推理能力)》中提出来的概念。它提出,如果生成一系列的中间推理步骤,就能够显著提高大型语言模型进行复杂推理的能力。
Few-Shot Chain of Thought
Few-Shot Chain of Thought是指在提示中提供少量的示例(通常是几个相关的输入-输出对),以帮助模型更好地理解任务的目标和输出要求,并通过这些示例引导模型进行链式推理(即一步步地思考并给出答案)。
比如,假设我们正在开发一个AI花店助手,它的任务是帮助用户选择他们想要的花,并生成一个销售列表。在这个过程中,我们可以使用CoT来引导AI的推理过程。
整体指导:你需要跟着下面的步骤一步步的推理。
- 问题理解:首先,AI需要理解用户的需求。例如,用户可能会说:“今天要参加朋友的生日Party,想送束花祝福她。”我们可以给AI一个提示模板,里面包含示例:“遇到XX问题,我先看自己有 没有 *相关知识,有的话,就提供答案;没有,就调用工具搜索,有了知识后再试图解决。 *”—— 这就是给了AI一个思维链的示例。
- 信息搜索:接下来,AI需要搜索相关信息。例如,它可能需要查找哪些花最适合生日派对。
- 决策制定:基于收集到的信息,AI需要制定一个决策。我们可以通过思维链让他详细思考决策的流程,先做什么后做什么。例如,我们可以给它一个示例:“*遇到生日派对送花的情况,我先考虑用户的需求,然后查看鲜花的库存,最后决定推荐一些玫瑰和百合,因为这些花通常适合生日派对。 *”—— 那么有了生日派对这个场景做示例,大模型就能把类似的思维流程运用到其它场景。
- 生成销售列表:最后,AI使用OutputParser生成一个销售列表,包括推荐的花和价格。
在这个过程中,整体上,思维链引导AI从理解问题,到搜索信息,再到制定决策,最后生成销售列表。这种方法不仅使AI的推理过程更加清晰,也使得生成的销售列表更加符合用户的需求。具体到每一个步骤,也可以通过思维链来设计更为详细的提示模板,来引导模型每一步的思考都遵循清晰准确的逻辑。
Zero-Shot CoT
Zero-Shot Chain of Thought是指在没有任何相关示例的情况下,直接对模型进行提问,并在问题中提示模型进行链式推理(即一步步地思考并给出答案)。
图中的(d)示例,在Zero-Shot CoT中,你只要简单地告诉模型“让我们一步步的思考(Let's think step by step) ”,模型就能够给出更好的答案!
简单总结一下:Few-Shot CoT,指的就是在带有示例的提示过程中,加入思考的步骤,从而引导模型给出更好的结果。而Zero-Shot CoT,就是直接告诉模型要一步一步地思考,慢慢地推理。
Tree of Thought
CoT是为了让大模型输出更好的答案,而对于更复杂的问题,光是简单的提示技巧是不够的,于是就衍生出思维树(Tree of Thoughts,ToT)框架。
ToT是一种解决复杂问题的框架,它在需要多步骤推理的任务中,引导语言模型搜索一棵由连贯的语言序列(解决问题的中间步骤)组成的思维树,而不是简单地生成一个答案。ToT框架的核心思想是:让模型生成和评估其思维的能力,并将其与搜索算法(如广度优先搜索和深度优先搜索)结合起来,进行系统性地探索和验证。
通过在具体的步骤中产生多条思考路径,ToT 框架为解决复杂问题提供了一种新的方法,这种方法结合了语言模型的生成能力、搜索算法以及强化学习,以达到更好的效果。