跳到主要内容

少样本饱和曲线:为什么添加更多示例最终会适得其反

· 阅读需 10 分钟
Tian Pan
Software Engineer

一个团队在路线优化任务上测试 Gemini 3 Flash,零样本准确率达 93%。他们开始添加示例,性能一路攀升——但在添加到八个示例时,准确率骤降至 30%。这不是噪声,而是少样本饱和曲线的猛烈反噬。这是大多数工程师只有在部署了一个四个示例时看起来正常、十二个示例时却出现问题的提示之后才会发现的故障模式。

"更多示例严格意味着更好"的直觉是错的。跨 12 个 LLM 和数十种任务类型的数据显示了三种截然不同的失败模式:稳定平台期(收益趋于平缓)、峰值回归(收益先升后崩)和选择诱导崩溃(更换示例检索策略后收益蒸发)。理解自己处于哪种模式,会改变你构建提示的方式、何时放弃少样本方案,以及是否应该转向微调。

三种失败模式

并非所有的少样本性能下降都长一个样子。

峰值回归是最具戏剧性的,也是最具诊断价值的。模型在 0 到 4 个示例之间持续改善,到达峰值后急剧下跌。上文的 Gemini 3 Flash 案例是一个极端例子——从峰值到 8-shot,性能下降了 63 个百分点。但这种模式在各模型中普遍存在:Qwen 3.5 在代码修复任务上,随着示例数量增加,准确率从 56% 骤降至 0%。这种情况发生在示例的分布开始让模型学到某些细微错误的时候。

稳定平台期是良性版本。收益趋于平缓,边际改善趋近于零,但性能不会崩塌。大多数工程师在不知情的情况下就处于这种状态——在第四个示例之后已经停止贡献的示例上浪费 token。代价是浪费而非灾难性。

选择诱导崩溃是最隐蔽的。固定示例表现良好;通过 TF-IDF 或语义相似度动态检索的示例,在同一任务、同一模型上导致 58% 的相对性能下降。示例的内容不会改变你的平均值,但选择策略决定了你是稳定地达到峰值性能,还是随机触发失败案例。生产环境中使用基于检索的示例选择的系统都面临这种风险。

为什么更多示例开始适得其反

一旦理解了模型实际上在用你的示例做什么,这些失败模式就变得合理了。

模型学习的是格式和分布,而不是映射关系。 这是 Min 等人(2022 年)令许多提示工程师至今未完全消化的不舒适发现:随机替换少样本示例中的正确标签,几乎不影响性能。模型并不是在学习"当输入看起来像 X 时,输出 Y"——它在学习输出格式、词汇风格、有效响应的结构。这意味着超过某个点之后,你不是在教它新的输入输出映射,而是在引入噪声。

中间迷失效应吞噬你的信号。 Transformer 的注意力在上下文中并非均匀分布。模型对提示开头和结尾的注意力更好;中间部分会被软焦点处理。堆入足够多的示例之后,实际的任务指令就被埋在了模型以降低注意力处理的上下文中间。那些本该提供帮助的示例变成了干扰。关于长上下文提示的研究持续显示,当关键信息位于上下文窗口中间 60% 时,准确率下降超过 30%。

虚假相关性随示例数量累积。 每个示例都是模型可以从中推断隐式规则的数据点。只有两三个示例时,这些规则受到约束——没有足够的模式来过拟合。有十或二十个示例时,模型开始拾取你无意传达的结构。如果你精心挑选的示例恰好共享某种句子结构、词汇风格或领域频率偏差,模型就会把那种虚假关联和合法关联一起学进去。然后把虚假规则应用到表面上匹配模式的输入上,不管底层任务逻辑是否适用。

一个具体的例子:如果你在对客服工单进行分类,而你的示例恰好在投诉中都使用了"紧急"一词,但在问询中从未使用,模型就会开始把"紧急"视为投诉类的强预测因子——即使工单是在询问一个紧急的产品问题。添加更多意外强化这种偏差的示例,你挖的坑就更深了,而不是更浅。

注意力是二次方的,上下文并非免费。 从 2 个示例扩展到 20 个示例不仅仅增加了线性的 token 成本。Transformer 的自注意力随上下文长度呈二次方扩展,这意味着模型在指数增长的成对关系集合上分配其有限的注意力容量。这种计算压力不会以错误的形式表现出来;它表现为对任何单个信号注意力的弱化,包括你的任务指令。

不同任务类型的饱和点

饱和不是普遍的——它因任务和模型而异,这就是为什么如果不做显式测试,这种失败模式很难发现。

翻译任务的可扩展性最好。对于低资源语言,一些模型在数百个示例内持续改善。这种规律足够一致,使得低资源翻译可以说是多样本提示最好的使用理由。任务格式严格,映射关系是确定性的,示例能添加真实的信号。

