《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 优先于 allow
3 档优先级: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 自动加载到上下文 | 每次工具调用都检查 |
| 典型用途 | 编码风格 / 命名规范 / 测试要求 | 限制危险命令 / 强制询问 push |
paths 条件匹配:规则按文件类型自动激活
指令规则的 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 配置:规则给建议、配置给硬值。规则要给建议、不要把配置写成规则。
最佳实践 2:paths 精准(不要 *.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 推理),Hooks 在"门卫层"(事件),MCP 在"桥梁层"(外部 API),SubAgent 在"角色层"(独立上下文),Tools 在"内功层"(最底层原子)。
| 维度 | Rules | Skills | Hooks | SubAgent | MCP | Tools |
|---|---|---|---|---|---|---|
| 工作层次 | 宪法层 | 招式层 | 门卫层 | 角色层 | 桥梁层 | 内功层 |
| 约束类型 | 软规范 + 硬权限 | 软规范 | 硬约束 | 独立上下文 | 外部 API | 原子操作 |
| 触发 | paths 匹配 / 工具调用 | description 匹配 | 工具前后 / Stop | @name 显式 | 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 的一次任务中可能全部触发、各自负责不同的层次、形成"完整的工程化体系"。
Rules × 5 种扩展机制完整图景(6 层工作流)
用户说话 ─→ ① Rules 层(软规范 + 硬权限)(路径匹配
src/**/*.py/ 加载.claude/rules/python-style.md/permissions字段:deny / ask / allow) ─→ Claude 推理(遵守软规范)(type hints / 写测试 / ruff format) ─→ ② Tools 层(原子操作)(Readsrc/api/users.py /Edit改代码 /Bashpytest / ruff) ─→ ③ PreToolUse Hook(硬约束拦截)(权限检查(deny / ask / allow) / 白名单命令检查 / 危险命令拦截) ─→ [放行] ─→ 工具执行 ─→ ④ PostToolUse Hook(记录审计)(audit-log 记录命令 / auto-format 自动格式化 / 触发 Skills 自动发现) ─→ ⑤ SubAgent 调起(复杂任务隔离)(@code-reviewer 跑代码审查,独立上下文,完成报告) ─→ ⑥ Skills 触发(软规范能力)(自动发现 commit-skill · 用 conventional commits 规范) ─→ ⑦ MCP 调用(连接外部世界)(mcp__github__create_pr自动化创建 PR) ─→ ⑧ Stop Hook(质量门控)(check-uncommitted / check-tests) ─→ 返回用户
🛠️ 实战代码
📄 指令规则完整示例(.claude/rules/python-style.md)
# .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)
📄 权限规则完整配置(.claude/settings.json)
// .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 都能配
📄 paths 条件匹配规则加载机制
# 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/**"
---
# 改这三个目录任一时,规则都激活
📄 Rules 与 Hooks 协同:软规范 + 硬约束
# 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 内功)。
更多推荐


所有评论(0)