别再把 Claude Code 用乱了:CLAUDE.md、Rules、Skills、Hooks 到底怎么分工?

0 阅读13分钟

很多人想深入接触 Claude Code,都会有一种很真实的崩溃感:

CLAUDE.mdrulesskillshookscompact……
名字都认识,放一起就开始乱。

更麻烦的是,这几个东西看起来都像“规则”,都像“约束”,都像“告诉 AI 该怎么做”。
于是问题来了:

  • CLAUDE.md 能约束
  • rules 也能约束
  • skill 也在影响行为
  • hook 看起来也像规则触发器

那到底什么时候该用哪个?

我一开始也绕了很久,后来终于想明白了:
别按“它能不能约束”来分,要按“它是怎么生效的”来分。

这篇文章就只做一件事:
把 Claude Code 里这几个最容易混的东西,用最通俗的方式讲明白,再顺手把“到底该怎么写”也说清楚。


先说结论:把它们想成一家公司就不容易乱

你可以直接这么记:

  • CLAUDE.md:公司总制度
  • rules:部门补充规定
  • skill:这类工作的 SOP 手册
  • hook:门禁 / 安检 / 自动检查脚本
  • compact:开会开久了,整理一下桌面和纪要

如果只记这一层意思,已经够用了。

再翻译成人话一点:

  • CLAUDE.md:全局长期生效的原则
  • rules:局部场景生效的规则
  • skill:告诉 AI“这类任务一般怎么做”
  • hook:别靠 AI 记,系统到点自动执行
  • compact:长对话太乱了,压缩一下上下文

1. CLAUDE.md:不是知识库,是“合作协议”

很多人第一次上手就喜欢往 CLAUDE.md 里塞一堆东西,最后写成项目百科全书。

其实它最适合放的是:

  • 这个项目默认用什么命令
  • 哪些目录不要碰
  • 完成任务前要做什么检查
  • 哪些原则每次都成立

比如:

  • pnpm,不用 npm
  • 改完代码先跑 lint 和 test
  • 不要修改 generated files
  • 涉及支付逻辑先看接口约定

这些都很适合放 CLAUDE.md

因为它不是在教 AI 怎么做一类复杂任务,
而是在告诉它:

“我们合作时,有一些长期不变的底线和习惯。”

所以你可以把 CLAUDE.md 理解成:

你和 Claude 之间的长期合作协议

不是团队 wiki,也不是项目知识库,更不是大杂烩。

CLAUDE.md 怎么写?

最重要的原则就一句话:

写长期成立、全局适用、足够稳定的东西。

别写太细,别写得像百科全书,也别把某个目录的局部规则全塞进来。

一个比较顺手的写法

# CLAUDE.md

## Commands
- Use `pnpm`, not `npm`
- Run `pnpm lint` and `pnpm test` before finishing code changes

## Safety
- Never edit files under `src/generated/`
- Do not modify production config unless explicitly asked

## Workflow
- For non-trivial changes, explain the plan first, then implement
- For payment-related changes, read API contracts before editing UI

## Style
- Prefer small, focused changes
- Do not refactor unrelated files

CLAUDE.md 适合写什么?

很适合写:

  • 默认命令
  • 全局完成标准
  • 高风险禁区
  • 默认工作方式
  • 整个仓库通用的 coding preference

不太适合写什么?

不太适合写:

  • 某个目录专属规则
  • 某种语言才生效的限制
  • 一整套复杂的排障流程
  • 很长的业务背景介绍

这些更适合给 rulesskills 或其他文档。

什么时候用 CLAUDE.md?

当你心里想的是:

  • “这个原则几乎每次都成立”
  • “每次开新会话都该知道”
  • “这是长期契约,不是局部技巧”

那就放 CLAUDE.md


2. rules:不是另一个 CLAUDE.md,而是“局部法规”

如果 CLAUDE.md 是全国通用法律,
rules 就更像地方法规。

它适合处理这种情况:

  • 只有某个目录才有这条规则
  • 只有某种语言才有这套规范
  • 只有某类文件才需要特殊处理

举个例子。

你项目里可能有这些情况:

  • src/components/ 下的组件必须用函数组件
  • backend/python/ 统一用 pytest
  • .sql 文件里不允许 SELECT *
  • 某个安全目录不允许随便改

