上下文越长,模型真的越差吗?
本课一问:第 1 课说「窗口迟早会满」。那没满之前呢?窗口标称 128K,塞到 100K 也照样好用吗?
这一课先不碰:怎么压缩(第 2 课)。这里只问:上下文变长这件事本身,会不会让模型变差。
从已有出发
第 1 课的账只回答了「装不装得下」。可装得下不等于用得好:同一个任务,把相关的那几行放在 1K 的上下文里,和埋在 30K 的上下文里,模型找得到的概率一样吗?换例子的原因:我们贯穿任务的上下文最长才两千多 token,测不出这个效应,所以这一课用公开的论文数据。
先猜,再看
数据:Modarressi 等,NoLiMa: Long-Context Evaluation Beyond Literal Matching(ICML 2025),arXiv:2502.05167v3 表 3(arXiv HTML 版,需联网;2026-09-26 转录)。数值从 arXiv HTML 版表格的文字转录(不是从图上估读);Base Score = 250/500/1K 三档里每题最高分的平均,×0.85 为阈值;有效长度 = 仍高于阈值的最大测试长度。58 组问题-针,5 组针,10 本开放版权书作干草堆。 任务是「针在干草堆里」的变体:问题和答案之间几乎没有字面重合,模型要靠语义联想找到那句话。它测的是长输入下的检索与联想,不是编码任务;迁移到 agent 场景时只能当方向性证据。
试三件事:① 先在每个长度上点出你的猜测,再点「揭示」;② 高亮 GPT-4o:它在 1K 时 98.1%,看它在哪一个长度第一次掉到黄线(基线 × 0.85)以下;③ 高亮 Llama 3.1 8B:它和我们录制用的 Qwen3-8B 同一个量级,注意它从 1K 就在往下走。
揭示之后能读出两件事:
- 长度本身就在伤害结果。这个测试里问题和答案之间几乎没有字面重合,模型得靠语义联想去找那一句;13 个模型里,到 32K 时有 11 个跌到了自己短输入成绩的一半以下。32K 只是它们标称窗口的零头。
- 「有效长度」远小于标称窗口。论文把「仍高于基线 × 0.85 的最大长度」叫有效长度:GPT-4o 是 8K,其余 12 个里有 12 个在 4K 及以下。LLM 课 C2·L5 从位置编码的角度讲过同一件事:窗口长度不等于有效长度。
Chroma 的《Context Rot》(2025-07-14)在更多设置下看到了同一个方向:18 个模型(含我们录制用的 Qwen3-8B),六类实验,包括把同一批问题分别放在约 300 token 的精简上下文和约 113k token 的完整对话里(LongMemEval,306 条)。它的各模型曲线只在报告的静态图里,本页没有转录,需联网看原文。
标称窗口是「放得下」,不是「用得好」。对 agent 的直接推论:能少放就少放——这正是第 2 课「先裁工具输出」、A7「让子 agent 去读、只把结论带回来」的动机。
另一个常被当成定律的说法是「上下文用到约 40% 就进入 dumb zone」(Dex Horthy 的演讲《No Vibes Allowed》)。那是讲者的个人经验断言,没有实验支撑;可以当提醒,不能当阈值。
我们自己的 trace 里:一次真实的「上下文中毒」
Anthropic 对 context rot 的官方表述是:上下文里的 token 越多,模型准确回忆其中信息的能力越下降(《Effective context engineering for AI agents》)。Drew Breunig 把长上下文的失败分成四种(《How Long Contexts Fail》,2025-06-22):中毒(poisoning,一个幻觉或错误进入上下文后被反复引用)、分心(distraction)、混淆(confusion)、冲突(clash)。
四种里,我们的短 trace 测得出的只有第一种,而且证据很完整。分层压缩那条运行(pd-v2-layered-s1)一共写了 17 份摘要,其中 16 份提到了 timezone(时区处理)——而这个任务从头到尾,任何工具输出、任务说明、system prompt 里都没有出现过这个词:
- 第 5、9 轮之前的那 2 份,摘要模型收到的输入里没有 timezone,是它自己编的;
- 其余 14 份,输入里已经带着上一份摘要,上一份摘要里就写着 timezone——编出来的东西被当成事实一份份传下去。
这些摘要里写的「可能是时区处理的问题」,把模型的注意力往一个根本不存在的方向引了十几轮。第 4 课会把这些摘要逐份拆开看。
🔍 另外三种失败,我们的数据为什么测不出来?
分心要足够长的上下文才出现(Breunig 转引的 Databricks 研究里,Llama 3.1 405B 在约 32K 开始变差,更小的模型更早);混淆与冲突需要多套工具或互相矛盾的信息源。我们的任务只有 6 个工具、上下文不到三千 token。本页不为它们编例子,想看例子请读原文(需联网)。
证据三问
| 问 | 本课的回答 |
|---|---|
| ① 它解决什么问题? | 提醒「装得下」不等于「用得好」:上下文要尽量短、尽量相关 |
| ② 为什么可能这样? | 注意力要在越来越多的位置之间分配,相关的那几个位置更难被选中;位置编码在远距离上也没训练充分 证据等级 · 有理论动机 有数学或机制上的理由说明它可能有效,但没有证明它一定更好。最后是否采用,仍然要看实验。 本条机制解释,不是证明;LLM 课 C2·L5、C3 讲过相关机制。 出处待补 |
| ③ 实验上呢? | NoLiMa:13 个模型、6 个长度,多数在 32K 前明显下降 证据等级 · 实验验证 由对比实验得出的经验结论,只在出处写明的模型、数据和规模下成立。换了条件可能不再成立,引用时要带上实验设置。 本条第三方研究;任务是检索与语义联想,不是编码;模型多为 2024–2025 年的版本,更新的模型可能更好。 出处NoLiMa · ICML 2025 ↗需联网 ;Chroma 18 个模型同方向 证据等级 · 实验验证 由对比实验得出的经验结论,只在出处写明的模型、数据和规模下成立。换了条件可能不再成立,引用时要带上实验设置。 本条第三方研究(Chroma 是向量数据库公司,有推广检索的立场);曲线只在静态图里。 出处Chroma ↗需联网 ;我们 trace 里的中毒是项目实测的单次运行 证据等级 · 实验验证 由对比实验得出的经验结论,只在出处写明的模型、数据和规模下成立。换了条件可能不再成立,引用时要带上实验设置。 本条项目实测:一条运行、17 份摘要;能说明现象存在,不能说明频率。 出处待补 |
演进地图
这一课不在演进链上:它解释的是整条链的动机——为什么要把上下文压小,而不只是「不超窗口」就行。
- A1 的循环(所有 harness 的底层事实:模型 API 不记得上一轮)解决了实现最简单,模型每轮都看得到全部经过。卡在pd-v2-cap20-s1 从第 1 轮的 947 token 涨到第 11 轮的 2,618;第 1 轮里工具定义就占 72%,到最后一轮工具结果占 44%。只增不减,总有撞墙的一轮。
- 朴素 超了就截掉最早的本课项目 miniagent 的 truncate(整轮丢,保留 system 与任务)、learn-claude-code s08 的 snip_compact(中段存档)解决了零成本,还能保证 tool 调用与结果不被拆散(按整轮丢)。卡在pd-v2-truncate-s1 截断 2 次共丢 3 轮,读文件那一轮也在其中;第 7 轮模型凭记忆改,那一行变成
+ 1 + 1,验收测试退出码 1。 - 先便宜 先裁工具输出,不花一次推理CoreCoder Layer 1、learn-claude-code micro_compact、OpenCode prune(默认关)、Anthropic tool result clearing解决了工具结果是最占地方、也最可再生的一块;裁它不用调模型。卡在按位置裁,不懂内容:分层运行里被裁过的 0 份测试输出,0 份丢了唯一关键的 AssertionError 行。另一头,本任务最长的工具输出 1,302 字符,CoreCoder 的 1,500 字符门槛一次都没碰到。
- CoreCoder 50 / 70 / 90%、Pi 窗口 − 16,384、OpenCode 窗口 − min(20,000, 最大输出)、Codex 90%解决了阈值定在撞墙之前,给压缩本身和下一次回复留出余地。卡在本地估算在中文上偏低:一段真实中文 118 token(录制模型的 tokenizer),CoreCoder v0.4.0 估成 60,按「字符数 ÷ 4」估成 45。只靠本地估算触发,就会晚。
- 再花钱 让模型把旧轮次写成摘要CoreCoder Layer 2、本课项目 miniagent L2解决了比截断保留更多:旧轮次不是消失,而是被压成一段话。卡在pd-v2-layered-s1 的 17 份摘要里,写下确切报错的 0 份,编出不存在的「timezone」的 16 份;第 10 轮模型把改对的一处改了回去。21 轮、73,168 token(摘要另花 11,832)才完成,是同组不压缩成功运行最少的 4.3 倍。
- Codex(交接摘要 + 保留用户原话)、Pi(结构化模板 + 文件清单)、OpenCode(五节模板)解决了把「必须留下什么」写进模板:目标、约束、进度、确切报错、下一步、相关文件;完整历史留在磁盘上。卡在仍然有损。Codex 每次压缩后提醒用户:「Heads up: Long threads and multiple compactions can cause the model to be less accurate. Start a new thread when possible to keep threads small and targeted.」→ 下一章:会话存在哪、明天还记得吗。
数字口径:本课项目 miniagent 用 Qwen/Qwen3-8B-MLX-4bit 本机录制的真实运行(2026-09-26),每轮发出的消息由重放得到并与录制的压缩事件、服务端 usage 逐轮核对一致;估算器的输出由 CoreCoder、Pi 的原实现在 pin 源码上跑出(a05-context.json,2026-09-26)。耗时不作比较(本机有其他任务同时占用)。
一句话
回到主线
最省事的办法:截掉最早的消息,行不行? → 第 2 课
你可能会问
- 「那窗口越大的模型越没用吗?」 不是。大窗口让你「放得下」,真正要做的是别把放得下当成要放满:把最相关的放进去,其余留在磁盘上按需取(第 2、4 课;A6、A7)。
- 「我们录制用的 Qwen3-8B 表现怎样?」 它在 Chroma 测试的 18 个模型里,但各模型的曲线只在报告的静态图里,本页没有转录;要看请打开原文(需联网)。NoLiMa 表 3 的 13 个模型里没有 Qwen。