Coding Agent 规则管理:CLAUDE.md、Skills、Hooks、Subagents 到底怎么选?
Coding Agent 用久了,规则管理就会变成一个绕不开的问题:哪些内容该放进项目说明,哪些流程得按需调用,哪些动作必须由系统强制执行。
Anthropic 发布了一篇 Claude Code 进阶指南,里面把 CLAUDE.md、Rules、Skills、Subagents、Hooks、Output styles 和 append system prompt 放在一起比较。在这里,我们借助该篇内容提供的分类方式,来讨论一个更通用的问题:Coding Agent 里的规则,究竟应该放在哪里。
规则分层
Coding Agent 的规则管理,大致可以分成几类:有些规则要在项目启动时就被读到,有些规则只在处理特定目录或文件时出现,有些规则更适合做成可调用的流程,还有一些规则必须交给系统机制稳定执行。
CLAUDE.md、Rules、Skills、Subagents、Hooks 之所以值得放在一起看,正是因为它们都在影响 Agent 的行为,但介入的位置不同。判断一条规则应该放在哪里,可以看它什么时候加载、会不会长期占用上下文,以及能不能提供确定性的约束。
这里,我们先粗略对照下:
- 项目背景,放 CLAUDE.md。
- 局部约束,放 Rules 或子目录 CLAUDE.md。
- 重复流程,放 Skills。
- 支线任务,交给 Subagents。
- 确定性动作和安全边界,用 Hooks、permissions 或 managed settings。
这套分层的作用在于,让 Agent 在需要时读到对应规则,而不是把所有说明都长期塞进主上下文里。下面,我们展开看一下。
CLAUDE.md:只放项目级背景
CLAUDE.md 是写给 Agent 的项目说明书。
它适合放那些进入项目后,立马需要知道的信息:项目是什么、怎么启动、怎么测试、目录怎么分、哪些模块的改动风险更高,以及团队通用的编码约定。Anthropic 的实践文也把根目录 CLAUDE.md 放在会话开始时加载的位置,用来承载构建命令、目录结构、Monorepo 说明、编码规范等项目级背景。

图注:工作目录 cwd 会影响哪些 CLAUDE.md 在会话开始时加载;子目录 CLAUDE.md 会在 Claude 触达对应目录时按需进入上下文。图源:Anthropic
这张图可以重点看 CLAUDE.md 背后的上下文分配方式:根目录文件负责项目级背景,子目录文件负责更靠近代码位置的补充说明。像是某个 API 模块的开发约定、某个 package 的测试方式、某个目录下需要谨慎修改的文件,都可以放到对应目录里,没必要全部堆进根目录。一旦发布流程、Review 清单、排障步骤、安全拦截这类内容长期混在 CLAUDE.md 中,就会让所有任务带上一堆用不上的规则,增加上下文负担,也会稀释 Agent 对当前任务的判断重点。
所以,CLAUDE.md 保留项目背景和基础约定就够了。更细的局部规则、流程型内容和强约束,可以放到后面对应的机制里处理。
路径规则:只让规则在相关文件里生效
很多规则只有在特定路径下才有意义。API handler 要先做输入校验,数据库变更脚本只能往后追加,某类测试文件得用固定命名,某个目录里的组件要遵守特定状态管理方式……这类规则如果全局加载,会让 Agent 在不相关任务里也带着它们。
Claude Code 里的 Rules 就是为这种场景准备的。它们是放在 .claude/rules/ 下的 Markdown 文件,可以通过 paths 字段限定作用范围。以这条路径规则为例:
---
paths:
- "src/api/**"
- "**/*.handler.ts"
---
All API handlers must validate input with Zod before processing.
配置好路径范围后,这条规则只会在 src/api/** 或 **/*.handler.ts 这类路径下生效。如果当前任务只是改文档,且没有触及这些路径,这条 API 规则就不会进入上下文。
这类路径规则解决的是“规则作用范围”的问题。它不适合写项目全局背景,也不适合写长流程。它比较适合表达某类文件、某个目录、某些跨目录但并非全局通用的约束。
判断这类规则该放在哪里,可以看一个标准:它是不是只和某些路径或文件类型有关。
Skills:流程型规则应该拆出来
当一段规则已经从“约定”变成“步骤”,它就不适合继续放在 CLAUDE.md 里。
发布检查、代码审查、安全审计、数据库变更、故障排查、上线前验证,都是典型例子。它们通常不只是几句提醒,而是一套操作流程:先看哪些文件,运行哪些命令,检查哪些结果,最后输出什么结论。
Claude Code 的 Skills 就是来处理这些流程问题的。每个 Skill 都是一个独立文件夹,里面包含 SKILL.md,可以写名称、描述、正文,也可以附带脚本和资源。会话开始时,Claude 只加载 Skill 的名称和描述;只有当任务需要调用某个 Skill 时,完整内容才会进入上下文。Skill 可以通过 slash command 手动调用,也可以由任务自动匹配。

