100 万 token 真的都能被"看到"吗
100 万 token 大概是 75 万字、7.5 万行代码,一个中型项目整个塞进去没问题。但 Transformer 的核心机制 self-attention 决定了,模型在生成每个 token 时,不是均匀地"看"所有历史内容,而是挑最相关的几个来参考。注意,是"几个",不是"所有"。
把 attention 的权重分布可视化出来,你会看到一个非常稳定的 U 型曲线:开头权重高,结尾权重高,中间塌下去了。
原因有两个。一个是 softmax 函数的特性,它本质上是 winner-take-all——只要某几个 token 的分数稍微领先,就能拿走绝大部分注意力。开头的 token 因为在训练过程中被反复引用,逐渐变成了"注意力黑洞",学术上叫 Attention Sink。另一个是 RoPE 位置编码让 token 之间距离越远、相关度越低,模型天然偏爱最近的内容,这叫 Recency Bias。
头尾强,中间弱。你把关键信息藏在 10 万字的中间?大概率被忽略。
但更要命的是 Attention Bandwidth 这个概念。模型每一步推理时真正能关注的 memory slot,可能就几十个。你塞了 100 万 token 进去,某一步推理用到的信息可能不到 100 条。说白了,context size ≠ 可用信息量。100 万的窗口,有效带宽可能只有几千。
实际用起来什么感觉
社区的反馈蛮一致的。有人反映 Sonnet 4.5 用到 128K-150K 左右,回答质量就开始肉眼可见地滑坡——不是变笨了,是开始"漂移"。忘记之前说好的约定,代码风格突然不一致,甚至重复之前已经被否决的方案。
很多人描述了一种叫 context rot 的体感:对话越长,模型越像一个加了 48 小时班的程序员,知道要做什么,但执行力全面下滑。命名规范开始乱,之前明确说不用的 pattern 又冒出来了。
有个评论总结得挺好:"1M context window 更像安全网,不是工作台。大多数时候 200K 就够了,关键是你往里放什么。"
也有人实测 Opus 4.6 跑大 context 效果确实更好,但代价是 token 消耗也更高。日常开发的话,精简 context 配合 Sonnet 反而性价比更高。
Claude Code 自己怎么处理这个问题
Anthropic 当然知道这事。他们在 Claude Code 里搞了一个叫 context compaction 的机制,大概流程是这样的:
- 持续监控 token 消耗
- 快到上限时触发压缩
- 模型自己总结对话历史,保留关键决策和未解决的 bug
- 用摘要替换原始对话,保留最近几个文件的完整内容
- 继续干活
听起来挺聪明,但说穿了,Anthropic 自己也在承认:你没法真正"使用"100 万 token 的全部信息,所以得主动管理哪些该留、哪些该扔。
compaction 的坑也很明显——你之前花 20 分钟讨论的一个设计决策,压缩后可能就剩一句话,模型后面基于这句话做判断,方向可能就歪了。
所以 Anthropic 现在推的核心概念不叫"更大的 context",叫 Context Engineering:精心管理模型能看到的一切信息。他们自己的测试数据也很说明问题——按需加载信息(just-in-time)比一股脑全塞(kitchen sink),agent 任务成功率提升了 54%。少放东西,反而做得更好。这个数字够反直觉吧?
我踩过的三个坑
什么都往 context 里塞,结果更乱。 一开始我也信"context 越大越好",对话历史全保留,工具输出全塞进去。结果对话长了之后 agent 开始"记忆混乱",该记的没记住,不该冒出来的旧信息反而干扰判断。就像你桌上堆了 200 份文件,找某一份的速度还不如桌上只放 10 份。
后来我搞了分层记忆系统:当前任务状态实时写文件、压缩后第一个恢复;每日日志记发生了什么;长期记忆只留精炼后的重要信息;复杂任务用独立 issue 追踪。核心思路就一句话——context window 是工作台,文件系统是档案室。工作台要干净,档案室要全。
不用 subagent,非要一个 context 扛所有。 复杂任务拆成子 agent 之后,体验好了很多。每个子 agent 有独立 context,做完只返回结果摘要。你让一个人同时记住 10 件事做判断,不如让 10 个人各记一件事、最后汇总。
而且子 agent 的 context 天然干净,没有主对话积累的噪音。同样的任务,子 agent 完成质量经常比主 agent 高,就是因为 context 更聚焦。Anthropic 自己的 best practices 也提了类似的点:像 code review 这类任务,用一个全新的子 agent 去审代码,效果比在同一个长对话里让模型"自查"好很多。写代码时积累的大量实现细节是噪音,换一个没有这些包袱的 agent 来审,反而能看到盲点。
调试时把几千行日志全塞进去。 有次想让模型帮忙 debug,把完整的命令行输出直接扔进 context,想着"信息越全越好"。结果模型反而更难找到问题,有用信息被噪音淹了。后来改成只摘关键几行,准确率立刻回来。跟 attention bandwidth 一个道理——信噪比低的大 context,还不如精选过的小 context。
实操建议
不是说 1M 没用,但用法绝对不是"全塞进去然后祈祷"。
- 当安全网,不当工作台。 正常工作保持 context 精简,1M 的价值是在你真需要回溯大量历史的时候不会被硬性截断。
- 关键信息放两头。 U 型注意力曲线摆在那,系统指令放开头,当前任务放最近的消息,中间放参考材料。
- 主动管理,别被动积累。 定期清 context,重要信息往外存。对话不是只进不出的垃圾桶。
- 拆任务,用子 agent。 一个大任务拆成多个小的,每个子 agent 用小而精的 context 做完汇报,比一个 agent 扛着 100 万 token 往前冲强太多。
- 结构化输入。 分隔符、标题层级、标签,让 attention 更容易命中,别逼模型在无格式文本里大海捞针。
1M context 是基础设施的进步,但就像给你一块 10TB 的硬盘不会让你变成更好的程序员——关键永远是你怎么组织里面的东西。对于搭 agent 的人来说,Context Engineering 才是真正该花时间研究的技能。