上下文学习(ICL)的原理与边界:为什么几个示例就能提升性能
一、从一个上线事故说起
去年我接手过一个工单意图分类系统:没有微调预算,只在提示词里放 8 条标注示例,准确率从 62% 直接涨到 88%。团队很兴奋,准备直接上线。结果我在验收时随手把示例顺序打乱重跑了一遍,准确率掉回 71%。更诡异的是,当某个类别的示例在 8 条里占了 5 条时,模型开始把大量中性问句也判进那个类别——即使那 5 条示例本身完全正确。
这两次翻车指向同一个事实:上下文学习(In-Context Learning, ICL)不是「示例越多越好」的线性叠加,而是一个有明确机制、也有明确边界的条件推理过程。绝大多数关于 ICL 的工程事故,都源于把它的输出当成了「微调出来的分类器」,而忽略了它本质上是在推断任务,而不是学习映射。
这篇文章想解决三个问题:ICL 究竟在模型内部做了什么?它在哪些任务上会失效?以及,如何用一套可复现的代码框架,把示例选择、顺序、标签平衡这些「玄学」变成可量化的工程参数。
二、ICL 的精确定义:冻结参数下的条件推断
给定一个参数冻结的预训练模型MθM_\thetaMθ、一个待分类的查询xxx,以及示例集合S={ (x1,y1),…,(xk,yk)}S=\{(x_1,y_1),\dots,(x_k,y_k)\}S={(x1,y1),…,(xk,yk)},ICL 输出的就是把这个上下文拼接后做自回归解码:
P(y∣x,S;θ)=∏t=1TP(yt∣x,S,y<t;θ)P(y \mid x, S;\theta) = \prod_{t=1}^{T} P\left(y_t \mid x, S, y_{<t}; \theta\right)P(y∣x,S;θ)=t=1∏TP(yt∣x,S,y<t;θ)
这个式子看起来平淡,但有三点在工程上极其重要:
第一,θ\thetaθ从不更新。所有的「学习」都发生在一次前向传播的激活值里,模型权重、优化器状态全程不变。这既是 ICL 的最大优势(零训练成本、秒级切换任务),也是它最大的天花板(不可写入新知识)。
第二,SSS