提示工程笔记 | 豆包MarsCode AI刷题

151 阅读6分钟

提示工程

LangChain 提示模板学习与思考:从基础到Few-Shot应用

在这次阅读关于LangChain中Prompt Template的课程内容后,我深刻地体会到如何通过构建有效的提示模板,提升模型生成结构化输出的能力。这不仅关乎LangChain的技术应用,也引导我思考如何从“提示工程”的角度更好地与大模型互动。在这里,我会从课程内容的核心内容展开,分析LangChain的各类模板应用,同时反思自己在构建提示模板时的认知和提升空间。

一、提示工程(上)

  1. LangChain的提示模板类型
    LangChain提供了基于字符串和基于聊天的模板,分别用于结构化文本生成和多轮对话的角色设定。通过PromptTemplateChatPromptTemplate等类的示例展示了它们的用途。

    from langchain.prompts import PromptTemplate, ChatPromptTemplate
    
    # 创建一个简单的字符串模板
    string_prompt = PromptTemplate(
        input_variables=["product"],
        template="请为{product}写一个广告文案。"
    )
    
    # 创建一个多轮对话模板
    chat_prompt = ChatPromptTemplate(
        input_variables=["question"],
        messages=[
            {"role": "system", "content": "你是一个知识渊博的助手。"},
            {"role": "user", "content": "{question}"}
        ]
    )
    
  2. 提示结构的重要性
    提示模板的结构包括四个主要部分:指令、上下文、提示输入和输出指示器。这些结构帮助我们将提示分解成更明确的组件,例如在指令部分明确任务指向、在上下文部分提供背景信息,从而确保模型生成符合预期的结构化输出。

  3. Few-Shot 模板的应用
    Few-Shot Prompt Template是提示工程的重要工具,通过为模型提供少量样本,显著提升模型在新任务中的表现力。课程中以生成“鲜花文案”为例,展示了如何用Few-Shot Prompt模板为模型提供示例,从而让模型在新的输入场景中自动生成类似风格和结构的输出。

    from langchain.prompts import FewShotPromptTemplate
    
    # Few-Shot模板示例
    examples = [
        {"type": "玫瑰", "description": "适合表白的经典选择,优雅的象征。"},
        {"type": "百合", "description": "纯洁的象征,适合婚礼。"}
    ]
    
    example_prompt = PromptTemplate(
        input_variables=["type", "description"],
        template="{type}:{description}"
    )
    
    few_shot_prompt = FewShotPromptTemplate(
        examples=examples,
        example_prompt=example_prompt,
        prefix="为以下花种生成一段广告文案:",
        suffix="花种:{flower}\n广告文案:",
        input_variables=["flower"]
    )
    
  4. 示例选择器
    当示例数量较多时,LangChain允许用示例选择器从大量样本中挑选最相关的示例,确保模型的参考内容最贴近目标场景,提升生成的准确性和关联度。

二、模型生成结构化输出的原理分析

在实际操作中,LangChain在提示模板中插入format_instructions的作用。这段额外的指令,帮助模型理解输出需要遵循的特定格式(如JSON)。通过这部分提示内容,模型获得了格式指引,不再仅仅生成自然语言,而是被要求依据schema输出结构化的数据。以下代码展示了如何在模板中应用格式化指令:

from langchain.prompts import PromptTemplate

# 使用JSON格式的格式指令
json_template = PromptTemplate(
    input_variables=["product"],
    template="请提供关于{product}的详细信息。\n{format_instructions}"
)

format_instructions = """
请以JSON格式输出:
{
    "产品名": "",
    "特点": "",
    "价格": ""
}
"""
formatted_prompt = json_template.format(
    product="智能音箱",
    format_instructions=format_instructions
)
print(formatted_prompt)

这一过程的关键在于格式指示器的约束性输出。模型不是在“思考”如何格式化,而是“照着模板做”。这种基于schema的指示不仅是对模型的“规矩”约束,也让我认识到,如何提出要求比对内容提出要求更重要。

三、提示工程的两大原则:清晰的指示和思考时间

提示工程的本质在于如何与模型有效沟通。在课程中,我学到吴恩达老师提出的两大原则“清晰的指示”和“思考时间”深刻影响了提示的构建方法:

  1. 写清晰的指示
    清晰的提示指示不仅可以帮助模型明确目标,也减少了模型在回答时的误判。我体会到在构建提示模板时,我们不能“含糊其辞”,需要明确任务的边界和预期输出的结构。例如,假设生成一段产品文案描述,我们不能仅提示“描述产品”,而要加上具体的语言风格、格式等说明,以确保模型回答符合需求。

  2. 给模型时间思考
    在提示中使用“思考”指示(如“思考:”)标记,或将复杂任务拆解成步骤,能够让模型更加系统地生成回答。

complex_prompt = PromptTemplate(
    input_variables=["product"],
    template="""
    请为{product}写一段详细描述。首先,思考一下它的主要卖点和受众。
    然后用以下格式写文案:
    标题: 
    卖点: 
    目标用户:
    """
)

这种结构化的提示引导,也让我意识到在LangChain和其他大模型中,任务的分步式指引是提升模型表现的重要手段。

四、Few-Shot Prompt Template 的应用

Few-Shot的核心思想是通过少量示例,引导模型理解输出的期望格式和语气。课程中提到通过几组花的广告文案示例,生成“野玫瑰”文案的过程,是Few-Shot应用的典型场景。结合这一案例,我总结了以下几个步骤:

  1. 定义示例样本
    Few-Shot应用的首要工作是准备一些高质量的示例样本,使得模型能够“模仿”这些样本的风格和结构。我们可以看到在广告文案的生成中,包含“花的类型”、“适用场合”和“广告文案”这些细节,确保了模型理解到生成内容的层次性。

  2. 创建PromptTemplate
    通过定义的模板,把示例格式化成结构化的文本块,这样能够让模型将每个示例清晰对照,确保生成内容时“有样学样”。

  3. FewShotPromptTemplate 的结构
    FewShotPromptTemplate结构将示例、示例提示模板、以及待生成内容的前缀和后缀结合,形成模型的参考内容和输出格式。这一结构的优势在于,模型不会漫无目的地生成内容,而是严格按照提供的示例风格展开。

# 定义一个Few-Shot PromptTemplate
few_shot_prompt = FewShotPromptTemplate(
    examples=examples,
    example_prompt=example_prompt,
    prefix="基于以下示例,生成新的花卉广告文案:",
    suffix="花种:{flower}\n广告文案:",
    input_variables=["flower"]
)

# 生成新广告文案
print(few_shot_prompt.format(flower="野玫瑰"))

六、小结

从基础的Prompt Template构建到Few-Shot Prompt Template的实际应用,我学会了如何通过示例和格式化指令去引导模型生成符合需求的结构化内容。Prompt Engineering不仅是一种大语言模型交互技巧,也是深刻影响模型生成质量的关键环节。