课程学习笔记:LangChain 提示工程与 Few-Shot 学习
1. 课程背景
该课程章节聚焦于使用 PromptTemplate
和 ExampleSelector
实现少样本学习,通过少量的示例帮助模型生成符合特定需求的文案。这种少样本学习在电商、客户服务等行业中尤其实用。
2. 主要概念
- PromptTemplate:提供灵活的模板定义,通过插入不同的变量生成不同的文本。可通过
from_template
方法定义模板。 - PipelinePromptTemplate:允许将多个
PromptTemplate
组合起来形成更复杂的生成流程,适合多个变量和多步任务的情境。 - Few-Shot Learning:少样本学习,通过少量示例引导模型完成类似的任务,减少对大规模标注数据的依赖。
3. 课程代码解析
首先,我们使用 PromptTemplate
为一个电商公司起名,根据销售产品的不同,给出相应的推荐:
from langchain import PromptTemplate
# 定义简单的 PromptTemplate,生成销售“鲜花”电商的公司名称
template = """\
你是业务咨询顾问。
你给一个销售{product}的电商公司,起一个好的名字?
"""
prompt = PromptTemplate.from_template(template)
print(prompt.format(product="鲜花"))
# 针对不同市场和产品推荐公司名称
prompt = PromptTemplate(
input_variables=["product", "market"],
template="你是业务咨询顾问。对于一个面向{market}市场的,专注于销售{product}的公司,你会推荐哪个名字?",
)
print(prompt.format(product="鲜花", market="高端"))
在这里,我们创建了一个 PromptTemplate
并通过变量插入的方式生成不同情境下的公司名称推荐。
4. 思考与拓展
观察 PromptTemplate
其他参数
LangChain 的 PromptTemplate
中还包含 template_format
和 validate_template
等参数。
- template_format:默认为
f-string
,可以更改为jinja2
等其他格式。 - validate_template:设置是否对模板进行验证,确保其正确性。
使用示例
from langchain import PromptTemplate
# 使用 Jinja2 格式创建模板
prompt_jinja = PromptTemplate(
input_variables=["product"],
template="你是{{ market }}市场的顾问,专注于销售{{ product }}。推荐公司名称。",
template_format="jinja2",
validate_template=True
)
print(prompt_jinja.format(product="鲜花", market="高端"))
自定义场景:鲜花店少样本学习任务
在鲜花店运营中,客服需要回答客户的常见问题(如价格、推荐、保养等),通过少样本学习训练模型掌握这些常见问题的答案格式。
from langchain.chat_models import ChatOpenAI
from langchain.prompts.chat import (
ChatPromptTemplate,
SystemMessagePromptTemplate,
HumanMessagePromptTemplate,
AIMessagePromptTemplate
)
# 创建 Few-Shot 客服示例
examples = [
{
"role": "user",
"content": "请问一束玫瑰花多少钱?"
},
{
"role": "assistant",
"content": "您好,一束玫瑰花的价格为 100 元。如需详细报价,请告知我们!"
},
{
"role": "user",
"content": "有什么适合生日送的花束推荐吗?"
},
{
"role": "assistant",
"content": "我们推荐百合与康乃馨的组合,非常适合生日礼物,寓意长寿和幸福。"
}
]
# 系统、用户、AI回复模板
system_template = SystemMessagePromptTemplate.from_template("你是鲜花店客服助理。")
human_template = HumanMessagePromptTemplate.from_template("顾客问:{user_query}")
# 将模板组合为 PipelinePromptTemplate
pipeline_prompt = ChatPromptTemplate(
system=system_template,
human=human_template,
ai=AIMessagePromptTemplate.from_example(examples)
)
# 使用 ChatOpenAI 完成少样本任务
chat_model = ChatOpenAI(model="gpt-3.5-turbo")
response = chat_model(pipeline_prompt.format(user_query="请问这束花适合新年送礼吗?"))
print(response)
思考题解答
-
探索
PromptTemplate
的其他参数-
template_format:
PromptTemplate
中的template_format
参数决定了模板的解析方式,默认值为f-string
,另外还支持jinja2
格式。在复杂的文本生成需求中,jinja2
模板的使用更为灵活,允许条件判断和循环等高级功能,适合多层次文本生成和逻辑较复杂的场景。优点:
jinja2
模板支持更复杂的逻辑控制,适用于动态内容较多的场景。
缺点:jinja2
模板相对复杂,可能会增加维护和调试的难度。 -
validate_template:
validate_template
参数用于检查模板的有效性,如果启用,当模板包含未声明的变量或格式错误时将提示错误。这在调试和确保模板结构正确时非常有用,可以在生成前预防错误。优点:在开发阶段及时发现潜在问题,防止不合法的模板投入生产。
缺点:会增加初始化的时间成本,但在生产环境下的影响通常可以忽略。
-
-
少样本学习的应用
在鲜花店客服对话生成中,除了价格和推荐内容,还可以添加以下常见问题,丰富模型的应答能力:
- 配送服务:如“请问可以配送到我家吗?费用是多少?”
- 鲜花保养:如“我该如何保养这束花,能保持多久?”
- 节日主题:如“有什么适合情人节送的花束推荐吗?”
- 会员优惠:如“是否有会员优惠或者折扣?”
- 包装定制:如“可以选择包装吗?有哪些款式?”
设计合理示例的思路:
- 自然性:示例应尽量自然、真实,模拟客户的日常提问方式。
- 多样性:提供不同风格、语气的示例,覆盖更多的问答情境。
- 简洁性:保持示例的简洁明了,确保模型能抓住核心应答要点。
示例:
examples = [ {"role": "user", "content": "请问一束玫瑰花多少钱?"}, {"role": "assistant", "content": "您好,一束玫瑰花的价格为 100 元。如需详细报价,请告知我们!"}, {"role": "user", "content": "可以配送到我家吗?费用是多少?"}, {"role": "assistant", "content": "我们提供配送服务,市内配送费用为 10 元,外地根据距离另行收费。"} ]
-
PipelinePromptTemplate 的使用
PipelinePromptTemplate
适合以下应用场景:- 多层次问题应答:例如,客服在回答价格问题后,可能进一步询问客户是否需要推荐或配送服务,可以分层引导用户获取更多信息。
- 多变量场景的生成:如果场景涉及多个变量(如市场、产品、用户偏好等),
PipelinePromptTemplate
能将不同变量在模板中层层处理,形成符合上下文的答案。
应用分析: 假设用户需要设计一款针对节日的鲜花推荐生成器,可以通过
PipelinePromptTemplate
设置多个层次的PromptTemplate
,首先问询用户的需求(如节日类型),然后根据用户回复引导推荐合适的花束,最后再询问是否需要定制包装或配送。这种分层引导方式可以增强用户体验,让生成内容更符合客户需求。