目录

一、什么是 Few-Shot 提示?

1.1 从 “零样本” 到 “少样本”

1.2 Few-Shot 能解决什么问题?

二、在 LangChain 中实现 Few-Shot 提示

2.1 核心组件一:FewShotChatMessagePromptTemplate(聊天场景)

核心参数与方法

实战代码:数学符号语义推理

2.2 核心组件二:FewShotPromptTemplate(文本提示场景)

三、实战案例:Few-Shot 的两大核心应用场景

3.1 案例一:推理引导 —— 让模型 “有逻辑地思考”

步骤 1:定义示例与提示模板

步骤 2:执行推理并验证结果

3.2 案例二:结构化信息提取 —— 从文本到标准化数据

完整实战流程

第一步:定义结构化返回模型(Pydantic)

第二步:构建 Few-Shot 示例集(覆盖多场景)

第三步:构造提示模板与示例消息

第四步:初始化模型并执行结构化提取

总结


在与大语言模型(LLM)交互时,我们常常希望它能以特定格式、逻辑或风格输出结果。Few-Shot 提示(少样本提示) 正是解决这一问题的关键技术。它通过向模型提供少量高质量的示例,引导其理解任务规则,从而在新的、未见过的输入上也能做出精准响应。本文将带你深入理解 Few-Shot 的核心概念,并通过 LangChain 框架,从理论到实战,一步步掌握这项强大的提示工程技术,还会延伸讲解示例选择的进阶策略,让你的提示工程更高效。


一、什么是 Few-Shot 提示?

Few-Shot 提示,即 “少样本提示”,是一种通过向 LLM 提供少量具体示例或样本,教会它如何执行某项特定任务的技术。

1.1 从 “零样本” 到 “少样本”

在没有任何示例的情况下,我们直接给模型一个问题,这被称为 “零样本提示”(Zero-shot prompting)。例如,直接问模型:"What is 2 🍎 9?",它很可能会因为不理解符号🍎的含义而给出错误或无意义的回答。

而 Few-Shot 提示则是在提出问题前,先给它看几道类似的、附有正确答案的例题。例如:

示例1:
输入:"2 🍎 2"
输出:"4"

示例2:
输入:"2 🍎 3"
输出:"5"

现在,请回答:"What is 2 🍎 9?"

通过这两个示例,模型可以迅速推断出🍎符号的含义是 “两数相加”,从而正确地得出11的答案。

1.2 Few-Shot 能解决什么问题?

LLM 虽然知识渊博,但有时我们需要它以非常特定的格式、风格或逻辑来回答问题。Few-Shot 提示正是解决这些痛点的利器:

  1. 强制输出格式:当你需要模型输出 JSON、XML 或特定列表格式时,提供示例可以作为格式样板,有效减少 “胡说八道” 的概率。
  2. 模仿特定风格:有些任务很难用文字指令清晰描述(如 “请用莎士比亚的风格写作”),提供几个例子比长篇大论的指令更有效。
  3. 引导复杂推理:对于需要多步推理的复杂任务,示例可以展示出思考链,引导模型遵循类似的推理路径。

二、在 LangChain 中实现 Few-Shot 提示

实现 Few-Shot 提示的第一步,也是最重要的一步,是提出一个好的示例数据集。好的示例应该在运行时相关、清晰、信息丰富,并提供模型尚不知道的信息。在 LangChain 中,我们主要使用FewShotChatMessagePromptTemplateFewShotPromptTemplate这两个类来实现,二者分别适配聊天模型和文本提示场景。

2.1 核心组件一:FewShotChatMessagePromptTemplate(聊天场景)

这个类实现了标准的 Runnable 接口,主要用于将示例实例化为聊天模型可以读懂的聊天消息列表,完美适配对话式大模型。

核心参数与方法
参数 / 方法 说明
examples 样本示例列表,是模型学习的核心素材
example_prompt 一个ChatPromptTemplate,用于格式化单个示例
invoke() 输入字典,返回完整的提示内容PromptValue
to_messages() 将提示转换为模型可识别的聊天消息列表
实战代码:数学符号语义推理
from langchain_core.prompts import ChatPromptTemplate, FewShotChatMessagePromptTemplate
from langchain_openai import ChatOpenAI

