课程学习笔记:LangChain 提示工程与 Few-Shot 学习

2 阅读5分钟

课程学习笔记:LangChain 提示工程与 Few-Shot 学习

1. 课程背景

该课程章节聚焦于使用 PromptTemplateExampleSelector 实现少样本学习,通过少量的示例帮助模型生成符合特定需求的文案。这种少样本学习在电商、客户服务等行业中尤其实用。

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_formatvalidate_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)

思考题解答

  1. 探索 PromptTemplate 的其他参数

    • template_formatPromptTemplate 中的 template_format 参数决定了模板的解析方式,默认值为 f-string,另外还支持 jinja2 格式。在复杂的文本生成需求中,jinja2 模板的使用更为灵活,允许条件判断和循环等高级功能,适合多层次文本生成和逻辑较复杂的场景。

      优点jinja2 模板支持更复杂的逻辑控制,适用于动态内容较多的场景。
      缺点jinja2 模板相对复杂,可能会增加维护和调试的难度。

    • validate_templatevalidate_template 参数用于检查模板的有效性,如果启用,当模板包含未声明的变量或格式错误时将提示错误。这在调试和确保模板结构正确时非常有用,可以在生成前预防错误。

      优点:在开发阶段及时发现潜在问题,防止不合法的模板投入生产。
      缺点:会增加初始化的时间成本,但在生产环境下的影响通常可以忽略。

  2. 少样本学习的应用

    在鲜花店客服对话生成中,除了价格和推荐内容,还可以添加以下常见问题,丰富模型的应答能力:

    • 配送服务:如“请问可以配送到我家吗?费用是多少?”
    • 鲜花保养:如“我该如何保养这束花,能保持多久?”
    • 节日主题:如“有什么适合情人节送的花束推荐吗?”
    • 会员优惠:如“是否有会员优惠或者折扣?”
    • 包装定制:如“可以选择包装吗?有哪些款式?”

    设计合理示例的思路

    • 自然性:示例应尽量自然、真实,模拟客户的日常提问方式。
    • 多样性:提供不同风格、语气的示例,覆盖更多的问答情境。
    • 简洁性:保持示例的简洁明了,确保模型能抓住核心应答要点。

    示例

    examples = [
        {"role": "user", "content": "请问一束玫瑰花多少钱?"},
        {"role": "assistant", "content": "您好,一束玫瑰花的价格为 100 元。如需详细报价,请告知我们!"},
        {"role": "user", "content": "可以配送到我家吗?费用是多少?"},
        {"role": "assistant", "content": "我们提供配送服务,市内配送费用为 10 元,外地根据距离另行收费。"}
    ]
    
  3. PipelinePromptTemplate 的使用

    PipelinePromptTemplate 适合以下应用场景:

    • 多层次问题应答:例如,客服在回答价格问题后,可能进一步询问客户是否需要推荐或配送服务,可以分层引导用户获取更多信息。
    • 多变量场景的生成:如果场景涉及多个变量(如市场、产品、用户偏好等),PipelinePromptTemplate 能将不同变量在模板中层层处理,形成符合上下文的答案。

    应用分析: 假设用户需要设计一款针对节日的鲜花推荐生成器,可以通过 PipelinePromptTemplate 设置多个层次的 PromptTemplate,首先问询用户的需求(如节日类型),然后根据用户回复引导推荐合适的花束,最后再询问是否需要定制包装或配送。这种分层引导方式可以增强用户体验,让生成内容更符合客户需求。