FewShot

分类、抽取、固定 JSON 格式等任务,零样本时模型常偏离格式;手写三四条示例进 system 字符串难以复用。Few-shot 模板把「示例列表 + 格式模板」结构化,按输入动态挑选或填充示例再拼进 messages。

段末注释Few-shot(少样本提示)= 在 prompt 中附带少量输入输出范例,引导模型模仿格式与行为。


1. 一句话定位

维度 内容
角色 能力层示例注入:提升格式遵从与任务对齐
输入 → 输出 变量 dict + 示例集 → 含示例的 message 列表
典型调用入口 FewShotChatMessagePromptTemplate + example_prompt
与 LangGraph 动态示例选择可放在节点内;复杂示例库管理可外置向量检索

2. 实现逻辑

静态 few-shot 流程:

1
2
3
4
5
1. 定义 examples = [{"input": "...", "output": "..."}, ...]
2. example_prompt = ChatPromptTemplate.from_messages([("human", "{input}"), ("ai", "{output}")])
3. few_shot = FewShotChatMessagePromptTemplate(examples=examples, example_prompt=example_prompt)
4. final = ChatPromptTemplate.from_messages([("system", "任务说明"), few_shot, ("human", "{user_input}")])
5. final.invoke({"user_input": "新样本"}) → messages 含 N 组示例 + 当前问题

字段级变形

1
2
3
examples[0] → HumanMessage("输入A") + AIMessage("输出A")
...
{"user_input": "输入B"} → 末尾 HumanMessage("输入B")

3. 原理说明

3.1 FewShotChatMessagePromptTemplate

位于 langchain_core.prompts.few_shot。每个 example dict 的键须与 example_prompt 占位符一致。示例以 交替 human/ai 插入最终 prompt。

FewShotChatMessagePromptTemplate(数据类)
功能:把静态或动态选中的 examples 渲染成消息片段,再嵌进外层 ChatPromptTemplate

字段 类型 默认值 最小维度
examples list[dict] / None None 静态时 len≥1;与 selector 二选一
example_prompt ChatPromptTemplate 必填 至少 1 条 human(常再加 1 条 ai)
example_selector BaseExampleSelector / None None 动态选例时必填
input_variables list[str] 推断 与外层当前输入键一致
1
2
3
4
5
6
7
few_shot = FewShotChatMessagePromptTemplate(
examples=[{"word": "happy", "antonym": "sad"}], # 最小 1 条
example_prompt=ChatPromptTemplate.from_messages([
("human", "反义词:{word}"),
("ai", "{antonym}"),
]),
)

3.2 示例选择器(Example Selector)

SemanticSimilarityExampleSelector(类)
功能:按与当前输入的 embedding 相似度取 Top-K。依赖 Embeddings + VectorStore。
默认值:k=4(视版本)。
最小维度:示例库 len≥1;k ≥ 1k ≤ 库大小

1
2
3
4
from langchain_core.example_selectors import SemanticSimilarityExampleSelector
selector = SemanticSimilarityExampleSelector.from_examples(
examples, embeddings, vectorstore_cls, k=2,
)

MaxMarginalRelevanceExampleSelector(类)
功能:在相似基础上减冗余(MMR)。k 同上;另有 fetch_k(候选池,默认常为 20)。
最小维度:fetch_k ≥ k ≥ 1

3.3 与 fine-tuning 的边界

Few-shot 不占训练成本,但占 context window。示例过多会挤掉 RAG 文档。长任务更宜微调或专用小模型。
最小维度(实践下界):能工作的 few-shot 至少 1 条高质量示例;0 条则退化为零样本。

3.4 Chat vs 字符串 FewShotPromptTemplate

FewShotPromptTemplate(数据类)
功能:completion 模型用的单字符串 few-shot:prefix + 示例拼接 + suffix。
默认值:example_separator="\n\n"
最小维度:examples len≥1;suffix 须含当前输入占位符。

1
2
3
4
5
6
7
from langchain_core.prompts import FewShotPromptTemplate, PromptTemplate
FewShotPromptTemplate(
examples=[{"q": "1+1", "a": "2"}],
example_prompt=PromptTemplate.from_template("Q:{q}\nA:{a}"),
suffix="Q:{q}\nA:",
input_variables=["q"],
)

Chat 模型用 FewShotChatMessagePromptTemplate,保持 role 边界。


4. 最小可运行示例

1
pip install -U langchain-openai
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate, FewShotChatMessagePromptTemplate
from langchain_core.output_parsers import StrOutputParser

examples = [
{"word": "happy", "antonym": "sad"},
{"word": "tall", "antonym": "short"},
]
example_prompt = ChatPromptTemplate.from_messages([
("human", "反义词:{word}"),
("ai", "{antonym}"),
])
few_shot = FewShotChatMessagePromptTemplate(
examples=examples,
example_prompt=example_prompt,
)
prompt = ChatPromptTemplate.from_messages([
("system", "只输出一个英文反义词,不要解释。"),
few_shot,
("human", "反义词:{word}"),
])

# 1) 先看拼好的 messages:system + 两对示例 + 当前 human
assembled = prompt.invoke({"word": "small"}).to_messages()
print([(m.type, m.content) for m in assembled])
# 预期:system, human/ai ×2, human「反义词:small」

model = ChatOpenAI(
model="qwen3.5:9b",
api_key="ollama",
base_url="http://localhost:11434/v1",
temperature=0,
)
print((prompt | model | StrOutputParser()).invoke({"word": "small"}))
# 预期形态:big(或 large;应是单词而非句子)

重要配置参数

参数(API 名) 类型 / 默认值 功能说明 作用与影响 参考起点 配置指导
examples list[dict],与 selector 二选一 静态 few-shot 样本库,每条键须对齐 example_prompt 条数多占窗口、挤 RAG;0 条退化为零样本 2~5 条 质量重于数量,覆盖边界 case
example_prompt ChatPromptTemplate,必填 把单条 example dict 渲染成 human/ai 消息 键缺失则格式化失败 human/ai 成对 键名与 examples 字段一致
example_selector BaseExampleSelector / None 按当前输入动态挑 K 条示例 需 Embeddings,增加一次检索延迟 k=2~4 静态够用就不要上 selector
input_variables list[str] 外层最终 prompt 还要填的变量 与 few_shot 后 human 模板不一致则 KeyError word 只列「当前真实输入」
suffix / 末条 human template 真正用户问题的位置与格式 与示例格式不一致则模型不会类比 与示例同格式 便于模型照葫芦画瓢
示例 token 总长 应用层预算 所有示例合计占用的上下文 过大挤掉资料与系统指令 < 30% window 与 RAG context 合计勿爆窗

5. 易踩坑

  1. 示例 output 与真实要求矛盾:示例里多解释一句,模型也会啰嗦。
  2. example_prompt 缺键:某条 example 无 antonym 键导致格式化失败。
  3. 静态示例过多:未用 selector 时 20+ 条示例拖慢且挤占 RAG 位。

小结

  • FewShotChatMessagePromptTemplate 把示例变成标准 human/ai message 序列。
  • 示例多时用 ExampleSelector 按相似度动态选取。
  • ChatPromptTemplate 组合:system → few-shot → 当前 human。
  • 注意示例 token 与 上下文窗口 的总占用。

参考链接

-------------本文结束感谢您的阅读-------------