# 1. 定义核心示例集
examples = [
    {"input": "2 🍎 2", "output": "4"},
    {"input": "2 🍎 3", "output": "5"},
]

# 2. 定义单示例格式化模板(匹配聊天消息格式)
example_prompt = ChatPromptTemplate.from_messages([
    ("human", "{input}"),
    ("ai", "{output}"),
])

# 3. 构建少样本聊天提示模板
few_shot_prompt = FewShotChatMessagePromptTemplate(
    example_prompt=example_prompt,
    examples=examples,
)

# 4. 组合最终提示(系统指令+示例+用户输入)
final_prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一个神奇的数学奇才,能通过示例理解特殊符号的语义。"),
    few_shot_prompt,
    ("human", "{input}"),
])

# 5. 初始化模型并执行推理
model = ChatOpenAI(model="gpt-4o-mini")
chain = final_prompt | model
chain.invoke({"input": "What is 2 🍎 9?"}).pretty_print()

运行结果

================================ Ai Message =================================
11

模型成功通过示例理解了🍎的 “加法” 语义,计算任务完美完成。

2.2 核心组件二:FewShotPromptTemplate(文本提示场景)

当我们需要引导模型按固定文本格式输出(如推理步骤、问答流程)时,FewShotPromptTemplate是更合适的选择,它支持通过prefixsuffix灵活拼接示例前后的提示文本。


三、实战案例:Few-Shot 的两大核心应用场景

为了让你真正掌握 Few-Shot 的落地方法,我们结合两个高频场景,从基础实现到结果验证,完整拆解实战流程。

3.1 案例一:推理引导 —— 让模型 “有逻辑地思考”

核心目标:强制模型展示多步推理过程,而非直接给出结论,提升答案的可信度和可解释性。

步骤 1:定义示例与提示模板
from langchain_core.prompts import PromptTemplate, FewShotPromptTemplate
from langchain_openai import ChatOpenAI

# 单示例格式化模板
example_prompt = PromptTemplate.from_template("Question: {question}\n{answer}")

# 构建包含推理步骤的示例集
examples = [
    {
        "question": "李白和杜甫,谁更长寿?",
        "answer": """是否需要后续问题:是的。
后续问题:李白享年多少岁?
中间答案:李白享年61岁。
后续问题:杜甫享年多少岁?
中间答案:杜甫享年58岁。
所以最终答案是:李白
"""
    },
    {
        "question": "腾讯的创始人什么时候出生?",
        "answer": """是否需要后续问题:是的。
后续问题:腾讯的创始人是谁?
中间答案:腾讯由马化腾创立。
后续问题:马化腾什么时候出生?
中间答案:马化腾出生于1971年10月29日。
所以最终答案是:1971年10月29日
"""
    }
]

# 构建少样本文本提示模板
prompt = FewShotPromptTemplate(
    examples=examples,
    example_prompt=example_prompt,
    suffix="Question: {input}",  # 拼接用户输入
    input_variables=["input"],
)
步骤 2:执行推理并验证结果
# 初始化模型并调用
model = ChatOpenAI(model="gpt-4o-mini")
response = model.invoke(prompt.invoke({"input": "《教父》和《星球大战》的导演来自同一个国家吗?"}))
print(response.content)

运行结果

是否需要后续问题:是的。
后续问题:《教父》的导演是谁?
中间答案:《教父》的导演是弗朗西斯·福特·科波拉。
后续问题:弗朗西斯·福特·科波拉来自哪里?
中间答案:弗朗西斯·福特·科波拉来自美国。
后续问题:《星球大战》的导演是谁?
中间答案:《星球大战》的导演是乔治·卢卡斯。
后续问题:乔治·卢卡斯来自哪里?
中间答案:乔治·卢卡斯也来自美国。
所以最终答案是:是