图注:会话开始时,Claude 只看到各个 Skill 的简短描述;当任务需要某个 Skill 时,再读取完整说明和相关材料。图源:Anthropic
这个机制可以带来一个直接的好处,就是流程平时不占主上下文,用到时再展开。
如果团队有一套发布检查流程,要检查 changelog、版本号、测试结果、兼容性说明和回滚步骤。放在 CLAUDE.md 的话,它会跟着每次会话一起进入上下文。当前任务如果只是改一个 README,这套流程压根用不上。只有真正发版时,它才需要完整展开。拆成 Skill 后,Agent 平时只需要知道“有一个发布检查流程可以调用”,到真正发版时再读取完整步骤就行。
所以,Skills 更像是 Coding Agent 的 runbook。发布检查清单、Review checklist、安全审查流程、数据库变更流程、故障排查流程,都适合从 CLAUDE.md 里拆出来,做成按需调用的流程说明。
Subagents:把专门任务的规则放到独立上下文里
有些规则的问题不在于步骤长,而在于它们只服务于某一类专门任务,并且执行过程中会产生大量中间信息。
日志分析、依赖审计、深度搜索、大范围代码理解、并行探索多个方案……这些任务往往需要自己的判断标准、工具使用方式和输出格式,也会产生搜索结果、日志片段、文件摘要、候选路径、失败尝试等临时材料。如果这些内容都进入主会话,Agent 正在处理的主线任务很容易被干扰。
因此,上面这些规则适合放进 Subagents。
在 Claude Code 中,Subagents 位于 .claude/agents/。每个 Subagent 可以定义名称、描述、可用工具、模型,以及自己的系统提示词。主会话开始时,只会加载 Subagent 的名称、描述和工具列表;更完整的任务规则不会直接进入主上下文。Claude 会通过 Agent tool 调用 Subagent,把具体任务交给它。Subagent 在自己的上下文窗口中执行,最后只把结果摘要和元数据返回主会话。

图注:Subagent 的详细上下文在单独窗口中运行,主会话最终只接收摘要结果和元数据。图源:Anthropic
这里容易和 Skills 混在一起。判断该用 Skill 还是 Subagent,可以看这类任务应该在哪里执行:是在主会话里按步骤展开,还是放到独立上下文里完成。
Skill 适合处理流程,让它在主会话里按步骤展开。像是发布检查、Review 清单、数据库变更流程,用户想看到每一步,方便中途调整的任务。
Subagent 适合处理专门任务的执行规则。它可以在独立上下文里完成搜索、分析和尝试,最后只把整理后的结论返回主会话。主 Agent 不需要带着所有中间材料继续工作。举个例子,主 Agent 正在修一个认证 bug,同时还要查最近日志、分析相关 PR、扫描依赖风险。日志分析和依赖审计都有自己的处理规则,也会产生大量临时材料。把它们交给 Subagents 后,主 Agent 可以继续留在修 bug 的主线里,等分析完成后,再拿结论辅助判断。
所以,Subagents 在规则管理里的位置,不只是“多开一个 Agent”。它更像是把某类专门任务的规则、工具和临时上下文单独封装起来,避免它们进入主会话。
Hooks:强约束要进入执行链路
Hooks 是这篇里最值得单独拎出来的机制,因为它处理的是另一类规则:有些要求不能只停留在“提醒 Agent 记住”,还要进入实际执行链路。
很多团队会把这类要求写进 CLAUDE.md,每次改完代码后要跑 formatter、每次提交前要跑测试、不要执行危险命令、不要改某些敏感文件。写成自然语言提示,当然可以提醒 Agent。但只要这些要求关系到稳定性、安全边界或权限控制,就不应该只依赖模型的记忆和理解。相对合适的方式,是让系统在关键节点自动触发检查,或者在危险动作真正执行前直接拦截。
Claude Code 的 Hooks 就是用来处理这类场景的。它可以在特定生命周期事件触发,比如会话开始、用户提交 prompt、工具调用前后、Subagent 启停、上下文压缩前后、会话结束等。Hook 本身可以是命令、HTTP endpoint、MCP tool、prompt 或 agent;其中 command、HTTP、mcp_tool 这几类适合做成确定性执行。