这些都不适合一股脑堆到根 CLAUDE.md 里。
因为不是所有任务都会碰到它们。

这时候 rules 的价值就出来了:

只在相关场景加载,只约束相关范围。

所以它和 CLAUDE.md 的关系不是谁替代谁,而是:

  • CLAUDE.md 管全局
  • rules 管局部

rules 怎么写?

rules 最适合的写法就是:

一条规则只负责一个局部场景。

比如按目录拆,按语言拆,按文件类型拆,都可以。

例子 1:前端组件目录规则

# rules for src/components/

- Prefer function components
- Prefer hooks over class components
- Keep components presentational when possible
- Avoid placing data-fetching logic directly in UI components

例子 2:SQL 文件规则

# rules for *.sql

- Do not use `SELECT *`
- Always specify affected tables explicitly
- Prefer readable queries over compressed one-liners
- Add comments for destructive migrations

例子 3:Python 目录规则

# rules for backend/python/

- Use `pytest`, not `unittest`
- Prefer type hints for public functions
- Keep business logic out of route handlers

rules 写的时候一个很实用的原则

不要把 rules 写成“再来一份小号 CLAUDE.md”。

它最好的价值,不是再写一堆全局原则,
而是把这些话说清楚:

  • 到了这个目录
  • 碰到这类文件
  • 就按这里的规则来

一个特别实用的判断方法

如果你脑子里冒出来的是:

“这条规则不是每次都成立,但到了这个目录/文件类型就必须成立”

那它大概率该放 rules


3. skill:不是一句 prompt,而是“任务说明书”

这是最容易被误解的地方。

很多人会把 skill 理解成“高级 prompt”。
这么想不算错,但不够准确。

更贴切一点,skill 是某类任务的操作手册

比如你让 Claude 去做“线上问题排查”,真正需要的往往不是一句 prompt,而是一套步骤:

  1. 先看日志
  2. 再看最近发布
  3. 再确认影响范围
  4. 再提出假设
  5. 再做验证
  6. 最后给 root cause 和修复建议

这就不是一句“请你帮我排查问题”能解决的了。
这是一套方法。

所以 skill 最适合装这种东西:

  • debug 流程
  • code review checklist
  • 发布 SOP
  • 迁移步骤
  • 某类业务改动的固定做法

skill 最像什么?

我觉得最形象的比喻是:

字典目录 + 对应章节

平时不会把整本手册全塞给模型,
而是先让它知道“有这么一本手册”。

等它判断这次任务像“部署”“排障”“重构”这种场景,
再把完整 skill 加载进来。

所以 skill 不是一开始全文常驻,
更像是:

  • 平时脑子里放一个“目录索引”
  • 真遇到这类题,再翻完整章节

这也是为什么 skill 常被说成是“按需加载的工作流”。

skill 怎么写?

Skill 最重要的不是写得多像 prompt,而是把 3 件事写清楚:

  • 什么时候用
  • 按什么步骤做
  • 最后输出什么

你可以把它理解成:
不是在“对 AI 说一段漂亮话”,而是在给它一份任务说明书。

一个顺手的 skill 写法

---
name: debug-issue
description: Use this skill when investigating bugs, failing tests, or unexpected runtime behavior.
---

## Goal
Find the likely cause with minimal blind changes.

## Steps
1. Reproduce the issue first
2. Narrow the scope
3. Inspect logs, stack traces, and recent changes
4. Propose 1-2 likely hypotheses
5. Verify each hypothesis before editing code
6. Prefer minimal fixes
7. Explain root cause and validation steps

## Output
- suspected root cause
- changed files
- validation steps
- remaining risks

再来一个发版类的 skill

---
name: release-checklist
description: Use this skill when preparing a release or deployment.
---

## Steps
1. Pull latest code
2. Run tests and build
3. Check environment config
4. Confirm migration or feature flag impact
5. Prepare rollback notes
6. Summarize release risks

## Output
- release checklist result
- blockers
- rollback notes

skill 写的时候有几个很实用的建议

第一,description 要写清使用场景。
因为这决定了模型什么时候更容易“命中”它。

第二,步骤不要写得过散。
最好是清晰、短、能执行。

第三,尽量写输出。
不然模型容易流程做了半天,最后交付物不统一。

