一个被反复验证的事实
用 AI 写代码的人都会遇到这个场景:你把整个项目丢给 AI,说”帮我改一下登录页面的 bug”。AI 迅速改完了登录页面,但顺手把旁边的支付模块也”优化”了一下。
你以为它不懂你的需求?不,它懂。但你的 context 里塞了太多跟登录页面无关的东西,它的注意力被分散了。就像你让一个人在嘈杂的工地里念一段电话号码,他能听到,但记不全。
这不是个别现象。我在多个项目里反复验证过同一个规律:context 的质量决定了 AI 输出的质量,而 context 的质量跟 token 数量几乎无关。
注意力是有预算的
很多人对 LLM 有一个根本性的误解:以为 context window 是一个”容器”,往里面装的信息越多,AI 就越”了解”你的项目。
但 context window 更像是一个注意力预算池。你往里面放的每一条信息,都在消耗这份预算。
Lost in the Middle
2023 年有一篇论文(Lost in the Middle: How Language Models Use Long Contexts)做了一个实验:把一条关键信息放在 context 的不同位置,然后让模型回答基于这条信息的问题。
结果很直观:
信息位置:开头 ████████████ 回答准确率:~95%
信息位置:中间 ░░░░░░░░░░░░ 回答准确率:~55%
信息位置:结尾 ████████████ 回答准确率:~90%
模型对 context 中间部分的信息,关注度显著低于开头和结尾。这不是 bug,是 Transformer 架构的固有特性,self-attention 机制天然会给首尾位置更高的权重。
所以当你把 200K tokens 的代码一股脑塞给 AI 时,真正被它”看到”的信息,可能只有开头和结尾的各 20%。中间那 60%,它大概是扫了一眼,就过去了。
这跟 AI Coding 有什么关系
关系很大。
你在 Cursor 或者 Claude Code 里打开一个项目,AI 能”看到”的东西包括:
- 你当前编辑的文件
- 你通过 @ 引入的其他文件
- 项目结构
- linter 错误
- terminal 输出
- git diff
- system prompt
每一项都在消耗注意力预算。
一个常见的反面案例:你在改一个 React 组件的样式问题,但 context 里还残留着上一次对话讨论的 API 重构方案。AI 这时候可能会把”API 优化”的思路带到”改 CSS”的任务上,给出的方案里夹带了完全不相关的建议。
这就是注意力偏移。它不是 AI”犯傻”,是你给了它错误的信号。
Context 管理的本质:信噪比
把 context 管理理解为 token 管理,是把问题想浅了。
真正的 context 管理是在做信噪比优化。你要做的是:
- 提升信号:只放跟当前任务直接相关的信息
- 压制噪声:过滤掉跟任务无关的内容
- 排列顺序:把最关键的信息放在注意力最高的位置
用一个具体的例子。假设你要让 AI 帮你修复一个 bug,你有两种 context 策略:
策略 A(大而全):
整个项目的文件结构
bug 所在文件的全部代码(800 行)
相关的类型定义文件
相关的测试文件
最近的 git diff
README
package.json
策略 B(精准裁剪):
bug 相关的函数及上下文(50 行)
函数的输入输出类型定义
触发 bug 的测试用例
一行项目背景说明
策略 B 的效果几乎总是更好。因为 AI 在 50 行代码里找 bug,和在 800 行代码里找 bug,是完全不同的任务。前者它真的在读每一行,后者它大概率只扫了前 200 行和后 200 行。
需求专注度:最常见的失败模式
AI Coding 里最常见的失败,不是 AI 写不出代码,是它偏离了你的需求。
偏离是怎么发生的
需求偏离通常不是一步到位的,而是一个渐变过程:
- 你给了一个明确的任务
- context 里有一些相关信息,AI 觉得”顺便一起改了会更好”
- AI 的修改引入了新的 context(改了文件 A,现在文件 B 也需要调整)
- 新的 context 又触发了新的”顺便”
- 你要的是改一个按钮颜色,AI 给你重构了整个组件体系
这个过程很像人类的”注意力漂移”。区别在于,人类漂移了自己能意识到,AI 漂移了它完全不知道,还觉得自己做得很好。
怎么防
几个实践中验证过的做法:
缩小 context 边界。 只给 AI 跟当前任务相关的文件和代码。不要把”可能有用”的东西也塞进去,“可能有用”和”确定有用”之间隔着巨大的信噪比差距。
显式声明约束。 在任务描述里加上明确的边界:“只修改这个函数的逻辑,不要改动其他函数。不要重构。不要优化。只修 bug。“这种看起来很”啰嗦”的约束,实际上是在帮 AI 划定注意力的边界。
分步执行。 一个大任务拆成几个小步骤,每一步只加载必要的 context。第一步做完,清掉跟第二步无关的上下文,再开始第二步。不要在一个超长对话里把所有事情都做了。
及时纠偏。 AI 开始”自由发挥”的时候,马上打断。不要指望它自己绕回来,它不会的。每发现一次偏离,就是一次重新校准 context 的机会。
Context 管理的几个工程模式
在 Agent 设计和 AI Coding 的实践中,有几个比较成熟的 context 管理模式。
1. 渐进式加载
不要一次性把所有信息塞进去,按需加载。
第一轮:任务描述 + 核心文件
第二轮:根据第一轮的分析结果,加载相关依赖
第三轮:根据前两轮的结果,加载测试和边界情况
每一轮只加载”当前缺少的信息”。这样做的好处是,AI 的注意力始终聚焦在当前步骤需要的信息上,不会被还没用到的内容分散。
2. 上下文裁剪
定期检查和清理 context,把已经完成、不再需要的上下文移除。
- 已修复的 bug 相关的报错信息?删掉
- 上一个任务的讨论记录?删掉
- 仅供参考、已经用完的文档?删掉
context 不是越积越多的,应该是流动的。用完的信息就应该腾出位置,给新的信息让路。
3. 结构化注入
往 context 里放信息的时候,不是堆砌,而是有结构的组织。
## 任务
修复用户注册表单的邮箱验证 bug
## 约束
- 只修改 validateEmail 函数
- 不改动表单组件的其他逻辑
- 保持现有的错误消息格式
## 相关代码
[只包含 validateEmail 函数及其直接依赖]
## 测试用例
[只包含邮箱验证相关的测试]
结构化的 context 让 AI 能快速定位每一部分信息的角色,减少”理解成本”,把更多注意力留给任务本身。
4. 场景隔离
不同场景之间共享 context 要极其谨慎。
A 项目的技术栈偏好,不要自动带入 B 项目。昨天对话里的临时决策,不要自动出现在今天的对话里。CLI 会话中的操作,不要自动关联到 Web 界面的会话。
这一点在我之前那篇讲 Hermes 和 OpenClaw 的文章里展开聊过。context 跨场景流动看起来像是”智能”,实际上往往是”污染”。每个任务、每个项目、每个会话都应该有自己干净的 context 边界。
5. 上下文预算
给每次 AI 调用设定一个隐性的”上下文预算”。比如:
- 简单 bug 修复:500-1000 tokens 的 context 就够了
- 功能开发:2000-5000 tokens
- 架构重构:5000-10000 tokens
如果你发现一个简单 bug 修复需要加载 20000 tokens 的 context,要么是你的任务拆分有问题,要么是项目结构需要优化了。
从”写好 prompt”到”管好 context”
Prompt engineering 这个词很容易让人产生一种错觉,以为 AI 工程的核心就是”写好一段话”。
写好 prompt 当然重要。但 prompt 只是 context 的一个组成部分。真正的能力在于:你知道在什么时间点,用什么结构,往 AI 的视野里放什么信息,不放什么信息。
这个能力的背后,是对注意力机制的直觉理解。你知道 AI 的注意力是有限的、是不均匀分布的、是容易被噪声带偏的。所以你做的每一个 context 相关的决策——给什么文件、不给什么文件、信息怎么排列、什么时候清理——都是在帮 AI 把有限的注意力花在刀刃上。
回到开头那个比喻。context window 不是容器,是注意力预算。你管理 context,本质上是在帮 AI 管理它的注意力。
做不好这件事的人,会在 AI 的”自由发挥”里反复踩坑。 做好这件事的人,会让 AI 的输出看起来像是它真的”懂”你的项目。
区别不在于 AI 的能力,在于你往它的视野里放了什么。