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 服务器数量和文件长度:

  1. 系统提示词(约 4,200 tokens):Claude 的核心行为指令、工具使用格式和响应格式化规则。你永远看不到它。
  2. 自动记忆(MEMORY.md(约 680 tokens,限前 200 行或 25KB):Claude 从历史会话中自己记录的信息,例如构建命令、项目模式、避免再犯的错误。
  3. 环境信息(约 280 tokens):工作目录、平台、Shell、操作系统版本、是否在 git 仓库中。Git 分支、状态和近期提交记录在系统提示词的末尾单独加载。
  4. MCP 工具(延迟加载)(约 120 tokens):只列出工具名称,让 Claude 知道哪些可用。默认情况下完整的工具 schema 保持延迟,Claude 在需要时按需加载。设置 ENABLE_TOOL_SEARCH=auto 可让 schema 在上下文窗口空余 10% 时提前加载,设为 false 则全部加载。
  5. 技能描述(约 450 tokens,每项一行):技能的单行描述,让 Claude 知道可以调用哪些技能。完整技能内容只在 Claude 实际使用时才加载。disable-model-invocation: true 的技能不在此列表中,完全不在上下文中,直到你通过 /技能名 主动调用。与其它启动内容不同,技能列表在 /compact不会重新注入,只有实际调用过的技能被保留。
  6. 全局 CLAUDE.md(~/.claude/CLAUDE.md)(约 320 tokens):你的全局偏好,影响所有项目。
  7. 项目 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.tstesting.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.additionalContext JSON 进入 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 的技能描述从一开始就不在上下文中,必须在调用时加载。