少样本提示(Few-Shot Prompting)实战指南
从 LangChain 的 FewShotPromptTemplate 出发,理解少样本提示的核心机制与工程落地方法。
一、什么是少样本提示?
少样本提示(Few-Shot Prompting)是向大语言模型(LLM)提供少量输入-输出示例,引导模型按照示例的格式、风格或推理逻辑来回答新问题的技术。
与零样本(Zero-Shot)直接提问不同,少样本通过"示范教学"让模型"照猫画虎",显著提升输出的一致性和准确性。
二、LangChain 中的 FewShotPromptTemplate
2.1 核心组件
python
from langchain.prompts import PromptTemplate, FewShotPromptTemplate
# 1. 定义单个示例的格式模板
example_template = (
"报警码: {code}
"
"报警信息: {message}
"
"根因分析: {root_cause}
"
"处理措施: {action}"
)
example_prompt = PromptTemplate.from_template(example_template)
# 2. 准备示例数据(字典列表)
examples = [
{
"code": "E-616",
"message": "Wp-Mag: chuck not clamped -> Feed release MC locked!",
"root_cause": "工件夹紧信号未到位,导致进给释放被锁定",
"action": "1. 检查夹具气压 2. 确认工件放置到位 3. 复位夹紧传感器"
},
{
"code": "W-617",
"message": "Robot signal Chucks Closed not dropped during change",
"root_cause": "换料时机器人夹具闭合信号未断开",
"action": "1. 检查机器人IO信号线 2. 确认换料节拍 3. 手动触发信号测试"
}
]
# 3. 组装少样本模板
prompt = FewShotPromptTemplate(
examples=examples, # 示例列表
example_prompt=example_prompt, # 单条示例格式
prefix="你是一名机床维护专家...", # 系统角色设定
suffix="现在遇到新报警:\n报警码: {code}\n报警信息: {message}\n根因分析:\n处理措施:", # 实际问题模板
input_variables=["code", "message"] # 外部传入变量
)
# 4. 调用生成完整提示
print(prompt.format(code="E-618", message="Spindle overload: current 85A"))
2.2 生成的 Prompt 结构
┌─────────────────────────────────────────┐
│ prefix:系统指令(角色+任务定义) │
├─────────────────────────────────────────┤
│ 示例1:完整输入-输出对 │
│ 示例2:完整输入-输出对 │
│ ... │
├─────────────────────────────────────────┤
│ suffix:当前问题(只给输入,留空输出) │
└─────────────────────────────────────────┘
三、示例数据的格式要求
3.1 基本规则
| 规则 | 说明 |
|---|---|
| Key 匹配 | 字典 key 必须等于 example_prompt 中的 {变量名} |
| 字符串值 | 所有值最终会拼接到文本中,建议均为 str |
| 顺序无关 | 输出顺序由 example_prompt 模板决定 |
| 数量灵活 | 示例可包含多余变量,但模板用到的必须存在 |
3.2 常见错误
python
# 错误:key 名不匹配
examples = [{"question": "2+3", "answer": "5"}] # key 是 question/answer
example_prompt = "算式: {input} 值: {output}" # 模板要 input/output
# 结果:KeyError: 'input'
# 正确:key 名完全一致
examples = [{"input": "2+3", "output": "5"}]
四、典型应用场景
4.1 工业报警知识库(故障诊断)
python
examples = [
{
"code": "E-616",
"message": "chuck not clamped",
"root_cause": "工件夹紧信号未到位",
"action": "检查夹具气压->确认工件放置->复位传感器"
},
{
"code": "E-600",
"message": "Workpiece change not completed",
"root_cause": "换料流程超时中断",
"action": "检查托盘传感器->确认CYCLE 320流程->查看PLC状态"
}
]
价值:将历史维修经验结构化,新报警进来时模型自动按同样格式输出根因分析和处理步骤。
4.2 SQL 语句生成
python
examples = [
{
"schema": "users(id, name, age, city)",
"question": "查询苏州所有用户",
"sql": "SELECT * FROM users WHERE city = '苏州';"
},
{
"schema": "orders(id, user_id, amount, create_time)",
"question": "统计本月订单总额",
"sql": "SELECT SUM(amount) FROM orders WHERE create_time >= DATE_TRUNC('month', NOW());"
}
]
价值:教会模型理解特定数据库的表结构,生成符合团队规范的 SQL。
4.3 代码审查意见
python
examples = [
{
"code": "for i in range(len(items)): print(items[i])",
"review": "建议改用 for item in items:,更Pythonic且避免索引开销。"
},
{
"code": "f = open('data.txt'); data = f.read(); f.close()",
"review": "建议使用 with open(...) as f: 上下文管理器,确保异常时正确关闭。"
}
]
五、进阶:动态示例选择(Example Selector)
当示例库很大时,全量拼接会浪费 token。LangChain 支持按语义相似度动态选择最相关的几条:
python
from langchain.prompts import SemanticSimilarityExampleSelector
from langchain.vectorstores import Chroma
selector = SemanticSimilarityExampleSelector.from_examples(
examples=examples, # 全部历史示例
embeddings=embedding_model, # 向量模型
vectorstore=Chroma, # 向量数据库
k=3 # 只选最相似的 3 条
)
prompt = FewShotPromptTemplate(
example_selector=selector, # 动态选择器替代固定 examples
example_prompt=example_prompt,
prefix="...",
suffix="...",
input_variables=["code", "message"]
)
优势:
- 新问题进来时,自动匹配最相关的历史案例
- 减少 prompt 长度,节省 token 成本
- 避免无关示例干扰模型判断
六、少样本 vs 其他提示策略
| 策略 | 示例数量 | 适用场景 | 成本 |
|---|---|---|---|
| Zero-Shot | 0 条 | 通用知识问答 | 最低 |
| One-Shot | 1 条 | 简单格式模仿 | 低 |
| Few-Shot | 2~10 条 | 结构化输出、特定风格 | 中等 |
| Fine-Tuning | 数百+ 条 | 深度定制、高频任务 | 高(训练成本) |
建议:
- 格式/风格问题 -> Few-Shot 通常足够
- 领域知识深度不足 -> 考虑 RAG + Few-Shot 结合
- 高频固定任务 -> 再评估 Fine-Tuning 性价比
七、总结
少样本提示的本质是**"用示例定义输出规范"**,而非"用指令描述输出规范"。在工程落地中:
- 示例质量 > 数量:精选 3~5 条高质量示例,远胜于 20 条模糊示例
- 变量命名要统一:example_prompt 与 examples 的 key 必须严格匹配
- 动态选择降本增效:示例库膨胀后务必引入 ExampleSelector
- 与 RAG 结合使用:示例教"格式",检索教"知识",两者互补
注:本文示例基于 LangChain 框架,核心思想适用于所有支持上下文学习的 LLM。