第四,别把 skill 写成 wiki。
wiki 偏资料库,skill 偏动作指南。

什么时候用 skill?

当你想表达的是:

“这类任务有一套固定做法,不能只靠 AI 临场发挥”

那就该用 skill。


4. hook:它其实很像 Husky

如果你觉得 hooks 抽象,那我建议你直接记一个类比:

hook 很像 husky / git hooks。

是不是一下就顺了?

Husky 干嘛的?

  • 你 commit 之前,自动跑 lint
  • 你 push 之前,自动跑 test
  • 不通过就拦住

重点是:

它不是提醒你记得做,而是系统自动帮你做。

Claude Code 里的 hook 也是同一个味道。
只不过 husky 绑定的是 Git 生命周期,Claude hooks 绑定的是 Agent 生命周期。

比如:

  • Claude 一启动会话,自动注入一些上下文
  • Claude 改完文件后,自动跑检查
  • Claude 尝试改敏感目录时,直接拦住
  • Claude 任务结束后,自动发通知

所以 hook 的本质不是“再写一条规则给模型看”,
而是:

某个时刻一到,系统自动执行一段逻辑

这就和 CLAUDE.mdrulesskill 完全不是一个层级了。

前面三个主要还是在“告诉模型怎么想、怎么做”。
而 hook 是在“系统层面插手执行过程”。

hook 怎么写?

最简单的理解方式就是:

写触发时机 + 匹配条件 + 执行动作。

也就是:

  • 在什么事件点触发
  • 对什么动作 / 文件生效
  • 然后执行什么命令

例子 1:改完 Rust 文件自动检查

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit",
        "pattern": "*.rs",
        "hooks": [
          {
            "type": "command",
            "command": "cargo check 2>&1 | head -30",
            "statusMessage": "Running cargo check..."
          }
        ]
      }
    ]
  }
}

这段话翻译成人话就是:

  • Claude 刚用了 Edit
  • 改的是 .rs 文件
  • 那就自动跑一次 cargo check

例子 2:改 ts/tsx 后自动 lint

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit",
        "pattern": "*.{ts,tsx}",
        "hooks": [
          {
            "type": "command",
            "command": "pnpm eslint . --ext .ts,.tsx",
            "statusMessage": "Running eslint..."
          }
        ]
      }
    ]
  }
}

例子 3:会话开始时注入上下文

{
  "hooks": {
    "SessionStart": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "git branch --show-current && node -v && pnpm -v",
            "statusMessage": "Collecting workspace context..."
          }
        ]
      }
    ]
  }
}

这类写法很适合收集当前分支、运行环境、工具版本。

hook 最适合什么场景?

hook 非常适合这类事:

  • 改完代码自动 lint / test
  • 高风险目录禁止修改
  • 会话开始自动收集现场信息
  • 任务结束自动提醒

一句话:

凡是“不该靠 AI 自觉记住”的事,都很适合 hook。

hook 写的时候有个特别重要的原则

尽量让它:

  • 可预测
  • 结果清晰

别把 hook 设计成一个超复杂的智能工作流。
它更适合做“自动安检”,不适合做“全流程总导演”。


5. compact:不是让回答更短,是“把脑子清一清”

compact 也经常被误解。

很多人以为它的作用是“简洁一点”“少说一点”。
其实不是。

它真正的价值是:

长对话里,帮你压缩上下文噪声。

这个问题在 Claude Code 里特别真实。

对话一长,里面会塞满很多东西:

  • 已经过时的尝试
  • 失败的中间方案
  • 很长的日志
  • 已经被推翻的结论
  • 重复的信息

这时候 AI 不是变笨了,
而是“工作台太乱了”。

compact 做的事,就像:

  • 不是把整个房间搬空
  • 而是把桌上真正有用的东西收拾出来
  • 把没用的纸团、草稿、废弃结论扔掉

所以它适合:

  • 任务还在继续
  • 但上下文已经开始变脏
  • 想保留进度,又不想继续带着一堆噪声往前跑

compact 怎么用?

和前面几个不同,compact 不是你去写一个文件。
它更像一个操作动作。

你可以把它理解成:

  • 不换任务
  • 不完全清空上下文
  • 只是把当前会话压缩成“对后续还有价值的版本”

一个很实用的使用场景

