阶段 7 · 用起来

上下文学习:一个权重都没改
模型却学会了新任务

上一章《评测、基准与幻觉》说:单次分数不算数——这一章说明它为什么会飘。 2020 年 GPT-3 的论文发现:写几个例子,模型就能做训练时没教过的事—— 这不是微调,参数一个都没变。

1

先说清楚这件事有多反常

在有「上下文学习」之前,让模型学会一个新任务的流程是这样的: 标注几千条数据 → 微调 → 得到一个专用模型。每次换任务都得重来一遍。

上下文学习把这个流程压成了一句话:

输入:猫 → 猫猫
输入:狗 → 狗狗
输入:鸟 → ?

模型输出:鸟鸟

它从来没有被训练过"把词重复一遍"这个任务。它是从你给的两个例子里,现场推出的规律。

三个名词,一件事

零样本 Zero-shot:不给例子,直接问。
单样本 One-shot:给 1 个例子。
少样本 Few-shot:给几个例子(通常 4~8 个)。
区别只是你给了几个例子,模型本身没有任何变化。
注意:此处的「零样本」说的是提示里给不给示例;CLIP 的「零样本分类」是另一回事—— 指不针对该类别训练。见 ViT / 多模态章。

互动 · 「给几个例子」到底改了什么

🎯 类比

像找一个见多识广但从没上过这门课的人。
你不教他理论,只是给他看两道例题,然后递上第三道。他看一眼就说:"哦,你是想让我把字重复一遍。"
他不是学会了这个任务,他是认出了这个任务的模式。 这就是上下文学习最接近真相的描述——它更像识别,而不是学习。

2

为什么给几个例子就能学会

答案藏在预训练数据里。互联网上到处都是"对照表":

单词表、词典条目、API 文档的输入输出示例、Excel 公式说明、
教程里的 "so that"、"that is"、"翻译如下"、"示例如下" ……
这些文本的共同结构就是:给几个输入输出对,然后来一个新的输入

模型在预训练时见过海量这种文本。它学到的不是"重复字"这条规则, 而是更抽象的一层:"当上下文呈现成这个形状时,我应该找出其中的映射关系,并把它用在新输入上。"

预训练学到的东西 不是"猫→猫猫"这个映射,而是"识别并延续模式"这个元能力
推理时做的事 把当前提示当成一个新的"对照表",现场做一次模式归纳——归纳的结果只活在这一轮对话里

同一副骨架,可以装任何任务

模型在预训练里见过成千上万段这样的文本。它记住的不是某一对答案,而是这个骨架——所以你在提示里摆出这个骨架,它就知道该干什么。

为什么给例子比讲规则更有效?因为例子直接匹配了模型在预训练里见过的那个"形状"——它认得出这是张对照表;而"请把每个词重复一遍"这种自然语言指令,是它见过得少得多的形状。 能示范就别解释——这是提示工程(不改模型权重,只改你写进提示的文字)里性价比最高的一条。

3

亲手跑一遍:例子越多越好吗

下面这个演示实现了一个"模式归纳器"—— 内置一池候选规则(重复、反转、取后两个字、加后缀……), 用你给的例子给每条规则打分,再用得分最高的规则去预测。 然后拿一整套测试任务跑一遍,统计这个示意模型自己的准确率。

先说明:本节和下面的曲线、读数都来自本页自搭的示意模型,它只把「只读最前面几个例子」和「注意力饱和」写成两条规则——趋势与真实大语言模型(LLM)一致,不是对某个真实模型的实测。

互动 · 示意模型里,例子数量对准确率的影响

互动 · 每多一个例子,能排除掉多少种可能

💡 这一章的核心大图

上面那条虚线(还活着的候选规则)就是「例子越多越准」的全部机制:每多给一个例子,能被解释的候选就少一批;两三个之后通常只剩一条,预测就唯一了。 准确率猛涨不是模型变聪明,是能被误选的规则已经被筛没了。

例子个数会发生什么
太少模型抓不住规律
4~8 个最好——「少样本」的「少」不是客气话,它真是个最优区间
太多① 例子占满上下文,真正的任务说明被稀释;② 例子之间可能冲突(同一个输入不同标签);③ 上下文越长,中间部分越容易被忽略(Lost in the Middle:关键信息放在长上下文中间时最容易被漏掉,见《RAG 检索增强》)
4

同一批例子,换个顺序结果就变

理论上,示例的顺序不应该影响结果——它们提供的信息是完全一样的。 但实际上影响非常大。而且这个影响不是随机的。

互动 · 同一批例子,打乱顺序后的波动

互动 · 同一批例子,只换顺序,准确率会跳

互动 · 模型会照抄示例里的标签比例(标签偏置)

