跳到主要内容

动态少样本检索:为什么你的静态示例正在损耗准确率

· 阅读需 12 分钟
Tian Pan
Software Engineer

当一个团队在系统提示开头硬编码三个示例输入输出对时,这看起来是合理的工程决策。这些示例经过人工验证,格式统一,模型行为也可预期地有所改善。六个月后,同样这三个示例还在那里——能很好地覆盖 30% 的输入查询,其余的则是敷衍了事,而且没有人去统计到底哪些是哪些。

静态少样本提示是生产 LLM 系统中最被忽视的性能黑洞。另一种方案——根据查询的语义相似度按需选择示例——在各类任务中的质量表现持续优于固定示例,差距往往达到两位数百分比。但这个迁移过程既不免费,也不无风险,而且动态方案的失败模式比静态方案更难察觉。

本文将介绍研究数据的实际结论、生产中检索栈的工作方式、大多数从业者忽视的排序和投毒风险,以及静态示例应该获胜的具体场景。

性能差距比团队预期的更大

动态少样本检索的学术研究已经足够成熟,可以为从业者提供具体数字,而非模糊的承诺。在分类、问答和工具调用任务中,固定示例与检索示例之间的差距通常大到足以证明工程投入是值得的。

在 2025 年一项跨七个 LLM 的临床笔记分类研究中,基于动态嵌入的检索相比零样本基线实现了宏观 F1 指标 39.3% 的提升,相比静态少样本基线提升了 21.1%——评估中的每个模型在动态选择下都取得了最高 F1 分数。对于知识图谱问答任务,动态选择在 LC-QUAD 2.0 上比静态示例高出 +21 个 F1 点(85.45 对比 64.46),在 QALD-9 Plus 上高出 +12 个点。

工具调用任务也呈现出类似的显著差距。用 Claude 进行结构化工具调用实验,准确率从零样本的 16% 上升到三个语义匹配示例下的 52%——一个较小的模型从 11% 跃升至 75%,实际上弥合了与更大模型零样本性能之间的差距。

机制上很直观:静态示例集只能覆盖其设计所针对的查询空间。每一个偏离该分布的请求,都只能得到勉强有用的示例。动态检索则选取与实际查询相似的示例——当示例与当前输入共享表层结构、实体类型和推理模式时,模型的上下文学习效果会大幅提升。

检索栈的工作原理

架构很直接:在构建阶段,使用句子编码器(MiniLM 或 SBERT 之类的模型效果不错;针对任务微调的编码器效果更好)对每个输入输出示例对进行嵌入,并将向量存入可检索的索引。推理时,对输入查询进行嵌入,运行近似最近邻搜索检索出 top-k 个最相似的示例,然后将它们注入提示中。

在合理的数据集规模下——1 万到 10 万个示例——使用 HNSW 的 FAISS 可以在亚毫秒级完成搜索,召回率超过 95%。托管向量数据库(Pinecone、Weaviate)会增加 1-5ms 的网络开销,但省去了基础设施管理。用小型编码器对查询进行嵌入需要 5-20ms。P50 下的总检索开销通常在 10-30ms。

对于需要最小化延迟开销的团队,基于聚类的预计算是一种选择:离线对示例池按嵌入进行 K-means 聚类,推理时将查询路由到最近的聚类,在该子集内搜索。这以牺牲少量召回率换取了大幅缩小的搜索范围。

混合检索(将 BM25 关键词匹配与稠密向量搜索结合)始终优于任何单一方法。BM25 在精确匹配查询上表现出色——代码模式、实体名称、领域专有术语——因为稠密嵌入会低估表层形式的权重。通过 Reciprocal Rank Fusion(RRF)或加权分数组合将两者结合,比纯向量检索的 nDCG 提升约 5%。如果你的查询包含代码、ID 或命名实体,混合检索是值得的额外复杂度。

最有原则的检索方式——NAACL 2022 的 EPR 方法——使用 LLM 反馈作为监督信号来训练双编码器检索器。它选择的不是"相似"示例,而是真正帮助 LLM 产出正确结果的示例。代价是需要一个代理 LLM 和标注输出用于训练阶段,这使得它只在拥有特定任务数据且质量要求很高时才实用。

没人警告你的排序效应

一旦获得了 k 个检索示例,将它们注入提示的顺序并非中性。相同的示例集,重新排列后,在相同输入上的准确率可能从接近最优水平跌落到接近随机水平。

LLM 同时表现出首因偏差(锚定早期示例)和近因偏差(锚定查询前最后几个示例)。机制可解释性研究表明,LLM 内部特定的注意力头会持续优先处理提示中的最后一个示例,这以具体方式解释了近因偏差——不是行为怪癖,而是架构属性。这些偏差的大小因模型架构和任务而异,没有一种普遍优越的排序方式。

实际影响:如果你动态检索的示例碰巧共享一个多数标签——比如三个示例的正确答案都是"正面情感"——而你把它们放在最后,那么模型会在当前输入上产生明显偏向预测该标签的倾向,即使这是错的。

几种值得默认应用的缓解措施:

  • 对每次请求的检索示例顺序随机化,以平均化偏差而非持续放大它。
  • 在注入前检查检索集的标签分布;如果分布严重偏斜,则重新平衡。
  • 优先使用同时优化多样性和相关性的检索方法——MMR(最大边界相关性)会惩罚近乎重复的示例,产生更多样化的选择。