比如你和 Claude 已经一起排查了 40 分钟问题,
中间尝试过 5 条路径,跑了很多日志,也否掉了几个错误方向。

这时候如果你继续往下聊,很容易越来越乱。
compact 的意义就是:

  • 保留最终确认过的结论
  • 保留当前剩余问题
  • 保留下一步计划
  • 丢掉大部分已经没用的中间过程

一个很实用的区分

  • 任务换了:适合 clear
  • 任务没换,但对话太乱了:适合 compact

所以 compact 不是配置项,
而更像你在长会话里的“上下文整理动作”。


6. 什么时候该用哪个?用一个例子一次讲清

假设你让 Claude 帮你改一个支付页面。

你有下面这些要求:

  1. 不要改 src/security/
  2. 前端统一用 hooks 写法
  3. 改支付逻辑前要先看接口约定
  4. 改完必须跑测试
  5. 发版前要检查埋点和截图

这 5 条要求,看起来都像“规则”,
但最适合放的位置完全不同。

放到 CLAUDE.md 的

比如:

  • 默认用 pnpm
  • 改完代码要跑测试
  • 涉及支付相关先看接口契约

这是长期都成立的项目合作习惯。

放到 rules 的

比如:

  • src/components/ 下面统一函数组件
  • *.sql 禁止 SELECT *

这是局部场景约束。

放到 skill 的

比如:

  • 支付流程改动的一整套 SOP
  • 先看 API,再确认埋点,再改 UI,再补测试,再截图验证

这是“这类任务怎么做”。

一个支付改动 skill 的简化版写法

---
name: payment-change
description: Use this skill for checkout or payment flow changes.
---

## Steps
1. Read payment API contracts
2. Identify affected analytics events
3. Update UI with backward compatibility in mind
4. Add or update tests
5. Capture before/after screenshots
6. Summarize risks

## Output
- changed files
- analytics impact
- validation steps
- risk summary

放到 hook 的

比如:

  • Claude 一旦想改 src/security/ 就直接拦住
  • 改完 .ts/.tsx 自动跑 eslint

这是“别靠它记,系统自动检查”。


7. 真正不容易混的判断口诀

以后你只要问自己四句话:

这是不是全局长期成立的?

是 → CLAUDE.md

这是不是只有局部场景才成立?

是 → rules

这是不是某类任务的一套标准做法?

是 → skill

这是不是必须自动执行 / 必须阻断,不能靠 AI 自觉?

是 → hook

如果任务还没变,但上下文已经乱成一锅粥了:

compact


8. 底层原理也顺手讲明白

很多人还会好奇:

skill 到底是怎么触发的?
是不是把一段 prompt 拼进 request body?

你可以粗暴但准确地理解成:

是,但不是一开始全塞进去。

skill 更像“先给目录,再按需翻正文”。

也就是说:

  1. 模型先知道有哪些 skill 可以用
  2. 当它判断当前任务像某个 skill 的适用场景
  3. 再把完整内容加载进来

所以 skill 的底层感觉,确实很像“查目录,再翻章节”。

而 hook 则完全不一样。

hook 更像程序世界里的事件监听:

  1. 某个时刻发生
  2. 系统检测到
  3. 自动执行脚本/命令
  4. 根据结果决定提示、校验还是阻断

所以 skill 更偏“让模型多懂一点”,
hook 更偏“让系统多管一点”。


9. 最后一遍,用一句话全记住

如果你看到这里还是怕以后又混,我给你一个最省脑子的版本:

  • CLAUDE.md:长期合作协议
  • rules:局部补充规定
  • skill:任务操作手册
  • hook:Husky 一样的自动检查脚本
  • compact:对话太长时的上下文收纳整理

说到底,这几个东西并不是“谁比谁高级”,
而是它们管的层面不同。

很多人一开始总想用一个东西包打天下:
要么什么都写进 CLAUDE.md
要么什么都想靠 skill,
要么干脆把 hook 当万能规则引擎。

最后通常都会越来越乱。

真正好用的方式反而很朴素:

  • 全局原则放全局
  • 局部规则放局部
  • 方法论交给 skill
  • 硬约束交给 hook
  • 上下文乱了就 compact

这样 Claude Code 才会慢慢从“有点聪明,但经常跑偏”,
变成“真能协作的工具”。