
上下文窗口是 AI Coding 中最稀缺的资源——主动管理上下文,比任何 Prompt 技巧都更能决定 Claude Code 的输出质量。
如果你用过 Claude Code 超过一周,你大概率遇到过这种情况:刚开始时它像天才,能精准理解你的意图,生成的代码几乎不用改。但一个小时后,它开始"变笨"——忘记了你半小时前约定的命名规范,在一个本应简单的重构上反复出错,甚至开始产生幻觉、编造不存在的函数。
你以为是模型不行。其实是你把它的"钱包"塞爆了。
每次你向 Claude Code 发送一条消息,它都在一个"上下文窗口"内处理所有信息。这个窗口装了什么?
组件 | 说明 |
|---|---|
系统提示 | Claude Code 的基础指令集,包含行为规范、工具使用规则 |
对话历史 | 你之前说过的所有话、模型的所有回复 |
文件内容 | 你引用的源代码、配置文件、文档 |
工具输出 | 搜索结果、文件读取结果、命令执行输出 |
你可能不知道的是,哪怕你一个字都没说,一个新会话启动时已经有大约 7850 tokens 的固定开销(基于典型配置的估算,实际数值会因你的 CLAUDE.md 内容、安装的 Skill 和 MCP 服务器数量而异):
固定开销项目 | 大约消耗 |
|---|---|
系统提示 | ~4200 tokens |
Auto memory(跨会话记忆) | ~680 tokens |
环境信息(OS、CWD 等) | ~280 tokens |
MCP 工具名称列表 | ~120 tokens |
Skill 描述 | ~450 tokens |
全局 CLAUDE.md | ~320 tokens |
项目 CLAUDE.md | ~1800 tokens |
这意味着在你打出第一个字之前,4% 的 200K 窗口已经用掉了。如果你用的是 1M 窗口,这个比例不到 1%,但问题在于——更大的窗口不等于更好的结果。
Anthropic 的 MTS Thariq Shihipar 在官方博客中明确说了一个反直觉的事实:模型性能会随着上下文增长而下降。 注意力被稀释到越来越多 token 上,早期的重要指令被"遗忘"。
更讽刺的是:模型在上下文快满的时候最"笨",而这恰好是自动压缩(Autocompact)触发的时机。 让一个已经处于"半迷糊"状态的模型去决定该保留什么、该丢弃什么——结果可想而知。
这就是为什么"主动管理上下文"不是可选项,而是使用 AI Coding 工具的基本技能。
Claude Code 提供了几个用于管理上下文的命令。它们各有用途,用对场景才能发挥最大效果。
命令 | 相当于 | 什么时候用 | 上下文影响 |
|---|---|---|---|
/clear | 关掉浏览器标签页重新打开 | 任务切换、当前会话偏离轨道 | 完全重置,仅保留 CLAUDE.md |
/compact | 把对话历史压缩成摘要 | 还在同一任务,但上下文快满了 | 有损压缩,关键决策可能丢失 |
Esc+Esc / /rewind | 回到存档点重来 | 模型走错方向,不想保留错误记录 | 丢弃指定节点后的所有内容 |
/btw | 在可关闭浮层中提问 | 突然想到一个快速问题 | 不进对话历史,零上下文开销 |
/context | 仪表盘 | 随时监控上下文使用情况 | 只读查看,零影响 |
/clear —— 任务切换时必用做完一个功能,开始一个新的——用 /clear。它清空当前对话历史,但保留所有 CLAUDE.md 配置。你可以给它一个名字:
/clear 开始用户认证模块的重构之后用 /resume 就能回到之前的工作。
/compact —— 手动压缩的正确姿势很多人的 /compact 用法是错的。他们直接敲 /compact,让模型自己决定保留什么。但 Anthropic 的建议是:给明确指令。
/compact 保留所有 API 决策和错误处理模式,丢掉测试调试过程Anthropic 特别指出,自动压缩(Autocompact)的问题在于——模型无法预测你接下来要做什么方向。 比如你调试了一个 bug,中间顺带查了个"副作用",之后你可能要回过头来用它,但自动压缩很可能把它当作无关内容丢掉了。手动指定保留重点可以大幅减少这种损失。
/rewind这是 Boris Cherny(Claude Code 的创建者)最推崇的习惯。当模型尝试某件事失败时,不要追加纠正消息。双击 Esc 回到失败之前的位置,把教训写进新的提示里,重新来。
Rewind > Correct,这是铁律。
/btw/btw 是个被低估的命令。它开了一个可关闭的浮层来回答问题,不会进入对话历史。你在 Claude Code 工作时突然想到"这个函数的复杂度是多少?"——用 /btw 问,答案看完就关,上下文不受影响。
注意:截至 2026 年中,/btw 只有读权限,不能执行文件操作(基于社区实践经验,具体限制可能随版本变化)。
/context 监控上下文状态随时可以用 /context 查看当前上下文的占用情况。你会看到一个彩色网格,直观告诉你还有多少空间。养成习惯,每次回来工作时先敲一下 /context。
每次 Claude Code 完成一轮工作后,你都面临一个五选一的决策:
继续对话 → /rewind → /clear → /compact → 子 Agent选哪个,取决于你的目标:
当前状态 | 推荐操作 |
|---|---|
同一任务正常推进 | 继续对话 |
模型走错方向 | /rewind 回退到正确节点 |
当前任务完成,开始新任务 | /clear |
同一任务但上下文太长 | /compact [指令] |
需要调研/审查/并行工作 | 使用子 Agent |
这是一个实操经验:如果连续两次工具调用后模型仍然给出错误输出,不要继续纠正。直接 /clear,然后重写初始提示。
原因很简单:一个已经被错误输出污染的上下文里,纠正的效率远低于干净上下文中一次性说清楚。每次错误输出都会占据上下文空间,而且模型会在后续生成中"引用"之前犯过的错。
举个例子,你在让 Claude Code 重构一个认证模块,它第一次写错了 token 刷新逻辑。你纠正了,它改对了但引入了新的漏洞。你再纠正——这时候上下文里已经充满了"错了改、改了再错"的对话历史。即使模型最终改对了,这些历史也在占用注意力,影响后续判断。
在这种情况下:/clear,然后写一个更详细的初始提示,把第一次犯的错作为约束条件写进去。
新手常犯的一个错误是:一个会话用到底,从早到晚所有工作都在同一个上下文里完成。
正确做法:一个任务一个会话。 当任务边界清晰("完成用户管理 CRUD"、"修复支付流程的并发 bug"、"添加日志中间件"),就在做完后用 /clear 开启新会话。即使你用的是 1M 上下文窗口,上下文腐烂依然会发生——只是发生得更慢而已。
Compaction 是上下文管理中最重要的技巧之一,也是最容易被搞砸的。
自动压缩在上下文约 83% 时触发(CLI 版本默认值,不同平台略有差异)。问题是——在 80%+ 时,上下文腐烂已经很明显了:模型的注意力涣散,早期指令被稀释,输出质量下降。让一个已经"半迷糊"的模型来决定压缩策略,结果大概率不理想。
手动压缩的核心原则:在模型还清醒的时候压缩。
建议的节奏:在上下文填充到 50-70% 时手动压缩。 这个阶段的模型还处于"清醒状态",能更好地判断什么该保留、什么该丢弃。
具体操作流程:
/context 确认当前使用率/compact 并附带明确指令/context 确认新的使用率好的指令告诉模型"保留什么"和"可以丢什么":
/compact Please include:
- All architectural decisions and their rationale
- All rejected approaches (with reasons)
- All files being modified and their current state
- Exact status of in-progress tasks
- Discard: debugging session details, side explorations, error reproduction steps你可以在 CLAUDE.md 中写入压缩相关的指令,告诉模型在压缩时优先保留哪些类信息。因为 CLAUDE.md 在压缩后会被重新注入,所以这些指令始终有效:
## Compaction Instructions
When compacting this session, always preserve:
- Current task goals and progress
- Key technical decisions and trade-offs
- Files being modified and whyCLAUDE.md 是 Claude Code 的"宪法"。它在你每次启动会话时被加载,并且——关键中的关键——它会在 /compact 后重新从磁盘读取并注入。这意味着 CLAUDE.md 中的指令永远不受上下文腐烂的影响。
Claude Code 按从全局到局部的顺序加载 CLAUDE.md 文件,后加载的内容可以覆盖前面的:
层级 | 位置 | 用途 | 谁控制 |
|---|---|---|---|
组织级 | Managed Policy(企业托管) | 组织规范、安全规则、合规要求 | 组织管理员 |
用户级 | ~/.claude/CLAUDE.md | 个人偏好、全局约定 | 个人开发者 |
项目级 | ./CLAUDE.md 或 ./.claude/CLAUDE.md | 项目规范、架构约定 | 团队(提交到 Git) |
本地级 | ./CLAUDE.local.md | 本地覆盖、个人工作流配置 | 个人(已 .gitignore) |
Boris Cherny 的原始建议:CLAUDE.md 不要超过 200 行。 原因是前沿模型能可靠地遵循约 150-200 条指令,而 Claude Code 的系统提示已经用掉了约 50 条槽位。超过这个限度,模型会开始选择性忽略规则——尤其是文件末尾的那些。
那么规则太多怎么办?答案是用 .claude/rules/。
.claude/rules/*.md + paths: —— 最优雅的上下文隔离这是 Claude Code 最被低估的机制。你可以在 .claude/rules/ 下放多个 Markdown 文件,每个文件通过 YAML frontmatter 中的 paths 字段声明它约束哪些文件:
---
paths:
- "src/api/**/*.ts"
- "src/handlers/**/*.ts"
---
# API 层规范
- 所有 handler 返回 { data, error } 格式
- 使用 zod 做请求体验证
- 错误码遵循 RFC 规范当 Claude 操作匹配路径下的文件时,这些规则自动加载——不操作就不加载。这使得你可以在项目中维护大量的、细粒度的规则,而不会撑爆上下文窗口。
工作方式:
paths 的规则文件 → 每次会话启动时加载(跟 CLAUDE.md 一样)paths 的规则文件 → 只在操作匹配文件时按需加载@import 语法CLAUDE.md 和规则文件可以用 @ 语法引用外部文件:
## 架构参考
项目架构见 @docs/architecture.md
Git 工作流见 @docs/git-workflow.md@import 在启动时立即加载(不是按需)/init 起步如果你还没有 CLAUDE.md,先跑 /init。Claude Code 会扫描你的项目,生成一个基础版本。然后把它作为起点,根据实际使用体验持续迭代。
Claude Code 默认使用 1M token 的上下文窗口,但 1M 不一定适合每个人和每个任务。
变量 | 作用 | 推荐值 |
|---|---|---|
CLAUDE_CODE_AUTO_COMPACT_WINDOW | 限制自动压缩的有效上下文窗口 | 200000 |
CLAUDE_AUTOCOMPACT_PCT_OVERRIDE | 设置自动压缩触发百分比(注:该变量来自社区实践,官方名称可能随版本变化) | 80 |
CLAUDE_CODE_SIMPLE_SYSTEM_PROMPT | 使用简化的系统提示 | 1 |
场景 | 推荐窗口 | 原因 |
|---|---|---|
日常编码、小范围重构 | 200K | 足够,且 token 消耗更低 |
大型代码库调研 | 1M | 需要一次性阅读大量文件 |
调试复杂 bug | 1M | 需要保留完整的问题上下文 |
快速原型开发 | 200K | 频繁切换任务,用大了浪费 |
代码审查 | 200K | 聚焦在 diff 上就够了 |
实操建议: 大部分人 90% 的工作用 200K 就够了。只在需要大量文件阅读时临时切到 1M。
设置 CLAUDE_CODE_SIMPLE_SYSTEM_PROMPT=1 可以使用简化的系统提示,减少约 2000 tokens 的固定开销。
组合使用效果:
CLAUDE_CODE_AUTO_COMPACT_WINDOW=200000
CLAUDE_AUTOCOMPACT_PCT_OVERRIDE=80
CLAUDE_CODE_SIMPLE_SYSTEM_PROMPT=1三者结合:窗口限制到 200K,压缩在 160K 触发(80%),启动固定开销减少约 2000 tokens。相比默认配置(1M 窗口、~83% 自动压缩),最大上下文积累量从约 830K 减少到约 160K,约 5 倍。(实际 token 节省幅度受 prompt 缓存命中率和对话轮数影响,场景不同会有差异。)
当一个任务产生大量中间输出,而你只关心最终结论时——用 Subagent。
Subagent 拥有独立的上下文窗口,它在自己的 200K 窗口里工作,文件读取、工具调用、对话历史全部留在子 Agent 的上下文中。当它完成任务后,只有你需要的结论回到主会话。
方案 | 上下文影响 | 适用场景 |
|---|---|---|
继续对话 | 持续累积 | 同一任务线性推进 |
/compact | 有损压缩 | 同一任务但上下文过长 |
/clear | 完全重置 | 任务切换 |
Subagent | 零影响 | 调研、审查、并行任务 |
Subagent 定义在 .claude/agents/ 目录下,YAML 格式:
---
name: code-reviewer
description: 代码审查专家。在代码修改后主动使用。
tools: Read, Grep, Glob, Bash
model: sonnet
---
# 角色
你是严格的代码审查者。审查时关注:
1. 安全漏洞(注入、认证、数据泄露)
2. 逻辑错误(边界条件、并发问题)
3. 代码质量(可读性、一致性、可维护性)
## 输出格式
对每个问题标注严重级别:
- CRITICAL:必须修复
- HIGH:应该修复
- MEDIUM:建议修复
- LOW:可选的优化更复杂的配置可以指定 mcpServers、hooks、permissionMode、memory 等:
---
name: bug-hunter
description: Debugging specialist for errors, test failures, and unexpected behavior
tools: Read, Edit, Bash, Grep, Glob
model: opus
permissionMode: acceptEdits
maxTurns: 30
---主会话(规划)
├── Subagent 1: 探索代码库结构
│ └── 返回:模块依赖图
├── Subagent 2: 实施功能 A
│ └── 返回:变更摘要
├── Subagent 3: 实施功能 B
│ └── 返回:变更摘要
└── Subagent 4: 代码审查
└── 返回:审查报告这就是 Boris Cherny 的工作方式——他管理的不是单个会话,而是数十甚至上百个并行 Subagent 构成的"代理舰队"。
上下文窗口再大也是有限的。但文件系统是无限的。这一组技巧的共同主题是:把文件系统当作上下文的延伸。
不要这样说:
看一下认证模块的代码
模型会去猜测你要看什么,可能多读几个文件,把无关内容塞进上下文。
要这样说:
看 @src/utils/auth.ts 和 @src/middleware/auth.ts
精确到文件路径,Claude 只加载这些文件到上下文。每少读一个无关文件,就为有用信息多留一份空间。
把关键信息写到 .md 文件中,然后用 @import 加载。这些文件不受上下文压缩影响,可以随时重新加载:
# 当前会话目标
完成用户管理的 CRUD 接口
# 已做的架构决策
- 使用 Repository 模式隔离数据访问
- 所有 API 返回 { data, error } 格式
- 分页参数统一用 page/limit
# 被否决的方案
- 直接用 Prisma 暴露给 Controller → 耦合太重,否决
# 进行中
- [x] UserRepository 接口定义
- [x] PrismaUserRepository 实现
- [ ] UserController CRUD 路由
- [ ] 单元测试这样做有一个额外的好处:你的决策过程有了持久记录。 不仅当前会话可用,以后回溯时也能清楚知道当时为什么做了这些选择。
.claudeignore 排除无关文件和 .gitignore 类似,.claudeignore 告诉 Claude 在搜索和读取时忽略哪些文件:
node_modules/
dist/
build/
*.min.js
*.bundle.js
coverage/每忽略一个不必要的目录,搜索速度更快,模型注意力更集中。
CLAUDE.md 中的指令是建议性的——模型读了但可以选择不遵守。对于必须执行的操作,用 Hook,它在 .claude/settings.json 中配置,是无条件执行的 shell 命令:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"command": "npx eslint --fix $CLAUDE_FILE_PATH 2>/dev/null || true"
}
]
}
}Hook 的上下文成本为零——配置本身不占用上下文窗口,但每次编辑后自动运行格式化/检查,省去了你在提示词中写"请确保代码格式正确"这样的指令。
把重复性工作流固化为 Skill。Skill 是按需加载的指令集,只有在被 / 调用时才占用上下文:
# skills/deploy-check/SKILL.md
# 部署检查流程
当你被调用时:
1. 运行 pnpm build
2. 运行 pnpm test
3. 检查是否有未提交的变更
4. 汇总报告每次部署前跑一下这个 Skill,不用在 CLAUDE.md 里写部署步骤。
模式 | 表现 | 根本原因 | 修复 |
|---|---|---|---|
遗忘指令 | Claude 忘记了你之前约定的命名规则 | 上下文腐烂导致早期指令被稀释 | 把必须遵守的规则写入 CLAUDE.md,它永远不烂 |
幻觉函数 | 调用不存在的 API 或函数 | 上下文太满,模型凭"印象"而非"阅读"生成 | 精确引用文件(@src/utils/auth.ts)vs 模糊描述 |
纠正死循环 | 同一个 bug 改了三轮还没好 | 在脏上下文中持续纠偏,效率递减 | 应用两次纠正失败法则——/clear 重来 |
自动压缩丢东西 | 压缩后丢失了关键决策记录 | 模型在"迷糊状态"下做了压缩决策 | 在 50-70% 时手动压缩,附带明确指令 |
上下文过载 | 响应速度变慢,输出质量全面下降 | 同时加载了太多无关文件 | 限制每会话 5-10 个核心文件,用 Subagent 做调研 |
.claude/rules/ + paths: 分流。/compact,附带明确指令告诉模型保留什么。这是对抗上下文腐烂的唯一主动手段。.md 文件里持久化。文件系统是无限的,用它来弥补窗口的有限。上下文管理不是"怎么省 token"的技术活。它决定了 Claude Code 的输出质量天花板在哪里。做得好,模型始终像刚启动时那样清醒。做不好,它就是你越来越失望的过程。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。