为什么 Claude Code 要有指令(Commands):本质是上下文管理
AI Coding 系列第 03 篇 · 上下文与 Commands
这篇想回答三个问题:
- 为什么一开始很好用的 Claude Code,会在长会话里越来越"跑偏"?
- 为什么有些纠正你明明说过很多次,它还是会回退?
- 为什么 Claude Code 要用
/clear、/compact、/memory这种命令,而不是全做成按钮?
如果你已经是高频用户,这篇不会提供很多新奇技巧,但会把这些现象背后的机制串成一套可操作的框架。对刚进入稳定开发阶段的用户,这比记住几个命令更重要。
先给结论
Claude Code 里的很多命令,看起来像快捷操作,实际上是在帮你管理三个东西:
- Claude 现在看到了什么
- Claude 接下来应该忘掉什么
- 哪些规则不应该继续留在“会衰减的对话历史”里
如果只把 /clear、/compact、/memory 当成“方便一点的小功能”,你会低估它们的价值。它们真正解决的,是长会话里最常见、也最让人误判的协作问题:Claude 不是突然变差了,而是上下文开始劣化了。
你大概遇到过这种情况
开始一个新任务,头几轮对话质量很高——Claude 理解你的意图,给出准确的方案,代码风格和项目一致。
但聊着聊着,情况变了:它开始重提已经否掉的方案,重复犯你纠正过的错误,或者在一个局部问题上越绕越深,忘了你们最初要解决什么。
这不是 Claude 变笨了,也不是你的 Prompt 写差了。这是上下文劣化——一个有规律、可以预测、也可以干预的现象。
一个贯穿全文的真实场景
假设你在做一个登录模块,从头到尾大概会经历这样一条线:
- 前期你和 Claude 一起讨论技术方案,聊过 Session、JWT、Redis、PostgreSQL,最后决定先用 PostgreSQL + JWT,把主流程跑通。
- 接着你开始写代码,发现 Claude 老是顺手加
console.log,你纠正了它两次。 - 做到一半你又决定把 ORM 从 Sequelize 换成 Prisma,因为前者在这个项目里太重。
- 再往后,对话已经很长了,你只是问一个事务边界问题,Claude 却开始同时聊缓存、日志、前端错误提示和部署建议。
如果你不理解上下文管理,这整条链看起来像是:“Claude 前面挺聪明,后面越来越不靠谱。”
但如果从上下文角度看,这其实是四类不同问题叠在一起:
- 前面讨论过但已经否掉的方案,还残留在历史里
- 你纠正过的规则,还停留在会衰减的对话层
- 已经废弃的 Sequelize 路线,还在干扰后续回答
- 对话长度过大以后,Claude 的注意力开始发散
也正因为它们是四类不同问题,所以不能指望一个万能 Prompt 解决。你需要的不是“再说清楚一点”,而是把正确的动作放在正确的层级上:该 /compact 的时候压缩,该 /clear 的时候重开,该进 CLAUDE.md 的规则就不要继续留在聊天记录里。
为什么 Claude Code 用命令,而不是全做成按钮
刚接触 Claude Code 的人常问:为什么不把这些能力做成 GUI?为什么要用 /clear、/compact 这种命令?
因为 Claude Code 管理的不是"功能开关",而是 Claude 此刻正在处理的内容。
举个对比:你在 VS Code 里点"开启 dark mode",改的是软件的配置文件,和编辑器当前打开了什么文件没关系。但你在 Claude Code 里输入 /clear,清掉的是 Claude 脑子里正在处理的所有东西——之前讨论过的方案、做过的决策、来来覆去的对话,全部抹掉,让它重新认识你。这不是改配置,是在决定 Claude 此刻"知道什么、记得什么"。
命令形式在这里有几个优势:它可重复,你可以稳定复现同一种操作;它可传达,你可以直接告诉同事"先 /clear 再开始";它也更容易固化成工作流,比如"任务切换先 /clear,长会话中途 /compact,提交前 /review"。对还在快速迭代的 AI 工具来说,命令也比 GUI 更容易快速交付新能力。
所以 Claude Code 的命令系统,本质上是一套让你主动管理 AI 工作现场的操控面板。
四种上下文劣化模式
模式一:早期探索污染后期决策
任务开始时,你和 Claude 在讨论方案,思路是发散的。"要不要用 Redis?""用 JWT 还是 Session?""这个表要不要拆?"——这些都是探索性的讨论,很多想法最终被否决了。
问题是:这些被否决的想法还留在上下文里,和最终确定的方案并排存在。Claude 看到的是一串讨论记录,它会对"用 Redis"和"不用 Redis"这两种可能性都保持某种权重。对话越长,早期探索的内容就越像已确认的决策。
例如:
你:认证这块先别上 Redis,先用 PostgreSQL 把主流程跑通。
Claude:好,先按 PostgreSQL 方案实现。
...
(十几轮后)
Claude:为了提高性能,建议把 session 放到 Redis。
你明明在第 5 轮确认了用 PostgreSQL,第 25 轮它开始建议你考虑一下 Redis 的方案。
模式二:纠正回退
你发现 Claude 用错了某个写法,纠正了它。它承认了,改对了。五轮之后,它犯了同样的错误。
这是因为"纠正"发生在对话的第 8 轮,而你现在在第 15 轮。纠正的内容在上下文里的位置越来越靠后,在 lost-in-the-middle 的注意力分布下,它的权重持续降低,直到 Claude 实际上已经"忘了"那次纠正,重新回到了训练数据里的默认行为。
例如:
你:不要用 console.log,用 logger.info。
Claude:好的,我改成 logger.info。
...
(五轮后)
Claude:这里我先加一个 console.log 方便排查。
你已经说了三次"不要用
console.log,用logger.info",但它还是偶尔会写console.log。
模式三:废弃方案的幽灵
你尝试了一种实现方式,做到一半发现不对,放弃了,换了另一种方式。旧的代码删掉了,但关于旧方案的讨论还留在上下文里。
这段"废弃的历史"会持续影响 Claude 的输出——它可能在新方案里混入旧方案的逻辑,或者在你遇到问题时建议你回到旧方案,因为旧方案在它的上下文里看起来也是一个"被讨论过的合理选项"。
例如:
你:Sequelize 这条路不走了,切到 Prisma。
Claude:明白,后续都按 Prisma 来。
...
(后来你问一个查询问题)
Claude:你可以在 Sequelize 的 include 里这样写...
你已经换掉了 ORM,但 Claude 还在参考旧 ORM 的写法给你示例。
模式四:注意力发散
随着上下文增长,Claude 需要处理的信息量越来越大。注意力是有限的——分给了 A 就少给了 B。越是长对话,Claude 越难在某一个具体问题上保持高度聚焦。它的回答开始变得面面俱到但不够深入,或者在你问一个具体问题时夹带了很多你没问的背景讨论。
例如:
你:只看这个接口的事务边界,哪里可能有问题?
Claude:这个接口本身有事务问题。另外认证模块、日志方案、缓存策略、
前端错误提示也建议一起调整...
任务越来越复杂,但 Claude 的回答越来越泛,不够犀利。
理解了劣化,命令就有了意义
这四种模式,对应的干预手段是不同的:
| 劣化模式 | 干预手段 | 原因 |
|---|---|---|
| 早期探索污染 | /compact 明确声明保留哪些决策 | 压缩时主动过滤探索内容,只留结论 |
| 纠正回退 | 把纠正写进 CLAUDE.md | 从"对话历史"变成"系统注入",每轮强制生效 |
| 废弃方案幽灵 | /clear 重开一个干净会话 | 彻底清除废弃历史,而不是试图覆盖它 |
| 注意力发散 | 拆任务 + 每个任务独立会话 | 每个会话只有一个聚焦点 |
但这些命令本质上是不同类型的东西,可靠性和适用场景差别很大——这是大多数人没意识到的。
5 条最实用的决策规则
如果你只想带走最实用的部分,可以先记这 5 条:
- 任务已经切换,就先
/clear。不要让上一个任务的残留背景继续污染当前任务。 - 任务没切,但会话已经很长,就
/compact。而且最好写清楚“只保留哪些已确认决策”。 - 同一条规则纠正两次以上,就别再聊了,直接写进
CLAUDE.md。 - 你要复用的是“提示词流程”,就做成自定义 command;你要复用的是“带权限约束的能力”,就做成 skill。
- 当 Claude 开始“什么都懂一点但什么都答不深”时,优先怀疑上下文过载,而不是先怀疑模型突然变差。
这 5 条的价值,在于它们能把“模糊感觉”迅速翻译成明确动作。真正影响协作质量的,不是你知不知道这些概念,而是你能不能在出现问题的当下做对动作。
Claude Code 命令的三种类型
第一类:CLI 状态操作命令
这些命令直接操作 Claude Code 进程的内部状态,不经过 AI 模型,执行的是确定性的代码逻辑。
/clear → 直接清空内存里的对话历史数组
/cost → 读取 token 计数器,格式化输出
/model → 修改当前会话的模型配置
/memory → 读取和展示 Memory 目录下的文件内容
/help → 输出命令列表
关键特性:结果确定,不依赖 Claude 的理解。 /clear 必然清空,/cost 必然显示费用,不会因为你的 Prompt 写得好不好而有差异。这类命令是系统层面的操作,不是 AI 行为。
第二类:自定义 Slash Command(提示词模板)
这类命令存放在 .claude/commands/ 目录下,每个命令是一个 .md 文件。文件名就是命令名,文件内容就是命令触发时注入给 Claude 的提示词。
.claude/
commands/
review.md → /review 命令
pr-desc.md → /pr-desc 命令
standup.md → /standup 命令
可以用 $ARGUMENTS 接收参数:
<!-- .claude/commands/review.md -->
对以下代码做专项 review,聚焦:$ARGUMENTS
检查顺序:
1. 安全漏洞(SQL 注入、权限校验缺失)
2. 边界条件和错误处理
3. 项目规范符合性(参考 CLAUDE.md)
每个问题标注严重等级:blocking / warning / suggestion
关键特性:本质上是一次对话,经过 AI 模型处理,结果有随机性。 你写的是提示词,不是程序——好的自定义命令写法和好的 Prompt 写法是一回事:具体、有约束、有明确的输出格式。
第三类:Skills(能力包触发)
Skills 比自定义命令更重,有完整的元数据配置:限制工具权限(allowed-tools)、指定触发条件(when_to_use)、选择模型(model)、设置上下文隔离(context: fork)。
---
name: security-audit
description: 安全审查
when_to_use: 审查代码安全漏洞时
allowed-tools:
- Read
- Grep
- Glob
model: claude-opus-4-5
context: fork
---
对 ${target} 执行安全审查...
Skills 触发时,会在隔离的子上下文里运行,工具权限是物理隔离的(不是靠 Claude 自律),结束后把结果返回主会话。
关键特性:比自定义命令更结构化,工具权限有硬约束,可以和主会话隔离运行。 适合封装有副作用、需要权限控制的操作。第 05 篇会专门讲 Skills 的设计。
三类命令的选用原则
需要确定性结果,不想靠 Claude 判断 → 第一类 CLI 命令。清空上下文、查费用、切模型,这些操作不该有歧义。
想复用一套工作流程,不需要特殊权限控制 → 第二类自定义命令。把反复用到的提示词结构固化下来,/standup、/pr-desc、/review 这类日常命令都适合。注意:它还是提示词,不是代码。
封装有风险的操作,或者需要隔离运行 → 第三类 Skills。权限隔离只有 Skills 能做到。
两个值得停下来想的洞见
把命令类型和劣化模式放在一起,有两个反直觉的结论。
洞见一:在对话里纠正 Claude 是徒劳的——这是机制决定的,不是你说得不够清楚
模式二"纠正回退"的根本原因不是 Claude 不配合,而是你在用错误的工具纠正它。
在对话里说"不要用 console.log",这条纠正被写进了"会随时间衰减的历史"——位置越来越靠后,注意力权重持续降低,最终必然回退。这不是偶然的,是 lost-in-the-middle 的机制决定的。
更重要的是,这件事其实很容易自己验证。你可以做一个小实验:
- 在纯对话里告诉 Claude:"不要用 console.log,用 logger.info。"
- 继续推进几轮任务,再让它生成新代码。
- 然后把同一条规则写进 CLAUDE.md,再重复一次类似流程。
大多数时候你会发现,两种方式的持久性差别非常明显。前者更容易回退,后者更稳定。这比单纯讲原理更有说服力,因为你能亲手看到规则所在层级不同,稳定性就不同。
真正有效的纠正只有一种:把规则从对话历史移进系统注入层。
# CLAUDE.md
- 日志统一用 logger.info/warn/error,禁止 console.log
- 所有异步函数必须有 try-catch,不依赖外层中间件捕获
- 禁止使用 any,类型必须明确
写进 CLAUDE.md 的规则,在每次对话开始时被系统自动注入,优先级高于对话历史,不会随对话长度衰减。这是 CLAUDE.md 存在的真实原因——不是"项目文档",是绕过对话历史衰减的唯一可靠手段。
判断标准很简单:如果你对同一件事纠正了两次以上,就不该继续在对话里纠正,而应该把它写进 CLAUDE.md。
洞见二:/compact 不是无损压缩,它本身就是一次 AI 调用
很多人以为 /compact 是把历史"存档"了,实际上 Claude Code 在压缩时会调用模型生成摘要——这意味着压缩结果的质量,取决于 Claude 怎么理解这段历史。
这里不需要依赖源码猜。单从行为上你就能判断出来:/compact 不是简单的机械压缩,而是在"理解历史之后生成摘要"。
为什么这么说?因为如果它只是确定性的算法压缩,那么你补不补"保留说明",结果应该差异很小;但实际使用中,空着用和带明确保留说明用,摘要质量往往差很多。这更像是模型在根据你的提示重新组织历史,而不是程序在做无损归档。
你在 /compact 后面附加的保留说明,本质上就是在告诉 Claude:哪些内容应该成为压缩后的锚点。有没有写、写了什么,会直接影响压缩后的摘要长什么样。
这有两个实际含义:
第一,/compact 不在第一类"确定性命令"里——尽管它看起来是内置命令,但压缩结果是 AI 行为,不是代码行为,存在质量差异。
第二,空着用和带保留说明用,结果可以差很多:
❌ /compact
→ Claude 自己判断什么重要,探索性讨论和已确认决策同等对待
✅ /compact 只保留已确认的决策:JWT 方案、Prisma 数据库表结构、
错误处理用 AppError 类。探索阶段被否决的方案不需要保留。
→ Claude 围绕这些锚点生成摘要,后续对话里这些决策记得最清楚
如果你一直在空着用 /compact,本质上是在让 Claude 替你决定什么值得记住。
两个可以立刻自己验证的小实验
如果你想判断这篇文章讲的是不是“经验之谈”,最好的办法不是相信我,而是自己试一下。
实验一:同一条规则,留在对话里 vs 写进 CLAUDE.md
找一条你平时经常纠正的规则,比如:
不要用 console.log,用 logger.info
先只在对话里说这条规则,继续推进几轮任务,再让 Claude 生成新代码。然后把同一条规则写进 CLAUDE.md,重新开始一个类似任务,再观察它的稳定性。
你大概率会看到一个很明显的差别:
留在对话里的规则更容易回退;写进 CLAUDE.md 的规则更稳定。
这个实验最重要的启发不是“CLAUDE.md 很有用”,而是:规则所在的层级不同,稳定性就不同。
实验二:空着 /compact vs 带保留说明 /compact
找一段讨论过很多方案的长会话。先在类似场景里直接执行:
/compact
再换一次,在压缩时明确写:
/compact 只保留已确认的决策:JWT 方案、Prisma 表结构、错误处理规范。
探索阶段被否掉的方案不保留。
然后比较压缩后的后续表现。你通常会发现,后者更不容易把探索阶段的噪音继续带下去。
这个实验说明的不是“提示词可以调得更好”,而是:/compact 本身就在重新组织历史,所以你不该把它当成无脑归档。
完整视图:五类控制机制
把命令扩展到所有控制机制,共五类:
| 类型 | 触发方式 | 经过 AI | 可靠性 |
|---|---|---|---|
CLI 状态命令(/clear、/cost 等) | 手动输入 | ❌ | 确定性 |
| 自定义 Slash Command | 手动输入 | ✅ | 依赖提示词质量 |
| Skills | 命令或自然语言触发 | ✅ | 工具权限有硬约束 |
| Hooks(PreToolUse 等) | 工具执行事件自动触发 | ❌ | 确定性 |
| 键盘快捷键(Plan Mode 等) | 键盘操作 | ❌ | 确定性 |
不经过 AI 的机制(CLI 命令、Hooks、快捷键)是确定性的,适合做强约束;经过 AI 的机制(自定义命令、Skills)有随机性,需要好的提示词设计,但表达能力更强。
这篇文章的边界
这里讲的现象,并不是 Claude Code 独有的怪癖,而是长上下文 AI 协作的一类共性问题。不同模型、不同客户端、不同版本,细节会有差别,但下面这几个事实不会变:
- 对话历史不是长期稳定记忆
- 早期探索内容会污染后续判断
- 留在对话层的规则会衰减
- 当上下文过长时,注意力一定会分散
所以这篇文章真正想讲的,不是“背命令表”,而是一个更底层的判断:
Claude Code 的核心问题,不是你会不会再写一个更长的 Prompt,而是你有没有把信息放在正确的层级上。
项目背景、长期规则、任务上下文、阶段性探索,这四种东西不应该混在一起管理。Claude Code 之所以有这些 Commands,本质上就是为了让你把它们拆开。
本篇实践任务
任务一: 找你最近一次“感觉 Claude 越来越糊涂”的会话,对照四种劣化模式,判断到底是哪一种在起作用,不要再笼统地归因于“模型变差”。
任务二: 检查你现在的 CLAUDE.md,有没有把“曾经在对话里纠正过不止一次”的规则写进去?把它们补进去,下次对话观察差异。
任务三: 做一次对照实验:一段长任务会话里分别试试“空着 /compact”和“带保留说明 /compact”,比较后续回答质量。
任务四: 在 .claude/commands/ 里创建一个你最常用操作的自定义 command,比如 /pr-desc 或 /standup,感受一下它和直接输提示词的区别。
下篇预告
第 04 篇:CLAUDE.md 完整指南——让 Claude 真正理解你的项目
你已经知道 CLAUDE.md 是"系统注入的长期记忆",优先级高于对话历史,是纠正回退的唯一可靠手段。但写什么进去、怎么写才能真正影响 Claude 的行为而不只是让它"读到",是另一个问题。下一篇专门讲这个。
AI Coding 系列持续更新。上下文劣化有规律,干预就有方法。