Zero-shot 与 Few-shot 学习
High Contrast
Dark Mode
Light Mode
Sepia
Forest
5 min read999 words

Zero-shot 与 Few-shot 学习

Zero-shot 和 Few-shot 是提示工程中最基础也最实用的技术。理解它们的原理和适用场景,是掌握所有高级提示技术的前提。

核心概念

graph LR A[提示学习策略] --> B[Zero-shot
零样本] A --> C[One-shot
单样本] A --> D[Few-shot
少样本] B --> B1[不提供示例
直接给指令] C --> C1[提供1个示例] D --> D1[提供2-6个示例] style A fill:#ede7f6,stroke:#5e35b1,stroke-width:3px style B fill:#e3f2fd,stroke:#1976d2,stroke-width:2px style C fill:#fff9c4,stroke:#f9a825,stroke-width:2px style D fill:#c8e6c9,stroke:#43a047,stroke-width:2px

Zero-shot(零样本学习)

Zero-shot 是最简单的提示方式——直接给模型指令,不提供任何示例。依赖模型在预训练阶段获得的通用能力。

# Zero-shot 示例
prompt = """
将以下句子的情感分类为"正面"、"负面"或"中性"。
句子:这家餐厅的服务太棒了,菜品也非常美味!
情感:
"""
# 模型输出: 正面

适用场景: - 任务简单且常见(翻译、摘要、分类) - 模型能力足够强(GPT-4o、Claude 3.5 等顶级模型) - 输出格式不需要严格控制

局限性: - 对于复杂任务或特定领域,准确率可能不够高 - 输出格式不稳定

Few-shot(少样本学习)

Few-shot 在提示词中提供若干个"输入→输出"的示例,让模型从示例中学习任务模式。

# Few-shot 示例:情感分类
prompt = """
将句子的情感分类为"正面"、"负面"或"中性"。
句子:快递很快,包装也完好无损。
情感:正面
句子:质量一般,和图片差距很大。
情感:负面
句子:已收到货,大小刚好合适。
情感:中性
句子:等了一个月才收到,客服态度还很差。
情感:
"""
# 模型输出: 负面

示例数量指南

示例数量 效果 适用场景
0(Zero-shot) 依赖模型通用能力 简单、常见任务
1-2 基本模式学习 格式明确的简单任务
3-5 最佳性价比 大多数分类、转换任务
6-10 边际收益递减 复杂的专业领域任务
>10 浪费 Token,可能过拟合 极少使用,考虑微调

Few-shot 的最佳实践

1. 示例要有代表性

示例应覆盖目标任务中的主要类别和边界情况。

# ❌ 差的示例选择:全是正面
bad_examples = """
句子:这件衣服太好看了!→ 正面
句子:性价比超高,推荐!→ 正面
句子:物流很快,包装完好。→ 正面
句子:颜色和图片不一样。→ ?
"""
# ✅ 好的示例选择:覆盖各类别
good_examples = """
句子:这件衣服太好看了!→ 正面
句子:颜色和图片差太远了。→ 负面
句子:已收到,还没穿过。→ 中性
句子:颜色和图片不一样。→ ?
"""

2. 示例格式要一致

所有示例必须使用完全相同的格式,模型会严格复制这个模式。

# ❌ 格式不一致
bad_format = """
输入:苹果 → 类别:水果
这是蔬菜:胡萝卜
三文鱼 - 海鲜类
柠檬是什么?
"""
# ✅ 格式严格一致
good_format = """
输入:苹果
类别:水果
输入:胡萝卜
类别:蔬菜
输入:三文鱼
类别:海鲜
输入:柠檬
类别:
"""

3. 示例要涵盖边界情况

# 情感分析中的边界示例
edge_cases = """
将用户评论的情感分类为"正面"、"负面"或"中性"。
评论:太好用了!五星好评!
情感:正面
评论:垃圾产品,退货退款!
情感:负面
评论:一般般吧,没什么特别感觉。
情感:中性
评论:功能很好但是价格太贵了。
情感:负面
评论:还行,比上一代好一些。
情感:正面
评论:收到了,还没用,先好评。
情感:中性
评论:我的电池续航有问题,但客服处理得很好。
情感:
"""

4. 示例的顺序也很重要

研究表明,Few-shot 示例的排列顺序会影响模型的表现(Lu et al., 2022):

graph TB A[示例排列策略] --> B[均匀分布] A --> C[由简到难] A --> D[最相似在后] B --> B1[各类别交替出现
避免连续相同类别] C --> C1[简单示例在前
复杂示例在后] D --> D1[与实际输入最相似的
示例放在最后] style A fill:#ede7f6,stroke:#5e35b1,stroke-width:3px style B fill:#e3f2fd,stroke:#1976d2,stroke-width:2px style C fill:#fff9c4,stroke:#f9a825,stroke-width:2px style D fill:#c8e6c9,stroke:#43a047,stroke-width:2px

