Claude Code上下文窗口为什么越用越乱
一个 Claude Code 会话刚开始时,模型往往能牢牢记住目标。它读了几十个文件、跑了几轮测试、改了几次方案以后,早期约束可能开始被遗漏,搜索也会重复,回答还会越来越慢。
很多小伙伴会把原因归结成“Token 快满了”。窗口容量确实重要,信息质量同样会影响结果。窗口里塞着过期日志、重复文件和已经推翻的判断,即使还有剩余空间,模型也要在噪声中寻找当前任务需要的内容。
我通常把问题拆成两部分:窗口装了什么,以及这些内容现在还有没有用。
上下文窗口是当前推理的工作区
模型每次生成下一步动作时,只能使用本轮请求带给它的信息。会话历史、工具返回、规则和 Skill 都要重新进入请求,模型不会在请求之间保留一个隐藏的项目大脑。
上下文窗口因此更像一张正在使用的工作台。桌面大小有限,东西摆得越多,找到当前那张设计图就越费劲。
这个类比有两个边界:
- 窗口里的文字会被模型整体处理,不等同于 JVM 中可以按地址精确读取的对象;
- 窗口容量增加能容纳更多材料,却不能保证长文本中每个细节都被同等关注。

一次模型请求里有哪些开销
上下文占用可以分成启动开销和运行增量。
启动开销
会话开始时,Claude Code 已经需要准备一批信息:
| 内容 | 作用 | 特点 |
|---|---|---|
| 系统指令 | 定义 Claude Code 的行为和工具使用方式 | 每轮都需要 |
| 工具描述 | 告诉模型有哪些工具、参数怎样写 | 工具越多,开销通常越大 |
CLAUDE.md | 项目和个人长期约定 | 会话启动时加载相应层级 |
| 无路径限制的 Rules | 对所有文件生效的项目规则 | 启动时进入上下文 |
| Auto Memory 索引 | 以前沉淀的项目经验入口 | 默认加载 MEMORY.md 前 200 行或 25KB |
| Skill 元数据 | 告诉模型有哪些按需能力 | 正文通常在调用后加载 |
项目规则写得过长、MCP Server 接得过多,任务还没开始,窗口余量已经被吃掉一部分。
运行增量
任务推进时,下面这些内容会持续增长:
- 用户补充的需求和纠正;
- Claude 的计划、解释与中间结论;
- Read 返回的源文件;
- Grep、Glob 等搜索结果;
- Bash、测试、构建和日志输出;
- Edit/Write 等工具调用记录;
- 当前加载过的 Skill 正文;
- Subagent 返回的结论;
- Hook 注入的 additional context。
同样聊 20 轮,只讨论概念和每轮都跑测试,窗口占用差别会很大。工具结果往往是 Coding Agent 会话里增长最快的部分。
可以用一个概念公式理解预算:
当前可用余量
≈ 模型窗口上限
- 启动上下文
- 对话历史
- 工具调用及结果
- 为后续输出与压缩保留的空间
这个公式用于理解组成,不适合反推出某个版本的精确阈值。Claude Code 会迭代压缩策略、模型窗口和保留预算,面试里死背内部常量很容易过时。
哪些内容最容易把窗口撑大
下面几类内容在工程会话里增长得最快,也最容易被当成“反正还在窗口里”而反复保留。
全量测试日志
几千行成功日志的价值很低,真正有用的通常是失败用例、异常栈和复现命令。可以让测试工具减少普通输出,或者只保留失败摘要。
重复读取同一批文件
Agent 忘了自己查过什么,或者压缩后没有明确线索,就可能重新搜索和读取。文件内容确实可以再取,但频繁重复会抬高成本,也说明任务状态记录得不够好。
无边界的仓库调查
“帮我看看这个项目”会让 Agent 在目录之间不断展开。把范围改成“只调查库存预占和订单关闭链路”,搜索结果会少很多。
过长的规则与说明书
把部署 SOP、代码审查清单、UI 规范全塞进 CLAUDE.md,每轮都要付出这笔上下文成本。低频流程更适合做成 Skill,局部规则更适合放带 paths 的 .claude/rules/。
工具注册过多
多个 MCP Server 可能暴露几十甚至上百个工具。工具描述占空间,名称相似还会增加误选概率。连接真正需要的 Server,并定期清理闲置工具,比单纯扩大窗口更有用。
Lost in the Middle讲的是什么
长文本中的信息位置会影响模型使用效果。关键限制出现在开头,当前问题出现在结尾,中间夹着大量工具结果时,中间位置的细节更容易被漏掉,这类现象常被称为 Lost in the Middle。
例如会话第 2 轮写着“对账金额必须使用银行回单值”,第 35 轮已经出现多次日志查询、SQL 输出和代码修改。模型可能重新使用订单表中的金额,虽然那条约束仍在历史里。
在后面重复一遍只能短暂提醒模型。长期有效的项目规则应该写进 CLAUDE.md 或正式文档;当前任务关键约束要进入计划、测试和交接文件;需要强制执行的边界放到权限、Hook 或 CI。
Context Rot为何比窗口用满更早出现
Context Rot 可以理解为上下文质量随着会话推进而下降。常见信号包括:
- 已经排除的方案又被提出来;
- 搜索同一个符号,却不使用上一轮结论;
- 忘记用户明确说过的修改边界;
- 任务还没完成就开始写收尾说明;
- 新证据与旧猜测冲突,回答却把两者一起保留;
- 对下一步说得越来越笼统,例如只说“继续优化相关逻辑”。
这些信号没有统一百分比阈值。网上常见的“40% 后一定变笨”更像某些任务与模型下的经验线,无法替代当前会话观测。模型、工具结果大小和信息组织方式都会改变退化时机。

