提示词追加示例(Few-shot prompt templates)
提示词中包含交互样本的作用是为了帮助模型更好地理解用户的意图,从而更好地回答问题或执行任务。小样本提示模板是指使用一组少量的示例来指导模型处理新的输入。这些示例可以用来训练模型,以便模型可以更好地理解和回答类似的问题。
例子:
Q: 什么是蝙蝠侠?
A: 蝙蝠侠是一个虚构的漫画人物。
Q: 什么是torsalplexity?
A: 未知。
Q: 什么是语言模型?
A:
告诉模型根据,Q是问题,A是答案,按这种格式进行问答交互。
下面讲解的就是Lanchain针对在提示词中插入少量交互样本提供的工具类。
使用示例集
创建示例集
下面定义一个examples示例数组,里面包含一组问答样例。
from langchain.prompts.few_shot import FewShotPromptTemplate
from langchain.prompts.prompt import PromptTemplate
examples = [
{
"question": "谁的寿命更长,穆罕默德·阿里还是艾伦·图灵?",
"answer":
"""
这里需要跟进问题吗:是的。
跟进:穆罕默德·阿里去世时多大?
中间答案:穆罕默德·阿里去世时74岁。
跟进:艾伦·图灵去世时多大?
中间答案:艾伦·图灵去世时41岁。
所以最终答案是:穆罕默德·阿里
"""
},
{
"question": "craigslist的创始人是什么时候出生的?",
"answer":
"""
这里需要跟进问题吗:是的。
跟进:craigslist的创始人是谁?
中间答案:craigslist由Craig Newmark创立。
跟进:Craig Newmark是什么时候出生的?
中间答案:Craig Newmark于1952年12月6日出生。
所以最终答案是:1952年12月6日
"""
},
{
"question": "乔治·华盛顿的祖父母中的母亲是谁?",
"answer":
"""
这里需要跟进问题吗:是的。
跟进:乔治·华盛顿的母亲是谁?
中间答案:乔治·华盛顿的母亲是Mary Ball Washington。
跟进:Mary Ball Washington的父亲是谁?
中间答案:Mary Ball Washington的父亲是Joseph Ball。
所以最终答案是:Joseph Ball
"""
},
{
"question": "《大白鲨》和《皇家赌场》的导演都来自同一个国家吗?",
"answer":
"""
这里需要跟进问题吗:是的。
跟进:《大白鲨》的导演是谁?
中间答案:《大白鲨》的导演是Steven Spielberg。
跟进:Steven Spielberg来自哪里?
中间答案:美国。
跟进:《皇家赌场》的导演是谁?
中间答案:《皇家赌场》的导演是Martin Campbell。
跟进:Martin Campbell来自哪里?
中间答案:新西兰。
所以最终答案是:不是
"""
}
]
创建小样本示例的格式化程序
通过PromptTemplate
对象,简单的在提示词模板中插入样例。
example_prompt = PromptTemplate(input_variables=["question", "answer"], template="问题:{question}\\n{answer}")
# 提取examples示例集合的一个示例的内容,用于格式化模板内容
print(example_prompt.format(**examples[0]))
返回:
问题:谁的寿命更长,穆罕默德·阿里还是艾伦·图灵?
这里需要跟进问题吗:是的。
跟进:穆罕默德·阿里去世时多大?
中间答案:穆罕默德·阿里去世时74岁。
跟进:艾伦·图灵去世时多大?
中间答案:艾伦·图灵去世时41岁。
所以最终答案是:穆罕默德·阿里
将示例和格式化程序提供给FewShotPromptTemplate
通过FewShotPromptTemplate
对象,批量插入示例内容。
# 接收examples示例数组参数,通过example_prompt提示词模板批量渲染示例内容
# suffix和input_variables参数用于在提示词模板最后追加内容, input_variables用于定义suffix中包含的模板参数
prompt = FewShotPromptTemplate(
examples=examples,
example_prompt=example_prompt,
suffix="问题:{input}",
input_variables=["input"]
)
print(prompt.format(input="乔治·华盛顿的父亲是谁?"))
返回:
问题:谁的寿命更长,穆罕默德·阿里还是艾伦·图灵?
这里需要跟进问题吗:是的。
跟进:穆罕默德·阿里去世时多大?
中间答案:穆罕默德·阿里去世时74岁。
跟进:艾伦·图灵去世时多大?
中间答案:艾伦·图灵去世时41岁。
所以最终答案是:穆罕默德·阿里
问题:craigslist的创始人是什么时候出生的?
这里需要跟进问题吗:是的。
跟进:craigslist的创始人是谁?
中间答案:craigslist由Craig Newmark创立。
跟进:Craig Newmark是什么时候出生的?
中间答案:Craig Newmark于1952年12月6日出生。
所以最终答案是:1952年12月6日
问题:乔治·华盛顿的祖父母中的母亲是谁?
这里需要跟进问题吗:是的。
跟进:乔治·华盛顿的母亲是谁?
中间答案:乔治·华盛顿的母亲是Mary Ball Washington。
跟进:Mary Ball Washington的父亲是谁?
中间答案:Mary Ball Washington的父亲是Joseph Ball。
所以最终答案是:Joseph Ball
问题:《大白鲨》和《皇家赌场》的导演都来自同一个国家吗?
这里需要跟进问题吗:是的。
跟进:《大白鲨》的导演是谁?
中间答案:《大白鲨》的导演是Steven Spielberg。
跟进:Steven Spielberg来自哪里?
中间答案:美国。
跟进:《皇家赌场》的导演是谁?
中间答案:《皇家赌场》的导演是Martin Campbell。
跟进:Martin Campbell来自哪里?
中间答案:新西兰。
所以最终答案是:不是
问题:乔治·华盛顿的父亲是谁?
使用示例选择器
将示例提供给ExampleSelector
这里重用前一部分中的示例集和提示词模板(prompt template)。但是,不会将示例直接提供给FewShotPromptTemplate
对象,把全部示例插入到提示词中,而是将它们提供给一个ExampleSelector
对象,插入部分示例。
这里我们使用SemanticSimilarityExampleSelector
类。该类根据与输入的相似性选择小样本示例。它使用嵌入模型计算输入和小样本示例之间的相似性,然后使用向量数据库执行相似搜索,获取跟输入相似的示例。
- 提示:这里涉及向量计算、向量数据库,在AI领域这两个主要用于数据相似度搜索,例如:查询相似文章内容、相似的图片、视频等等,这里先简单了解下就行。
from langchain.prompts.example_selector import SemanticSimilarityExampleSelector
from langchain_community.vectorstores import Chroma
from langchain_openai import OpenAIEmbeddings
example_selector = SemanticSimilarityExampleSelector.from_examples(
# 这是可供选择的示例列表。
examples,
# 这是用于生成嵌入的嵌入类,该嵌入用于衡量语义相似性。
OpenAIEmbeddings(),
# 这是用于存储嵌入和执行相似性搜索的VectorStore类。
Chroma,
# 这是要生成的示例数。
k=1
)
# 选择与输入最相似的示例。
question = "乔治·华盛顿的父亲是谁?"
selected_examples = example_selector.select_examples({"question": question})
print(f"最相似的示例:{question}")
for example in selected_examples:
print("\\n")
for k, v in example.items():
print(f"{k}:{v}")
这里匹配了跟问题相似的例子,下面是返回:
使用本地API直接运行Chroma。
使用DuckDB内存中的数据库。数据将是短暂的。
最相似的示例:乔治·华盛顿的父亲是谁?
question:乔治·华盛顿的祖父母中的母亲是谁?
answer:
这里需要跟进问题吗:是的。
跟进:乔治·华盛顿的母亲是谁?
中间答案:乔治·华盛顿的母亲是Mary Ball Washington。
跟进:Mary Ball Washington的父亲是谁?
中间答案:Mary Ball Washington的父亲是Joseph Ball。
所以最终答案是:Joseph Ball
将示例选择器提供给FewShotPromptTemplate
最后,创建一个FewShotPromptTemplate
对象。根据前面的example_selector示例选择器,选择一个跟问题相似的例子。
prompt = FewShotPromptTemplate(
example_selector=example_selector,
example_prompt=example_prompt,
suffix="问题:{input}",
input_variables=["input"]
)
print(prompt.format(input="乔治·华盛顿的父亲是谁?"))
返回:
问题:乔治·华盛顿的祖父母中的母亲是谁?
这里需要跟进问题吗:是的。
跟进:乔治·华盛顿的母亲是谁?
中间答案:乔治·华盛顿的母亲是Mary Ball Washington。
跟进:Mary Ball Washington的父亲是谁?
中间答案:Mary Ball Washington的父亲是Joseph Ball。
所以最终答案是:Joseph Ball
问题:乔治·华盛顿的父亲是谁?