你精心挑选了5个少样本示例,塞进系统提示词,上线。测试集通过率漂亮,生产环境仪表盘数字稳定——直到一封邮件砸进来:一个退款咨询被错分成物流问题,用词和你的5个示例毫无相似之处。

这是每个静态少样本提示词终将撞上的墙。5个示例只能覆盖输入分布的头部,尾部无处不在,而真正的bug都藏在尾部。

打开网易新闻 查看精彩图片

解法是把示例从常量变成检索问题。每个查询进来,从库中拉取最相似的k个历史示例,注入提示词,再调模型。提示词随查询变形。下面70行代码就是全部。

手工挑选示例本质是抽样问题。你读了50条工单,选5个"有代表性"的,上线。这5个锚定了模型对所有后续输入的行为——长得像这5个的能泛化,不像的就翻车。

三股力量让情况随时间恶化:

你可以靠堆更多静态示例暂时掩盖。到20个开始吃上下文预算,到40个明显拖慢每次调用、抬高单请求成本,到60个模型开始忽略列表后面的示例。示例数量与准确率的关系绝非线性。Anthropic的提示工程指南建议多数任务用3到5个,正对应这个天花板。

天花板不是示例数量,而是它们是否匹配眼前的查询。

建一个库:历史输入配正确输出。把库中每个输入嵌入向量存储。查询时嵌入新输入,检索最相似的k个示例,格式化进提示词,调模型。库可以是测试集、历史标注数据、或过去修正的反馈日志。

相比静态,三处变化:

成本是每次查询一次嵌入查找(热内存索引上约几十毫秒),上下文窗口仍装5个示例,只是按查询动态挑选。k值可在3到10之间调,代码改动很小。

动态胜出的场景,按影响排序:

静态仍赢的场景:

数据量经验法则:少于约50条标注,保持静态;超过约200条,动态几乎总赢;中间区间,两边跑eval让数字说话。这些是启发式而非实证发现,有条件时锚定到自己的测试集。

下面是完整Python实现。用Anthropic做对话调用,本地sentence-transformers做嵌入(无需搭建向量数据库即可运行)。真实部署时,把内存numpy索引换成pgvector、Qdrant或你现有栈里的方案。