序列选择方法(如 ACL 2024 的 Se²)通过将示例选择视为带束搜索的序列决策问题,系统性地解决了这个问题。这类方法不是对每个候选示例独立评分,而是考虑示例间的相互关系——给定已选示例,这个示例能增加什么?结果是更连贯、更多样的选择。在 23 个 NLP 任务上,这种方法比随机选择提升了 42% 的相对性能。

示例投毒是一种无声的失败模式

动态检索最危险的特性是:示例池中少量的坏示例可以悄无声息地降低大量请求的质量,而不产生任何可见的错误信号。

"坏"并不意味着是对抗性注入的(尽管这种风险是真实存在的——下文会提到)。在大多数生产系统中,坏示例是日常运营的结果:产品转型期间添加的示例,已不再匹配当前任务框架;当时正确但反映了过时业务规则的示例;格式与当前提示模板略有偏差的示例。

当一个坏示例被检索到时,效果不是崩溃——而是输出结构上看起来正确,但实际上是错的。在分类任务中,这表现为对与坏示例相似的查询的系统性误分类。在生成任务中,产生的输出具有错误的语气、结构或事实框架。这两种失败都不会发声。

"少样本崩溃"现象(2025 年研究跨八个模型和四个任务记录)是这种问题的极端版本。在一个案例中,在 4-shot 下准确率达到 64% 的模型在 8-shot 下跌回 33%——与零样本持平——因为额外检索的示例是净负值。更糟糕的是,一种基于 TF-IDF 的动态选择方法导致一个大型开源模型在 2-shot 下准确率崩溃至 35%,而固定示例下超过 50%——这是检索方法主动造成质量退步的案例。

对抗性投毒是同一问题的更难版本。NAACL 2025 的研究表明,对示例池进行同义词替换和对抗后缀注入可以在不破坏明显过滤器的情况下污染检索。推荐的对策是把你的示例池当作生产依赖项来对待:版本控制、变更代码审查,以及通过保留集评估进行监控。不再经过离线评估验证的示例应被标记为待审查,而不是悄悄留在池中。

生产监控建议:

  • 追踪每次查询的检索距离。随时间上升的平均距离意味着输入查询正在偏离示例池——这是池需要刷新的无声信号。
  • 监控每批检索示例的标签分布。对某一标签的系统性偏斜是示例被投毒或过时的先行指标。
  • 每月在保留集上进行有无检索的 A/B 评估。如果静态示例基线在缩小差距,则调查示例池。

静态示例获胜的场景

有四种情况的成本收益分析支持静态示例,团队应该诚实面对这些情况,而不是把动态检索当作架构地位的象征来追求。

提示缓存的经济性不可忽视。 当静态示例出现在提示开头时,服务商会缓存 KV 计算结果并在请求间复用。这种缓存使首字节中位延迟降低约 65%,并在规模上带来可观的成本节省——以每天 1 万次请求估算,每年约节省 237,500 美元。动态检索每次请求都改变提示前缀,消除了这种缓存复用。对于高流量、对延迟敏感的应用,经济账可能倾向于精心维护的静态示例集,而非动态检索。

输入分布窄且稳定。 如果你的用户只提交三种类型的查询——而非上百种——那么覆盖这三种类型的静态集操作更简单,行为更一致。动态检索的优势与输入分布的方差成正比。方差低意味着优势小。

格式和风格强制执行。 对于主要目标是输出格式一致性的任务(JSON schema 遵从、品牌语调、法规措辞),人工验证的静态示例比动态检索的示例更可靠,因为后者在整个池中的格式可能各异。静态示例中结构的一致性能教会输出的一致性;异质的检索池则教会异质的风格。

早期阶段验证。 在构建检索基础设施之前,静态示例可以验证少样本方法是否对该任务有效。如果 3 个手写示例不能提升质量,50 个检索示例也可能无法做到——你省去了构建错误系统的麻烦。

迁移到动态检索的实践建议

一些从文献中看不出来的实现决策:

将检索示例注入提示的末尾,而非开头。 许多团队出于组织原因将少样本示例放在系统提示中。这对动态示例来说恰恰是错误的位置——它阻止了静态系统提示的 KV 缓存复用,意味着你指令中的每个 token 都要为每次请求重新计算。相反,将检索示例作为伪对话轮次注入,紧接在用户消息之前。静态系统提示得以缓存;只有动态注入部分产生边际计算开销。

从 3-5 个示例开始,不要默认增加。 研究一致表明,超过 5 个示例后,额外的样本提供的收益微乎其微,甚至对模型具有强先验的任务有害。如果你发现自己在想"不如加 10 个示例",先调查一下微调是否才是正确的工具。

验证示例池,而不只是单个示例。 一个有 1000 个示例、其中 8% 过时或略有错误的池,从功能上讲就是一个被投毒的检索系统。在任何示例进入生产前,建立一个简单的离线评估流水线。基础检查——LLM 在该示例存在时是否产出正确输出——每个示例只需几分钟,就能捕获大多数质量退步。

优先选择不重复的示例。 对多样本学习的研究发现,将一小组示例重复多次"显著落后于"用同等 token 预算使用唯一示例。这也适用于检索池:覆盖输入分布的 200 个多样化示例,比围绕同几种查询类型聚集的 1000 个示例检索效果更好。

动态少样本检索是已经优化了提示和系统指令的团队可用的高杠杆干预措施之一。10-40% 范围内的质量提升是真实且可重现的。失败模式——排序偏差、示例池退化、KV 缓存破坏——在运营纪律下是可以管理的。代价是你现在在 LLM 旁边运营着一个检索系统,这意味着它需要与任何其他生产依赖相同的关注:版本控制、监控,以及处理漂移的流程。

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