效应表现机制猜测
位置偏好 最前面、和紧挨着查询的例子,影响都比较大;中间的最弱 在注意力里,靠开头和靠查询的 token 更容易被读到。本页的示意模型把它简化成「只读最前面几个」,所以顺序一变,进窗口的例子就变了
标签偏置 如果例子里"正面"出现得比"负面"多,模型会倾向答"正面"——哪怕查询明显是负面的 模型从示例里算了标签的先验分布,并把它当成了答案的先验
随机改错标签 把示例里的标签随机改错,性能几乎不掉——典型只降 0–5% 说明模型主要依赖示例的格式和标签空间,而不是标签是否正确
示例格式的一致性 示例文本和标签的分隔符是否统一,影响很大 格式是模型识别"这是对照表"的信号
⚠️ 这件事的工程含义很重

如果你的提示效果对示例顺序敏感,那么:
① 你测出来的效果不稳定——换个顺序可能差 10 个点;
② 你看到的"某次调用效果特别好"很可能是运气,不是提示写得好;
③ 上线后用户输入变化,顺序效应会以你无法复现的方式影响结果。
正确做法:评估提示时至少跑 5~10 种随机顺序,看均值和方差。只看单次结果的自测是没有意义的。

推荐的摆法:把最有区分力的例子放最前面(这个示意模型的窗口只读最前几个);把和查询最像的那个放最后(真实模型通常在结尾处读得更清)。

5

提示工程的技巧,每条都有机制

下面是真正被验证有效的几条。注意:每一条都有一个"为什么", 而不是"大家都这么做"。

互动 · 为什么「一步步想」有用:把一步大计算拆成几步小计算

四条技巧串起来看

把上面四条放在一起看,会发现它们是同一个逻辑的不同侧面: 模型的行为由"当前上下文最像训练数据里的什么"决定。
· 角色设定 → 让上下文更像某类语料
· 输出格式约束 → 缩小候选空间,让"最像的那个"更明确
· 分步骤 → 把串行推理外化,让每一步都变成独立的、简单的模式匹配
· 示例顺序 → 改变了上下文的形状,从而改变了"最像什么"
提示工程本质上是在做"上下文检索":不用去数据库里查,要的是在模型的训练分布里找到最匹配的那块区域。

6

这些坑几乎人人都踩过

症状真实原因怎么修
输出格式时对时不对 你只在指令里描述了格式,没有在示例里展示它 在示例里就把格式写死。用 JSON 就每个示例都是 JSON
约束互相打架 "要详细" + "不超过 50 字" + "覆盖所有要点"——三条在长回答上不可兼得 给约束排优先级,或者干脆减少约束数量
关键信息被忽略 上下文很长时,开头和结尾被记住的概率远高于中间(Lost in the Middle) 把最重要的指令重复一次放在最后,或把关键材料放开头
混入了无关内容 无关文本会稀释信号,而且可能意外匹配到别的模式 删掉所有"以防万一"的补充说明
换个模型就废了 提示是针对某个模型过拟合出来的——它利用了那个模型的特定偏置 写提示时保留"为什么这样写"的理由;换模型要有回归测试集
示例写错了但效果更好 如果示例标签全是同一个,模型会学到这个偏置,在某些测试集上"看起来"准确率更高 这是假的提升。检查示例的标签分布是否均衡

互动 · 上下文越长,中间那段越容易被忘记

🎯 类比

写提示像给一个极其聪明但从没来过你公司、而且看不见你表情的新同事写工单。
他不会问你,也不会猜你的意图——他严格按字面理解,并且会下意识地模仿你给的任何样例。
所以:你说的话会被字面执行,你做的示范会被完全照抄。 当这两者冲突时,他通常听示范的。

7

从零样本到自动优化提示

互动 · 点一下看每一步在改什么

互动 · Self-Consistency:多采几条一起投票,值不值

方法核心做法什么时候值得用
Zero-shot直接下指令,不给例子 任务简单、模型足够强。迭代最快
Few-shot给 4~8 个示例 最通用的做法。任务是"照格式做事"时尤其有效
CoT 思维链要求"一步步想",或示例里就带推理过程 数学、逻辑、多跳推理。本质是把串行计算外化到上下文
Self-Consistency采样多条推理路径,对答案投票 有唯一正确答案的任务。代价是 N 倍成本
ReAct让模型交替进行"推理"和"调工具" 需要外部信息或计算的任务(《Agent 与工具调用》的基础)
APE / OPRO让模型自己生成并迭代优化提示 有明确评估指标、且你愿意跑很多次调用时
DSPy把提示当成可编译的程序,用数据自动调优 有几十到几百条标注数据、想要可复现的流水线时
M

数学 · 例子是怎么把规则筛出来的

前面说模型会「现场归纳规律」。把它拆开其实只有两步: 每条候选规则先算一个分,再用分数投票。 下面这张表就是那两步——拖一下例子个数,看规则一条条被淘汰。

默认给了 3 个例子,但模型只读最前面的 2 个(注意力饱和),多出来的第 3 个不参与打分——所以下面公式里的分母是 2。

互动 · 一张打分表:九条规则,谁还活着

这张表就是这一章唯一的公式(上面那张卡)在跑:c 是「能解释几个被读到的例子」,π 是这条规则本身多常见,s 是两者的合成。 一个例子能排掉一批候选,但排得最少;到两三个例子之后,通常只剩一条规则能解释全部被读到的例子——预测就唯一了。