模型严格遵循示例中的推理框架,一步步拆解问题、验证信息,最终给出结论,逻辑清晰可追溯。

3.2 案例二:结构化信息提取 —— 从文本到标准化数据

核心目标:利用 Few-Shot 结合 Pydantic,让模型从非结构化文本中精准提取指定格式的结构化数据,解决信息提取的标准化难题。

完整实战流程
第一步:定义结构化返回模型(Pydantic)

通过 Pydantic 约束输出格式,确保模型返回的数据符合业务要求:

from typing import List, Optional
from pydantic import BaseModel, Field

class Person(BaseModel):
    """单个人物的信息结构"""
    name: Optional[str] = Field(default=None, description="人物姓名")
    hair_color: Optional[str] = Field(default=None, description="头发颜色")
    skin_color: Optional[str] = Field(default=None, description="肤色")
    height_in_meters: Optional[float] = Field(default=None, description="身高(米)")

class Data(BaseModel):
    """人物信息提取的根结构"""
    people: List[Person]
第二步:构建 Few-Shot 示例集(覆盖多场景)

示例需包含 “无人物”“部分信息缺失” 等边界场景,让模型学会处理复杂情况:

examples = [
    # 场景1:无人物信息
    (
        "海洋是广阔而蓝色的,它有两万多英尺深。",
        Data(people=[])
    ),
    # 场景2:部分人物信息缺失
    (
        "小强从中国远行到美国。",
        Data(people=[Person(name="小强", height_in_meters=None, skin_color=None, hair_color=None)])
    ),
]
第三步:构造提示模板与示例消息

利用tool_example_to_messages工具,将示例转换为模型可识别的聊天消息格式:

from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.messages import HumanMessage, SystemMessage
from langchain_core.utils.function_calling import tool_example_to_messages

# 定义核心提示模板
prompt_template = ChatPromptTemplate.from_messages([
    SystemMessage(content="你是一个提取信息的专家,只从文本中提取相关信息。如果不知道提取的属性值,属性值返回null"),
    MessagesPlaceholder("example_messages"),  # 动态插入示例消息
    ("user", "{new_message}"),  # 插入用户待处理文本
])

# 转换示例为聊天消息
example_messages = []
for txt, tool_call in examples:
    # 根据示例结果生成模型响应
    ai_response = "检测到人" if tool_call.people else "未检测到人"
    # 转换为模型可理解的消息格式
    example_messages.extend(
        tool_example_to_messages(
            txt, tool_call, ai_response=ai_response
        )
    )
第四步:初始化模型并执行结构化提取

通过with_structured_output让模型自动输出 Pydantic 结构化数据:

from langchain_openai import ChatOpenAI

# 初始化模型并绑定结构化输出
model = ChatOpenAI(model="gpt-4o-mini")
structured_model = model.with_structured_output(schema=Data)

# 构建链并执行提取
chain = prompt_template | structured_model
result = chain.invoke({
    "example_messages": example_messages,
    "new_message": "篮球场上,身高两米的中锋王伟默契地将球传给一米七的后卫友李明,完成一记绝杀。这对老友用十年配合弥补了身高的差距。"
})

# 输出结果
print(result)

运行结果

people=[
    Person(name='王伟', hair_color=None, skin_color=None, height_in_meters=2.0),
    Person(name='李明', hair_color=None, skin_color=None, height_in_meters=1.7)
]

模型精准提取了文本中的两个人物信息及身高数据,完美匹配我们定义的结构化格式,即使文本中未提及发色、肤色,也按要求返回null


四、总结

Few-Shot 提示是提升大语言模型输出质量和可控性的核心工具,其核心逻辑是用示例 “教” 模型做事,而非用指令 “命令” 模型做事。

从基础的符号语义推理,到复杂的结构化信息提取,再到进阶的示例选择器优化,LangChain 为 Few-Shot 提示的落地提供了完整的工具链:通过 Pydantic 定义输出规范,通过FewShotChatMessagePromptTemplate/FewShotPromptTemplate组织示例,通过链式调用简化流程,通过示例选择器优化效率。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