Few-shot 设计的关键是在 2-4 个示例的预算内最大化判断多样性,而不是最大化示例数量。3 个覆盖不同判断类型(标记、模糊、可接受)的示例,在相同 token 开销下,效果优于 3 个同类型示例。
数据:多样性 vs 数量
| 示例集 | 准确率 | 误报率 |
|---|---|---|
| 3 个纯正例(全是 bug) | 78% | 35% |
| 1 个正例 + 1 个模糊 + 1 个”不标记” | 91% | 8% |
同样的 token 开销。多样集教了三种技能;同质集把一种技能教了三遍。
对 300 次审查的均衡对比验证了这一点:
| 配置 | 准确率 | 误报率 | 漏检 bug |
|---|---|---|---|
| 3 个简单 bug | 82% | 31% | — |
| 1 个 bug + 1 个模糊 + 1 个可接受 | 93% | 6% | — |
| 1 个 bug + 2 个可接受 | 85% | 4% | 18% |
配置 B 是最优的——均衡覆盖产出最佳综合准确率。配置 C 过度偏向克制,误报率降了但漏掉了 18% 的真实 bug。
三个判断维度
每个 few-shot 集合应该覆盖:
- 明确的正例 — 毫无歧义的发现。建立输出格式的基线。永远作为第一个示例。
- 边界/模糊案例 — 可标可不标的模式。展示判断过程的推理。生产环境中的不一致性恰恰发生在这里。
- 反例 — 看起来可疑但不应该标记的模式。教会克制。没有这个,Claude 会把哪怕只是沾点边的东西都标出来。
第一个示例定格式。第二和第三个教判断。
构建顺序
从明确案例开始。根据哪种失败模式更重要,决定先加边界还是反例:
- 误报率高? 第二个加反例(“这看起来像 bug 但可以接受,因为…”)
- 漏检真 bug? 第二个加边界案例(“这个微妙的模式确实是 bug,因为…”)
- 两者兼有? 三个示例:明确 → 边界 → 反例
Token 受限设计
只有 2 个示例预算时,最优分配是:
- 一个 bug 发现示例(建立格式 + 什么该标记)
- 一个”可接受/无发现”示例(教克制)
这对组合覆盖的判断面比两个 bug 示例更大。两个 bug 示例强化的是”标记东西”——模型默认就会这么做。反例教的是更难的技能:什么时候不标记。
全正例:35% 误报问题
只展示 bug 的示例教会 Claude 找 bug。Claude 学到:“像这样的模式 → 标记。“没有反例展示”像这样的模式 → 可接受”,Claude 会把任何哪怕只是略像 bug 的东西都标出来。
在一个全 REPORT 的示例集中加入 2 个 SKIP 示例,误报率从 38% 降到 9%,漏检只增加了 1%。克制维度是杠杆率最高的补充。
超过 4 个:收益递减
超过 4 个示例后收益急剧下降。这个关系不是单调正相关的——核心判断维度覆盖完之后,额外示例增加成本但质量提升不成比例。
多语言支持(Python、TypeScript、Go)在 4 个示例预算下:每种语言一个示例展示相同的输出结构 + 一个跨语言的模糊模式。这同时教会了格式一致性和语言无关的判断。
每个示例应该教不同的技能
功能重复的示例浪费预算。第二个格式示例教的是同一课;那个位置应该教边界判断或 null 处理。
不要为了塞进更多示例而缩减推理过程。模糊案例中的推理本身就是课程——没了它,Claude 学会的是产出不完整的输出,不是更好的判断。
一句话总结: 在 2-4 个示例中最大化判断多样性——一个明确发现、一个边界案例、一个”不标记”——因为 3 个多样示例的 91% 准确率打败 8 个同质示例的 78%。