少样本提示词模板
文章目录
- 少样本提示词模板
少样本提示词模板
少样本提示是一种基于机器学习的技术,利用少量的样本(即提示词的示例部分)来引导模型对特定任务进行学习和执行。这些示例能让模型理解开发者期望它完成的任务的类型和风格。在给定的任务中,这些提示通常包含问题(或任务描述)及相应的答案或解决方案。例如,如果希望一个大语言模型能够以某种特定的风格来回答用户的问题,那么可以给模型提供几个已经按照这种风格编写好的问题和答案对。这样,模型就能通过这些示例来理解期望的回答风格,并在处理新的用户问题时尽可能地模仿这种风格。
OpenAI的文档中也强调了这种技术的重要性。文档指出,尽管通常情况下,为所有示例提供适用的一般性指令比示例化所有任务更为高效,但在某些情况下,提供示例可能更为简单,尤其是当你想让模型复制一种难以明确描述的特定响应风格时。
在这种情况下,“少样本提示”能够通过少量的示例,帮助模型理解并复制这种特定的响应风格,从而大大提高模型的使用效率和效果。FewShotPromptTemplate类与PromptTemplate。FewShotPromptTemplate是LangChain内置的一个少样本提示词模板类,其独特之处在于支持动态添加示例和选择示例。这样,示例在提示词中就不再是固定的,而是可以动态变化的,能够适应不同的需求。这符合OpenAI文档中的建议,LangChain也认为这个内置模板是必须有的,它可以为开发者节约大量的时间。另外,LangChain还封装了示例选择器,以支持这种模板的动态化。
通过观察FewShotPromptTemplate类的源码,可以看到它如何实现这种动态化。这个类继承自PromptTemplate类,它的实例化方法和PromptTemplate类完全一样。然而,FewShotPromptTemplate类在参数上多了一些内容,例如examples(示例)和example_selector(示例选择器),这些参数可以在实例化模板对象时添加示例,或者在运行时动态选择示例。
即使这个类中添加了一些新的特性,但它的使用方式仍然和PromptTemplate类一样。如果你想要在链组件上使用它,那么只需要像使用PromptTemplate类一样使用即可。实际上,FewShotPromptTemplate类只是给实例化模板对象添加了更多的外部数据,即示例,并没有改变使用方式。
如果你想引导模型得到更好的结果,可以更多地使用FewShotPromptTemplate类,因为它在PromptTemplate类的基础上添加了示例功能。正如前面所说的,添加示例的提示词会引导模型生成更准确的回答。PromptTemplate类和FewShotPromptTemplate类都是LangChain的内置提示词模板类,但它们有一些重要的区别。
PromptTemplate类是一种基本的提示词模板,它接收一个包含变量的模板字符串和一个列表,示例如下:
example_prompt=PromptTemplate (input_variables=["input","output"],
template="""
词语:{input)n
反义词:{output)\n"""
template是一个包含两个变量{input}和{output}的模板字符串,而input_variables是一个包含这两个变量名的列表。PromptTemplate对象可以用来生成提示词,例如通过调用example_prompt..format(nput="好",output=-"坏")
可以生成提示词“n词语:好反义词:坏”。
FewShotPromptTemplate类提供了更高级的功能,不仅继承了PromptTemplate类的所有属性和方法,还添加了一些新的参数来支持少样本示例:
few_shot_prompt = FewShotPromptTemplate(
examples=examples,
example_prompt=example_prompt,
example separator="\n",
prefix="来玩个反义词接龙游戏,我说词语,你说它的反义词\n",
suffix="词语:(input)\n反义词:",
input variables=["input"],)
在这个示例中,examples是示例列表,example prompt是用于格式化列表中示例的PromptTemplate对象。而prefix和suffix则构成了用于生成最终提示词的模板,其中suffix还接收用户的输人。这种设计使得FewShotPromptTemplate类可以在给出指导和接收用户输人的同时,还能展示一系列的示例。可以看到,FewShotPromptTemplate类的prefix和suffix参数的组合实际上等价于PromptTemplate类的template参数,因此它们的目的和作用是一样的。然而,FewShotPromptTemplate类提供了更高的灵活性,因为它允许在提示词中添加示例。
这些示例可以是硬编码在模板中的,也可以是动态选择的,具体取决于是否提供了ExampleSelector对象。总的来说,FewShotPromptTemplate类是PromptTemplate类的扩展,它在保留了PromptTemplate类所有功能的同时,还提供了对少样本示例的支持,可以更方便地使用少样本提示技术,而这种技术已经被证明能够改善模型的性能。少样本提示词模板的使用要想使用少样本提示词模板,首先需要了解新参数。在FewShotPromptTemplate类中,参数example_selector、example_prompt、prefix和suffix具有以下含义和使用方式。
example_selector是一个ExampleSelector对象,用于选择要被格式化的示例(这些示例被嵌入提示词)。如果你想让模型基于一组示例来生成响应,那么你可以提供一个ExampleSelector对象,该对象会根据某种策略(例如随机选择、基于某种标准选择等)从一组示例中选择一部分。如果没有提供ExampleSelector对象,那么你应该直接提供一个示例列表(通过examples参数)。example_selector是必填参数。
example prompt是一个PromptTemplate对象,用于格式化单个示例。当你提供了一组示例(无论是直接提供示例列表,还是提供ExampleSelector对象)后,FewShotPromptTemplate类会通过example_prompt来格式化这些示例,生成最终的提示词。example_prompt是必填参数。前面说过,prefix和suffix参数的组合实际上等价于PromptTemplate类的template参数,因此它们的目的和作用是一样的。其中sux参数是必填的。下面我们编写一个包含正反义词的示例列表,少样本提示词模板需要传人的examples参数的格式如下:
examples
("input":"高","output":"矮"),
("input":"胖","output":"瘦"),
("input":"精力充沛","output":"菱靡不振"},
("input":"快乐","output":"伤心"),
("input":"黑","output":"白"},
假设现在的任务是让模型进行反义词接龙游戏。在这个任务中,给模型一个词,然后期望模型返回这个词的反义词。我们需要提供一些示例,例如“高”的反义词是“矮”,“胖”的反义词是“瘦”,以此类推。像构造提示词模板对象一样,构造个普通的PromptTemplate对象,用于格式化单个示例:
example_prompt=PromptTemplate (input variables=["input","output"],
template="""
词语:{input}\n
反义词:{output}\n"""
调用format方法,填入input和output参数:example_prompt.format (**examples [0])
#打印的结果:\n词语:高\n\n反义词:矮n\n。当你写example_prompt…format(*examples[O])时,*examples[0]会将第一个字典的键值对解开,作为关键字参数传递给format方法,等价于example prompt.format(input仁"高",output=-"矮")
,然后通过实例化FewShotPromptTemplate类来设置提示词
模板:
few_shot_prompt =FewshotPromptTemplate(
examples=examples,
example_prompt=example_prompt,
example_separator="\n",)
prefix="来玩个反义词接龙游戏,我说词语,你说它的反义词n",
suffix="现在轮到你了,词语:{input)\n反义词:",
input variables=["input"],
few_shot prompt.format (input="")
需要为模型设置一些标准的示例(examples),以帮助模型理解任务需求。接下来,实例化一个FewShotPromptTemplate类,然后传人示例。example_prompt是一个PromptTemplate对象,用于格式化单个示例。还要设置一个前缀(prefix=“来玩个反义词游戏,我说词语,你说它的反义词n”)和一个后缀(suffix-=“词语:{input}n反义词:”)),这样可以帮助构造一个结构清晰的提示词文本:·来玩个反义词接龙游戏,我说词语,你说它的反义词
词语:高
反义词:矮
词语:胖
反义词:瘦
词语:精力充沛
反义词:萎靡不振
词语:快乐
反义词:伤心
词语:黑
反义词:白
可以看到,上述示例仍然使用FewShotPromptTemplate类的函数式调用方法来实例化对象。运行代码,看看模型能否正确地生成期望的结果。例如,如果输人“冷”,模型就应该返回“热”,这就是我们期望看到的结果。
from langchain.11ms import OpenAI
from langchain.chains import LLMChain
chain=LLMChain(llm=OpenAI(openai_api_key="这里填入OpenAI的密钥"),
prompt=few_shot_prompt)
chain.run("冷")
这段代码中首先实例化了一个LLMChain对象。这个对象是LangChain库中的个核心组件,可以理解为一个执行链,它将各个步骤连接在一起,形成一个完整的运行流程。LLMChain对象在实例化时需要两个关键参数:一个是llm,这里使用了OpenAI提供的大语言模型;另一个是prompt,这里传人的是刚刚创建的few_shotprompt对象。
然后通过调用LLMChain对象的run方法来运行执行链。这个方法中传人了一个字符串“冷”,这个字符串将作为输人传递给few _shot prompt.对象。最后,模型返回了“热”,这就是我们期望看到的反义词。热示例选择器实际应用开发中面临的情况常常很复杂,例如,可能需要将一篇新闻摘要作为示例加人提示词。更具挑战性的是,还可能需要在提示词中加入大量的历史聊天记录或从外部知识库获取的数据。然而,大型语言模型可以处理的字数是有限的。如果提供的每个示例都是一篇新闻摘要,那么很可能会超过模型能够处理的字数上限。
为了解决这个问题,LangChain在FewShotPromptTemplate类上设计了示例选择器((Example Selector)参数。示例选择器的作用是在传递给模型的示例中进行选择,以确保示例的数量和内容长度不会超过模型的处理能力。这样,即使有大量的示例,模型也能够有效地处理提示词,而不会因为示例过多或内容过长而无法处理。而且,尝试适应所有示例可能会非常昂贵,尤其是在计算资源和时间上。
这就是示例选择器能发挥作用的地方,它帮助选择最适合的示例来提示模型。示例选择器提供了一套工具,这些工具能基于策略选择合适的示例,如根据示例长度、输入与示例之间的n-gram重叠度来评估其相似度并打分,找到与输入具有最大余弦相似度的示例,或者通过多样性等因素来选择示例,从而保持提示成本的相对稳定。
根据长度选择示例是很普遍和现实的需求,下面我们介绍具体方法。少样本提示词模板的示例代码里没有提供示例选择器对象,而是通过examples参数直接提供了一个示例列表。本节示例提供ExampleSelector参数,使用示例选择器,选择根据长度选择示例的LengthBasedExampleSelector类,其他几种策略工具类LangChain都设计好了,开发者可以直接导人使用。本节示例首先导人LangChain的LengthBasedExampleSelector类,其他均重复少样本提示词模板的代码。
LengthBasedExampleSelector类是一个示例选择器,用于根据指定的长度选择示例。
from langchain.prompts.example_selector import LengthBasedExampleSelector
然后实例化一个LengthBasedExampleSelector对象,传人之前定义的示例列表(examples)和示例提示词模板(example_prompt),并设置最大长度(max_length)为25。这意味着示例选择器将选择那些长度不超过25的示例。
example_selector =LengthBasedExampleSelector
examples=examples,
example_prompt=example_prompt,
max_length=25,)
接着创建一个FewShotPromptTemplate对象,传人新创建的示例选择器参数(example_selector)及其他参数,根据选择器所选择的示例来生成提示词:
example_selector_prompt= FewShotPromptTemplate(
example_selector=example_selector,
example_prompt=example_prompt,
example_separator="\n",)
prefix=-"来玩个反义词接龙游戏,我说词语,你说它的反义词n",
suffix="现在轮到你了,词语:(input)\n反义词:",
input variables=["input"],
example_selector_prompt.format (input="")
当调用example_selector_prompt.format(input=-"好")
程序将根据input值和示例选择器来生成一个提示词:来玩个反义词接龙游戏,我说词语,你说它的反义词小n\n\n词语:高\n\n反义词:矮\n\nn\n词语:胖n\n反义词:瘦\nn\n现在轮到你了,词语:好n反义词:坏在结果中,我们发现并不是所有的示例都出现在了生成的提示词中,这是因为设置的最大长度为“25”,一些过长的示例被选择器过滤掉了。此时将最大长度参数改
为“100”(max_length-=l00):
example selector =LengthBasedExampleSelector(
examples=examples,
example_prompt=example_prompt,
max1 ength=100,#将最大长度由25修改为100)
所有的示例都将被选择,因为所有示例的长度都不超过“100”,结果如下:
[('input':'高','output':'矮},('input':'胖','output':'瘦'},('input':
'精力充沛','output':'菱靡不振'),('input':'快乐','output':伤心'},('input':
'黑',output':'白')]
这段代码展示了如何使用基于长度的示例选择器(LengthBasedExampleSelector)和少样本提示词模板(FewShotPromptTemplate)来创建复杂的提示词。这种方法可以有效地管理复杂的示例集,确保生成的提示词不会因过长而被截断。示例选择器是一种用于选择需要在提示词中包含什么示例的工具。LangChain中提供了多种示例选择器,分别实现了不同的选择策略。
- 基于长度的示例选择器(LengthBasedExampleSelector):根据示例的长度来选择示例。这在担心提示词长度可能超过模型处理窗口长度时非常有用。对于较长的输人,它会选择较少的示例,而对于较短的输入,它会选择更多的示例。
- 最大边际相关性选择器(MaxMarginalRelevanceExampleSelector):根据示例与输入的相似度及示例之间的多样性来选择示例。通过找到与输人最相似(即嵌入向量的余弦相似度最大)的示例来迭代添加示例,同时对已选择的示例进行惩罚。
- 基于n-gram重叠度的选择器(NGramOverlapExampleSelector):根据示例与输人的n-gram重叠度来选择和排序示例。n-gram重叠度是一个介于0.0和1.0之间的浮点数。该选择器还允许设置一个阈值,重叠度低于或等于阈值的示例将被剔除。
- 基于相似度的选择器(SemanticSimilarityExampleSelector):根据示例与输人的相似度来选择示例,通过找到与输人最相似(即嵌人向量的余弦相似度最大)的示例来实现。
LangChain设计示例选择器的目的是帮助开发者在面对大量示例时能够有效地选择最适合当前输入的示例,以提升模型的性能和效率。对于上述示例选择器,它们实例化参数的方式的确有所不同,但都需要向其中传人基础的参数,如examples和example_prompt。根据示例选择器的不同,还有一些额外的参数需要设置。对于LengthBasedExampleSelector,除了examples和example_prompt,还需要传入max_length参数来设置示例的最大长度:
example selector LengthBasedExampleSelector(
examples=examples,
example_prompt=example_prompt,
max_length=25,)
对于MaxMarginalRelevanceExampleSelector,除了examples,还需要传入一个用于生成语义相似性测量的嵌人类(OpenAIEmbeddings(),一个用于存储嵌入类和执行相似性搜索的VectorStore类(FAISS),并设置需要生成的示例数量(k=2):
example_selector =MaxMarginalRelevanceExampleSelector.from examples(
examples,
OpenAIEmbeddings ()
FAISS,
k=2,)
对于NGramOverlapExampleSelector,除了examples和example_prompt,还要传人一个threshold参数用于设定示例选择器的停止阈值:
example_selector =NGramOverlapExampleSelector(
examples=examples,
example_prompt=example_prompt,
threshold=-1.0,)
对于SemanticSimilarityExampleSelector,.除了examples,还需要传人一个用于生成语义相似性测量的嵌人类(OpenAIEmbeddings()),一个用于存储嵌人类和执行相似性搜索的VectorStore类(Chroma或其他VectorStore类均可),并设置需要生成的示例数量(k=1)。
example selector= SemanticsimilarityExampleSelector.from examples(
examples,
OpenAIEmbeddings ()
Chroma,
k=1)
每种示例选择器都有其独特的参数设置方案,以满足不同的示例选择需求。参数设置虽然不一样,但是使用方式基本一致:实例化后,通过example_selector参数传递给FewShotPromptTemplate类。应该注意的是,每一种示例选择器都可以通过函数方式来实例化,或者使用类方法from_examples来实例化。比如MaxMarginalRelevanceExampleSelector类使用类方法from_examples来实例化,而LengthBasedExampleSelector类则使用函数方式实例化。