📌 本讲摘要

前 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.jsonpermissions 字段。
  • 作用:告诉 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.jsonpermissions 字段、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 模式覆盖大部分场景。

加载顺序

  1. 用户级规则(~/.claude/rules/)先加载。
  2. 项目级规则(.claude/rules/)后加载(覆盖用户级)。
  3. paths 匹配当前 file_path 的规则被激活。
  4. 不匹配的规则不加载(节省上下文)。

加载顺序:用户级 < 项目级、通用规则 < 专项规则。

多 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 层(原子操作)Read src/api/users.py / Edit 改代码 / Bash pytest / 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 内功)。


Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