数学推理更早达到饱和。MATH 数据集的性能通常在大约 125 个示例时达到峰值,然后下降。GPQA(研究生级科学推理)也是如此——125-shot,然后在 250 时下降。抽象推理任务的饱和速度似乎比程序性任务更快:一旦模型学会了答案格式,更多示例并不能教它更好地推理。

分类和提取任务饱和最快。大多数行业基准测试显示,2-5 个示例的范围能获取 80% 的可实现收益。超过 8 个示例后,这些任务类型的改善就落入噪声区间。这是最常见的生产工作负载,这意味着大多数工程师在一个他们的示例已经停止帮助的区间中操作。

编码和代码验证任务处于中间。CodeLlama 研究表明饱和点在六个示例左右。超过这个点,你在添加损害上下文效率而不增加准确率的 token。

找到你的饱和点

如果你没有系统地测试这一点,你就不知道自己在曲线的哪个位置。方法很简单。

从 50-100 个代表生产分布的测试用例基线集开始。以 0、1、2、4、8 个示例运行相同的测试——每次运行保持示例相同,只改变数量。画出准确率与示例数量的图表。找出边际收益低于每增加一个示例 1% 的拐点,或曲线反转的位置。

实践中有三件事会让这个测试失效:

  • 在每个样本数量使用不同的示例。 你在测量示例质量的变化,而不是饱和。2-shot 和 4-shot 运行需要使用相同的前两个示例,4-shot 再额外添加两个。
  • 测试集太小,无法检测 1-2% 的准确率变化。 10 个测试用例无法区分饱和和噪声。你至少需要 50 个。
  • 没有测试你的实际示例选择策略。 如果生产使用基于检索的选择,你的固定示例饱和测试告诉你的只是最佳情况。用你的实际检索方法测试。

最后的决策规则很简单:找出准确率收益低于 1% 或出现反转的样本数量,然后减一。那就是你的最优样本数量。如果你目前超过这个数量,你就在为性能下降付出 token 代价。

何时停止提示,开始微调

饱和曲线有一个自然的出口。如果你的任务有明确的输入输出格式,你的示例质量很高,但在 8 个示例时仍然达不到可接受的性能——你已经触及了这个模型在这个任务上少样本提示所能实现的上限。

微调的实际门槛是闭源模型(GPT-4o、Claude)50-100 个标注示例,开源权重模型稍多。低于 50 个示例,少样本通常更好:微调更新噪声太大,无法胜过清晰的上下文演示,而且你会失去快速迭代的能力。

微调的理由不仅仅是准确率上限,还有 token 效率。一个已经内化了你的任务格式的微调模型,用零样本提示产出的质量,等同于基础模型用 10-shot 提示产出的质量——每次推理的 token 成本只有后者的十分之一。规模化后,这会产生复利效应。如果你运行数百万次推理,微调投资的盈亏平衡点往往在几周内到来。

一个注意事项:微调模型通常在分布外输入上表现不佳。当测试分布与训练分布偏移时,上下文学习表现出更好的泛化能力。如果你的生产输入随时间漂移显著,带有动态示例选择的少样本可能比微调保持更强的鲁棒性,即使其峰值准确率更低。

工程师的实用默认值

根据研究,以下默认值能最大限度地减少意外降级:

  • 从 2-3 个示例开始。 这个范围能获取大部分格式学习收益,而不会冒虚假相关性过拟合的风险。在添加更多示例之前先获取基线指标。
  • 有意识地递增。 从 3 到 5,测量,再从 5 到 8。不要直接跳到"越多越好"。
  • 将最好的示例放在首尾。 考虑到中间迷失效应,定义关键边缘情况的示例应该在你的示例块的开头和结尾,而不是埋在中间。
  • 在尝试检索之前先用固定示例。 动态示例选择引入了选择诱导崩溃的风险。在为此构建基础设施之前,先验证你的任务是否受益于检索。
  • 对推理模型降低示例数量。 如果你使用 o1、o3 或 Claude 的扩展思考模式,从零样本开始。这些模型受益于推理空间,而非受约束的演示。少样本提示已被证明会降低这类模型的性能——它们内化了自己的思维链,而不是遵循你的。
  • 如果需要超过 8 个示例才能达到目标准确率,研究微调。 你很可能已经到达了上下文学习所能做到的上限。

结语

少样本饱和曲线不是理论上的担忧——它是一种生产故障模式,出现在 A/B 测试、提示更新后的回归 bug,以及工程师试图通过添加更多示例来"改进"提示后莫名其妙的质量下降中。经验证据足够清晰,应该改变你的默认值:将示例数量视为需要测试的超参数,而不是可以随意增加的旋钮。

操作影响很直接:如果你没有对生产提示进行饱和测试,你可能有些示例正在损害你。这个测试需要一个下午的时间。token 节省和准确率恢复往往使其成为你能做的最高 ROI 的提示工程工作。

Let's stay in touch and Follow me for more thoughts and updates