8

为什么提示工程让人又爱又恨

问题说明什么时候真的会痛 → 换什么
极度依赖模型 一条精心调过的提示,换一个模型版本可能直接失效。 模型升级本来该是好事,却变成了回归测试的负担 版本一升就翻车、要重调 → 写提示时保留「为什么这样写」的理由,建一组回归测试集(固定输入,用来确认改动没把原来好的弄坏)
效果不可复现 温度不为 0 时,同一个提示每次结果不同;示例顺序一变效果就飘。 你没法像代码那样"跑一遍确认它还对" 要可复现的线上效果 → 温度调低、示例顺序固定,并跑多种顺序看方差
脆弱得不像工程 加一个句号、把"请"去掉,效果可能变化。 这让提示变得难以维护——你不知道哪一句是真正起作用的 提示要长期维护、多人协作 → 别把它当代码管;用 DSPy 这类把它编译成可复现的流水线
上下文是花钱买的 示例越多,每次调用的输入 token 越多。20 个示例可能让成本翻几倍, 而收益早已进入平台期 调用量大、按 token 计费 → 停在曲线的拐点(3~4 个示例),别靠堆示例
无法真正"教"新知识 上下文学习只能激活模型已经会的能力或模式。 它学不会训练数据里完全不存在的东西 要灌新知识 / 新语言 → 继续预训练(把知识写进权重)或 《RAG 检索增强》;行为类微调做不到这件事(见 《LoRA 与高效微调》)
提示本身可能被攻击 用户输入里如果混进"忽略以上指令",模型可能照做。 这是提示注入(Prompt Injection) 用户输入不可信、会拼进提示 → 见 《对齐、安全与越狱》

互动 · 例子越多,每次调用越贵

互动 · 把两边放一起:每多花一千 token,能换回多少准确率

9

小结

这一章只推了一条公式(就在上面「数学」那节),但它仍然落在七条线里某一条上。

它对应哪条线 ② 没有免费午餐 → 必须有归纳偏置——几个例子之所以管用,是因为预训练给模型留下了一个偏置: “上下文里的模式,就是要执行的任务”。
一句话 这一章的现象,本质上是在用几句话去“触发”一个预训练时就形成的偏置—— 不是模型在学,而是那个偏置被点亮了。
它牺牲了什么 牺牲了稳定性与可复现性。触发式的东西对措辞、顺序、标签分布极其敏感(第 4 节), 所以同一个提示你今天能用、明天可能就不行。
💡 检验一下:你现在能指着哪个互动说这句话

回到第 4 节那张“打乱顺序后的波动”。把「例子个数」滑杆拖到 6, 再看那几根柱子的高度差——同一批例子,只是换个顺序,准确率就上下跳。

那个跳动就是“触发,不是教学”的证据:如果模型真在学一套固定规则,顺序不该有这么大影响。 它在乎,说明答什么取决于上下文里放了什么——这是一次前向的匹配,不是权重里的稳定知识。 如果你刚才没有想指着那几根柱子说这句话,这一节对你就是没用的——回到图上再拖一次。

互动 · 只看一次结果,等于只看运气

它在暗线里站在哪

暗线这一章的回答
A 信息流动 一个提示 = 系统指令(平台预先设定、用户看不见的那段)+ k 个「输入→输出」例子 + 1 个查询,全部拼成一条 token 序列;模型只在最后一个位置取出一个概率分布,权重零更新
C 参数账本 0 个参数被更新——全站唯一训练成本为零的一章。但推理成本不是零:7B 模型 fp16 权重约 14 GB,每生成一个 token 都要把它基本读一遍;提示从 2-shot 加到 8-shot,输入长度约翻 3~4 倍。KV 读写随 token 数线性增长,注意力算力是平方级
F 违背了哪个直觉 直觉是「不更新权重就没法学新东西」;这一章整个在说:不更新权重也能改行为
🎯 前后钩子

它接住了上一章的什么:《评测、基准与幻觉》讲的是怎么判断模型行不行; 这一章解释为什么同一个提示的分数会飘——看单次结果不算评测,得跑多种顺序。

它给下一章留了什么:例子多到放不下时,得先按相关度把最该放的那几条挑出来 → 《向量嵌入与检索》。再往后,有些任务靠措辞永远做不成,那就得动权重 → 《LoRA 与高效微调》。

一句话带走上下文学习

上下文学习 = 不更新任何权重,只在提示里给几个例子,模型现场归纳出规律——它做的是认出并延续预训练里见过的模式形状,所以示范比解释有效。
顺序和标签比例会明显改变结果,评估提示必须跑多种随机顺序、看方差,不能只看单次。

10

拓展阅读

上面讲的都是「够用」的版本。想往下挖,这里有三个入口—— 它们不是必修内容,是给想再往前走一步的读者准备的。

📄 这一章的说法从哪来

💻 工业界怎么写

∑ 更严格的形式