图注:Hooks 可以在 Claude Code 会话的多个阶段触发,包括 Session Start、UserPromptSubmit、PreToolUse、PostToolUse、SubagentStart / Stop、PreCompact、PostCompact、SessionEnd 等。图源:Anthropic
从规则管理的角度看,Hooks 主要接管两类事情。一类是每次都要稳定发生的动作,像是文件编辑后自动跑 formatter、工具调用后自动跑 linter、任务结束后发 Slack 通知、压缩上下文前备份聊天历史。另一类是绝对不能放行的动作,比如危险命令、越权访问、敏感文件写入。Anthropic 在文章里举了 PreToolUse hook 的例子:它可以在工具真正执行前介入,检查这次调用是否安全,并通过 exit code 2 阻止高风险操作。
这里可以形成一个很实用的判断:凡是“希望 Agent 记住”的规则,可以写进提示或项目说明;凡是“必须稳定发生”或“绝对不能发生”的规则,应该交给 Hooks、permissions 或 managed settings。自然语言规则适合表达偏好、背景和约定,系统机制更适合处理自动化、拦截和权限边界。
Output styles 和 append system prompt:只适合放轻量偏好
Output styles 和 append system prompt 也能影响 Agent 的行为,但它们更适合放在规则体系的最外层,用来处理输出格式、表达方式、临时偏好,以及某些场景下的协作风格。
Output styles 会注入系统提示词,影响 Claude 的整体角色和工作方式。自定义 output style 会替换 Claude Code 默认的软件工程助手行为,比如修改范围、注释习惯、安全关注和测试验证习惯。因此,它可以用来调整“Agent 以什么方式协作”,不适合来放具体项目规则。
append system prompt 则更轻一点。它是在调用时追加的系统提示,只对当前调用生效,适合补充输出格式、语气要求、特定编码标准或领域知识。Anthropic 也提醒,追加指令存在边际递减:指令越多,模型越难严格遵守,尤其在指令互相冲突时。
所以,这两类机制最好用来处理轻量偏好。如果你希望回答更简洁、输出固定格式、临时遵守某个代码风格,都可以用这个;但项目结构、路径约束、流程手册、安全拦截这类规则,应该交给前面那些更合适的层级。
一个简单选择表
可以把整套判断压缩成下面这张表:

几个常见放错位置
规则分层看起来不复杂,但真正落到项目里,最容易出问题的地方往往是这些。
第一,把流程塞进 CLAUDE.md。
发布步骤、Review checklist、排障流程…这类内容平时不一定用得上,写在 CLAUDE.md 里会跟着每次会话一起进入上下文。应该把它们拆成 Skill,用到时再展开。Anthropic 在文章里的 quick tips 也把“30 行流程写进 CLAUDE.md”列为应该迁移的典型情况。
第二,把强制规则写成提示词。
“永远不要执行某个命令”这类要求,如果只是团队偏好或操作习惯,写进项目说明里问题不大;但如果它涉及安全边界、权限控制或高风险操作,就不能只依赖模型记住。提示词可以提醒 Agent 注意这条规则,真正需要拦截风险时,还要交给 Hooks、permissions 或 managed settings 这类确定性机制。
第三,路径规则没有限定路径。
如果一条规则只适用于 src/api/**,就应该写清楚 paths:。没有路径限定,它就可能在不相关任务里继续进入上下文,既浪费空间,也容易干扰判断。
第四,把个人偏好写进项目级文件。
项目级文件应该服务团队和代码库。个人习惯,比如固定的提交信息风格、回答语气偏好,更适合放在用户级配置或临时 prompt 里。项目规则和个人偏好混在一起,时间一长会很难维护。
小结
借 Claude Code 这套设计来看,Coding Agent 的规则管理可以拆成几层:CLAUDE.md 负责项目背景,路径规则负责局部约束,Skills 负责可复用流程,Subagents 负责隔离支线任务,Hooks 负责确定性自动化和安全边界,Output styles 与 append system prompt 负责表达方式和临时偏好。
这套分层的重点,是让规则在合适的时机出现。该长期加载的放在项目说明里,该按需调用的做成 Skill,该隔离执行的交给 Subagent,该强制执行的放进 Hooks 或权限机制。这样 Agent 在复杂工程里读到的上下文更干净,关键动作上的边界也更稳定。
更多推荐

所有评论(0)