Claude Code 上下文窗口:启动加载顺序与 /compact 压缩后幸存机制
Claude Code 的上下文窗口在启动时自动加载系统提示、CLAUDE.md、自动记忆、MCP 工具和技能描述,每项都有明确 token 区间。文件读取是主要消耗源,路径范围规则在匹配文件读取时同步加载。/compact 压缩后系统提示和 CLAUDE.md 重新注入,但带 paths: 的规则和子目录 CLAUDE.md 会丢失,直到对应文件再次被读取。运行 /context 查看当前会话的实时分类用量,/memory 确认加载了哪些指令文件。
Claude Code 的上下文窗口包含 Claude 在会话中知道的一切:指令、读取的文件、自身响应,以及从不出现在终端的内容。理解各类机制何时加载、占用多少 token,以及 /compact 压缩后哪些内容会重新注入,有助于管理上下文使用效率和成本。
启动加载顺序:从运行 claude 到你输入第一条消息
运行 claude 后,在终端等待你输入之前,以下内容已经按顺序加载。后面的 token 区间是演示用参考值,实际数值取决于你的 CLAUDE.md 大小、MCP 服务器数量和文件长度:
- 系统提示词(约 4,200 tokens):Claude 的核心行为指令、工具使用格式和响应格式化规则。你永远看不到它。
- 自动记忆(MEMORY.md)(约 680 tokens,限前 200 行或 25KB):Claude 从历史会话中自己记录的信息,例如构建命令、项目模式、避免再犯的错误。
- 环境信息(约 280 tokens):工作目录、平台、Shell、操作系统版本、是否在 git 仓库中。Git 分支、状态和近期提交记录在系统提示词的末尾单独加载。
- MCP 工具(延迟加载)(约 120 tokens):只列出工具名称,让 Claude 知道哪些可用。默认情况下完整的工具 schema 保持延迟,Claude 在需要时按需加载。设置
ENABLE_TOOL_SEARCH=auto可让 schema 在上下文窗口空余 10% 时提前加载,设为false则全部加载。 - 技能描述(约 450 tokens,每项一行):技能的单行描述,让 Claude 知道可以调用哪些技能。完整技能内容只在 Claude 实际使用时才加载。
disable-model-invocation: true的技能不在此列表中,完全不在上下文中,直到你通过/技能名主动调用。与其它启动内容不同,技能列表在/compact后不会重新注入,只有实际调用过的技能被保留。 - 全局 CLAUDE.md(~/.claude/CLAUDE.md)(约 320 tokens):你的全局偏好,影响所有项目。
- 项目 CLAUDE.md(约 1,800 tokens):项目约定、构建命令、架构说明。保持它在 200 行以内,将参考内容移到技能或路径范围规则中,只在需要时加载。
会话过程中:文件读取、规则触发、hooks 和子代理
随着你在会话中输入指令,Claude 开始读取文件、触发规则和 hooks。下面是一次修复 bug 会话的典型流程:
你输入指令
你输入“修复用户 token 刷新后返回 401 的认证 bug”(约 45 tokens)。
Claude 开始读取文件
- 读取
src/api/auth.ts(2,400 tokens):在终端只显示“Read auth.ts”,内容对终端不可见 - 读取
src/lib/tokens.ts(1,100 tokens):追踪导入链 - 路径范围规则自动加载:当 Claude 读取
src/api/目录下的文件时,匹配/claude-code/rules/api-conventions.md自动加载(380 tokens),终端显示一行“Loaded”通知 - 读取
middleware.ts(1,800 tokens):继续追踪认证流程 - 读取
auth.test.ts(1,600 tokens):检查已有测试的预期行为 - 再次触发路径范围规则:匹配
*.test.ts的testing.md规则加载(290 tokens),同样以一行“Loaded”通知显示 - 全局搜索
refreshToken(600 tokens):终端显示命令执行,不显示完整输出
Claude 分析并修复
- Claude 分析(800 tokens):解释 bug 原因是 token 轮换中过早失效,在终端可见
- 编辑
auth.ts(400 tokens):修复 token 轮换顺序,差异内容在终端可见 - PostToolUse Hook 自动触发:例如在
settings.json中配置的 prettier hook(120 tokens),在编辑后自动运行。Hook 输出通过hookSpecificOutput.additionalContextJSON 进入 Claude 上下文。退出码 0 且无错误输出的 stdout 只写入调试日志,不会进入上下文。退出码 2 会将 stderr 以错误形式呈现给 Claude - 编辑
auth.test.ts(600 tokens):添加回归测试 - 再次触发 prettier hook(100 tokens)
- 运行测试套件(1,200 tokens):终端显示“Running npm test…”和通过计数,不显示完整输出
- Claude 总结(400 tokens):“修复了 token 轮换,增加了回归测试,所有测试通过”
后续指令与子代理
你继续输入“使用子代理研究会话超时处理,然后修复它”(40 tokens)。
Claude 生成一个子代理,在自己的独立上下文窗口中工作。子代理的上下文包含:
- 自己的系统提示(约 900 tokens,比主会话短)
- 项目 CLAUDE.md 的副本(1,800 tokens)
- 相同的 MCP 和技能设置(970 tokens),但排除计划模式控制、后台任务工具和默认情况下不包含 Agent 工具(防止递归)
- 主会话给出的任务提示(120 tokens):“研究代码库中的会话超时处理”
子代理在独立上下文中读取文件,不会占用你的主会话上下文:
- 读取
session.ts:在子代理上下文消耗 2,200 tokens - 读取
timeouts.ts:800 tokens - 读取
config/*.ts:3,100 tokens
子代理的最后回复(420 tokens)返回给主会话,加上 token 计数和耗时的元数据尾部。子代理读取了 6,100 tokens 的文件,你只得到了 420 tokens 的结果——这就是上下文节省。
使用 ! 前缀运行 Shell 命令
你通过 !git status(180 tokens)查看 Claude 修改了哪些文件。命令输出与命令一起作为你的消息进入上下文。适用于让 Claude 基于命令输出工作,而不需要它自己运行该命令。
调用用户专用技能
你调用 disable-model-invocation: true。该技能描述在启动时没有出现在技能索引中,所以启动时消耗 0 tokens。现在完整技能内容加载,Claude 按照指令暂存、提交并推送你的更改。对于有副作用(提交、部署、发送消息)的技能,建议设置 disable-model-invocation: true,保持它们完全不占用上下文,直到你需要。
压缩 /compact 后:哪些机制存活,哪些需要重新触发
当长会话压缩时,Claude Code 将对话历史汇总为结构化摘要。各机制的处理方式:
| 机制 | 压缩后行为 |
|---|---|
| 系统提示词和输出风格 | 不变,不属于消息历史 |
| 项目根目录 CLAUDE.md 和无作用域规则 | 从磁盘重新注入 |
| 自动记忆(auto memory) | 从磁盘重新注入 |
带 paths: 的规则 |
丢失,直到匹配文件再次被读取 |
| 子目录中的 CLAUDE.md | 丢失,直到对应子目录内的文件再次被读取 |
| 已调用的技能内容 | 重新注入,每个技能上限 5,000 tokens,总上限 25,000 tokens;最旧的优先丢弃 |
| Hooks | 不适用;hooks 作为代码运行,不占上下文 |
路径范围规则和子目录 CLAUDE.md 在消息历史中加载,压缩时被一起摘要化。如果规则必须跨压缩持续生效,去掉 paths:、或将内容移到项目根目录的 CLAUDE.md 中。
技能内容在压缩后重新注入,但大型技能会按上限截断——保留文件开头。最重要的指令应写在 SKILL.md 顶部。
在终端看到的 vs Claude 看到的
| 可见性 | 说明 |
|---|---|
| 隐藏(hidden) | 终端完全不可见。例如系统提示词、自动记忆、MCP 工具列表、CLAUDE.md 内容。从不出现在终端 |
| 单行(brief) | 终端只显示一行通知。例如文件读取时显示“Read auth.ts”、路径范围规则加载显示“Loaded api-conventions.md”、子代理工作时的通知。内容在 Claude 的上下文中,但终端用户看不到内容 |
| 完整(full) | 终端显示实际内容。你的提示词、Claude 的分析、编辑差异、测试运行结果的一部分 |
用命令检查你的会话
/context:查看按类别细分的实时 token 用量和优化建议/memory:检查启动时加载了哪些 CLAUDE.md 和自动记忆文件
常见问题
为什么有些 CLAUDE.md 内容在长会话后消失了?
子目录 CLAUDE.md 和带 paths: 的规则在消息历史中加载,/compact 会摘要化它们。压缩后只有系统提示、项目根 CLAUDE.md 和无作用域规则自动重新注入。要让指令跨压缩持续生效,去掉 paths: 或将内容迁移到项目根目录的 CLAUDE.md 中。
子代理文件读取会占用主会话的上下文 window 吗?
不会。子代理在独立的上下文窗口中工作,所有文件读取完全隔离。只有子代理的最终回复和少量元数据(token 计数和耗时)返回给主会话。研究密集型任务应优先使用子代理。
/compact 后技能会丢失吗?
已调用的技能会在压缩后重新注入,但有两个限制:每个技能最多 5,000 tokens(保留文件开头),总技能内容不超过 25,000 tokens,最旧的技能被丢弃。启动时列出的技能描述不会重新注入——只有实际调用过的技能被保存。disable-model-invocation: true 的技能描述从一开始就不在上下文中,必须在调用时加载。