本页目录11
- Claude Code 提供 CLAUDE.md、Rules、Skills、Subagents、Hooks、Output Styles、append-system-prompt 共 7 种指导方式,核心差异在于加载时机、压缩后是否保留、上下文成本三个维度。
- 根目录 CLAUDE.md 会话开始即加载且全程保留,适合放构建命令、目录结构、编码规范;子目录 CLAUDE.md 按需加载、压缩后丢失,适合放局部规范。
- Rules 可通过 frontmatter 的 paths 字段做路径限定,只在相关目录工作时才加载,避免无关任务也占用 token。
- Skills 会话开始只加载名称和描述,调用时才加载完整内容,适合部署、发布清单等流程性工作;Subagents 在独立上下文中运行,只把最终结果带回主会话,适合会产生大量中间输出的侧任务。
- Hooks 在特定生命周期事件(如文件编辑后、PreToolUse)触发确定性命令、HTTP 调用或 LLM 判断,不占主上下文,是「每次 X 都要 Y」类需求的正确落地方式,而不是写进 CLAUDE.md 靠模型自觉执行。
- 文章给出常见反模式:把总是执行的动作写进 CLAUDE.md 该用 hooks、把绝对禁止的规则写进 CLAUDE.md 该用 PreToolUse 拒绝、把多步流程写进 CLAUDE.md 该用 Skills、无路径限定的规则该加 paths、个人偏好不该写进项目级 CLAUDE.md。
本文是对 Anthropic 官方博文《Steering Claude Code: CLAUDE.md files, skills, hooks, rules, subagents and more》的中文要点摘要,完整内容以原文为准:https://claude.com/blog/steering-claude-code-skills-hooks-rules-subagents-and-more
Claude 设计上会去适配用户的工作方式,而 Claude Code 提供了多种「指导」它行为的机制。原文将这些机制归纳为 7 种,并从三个维度做区分:
- 指令何时加载进上下文
- 长会话被压缩(compact)后能否留存
- 占用的 token 成本高低
一图看懂 7 种方法
| 方法 | 加载时机 | 压缩后表现 | 上下文成本 | 典型场景 |
|---|---|---|---|---|
根目录 CLAUDE.md | 会话开始,全程保留 | 压缩后会重新读取 | 高 | 构建命令、目录结构、团队规范 |
子目录 CLAUDE.md | 按需,读到该目录文件时才加载 | 压缩后丢失 | 低 | 子目录专属规范 |
Rules(.claude/rules/) | 会话开始或路径匹配时 | 压缩时重新注入 | 中 | 特定约束/规范 |
Skills(.claude/skills/) | 会话开始只加载名称+描述,调用时加载全文 | 在共享预算内重新注入,最旧的先被丢弃 | 低 | 部署、发布清单等流程 |
Subagents(.claude/agents/) | 会话开始加载名称、描述、工具列表,调用时加载主体 | 只有最终消息回传主会话 | 低 | 并行或需要隔离的侧任务 |
| Hooks | 生命周期事件触发时 | 绕过压缩机制 | 低 | 确定性自动化 |
Output styles(.claude/output-styles/) | 每个会话开始 | 从不压缩 | 高 | 大幅度角色转变 |
append-system-prompt(CLI flag) | 调用时传入 | 从不压缩 | 中 | 语气、格式、响应长度等偏好 |
逐项说明
CLAUDE.md
分两类:根目录 CLAUDE.md 在会话开始加载且贯穿全程,压缩后会被重新读取,适合放构建命令、monorepo 结构、编码规范这类「全程都要用得上」的信息。子目录下的 CLAUDE.md(比如 app/api/CLAUDE.md)只在 Claude 读取该目录文件时才触发加载,压缩后会丢失,直到再次访问才恢复,适合放局部规范。
最佳实践:控制在 200 行以内、明确所有者、像审代码一样审查它的改动;monorepo 里可以给每个团队目录建独立子目录 CLAUDE.md,并用 claudeMdExcludes 设置跳过不相关团队的内容;组织级标准可通过 MDM 集中下发。
Rules
.claude/rules/ 下的 markdown 文件,给 Claude 提供具体约束。默认「未限定」的规则在会话开始就加载,即便任务无关也会占用 token。更推荐的做法是在 frontmatter 里加 paths 字段做路径限定,例如:
---
paths:
- "src/api/**"
- "**/*.handler.ts"
---
All API handlers must validate input with Zod before processing.
这样规则只在相关子目录工作时才加载。原文举例:「迁移文件只能追加(append-only)」这类针对特定文件的约束最适合写成带 paths 限定的规则;当约束涉及散布在代码库多处(而非全部)的横切关注点或文件时,应优先选路径限定规则而不是子目录 CLAUDE.md。
Skills
.claude/skills/ 下的文件夹,包含带名称、描述和主体的 SKILL.md。会话开始时只加载名称和描述,通过斜杠命令(如 /code-review)调用或任务自动匹配时才加载完整主体。压缩时,已调用的技能会在共享预算内重新注入,若一次会话调用多个技能,最旧的会先被丢弃。适合部署工作流、发布清单这类流程性任务。
Subagents
.claude/agents/ 下的 markdown 文件,frontmatter 里写名称、描述,可选模型和工具访问范围,主体则作为子代理的系统提示。会话开始只加载名称、描述、工具列表,真正调用时通过 Agent 工具传入提示字符串,在独立上下文窗口里运行,原文强调「子代理主体内的大段上下文不会自动进入父对话」——只有最终消息(通常是聚合结果)加元数据会传回主会话。子代理最多可嵌套五层,适合深度搜索、日志分析、依赖审计这类会产生大量中间结果、容易搞乱主对话的侧任务。
Hooks
用户定义的命令、HTTP 端点或 LLM 提示,在 Claude 生命周期的特定事件(文件编辑、工具调用、会话开始等)触发,提供确定性控制。原文列出 5 种钩子类型:command、HTTP、mcp_tool、prompt、agent——前三种是确定性执行,后两种依赖 Claude 的判断。配置位置包括 settings.json、管理策略设置,以及技能/代理的 frontmatter。典型用法:编辑后跑 linter、任务完成发 Slack 消息、PreCompact 事件里备份聊天记录、PreToolUse 事件里用 exit code 2 拒绝某个工具调用。大多数钩子输出不会进主上下文,除非明确配置返回;而拒绝性钩子的报错信息会保留,让 Claude 知道调用为什么被拒。原文的建议是:「凡是应该确定性发生的事,都用 hooks 处理」,因为它们是运行的代码而不是加载进上下文的指令,成本很低。
Output styles
.claude/output-styles/ 下的文件,直接注入系统提示,每个会话开始都加载、从不压缩,权重最高。默认输出风格里包含如何限定改动范围、何时加/省注释、如何处理安全问题、验证习惯(先跑测试再说完成)等关键指令。原文特别提醒:自定义输出风格会把这些默认指令全部清空,除非在 frontmatter 里设置 keep-coding-instructions: true,否则 Claude 会从「软件工程助手」变成通用助手。内置风格有 Proactive、Explanatory、Learning 三种。
append-system-prompt
通过 CLI flag append-system-prompt 传入,仅对该次调用生效,只是在原系统提示后追加内容、不改变 Claude 的角色定位,从不压缩,但会享受 prompt caching 带来的成本下降。优点是只做加法不改角色,缺点是指令越堆越多,遵循度会下降,尤其是指令之间互相矛盾时。适合临时加编码规范、输出格式或领域知识。
常见误用与修正建议
原文总结了几类典型「用错工具」的情况:
- CLAUDE.md 里写「每次 X 都要 Y」:模型是否执行取决于它的判断,不等于工具自动运行——应该用
settings.json里的 hooks。 - CLAUDE.md 里写「绝不能做 X」:长会话、模糊场景或提示注入下这类指令容易失效——应该用 hooks 的
PreToolUse(exit code 2 拒绝)或管理设置来兜底。 - CLAUDE.md 里塞 30 行的操作流程:这类内容应该按需加载——放进
.claude/skills/里更合适。 - API 专属规则没写路径限定:会在无关工作时白白消耗 token——给规则加上
paths:限定范围。 - 项目级 CLAUDE.md 里写个人偏好:个人偏好应该全局生效——放本地文件,项目级文件只放团队共识内容。
延伸阅读
原文提到可参考官方《best practices for Claude Code》文档获取更多模式;技能、子代理、钩子、输出风格都可以打包成插件,与团队或项目共享设置。