💡 实用建议:将与实际输入最相关的示例放在提示词的末尾(紧挨着实际输入),因为模型对结尾位置的信息关注度更高。

动态 Few-shot:进阶技巧

在生产环境中,我们通常不会硬编码示例,而是根据每次输入动态选择最相关的示例。

from openai import OpenAI
import numpy as np
client = OpenAI()
# 示例库
example_pool = [
{"input": "iPhone 15 Pro太棒了,拍照画质惊人", "output": "正面", "category": "电子产品"},
{"input": "这双鞋穿两天就开胶了", "output": "负面", "category": "鞋类"},
{"input": "洗衣液味道还行,清洁力一般", "output": "中性", "category": "日用品"},
{"input": "MacBook Air续航太强了,一天不用充电", "output": "正面", "category": "电子产品"},
{"input": "T恤掉色严重,洗一次就不能穿了", "output": "负面", "category": "服装"},
{"input": "沙发软硬适中,但颜色比图片深", "output": "中性", "category": "家具"},
]
def get_embedding(text: str) -> list[float]:
"""获取文本的向量表示"""
response = client.embeddings.create(
model="text-embedding-3-small",
input=text
)
return response.data[0].embedding
def select_dynamic_examples(
user_input: str,
example_pool: list[dict],
k: int = 3
) -> list[dict]:
"""
根据用户输入,从示例池中选择最相关的k个示例。
Args:
user_input: 用户输入文本
example_pool: 示例池
k: 选择的示例数量
Returns:
最相关的k个示例
"""
input_embedding = get_embedding(user_input)
scored_examples = []
for example in example_pool:
example_embedding = get_embedding(example["input"])
# 计算余弦相似度
similarity = np.dot(input_embedding, example_embedding) / (
np.linalg.norm(input_embedding) * np.linalg.norm(example_embedding)
)
scored_examples.append((similarity, example))
# 按相似度降序排序,取前k个
scored_examples.sort(key=lambda x: x[0], reverse=True)
return [ex for _, ex in scored_examples[:k]]
def build_few_shot_prompt(user_input: str) -> str:
"""构建动态 Few-shot 提示词"""
selected = select_dynamic_examples(user_input, example_pool, k=3)
prompt = "将用户评论的情感分类为"正面"、"负面"或"中性"。\n\n"
for ex in selected:
prompt += f"评论:{ex['input']}\n情感:{ex['output']}\n\n"
prompt += f"评论:{user_input}\n情感:"
return prompt
# 使用
user_review = "这个耳机音质不错,但佩戴久了耳朵疼"
prompt = build_few_shot_prompt(user_review)
response = client.chat.completions.create(
model="gpt-4o-mini",
temperature=0,
messages=[{"role": "user", "content": prompt}]
)
print(response.choices[0].message.content)

Zero-shot vs Few-shot:如何选择?

graph TB A{任务类型?} --> B{简单且常见?} B -->|是| C[Zero-shot] B -->|否| D{有高质量示例?} D -->|是| E{输出格式严格?} D -->|否| F[Zero-shot +
详细指令] E -->|是| G[Few-shot
3-5个示例] E -->|否| H[Few-shot
1-2个示例] style A fill:#ede7f6,stroke:#5e35b1,stroke-width:3px style C fill:#e3f2fd,stroke:#1976d2,stroke-width:2px style F fill:#fff9c4,stroke:#f9a825,stroke-width:2px style G fill:#a5d6a7,stroke:#2e7d32,stroke-width:3px style H fill:#c8e6c9,stroke:#43a047,stroke-width:2px

决策矩阵

场景 推荐策略 原因
通用翻译 Zero-shot 模型内置能力足够
特定领域分类 Few-shot (3-5) 需要示例定义类别边界
格式化数据转换 Few-shot (2-3) 示例定义输入输出格式
创意写作 Zero-shot + 详细指令 示例可能限制创意
代码生成 Zero-shot 或 One-shot 模型代码能力强
专业术语提取 Few-shot (3-5) 需要定义领域术语

动手练习

练习1:设计 Few-shot 提示词

设计一个 Few-shot 提示词,将客服对话分类为以下类别: - 产品咨询 - 技术支持 - 投诉反馈 - 退换货 - 其他

要求:提供至少3个高质量示例,覆盖主要类别和一个边界情况。

练习2:对比实验

分别使用 Zero-shot 和 Few-shot(3个示例)来完成同一个文本摘要任务,比较: - 输出格式的一致性 - 内容的准确性 - 摘要的长度控制

本章要点


下一步思维链 (Chain-of-Thought) 🚀