Prompt Cache能不能解决窗口压力
Prompt Cache 主要降低重复输入的费用和延迟。相同的系统指令、工具定义和历史前缀命中缓存后,服务端可以复用计算。
缓存并不会把这些内容从上下文窗口移走。它们仍属于本轮请求的输入,也会继续占用窗口容量。可以把它理解成“同样的数据读得更便宜”,不能理解成“数据不再占空间”。
这也是面试里很容易混的一点:成本优化和上下文治理有关联,解决目标并不相同。
/context应该怎么看
Claude Code 的 /context 命令用来查看当前窗口被什么占用。实际界面会随版本变化,通常可以看到模型窗口、已用空间和系统提示、工具、Memory、消息、Skills 等分类。
我会关注三件事:
- 固定开销是否异常,例如工具与规则刚启动就占了很大比例;
- 运行增量里哪类内容增长最快,是文件、日志还是长对话;
- 当前阶段结束后,哪些材料已经可以丢弃或写到文件外化。

怎样减少低价值上下文
我的处理原则是让模型看到当前决策真正需要的材料,其余内容保留可重新获取的入口。
给探索设置边界
把目录、目标和禁止动作写清楚。先找符号和入口,再读关键文件,避免把整个仓库一次性展开。
控制命令输出
测试命令尽量使用简洁模式。日志分析先按时间、请求 ID 或错误码过滤,再打开关键上下文。
阶段结束就沉淀结论
探索结束后,把确认的调用链和方案写进计划。实现结束后,把变更和验证写进交付记录。旧搜索结果随后即使被清理,也不会丢掉当前决策。
把支线交给Subagent
日志归因、跨目录搜索和独立审查会产生很多一次性材料。Subagent 在独立窗口里完成过程,只把结论和证据带回主会话,可以明显减少主线污染。
把内容放到正确的载体
| 信息 | 合适位置 |
|---|---|
| 当前正在看的代码片段 | 会话上下文 |
| 每次会话都要遵守的项目规则 | CLAUDE.md |
| 只影响某类路径的规则 | .claude/rules/ |
| 可复用的多步骤流程 | Skill |
| 当前任务状态与决策 | Plan、Spec、Issue或交接文件 |
| 可在源码中重新查到的事实 | 需要时重新查询 |
| 必须强制执行的限制 | 权限、Hook、Sandbox、CI |
上下文变长时先做什么
看到占用升高,不用马上清空会话。可以按下面顺序处理:
- 停止无边界搜索,确认当前阶段目标;
- 把关键约束、决策、失败用例和下一步写进任务状态;
- 清理或避免继续产生全量日志与重复结果;
- 阶段边界使用
/compact压缩历史; - 压缩后复述目标、已改文件、待办和验证命令;
- 多次压缩仍然接不上时,写 handoff 并换新会话。
压缩能释放空间,也会丢掉原始细节。真正稳定的长任务需要让重要状态离开聊天历史,进入可以重新读取的文件、测试和 Git diff。
Claude Code 的上下文由启动开销和运行增量组成。系统指令、工具定义、规则与Memory索引构成起步成本;文件内容、搜索结果、测试日志和对话会持续增长。窗口变长后,模型可能出现Lost in the Middle和Context Rot,表现为漏约束、重复探索和使用旧判断。Prompt Cache能降低重复输入的成本与延迟,不能释放窗口。工程上要限制探索范围、控制工具输出、把任务状态写到文件、用Subagent隔离支线,并在阶段边界压缩会话。