《Claude Code 工程化实战》第 22 讲 Rules 规则系统深度剖析

《Claude Code 工程化实战》第 22 讲 Rules 规则系统深度剖析 本讲摘要前 21 讲我们学了 5 种扩展机制SubAgent / Skills / Hooks / MCP / Tools) Headless CI/CD、但没系统讲过规则——Claude 行为的宪法。本讲进入 Rules——两套规则协同构成行为约束指令规则.claude/rules/*.md 告诉 Claude 该怎么做、路径匹配自动加载 权限规则.claude/settings.json 的 permissions 字段告诉 Claude 能做什么,deny/ask/allow 3 档。Rules 是 Claude Code 工程化的软规范层——不强制执行像 Hooks 那样、但 Claude 推理时会看这些规则、被约束在团队规范内。本讲的三条主线第一、两套规则系统 路径匹配加载——指令规则instruction rules,.claude/rules/*.md 路径匹配自动加载 权限规则permission rules,.claude/settings.json 的 permissions 字段 deny/ask/allow 3 档。第二、paths 条件匹配 Rules 最佳实践——指令规则 paths 字段支持 glob 模式改 src/api.py 自动加载 src 规则;3 实践规则写做什么不写细节/ paths 精准/ 进 git 团队共享。第三、Rules × 5 种扩展机制完整图景——Rules 规范软规范硬权限/ Skills 能力 / Hooks 拦截 / SubAgent 角色 / MCP 桥梁 / Tools 内功6 者协同工作。学完本讲你应该能写 .claude/rules/*.md 指令规则、能配 permissions 字段 deny/ask/allow、能用 paths 条件匹配自动激活规则、能区分 Rules 和 Hooks 的软规范 vs 硬约束边界、能理解 6 种扩展机制的完整图景。 详细内容Rules 是什么?两套规则系统前 21 讲我们学了 5 种扩展机制SubAgent / Skills / Hooks / MCP / Tools)、每种机制解决一类问题、但还有一类问题没解决“Claude 行为的规范”——比如团队约定用 ruff format / “测试覆盖率 80%” / “commit message 用 conventional commits”、这些规范怎么让 Claude 知道?答案是 Rules。Rules 是 Claude Code 的宪法层——告诉 Claude 该怎么做、能做什么。两套规则系统协同构成软规范 硬约束。规则 1指令规则instruction rules)配置位置.claude/rules/*.md项目级 ~/.claude/rules/*.md用户级。作用告诉 Claude 该怎么做——团队规范 / 编码风格 / 测试要求 / commit message 规范等。Claude 推理时会看这些规则、被约束在规范内。特征软规范——Claude 努力遵守、但不强制像 Skills 一样。规则 2权限规则permission rules)配置位置.claude/settings.json 的 permissions 字段。作用告诉 Claude 能做什么——deny完全禁止/ ask每次询问/ allow允许3 档。Claude 跑工具前会查权限、被约束在允许范围内。特征硬约束——Claude 不能跑 deny 的工具跑 ask 的工具前必须问用户只有 allow 的工具能直接跑。两套规则的协同指令规则软规范 权限规则硬约束 行为约束的纵深防御。例团队规范用 ruff format指令规则、软规范 Hook 强制写完代码自动跑 ruff format硬约束。Claude 看到指令规则后努力用 ruff即使忘了、Hook 强制执行。这是规则和 Hook 协同的典型。两套规则不互斥指令规则给做事的建议、权限规则给做事的边界。两者配合、Claude 既有章可循、又不越界。指令规则.claude/rules/*.md 路径匹配自动加载指令规则是 Markdown 文件、放在 .claude/rules/ 目录项目级或 ~/.claude/rules/用户级。基本结构每个规则文件 frontmatter(YAML) Markdown 正文。frontmatter 字段paths路径匹配模式、glob 语法。Markdown 正文具体的规则描述。完整示例见后面指令规则完整示例代码块。paths 字段的自动加载机制paths 字段是 glob 模式如*.py/src/api/**/tests/**。自动加载流程Claude 改文件 file_path → 检查所有规则文件的 paths 字段 → 匹配上的规则被加载到上下文 → Claude 推理时遵守这些规则。例Claude 改src/api/users.py→ 匹配src/api/*.py规则 → 加载该规则到上下文 → Claude 看到用 type hints / 写单元测试等规范。2 个加载级别级别 1项目级(.claude/rules/)——当前项目的规则、进 git、团队共享。例项目级规则用 ruff format / “测试覆盖率 80%”。级别 2用户级(~/.claude/rules/)——用户的个人规则、跨项目通用、不入 git。例个人偏好用中文注释 / “用 EditorConfig 风格”。2 级别叠加项目规则 用户规则都加载、合并到 Claude 上下文。项目规则优先团队规范 个人偏好。规则文件命名建议建议用主题命名python-style.md / testing-rules.md / git-commit.md / security.md。一目了然、便于维护。权限规则deny / ask / allow 3 档权限规则配置在 .claude/settings.json 的 permissions 字段、3 档机制。3 档语义•deny完全禁止——Claude 不能调这个工具。例deny: [Bash(rm:*), Bash(curl:*)]禁止所有 rm / curl 命令。•ask每次询问——Claude 跑这个工具前问用户。例ask: [Bash(git push:*)]每次 push 前问。•allow允许——Claude 直接跑、不问。例allow: [Read, Grep, Glob, Bash(git:diff)]。3 档叠加形成白名单收窄 / 黑名单防护 / 灰名单询问。Bash 工具的通配符权限规则对 Bash 工具有通配符支持•Bash(git:*)——所有 git 命令。•Bash(npm run test:*)——npm run test 开头的命令。•Bash(rm:*)——所有 rm 命令。•Bash(*)——所有 Bash 命令粗粒度。完整配置见后面权限规则完整配置代码块。deny 优先于 ask 优先于 allow3 档优先级deny ask allow。例同一命令Bash(rm:*)既在 deny 又在 allow、实际 deny优先。这种优先级让明确禁止的命令不会被 allow 列表误放。3 档的设计哲学deny 给明确禁止ask 给模糊地带allow 给明确安全。3 档分清楚、边界清晰。维度指令规则权限规则配置位置.claude/rules/*.md.claude/settings.json permissions触发方式文件路径匹配paths glob)工具调用时检查约束力度软规范LLM 努力遵守硬约束deny 不能跑、ask 必须问加载机制按 paths 自动加载到上下文每次工具调用都检查典型用途编码风格 / 命名规范 / 测试要求限制危险命令 / 强制询问 pushpaths 条件匹配规则按文件类型自动激活指令规则的 paths 字段是核心特性——按文件路径自动激活规则、节省上下文。glob 模式支持•*.py——所有 .py 文件根目录。•**/*.py——所有 .py 文件任意子目录。•src/api/**——src/api 目录下所有文件。•tests/**——tests 目录下所有文件。•*.{js,ts}——所有 .js 和 .ts 文件。5 种 glob 模式覆盖大部分场景。加载顺序用户级规则~/.claude/rules/先加载。项目级规则.claude/rules/后加载覆盖用户级。paths 匹配当前 file_path 的规则被激活。不匹配的规则不加载节省上下文。加载顺序用户级 项目级、通用规则 专项规则。多 paths 模式paths 字段支持数组、多个模式 OR 匹配--- paths: - src/api/** - src/lib/** ---这个规则在改 src/api/ 或 src/lib/ 时激活。完整加载机制见后面paths 条件匹配规则加载机制代码块。Rules 的 3 个最佳实践 与 Hooks 的边界会用规则是基础、精通规则需要 3 个最佳实践。最佳实践 1规则写做什么不写做什么细节规则是给 LLM 看的、要给推理空间、不要给死规定。反例细节太死:“用 ruff format 时必须 --line-length 100、必须 --indent-size 4”。LLM 看不到全局、反而被限制。正例给推理空间:“用 ruff format 保持代码风格一致”。LLM 自己跑 ruff format、具体参数用默认。规则 vs 配置规则给建议、配置给硬值。规则要给建议、不要把配置写成规则。最佳实践 2paths 精准不要 “*.py” 覆盖所有paths 太宽、所有 .py 文件都加载规则、上下文浪费。paths 太窄、规则覆盖不到。反例太宽paths: **/*.py——改测试时也加载主代码规则。正例精准主代码规则paths: src/** 测试规则paths: tests/**分开。精准 paths 节省上下文 更高效。最佳实践 3进 git 团队共享项目级规则 (.claude/rules/) 一定要进 git、团队成员共享规范。否则各人维护各人的规则、规范不一致。判断标准.claude/rules/ 目录在 git 跟踪吗?没在、赶紧入 git。Rules vs Hooks 边界Rules 是软规范(LLM 看 description 推理时遵守、不强制;Hooks 是硬约束(exit 2 强制执行。边界判断这件事是建议 Claude 做吗?是 → Rules。这件事是必须强制吗?是 → Hooks。典型协同规则说用 ruff format软建议 Hook 强制写完代码自动跑 ruff format硬约束。两层防御。Rules × Skills × Hooks × SubAgent × MCP × Tools 6 种扩展机制完整图景前 22 讲我们学了 6 种扩展机制本讲加入 Rules 作为第 6 种。6 者的工程定位不同、协同工作形成完整图景。6 者的工程定位•Rules宪法——软规范 硬权限、告诉 Claude 该怎么做 / 能做什么。•Skills招式——LLM 推理该用就用、渐进披露。负责本地能力。•SubAgent分身——独立上下文、name 显式调。负责复杂任务隔离。•Hooks门卫——事件驱动、硬约束。负责瞬间检查。•MCP桥梁——连接外部 API、标准化协议。负责调用外部世界。•Tools内功——原子操作、LLM 调用的最底层。负责做原子动作。6 者的工作层次不同Rules 在宪法层最顶层规范,Skills 在招式层(LLM 推理,HW 在门卫层事件,MCP 在桥梁层外部 API),SubAgent 在角色层独立上下文,Tools 在内功层最底层原子。维度RulesSkillsHooksSubAgentMCPTools工作层次宪法层招式层门卫层角色层桥梁层内功层约束类型软规范 硬权限软规范硬约束独立上下文外部 API原子操作触发paths 匹配 / 工具调用description 匹配工具前后 / Stopname 显式LLM 推理LLM 推理配置位置.claude/rules/ permissions.claude/skills/.claude/settings.json hooks.claude/agents/.mcp.json内置 .mcp.json典型用途团队规范 / 权限边界本地能力描述危险拦截 / 自动格式化复杂任务隔离外部 API读 / 写 / 搜 / 执行调试看 rules 内容 / 权限错误看 SKILL.md description看 stderr 输出看 subagent 报告mcp-inspector看工具输出6 者的协同典型完整工作流用户说话 → Rules 加载路径匹配激活→ Claude 推理遵守 Rules 软规范→ 调 Tools 原子操作 → PreToolUse Hook 拦截硬约束→ 调用 SubAgent独立上下文→ 触发 Skills 自动发现软规范→ 通过 MCP 调外部 API桥梁→ 返回结果 → PostToolUse Hook 记录 → Stop Hook 质量门控 → 返回用户。6 种机制在 Claude 的一次任务中可能全部触发、各自负责不同的层次、形成完整的工程化体系。️ 实战代码 第 22 讲配套指令规则完整示例.claude/rules/python-style.md 含 frontmatter paths 字段 Markdown 正文 5 条规则# .claude/rules/python-style.md # 项目级指令规则(进 git,团队共享) --- paths: - src/**/*.py - tests/**/*.py --- # Python 编码规范 ## 1. 类型提示(Type Hints) 所有函数必须有类型提示: python def get_user(user_id: int) - User: ... ## 2. 文档字符串(Docstrings) 所有 public 函数必须有 docstring(Google 风格): python def get_user(user_id: int) - User: 根据用户 ID 获取用户对象。 Args: user_id: 用户 ID Returns: User 对象 Raises: UserNotFoundError: 用户不存在 ... ## 3. 错误处理 - 不要吞异常(except: pass) - 抛出具体异常,不要用 Exception - 资源用 with 上下文管理 ## 4. 测试覆盖 - 所有 public 函数必须有单元测试 - 测试覆盖率 ≥ 80% - 用 pytest,不用 unittest ## 5. 代码风格 - 用 ruff format(自动格式化) - 用 mypy(类型检查) - import 顺序: 标准库 / 第三方 / 本地 # 自动加载机制 # Claude 改 src/api/users.py 时: # 1. 检查所有 .claude/rules/*.md 的 paths # 2. src/**/*.py 匹配 → 加载本规则 # 3. Claude 看到 5 条规范,推理时遵守 # 规则 vs 死规定 # 这 5 条都是软规范,给 LLM 推理空间 # 不要写必须 line-length 100 这种死规定 # 留给 ruff 自己配(在 pyproject.toml) 第 22 讲配套权限规则完整配置.claude/settings.json 的 permissions 字段 deny / ask / allow 3 档配置 Bash 工具通配符// .claude/settings.json(权限规则完整配置) { permissions: { deny: [ // 危险命令:完全禁止 Bash(rm -rf:*), Bash(rm -fr:*), Bash(curl | sh:*), Bash(curl | bash:*), Bash(wget | sh:*), Bash(chmod 777:*), Bash(dd:*), Bash(git push --force:*), Bash(git push -f:*) ], ask: [ // 模糊地带:每次问用户 Bash(git push:*), Bash(git reset:*), Bash(git rebase:*), Bash(npm publish:*), Bash(docker push:*), Bash(sudo:*) ], allow: [ // 明确安全:直接跑 Read, Glob, Grep, Edit, Write, Bash(git:diff), Bash(git:status), Bash(git:log), Bash(git:add), Bash(git:commit), Bash(pytest:*), Bash(ruff:format), Bash(ruff:check), Bash(mypy:*), Bash(npm run test), Bash(npm run lint), Bash(ls:*), Bash(cat:*) ] } } // 3 档语义 // deny: 完全禁止, Claude 不能跑 // ask: 每次问用户, 用户确认才跑 // allow: 直接跑, 不问 // 优先级 // deny ask allow // 同一命令在多个档位, deny 生效 // Bash 通配符 // Bash(git:*) 所有 git 命令 // Bash(rm -rf:*) 所有 rm -rf 开头 // Bash(npm run:*) npm run 开头的命令 // 跨工具 // 不只 Bash, 所有工具都能 deny/ask/allow // Edit / Write / Read / Glob / Grep 都能配 第 22 讲配套paths 条件匹配规则加载机制3 个规则文件 glob 模式 加载顺序# paths 条件匹配规则加载机制 # 规则文件 1:主代码规则 # .claude/rules/src-style.md --- paths: - src/**/*.py --- # src 目录的 Python 代码规范 - 用 type hints - 用 ruff format - 写单元测试 # 规则文件 2:测试规则 # .claude/rules/test-style.md --- paths: - tests/**/*.py --- # tests 目录的测试规范 - 一个测试一个断言(尽量) - 用 pytest fixture - 命名 test_xxx - 覆盖率 ≥ 80% # 规则文件 3:API 路由规则 # .claude/rules/api-routes.md --- paths: - src/api/**/*.py --- # src/api 目录的 API 规范 - 用 FastAPI - 所有端点有 Pydantic model - 错误用 HTTPException - 加 /docs 自动文档 # 加载机制 # Claude 改 src/api/users.py: # 1. 检查所有规则文件的 paths # 2. 规则 1 (src/**/*.py) 匹配 ✓ 加载 # 3. 规则 2 (tests/**/*.py) 不匹配 ✗ 不加载 # 4. 规则 3 (src/api/**/*.py) 匹配 ✓ 加载 # 5. Claude 看到规则 1 规则 3 的内容, 推理时遵守 # 加载顺序 # 1. 用户级规则 (~/.claude/rules/) 先加载 # 2. 项目级规则 (.claude/rules/) 后加载(覆盖) # 3. paths 匹配当前 file_path 的规则被激活 # 4. 不匹配的规则不加载(节省上下文) # 多 paths 模式 --- paths: - src/api/** - src/lib/** - src/utils/** --- # 改这三个目录任一时,规则都激活 第 22 讲配套Rules 与 Hooks 协同软规范 硬约束指令规则说用 ruff format Hook 强制写完代码自动跑 ruff format)# Rules 与 Hooks 协同:软规范 硬约束 # 规则层(软规范) # .claude/rules/python-style.md --- paths: - **/*.py --- # Python 编码规范 - 用 ruff format 保持代码风格一致 - 所有函数写 type hints - 写单元测试 # Hook 层(硬约束) # .claude/settings.json { hooks: { PostToolUse: [ { matcher: Edit|Write, hooks: [ // Hook 强制:写完代码自动 ruff format {type: command, command: bash .claude/hooks/auto-format.sh} ] } ] } } # .claude/hooks/auto-format.sh #!/usr/bin/env bash INPUT$(cat) FILE_PATH$(echo $INPUT | jq -r .tool_input.file_path // ) if [[ $FILE_PATH *.py ]]; then ruff format $FILE_PATH 2/dev/null || true echo ✅ 已自动格式化: $FILE_PATH fi exit 0 # 协同效果 # 1. Claude 看到规则用 ruff format(软规范,努力遵守) # 2. 即使 Claude 忘了,Hook 强制 ruff format(硬约束) # 3. 两层防御,代码风格始终一致 # 二选一或分层 # 不是说 Hooks 一定能替代 Rules,而是: # - 建议 Claude 做 → Rules # - 必须强制 → Hooks # - 两者结合 → 软规范 硬约束,纵深防御 # 反协同(不要重复) # 规则说不要用 rm -rf(软规范,LLM 推理时不跑) # Hook 拦 rm -rf(硬约束,即使 Claude 跑了也拦) # 这是重复拦截,不必要 — 二选一(用 Hook 更保险) # 协同清单 # 规则: 编码风格 / 命名规范 / 测试要求 / commit 规范 # Hook: 危险命令拦截 / 自动格式化 / 质量门控 / 审计日志 # 规则 Hook: 软规范 硬约束, 完整行为规范⚠️ 常见坑⚠️ 指令规则 paths 写太宽写 *.py 覆盖所有 Python 文件、改测试时也加载主代码规则、改用 src/** 和 tests/** 分开paths 覆盖太宽陷阱指令规则 paths 写**/*.py覆盖所有 Python 文件、改测试时也加载主代码规则、上下文浪费。修正paths 精准——主代码规则paths: src/**、测试规则paths: tests/**分开、各自只加载相关规则。判断标准你的规则 paths 是宽泛*.py还是精准分目录?宽泛、改精准。⚠️ 权限规则 deny 太多把常用命令都 deny,Claude 跑什么都不方便、只 deny 真正危险的deny 过多反噬陷阱权限规则 deny 列表加太多命令Bash(rm:*)/Bash(curl:*)/Bash(npm:*)/Bash(docker:*)等、结果 Claude 跑什么都不方便、频繁问用户。修正deny 只放真正危险的rm -rf/curl | sh/dd/chmod 777/git push --force)、常用命令git status/npm test/pytest放 allow。判断标准你的 deny 列表 10 条?精简到 5 条真正危险的。⚠️ 规则不进 git团队成员各自维护规则、规范不一致、进 git 团队共享“规则孤岛陷阱项目级 .claude/rules/ 没进 git、团队成员各自维护、规范不一致有的用 ruff、有的用 black有的要 type hints、有的不要。修正进 git 团队共享——git add .claude/rules/ commit push。PR 时 review 规则变更。判断标准.claude/rules/ 在 git 跟踪吗?没在、赶紧入 git。⚠️ Rules 和 Hooks 重复拦截规则说不要用 rm -rf,Hook 拦 rm -rf、做无用功、二选一或分层“软硬重复陷阱规则说不要用 rm -rf”软规范、LLM 推理时不跑 Hook 拦 rm -rf硬约束、即使 Claude 跑了也拦。这是重复拦截”、做无用功。修正二选一或分层——重要操作rm -rf / curl | sh用 Hook 拦截LLM 不可靠、必须硬约束建议性规范用 ruff format / 写 type hints用规则LLM 努力遵守危险操作不要依赖规则LLM 可能忘、必须 Hook。判断标准你的规则和 Hook 都在拦截同一类东西吗?重复了、精简。 一句话备忘Rules 是 Claude Code 行为的宪法——两套规则系统协同指令规则软规范 权限规则硬约束,paths 条件匹配自动激活、6 种扩展机制完整图景Rules 宪法 / Skills 招式 / Hooks 门卫 / SubAgent 角色 / MCP 桥梁 / Tools 内功。