提示工程(上)
这是一篇菜鸟的学习心得~
一、提示工程(上):用少样本FewShotTemplate和ExampleSelector创建应景文案
Q:为什么模型可以生成结构化的输出?
A:因为LangChain在输出解析器中加入 了{format_instructions} ,注明用户希望得到的回答以及回答的具体格式。提示指出,模型需要根据一个schema来格式化输出文本,schema 从 ```json 开始,到 ``` 结束。
- 写清晰的指示
- 给模型提供参考(也就是示例)
- 将复杂任务拆分成子任务
- 给GPT时间思考
- 使用外部工具
- 反复迭代问题
-
提示的结构:指令+上下文+提示输入+输出指示器
- 指令:定义任务要求和做法,如信息使用、查询处理和输出构造,常设为固定提示模板,如“你是XX助手”。
- 上下文:提供额外知识,可手动插入、数据库检索或API等方式获取,常用于传递向量数据库知识。
- 提示输入:是具体问题或任务,可与指令合并但独立更便于复用,作为变量传递给模板。
- 输出指示器:标记输出开始,如“解”或“import”引导,LangChain常用“Thought:”引导模型输出推理。
-
LangChain 提示模板的类型
String和Chat两种基本模型,采用“from…import…”导入。
1、PromptTemplate
from langchain import PromptTemplate
template = """\
你是业务咨询顾问。
你给一个销售{product}的电商公司,起一个好的名字?
"""
prompt = PromptTemplate.from_template(template)
print(prompt.format(product="鲜花"))
使用LangChain库中的PromptTemplate可生成适用于不同场景的提示。
通过定义一个包含占位符的原始提示模板,我们可以利用PromptTemplate的from_template方法创建一个提示模板对象。随后,通过调用该对象的format来替换模板中的占位符,从而生成一句具体的提示。
此外,也可以不使用from_template,可直接创建提示模板。
prompt = PromptTemplate(
input_variables=["product", "market"],
template="你是业务咨询顾问。对于一个面向{market}市场的,专注于销售{product}的公司,你会推荐哪个名字?"
)
print(prompt.format(product="鲜花", market="高端"))
-
ChatPromptTemplate
应用聊天模型时,注意需要导入openai、指定模型以及设置消息列表(角色role、内容content)。
其中,消息应以消息对象的数组形式呈现,每个对象均明确标注其角色(系统、用户或助理)并附带具体内容。
1、系统消息(非必要):可设定助手的行为模式和个性特征,给出在整个对话流程中助手应遵循的具体指引。
2、用户消息:承载着用户向助理提出的请求或发表的评论。
3、助理消息:既包含助手之前的回应记录,也允许工作人员根据需求编写示例,以展示期望的行为模式。
-
FewShot
1、三样本概念:
Zero-Shot Learning(零样本学习):
零样本学习是指模型在没有见过任何属于目标类别的训练样本的情况下,能够对新的、未见过的类别进行分类或生成。这通常依赖于模型对类别之间关系的理解,比如通过语义信息(如词嵌入)来推断未见类别的特征。例如,一个模型可能通过学习“狗”和“猫”的概念,以及它们与“动物”这一更广泛类别的关系,来识别一个新的、未见过的动物类别,如“狐狸”。
One-Shot Learning(单样本学习):
单样本学习是指模型在仅有一个训练样本的情况下,就能学会识别一个新的类别。这要求模型能够高效地利用有限的信息进行学习和泛化。在单样本学习中,模型通常依赖于强大的先验知识或特征表示,以便从单个示例中提取足够的信息来识别新类别。例如,给定一张“熊猫”的照片,模型应该能够学会识别所有未来的“熊猫”图片,即使它只见过这一张。
Few-Shot Learning(少样本学习):
少样本学习是指模型在只有极少数训练样本(通常少于20个)的情况下,就能有效地学习并识别新的类别。少样本学习旨在解决数据稀缺的问题,通过利用迁移学习、元学习等技术,使模型能够从少量的数据中快速适应并泛化到新的任务上。例如,给定几张不同角度和光照条件下的“长颈鹿”照片,模型应该能够学会识别所有类似的“长颈鹿”图片,即使它只见过这几张。
在提示工程中,一般采用少样本学习和零样本学习。少样本,即模型被给予几个示例,用以理解任务,并生成正确的响应;零样本,即模型只根据任务的描述生成响应,不需要任何实例。
2、使用 FewShotPromptTemplate
(1)创建示例样本
设置sample列表,创建字典作为示例。
(2)创建提示模板
使用前述的PromptTemplate模块。
# 2. 创建一个提示模板
from langchain.prompts.prompt import PromptTemplate
template="鲜花类型: {flower_type}\n场合: {occasion}\n文案: {ad_copy}"
prompt_sample = PromptTemplate(input_variables=["flower_type", "occasion", "ad_copy"], template=template)
print(prompt_sample.format(**samples[0]))
(3)创建 FewShotPromptTemplate 对象
(4)调用大模型创建新文案
调用模型,并将format输入可得到文案。
3、使用示例选择器:适用于exampl较多的情况,可提高效率
# 初始化示例选择器
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="爱情"))
首先,该过程初始化了一个名为SemanticSimilarityExampleSelector的对象,此对象具备根据语义相似度挑选最贴切示例的功能。同时,构建了一个新的FewShotPromptTemplate对象,该对象巧妙地运用了之前创建的选择器,以挑选出的最相关示例为基础来生成提示。
针对特定需求——即创作关于红玫瑰的文案,prompt生成了一个新的提示。在这个过程中,示例选择器example_selector会依据语义的相似程度(具体采用余弦相似度作为衡量标准)来锁定与“红玫瑰”最为接近的示例,也就是“玫瑰”。之后,便利用这个高度相关的示例来构建FewShot模板。
💡 运行问题run之后提示错误:
原因:
protobuf 库版本不兼容。具体来说,protobuf 的版本过高,导致在创建描述符时出错,或者是.proto 文件已经过时。
解决方式:
在调试控制台中输入
export PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python
即编译仅使用纯 Python 来实现。
运行结果: