CLAUDE.md rules settings.json 分工与协同 - claude08

这篇讲 CLAUDE.md 三种 scope、monorepo 下 sibling 不加载的缘由、settings 五层优先级,再附上写 CLAUDE.md 的六条经验。 这是系列文章的第8篇。

Claude 到底是怎么知道"该做什么"的?

答案藏在两种东西里:

  • 记忆 (memory):CLAUDE.md、.claude/rules/*.md、AGENTS.md------这些是写给 Claude 读的"知识"
  • 配置 (settings):.claude/settings.json、.claude/settings.local.json、managed policies------这些是告诉 Claude"能做什么"的"规则"

两者都是分层的,都有优先级,都能被覆盖。搞懂这套分层,是让 Claude Code 在团队项目里稳定工作的前提。


目录概要

  1. 类比:入职文档 vs 公司制度
  2. CLAUDE.md 的三种 scope:user / project / component
  3. 上溯 vs 下行------为什么 monorepo 里 sibling 永远不加载
  4. .claude/rules/*.md + glob------比 CLAUDE.md 更精准的知识注入
  5. settings 的 5 层优先级
  6. managed settings:组织级强制策略
  7. 数组类字段的合并规则(允许列表会叠加)
  8. CLAUDE.md 写作的 6 条实战经验
  9. 踩过的坑
  10. 写到这里

一、为什么要分两种:记忆 vs 配置

这俩经常被混为一谈,但其实角色完全不同------

记忆 是给 Claude 读的"背景知识 "------项目约定、命名风格、业务术语、别碰哪些目录。 配置 是给 Claude Code CLI 读的"行为开关"------用哪个模型、允许哪些工具、hooks 怎么接、MCP 连哪些服务。

用人来类比:

  • CLAUDE.md ≈ 新员工入职第一天拿到的岗位说明书。项目是怎么回事、团队有哪些约定、犯忌讳的线在哪里。
  • settings.json ≈ 公司制度。门禁卡开几号门、能不能用自己的电脑、报销流程走哪条。

员工读入职文档是要"理解";员工执行公司制度是要"遵守"。两者合起来才让人在公司里能正常工作。


二、CLAUDE.md 的三种 scope

先看记忆这一侧。Claude Code 支持 CLAUDE.md 写在三个层级:

scope 位置 作用范围 是否入 git
user ~/.claude/CLAUDE.md 所有项目、所有 session 不(在你 home 下)
project <repo>/CLAUDE.md 当前仓库 是(团队共享)
local <repo>/CLAUDE.local.md 当前仓库 否(git-ignored)

Claude Code 启动时把它能找到的全部加载进 system prompt。

三层的典型分工:

  • user 级:我个人的偏好。"回答用中文"、"不要废话"、"代码注释也用中文"
  • project 级 :团队约定。"本项目用 TypeScript strict mode"、"测试放在 __tests__/"、"commit 一次只改一个文件"
  • local 级 :我对当前项目的个人调教。"别给我跑 npm install"、"忽略 docs 目录的改动"

关键洞察:user 是你作为人带着走的偏好、project 是团队合同、local 是你和这个项目之间的"潜规则"。三者叠起来就是 Claude 在这个 session 里的全部"背景知识"。


三、上溯 vs 下行------monorepo 里 CLAUDE.md 的加载机制

这部分是 Claude Code 用户踩坑最多的地方。Boris Cherny 在 Twitter 上专门出来澄清过一次^1^,但依然容易搞错。

3.1 两种加载方向

Claude Code 启动时,对 CLAUDE.md 有两种加载方向:

graph TB subgraph Monorepo["/mymonorepo/"] Root[CLAUDE.md 根] Front["frontend/CLAUDE.md"] Back["backend/CLAUDE.md"] Api["api/CLAUDE.md"] end CWD[你的 cwd: frontend/] CWD -. 上溯 ancestor .-> Root CWD -. 同级 .-> Front CWD -. 不加载 .-> Back CWD -. 不加载 .-> Api style Root fill:#afa style Front fill:#afa style Back fill:#fcc style Api fill:#fcc
  • 上溯(ancestor loading) :从 cwd 一路往根目录走,遇到的每个 CLAUDE.md 都在启动时立即加载
  • 下行(descendant loading) :子目录里的 CLAUDE.md 启动时不加载,只有当 Claude 读/写那个子目录的文件时才"顺便"加载进来(lazy load)

3.2 两种场景的对照

场景 1:从根跑 Claude Code

bash 复制代码
cd /mymonorepo
claude
文件 启动时加载? 为什么
/mymonorepo/CLAUDE.md ✅ 就是 cwd
/mymonorepo/frontend/CLAUDE.md ❌(lazy) 子目录,读到 frontend 文件时才加载
/mymonorepo/backend/CLAUDE.md ❌(lazy) 同理

场景 2:从 frontend 子目录跑

bash 复制代码
cd /mymonorepo/frontend
claude
文件 启动时加载? 为什么
/mymonorepo/CLAUDE.md ✅ ancestor
/mymonorepo/frontend/CLAUDE.md ✅ cwd
/mymonorepo/backend/CLAUDE.md ❌(永远) sibling,不是 ancestor 也不是 descendant
/mymonorepo/api/CLAUDE.md ❌(永远) 同理

三个关键推论------

  1. Ancestor 永远在启动时加载,保证"根级规则"一定生效
  2. Descendant 是 lazy 的,读到就加载,避免启动时爆上下文
  3. Sibling 永远不会加载------你在 frontend 里工作,永远看不到 backend/CLAUDE.md,设计上隔离得非常干净

3.3 这个设计解决了什么问题

想象一个 20 个子项目的 monorepo。如果所有 CLAUDE.md 都在启动时加载,上下文秒满。官方的解法是------共享约定往上走、组件特性往下走、横向不串门。

这就要求写 CLAUDE.md 时严格按层级组织:

  • 根 CLAUDE.md:全仓库公共的(代码风格、commit 规范、branch 命名)
  • 子 CLAUDE.md:子项目特有的(frontend 的 React 版本、backend 的 DB schema 约定)

层级清楚了,按需加载才合理。


四、.claude/rules/*.md------比 CLAUDE.md 更精准的玩法

CLAUDE.md 再怎么分子目录也粒度有限。举个例:你想说"只有改 presentation/ 下的文件时才提醒 agent 走特殊流程"------靠 CLAUDE.md 做不到。

这时候 .claude/rules/*.md 就登场了。每个 rule 文件开头写一个 glob,只在匹配到的文件被读写时才把这个 rule 注入上下文:

一个真实的 .claude/rules/presentation.md 例子:

markdown 复制代码
# Glob: presentation/**

## Delegation Rule

Any request to update, modify, or fix the presentation (`presentation/index.html`)
MUST be handled by the `presentation-curator` agent...
markdown 复制代码
# Glob: **/*.md

## Documentation Standards

- Keep files focused and concise --- one topic per file
- Use relative links between docs...

两种规则:一种只在碰 presentation/** 时生效,一种只在读写 .md 时生效。精度远高于 CLAUDE.md。

触发时会有 InstructionsLoaded hook(上一篇事件表里提过)fire,matcher 可以按 load_reason 筛(session_start / nested_traversal / path_glob_match / include / compact)。

对比:CLAUDE.md 是"一上来就念给 Claude 听的员工手册",rules/*.md 是"翻到那一页时才抽出来的章节"。两者互补------公共纪律写 CLAUDE.md,专题规矩写 rules。


五、settings 的 5 层优先级

现在换到配置这一侧。Claude Code 的 settings 有 5 层 ^2^,按优先级从高到低:

优先级 位置 作用范围 是否入 git 用途
1 managed settings 组织 IT 部署 安全策略,强制不可覆盖
2 命令行参数 单 session --- 临时覆盖
3 .claude/settings.local.json 项目 否(ignored) 个人项目偏好
4 .claude/settings.json 项目 是 团队共享
5 ~/.claude/settings.json 用户 --- 全局个人默认值

低优先级被高优先级覆盖------但有个特例,稍后讲。

5.1 典型使用场景

看个具体例子。一份典型的 .claude/settings.json 可能写成:

json 复制代码
{
  "permissions": {
    "allow": ["Edit(*)", "Write(*)", "Bash", "WebFetch(domain:*)"],
    "ask": ["Bash(rm *)", "Bash(npm *)", "Bash(docker *)"]
  }
}

这是团队共享的------push 到 git,每个 clone 这个项目的人都拿到一样的配置。

但我个人嫌某些规则太啰嗦,可以在 .claude/settings.local.json 里覆盖:

json 复制代码
{
  "permissions": {
    "ask": ["Bash(rm -rf *)"]
  }
}

local 优先级更高,我这台机器上 rm 不再弹确认(只对 rm -rf 弹)。但这个覆盖不会 push 到 git------队友的配置不受影响。

5.2 user 级的默认值

~/.claude/settings.json 是全局默认------所有项目都生效,除非被项目级覆盖。适合放:

json 复制代码
{
  "model": "sonnet",
  "alwaysThinkingEnabled": true,
  "language": "chinese"
}

"我在任何项目里都想用 sonnet、都想打开 thinking、都用中文回答"------放 user 级最合适。

5.3 命令行参数------临时覆盖

bash 复制代码
claude --model opus

当前 session 用 opus 模型,不影响配置文件。优先级高于 settings.local.json,但低于 managed。


六、Managed settings------组织级的强制策略

第 1 层 managed settings 很特殊:任何人都不能覆盖它。即使是命令行参数也不行。

这层是给企业 IT 用的。IT 管理员能通过以下几种方式部署:

  • 服务器下发(server-managed,远程)
  • MDM profile (macOS plist: com.anthropic.claudecode)
  • 注册表策略 (Windows: HKLM\SOFTWARE\Policies\ClaudeCode)
  • 文件部署 (managed-settings.json、managed-mcp.json)
  • Drop-in 目录 (managed-settings.d/*.json,v2.1.83 新增,类似 systemd 约定)

文件路径按平台不同:

javascript 复制代码
macOS:    /Library/Application Support/ClaudeCode/
Linux:    /etc/claude-code/
Windows:  C:\Program Files\ClaudeCode\

举个场景:公司禁止员工的 Claude Code 连任何非白名单 MCP 服务。IT 部署一个 managed 配置:

json 复制代码
{
  "permissions": {
    "deny": ["mcp__external__*"]
  }
}

员工在自己项目里想添回来也没用------deny 规则永远优先 ,低优先级的 allow 覆盖不动。

6.1 drop-in 目录的合并规则

v2.1.83 新增的 managed-settings.d/ 值得一提。它沿用 systemd 的约定:

bash 复制代码
managed-settings.json            # base,先合并
managed-settings.d/10-telemetry.json  # 后合并
managed-settings.d/20-security.json   # 再后合并
managed-settings.d/.hidden.json       # 忽略(以 . 开头)

合并顺序:base → drop-in 按字母序。标量字段后覆盖前;数组拼接 + 去重 ;对象深合并。

为什么这么设计?------不同小组写不同规则文件不打架。安全组写 20-security.json、埋点组写 10-telemetry.json,各管各的。


七、数组字段的合并------不是覆盖,是拼接

上一节最后提到一个关键点:数组类设置跨层级是拼接合并,不是替换。

比如:

  • user ~/.claude/settings.json: "allow": ["WebSearch"]
  • project .claude/settings.json: "allow": ["Bash", "Edit"]
  • local .claude/settings.local.json: "allow": ["Write"]

最终 Claude Code 生效的 allow 列表是:

css 复制代码
["WebSearch", "Bash", "Edit", "Write"]

全部拼接、去重,不是 local 覆盖 project 覆盖 user。

这个设计很符合直觉:权限列表是"加白名单"的动作,合并是叠加而不是覆盖。想像一下如果每一层都是覆盖------每个开发者的 local 要重新抄一遍 project 的所有 allow,才能加一条自己的。这显然很蠢。

但另一个字段行为不同:

deny 规则有最高安全优先级,不能被低优先级的 allow/ask 覆盖。

也就是说,如果 managed 里写了 deny: ["Bash(rm -rf /)"],你无论在哪一层 allow 都没用。deny 是全局安全底线。


八、CLAUDE.md 的写作经验

讲完机制,讲点实操。我自己维护 CLAUDE.md 经历过多次迭代,总结了 6 条经验:

8.1 一个文件 200 行以内

这是反复试出来的经验值。超过 200 行,Claude 对前半段的遵守度明显下降------注意力是有限的。

如果内容超过 200 行,拆:

bash 复制代码
CLAUDE.md                  # 纲领性说明 + 指路
.claude/rules/testing.md   # 测试相关约定
.claude/rules/commit.md    # commit 规范
.claude/rules/i18n.md      # 国际化约定

8.2 "做什么" 比 "不做什么" 更有用

❌ "不要使用任何外部库" ✅ "依赖必须走 pnpm add,不要改 package.json"

负面指令告诉 Claude"什么是错的",但不告诉它"什么是对的"。正面指令既说了规则又说了做法。

8.3 用代码块展示规范

❌ "commit message 要简洁有意义" ✅ ```格式:: ,subject 用祈使语气。示例:feat: 添加用户头像上传、`fix: 修复登录表单验证````

规则越具体,遵守度越高。能给例子就给例子。

8.4 开头定位,不要写目录

❌

markdown 复制代码
# 目录
1. 项目概述
2. 编码规范
...

✅

markdown 复制代码
# CLAUDE.md

This file provides guidance to Claude Code when working with code in this repository.

## Repository Overview
...

Claude 不需要 TOC,它会一口气读完。开头直接讲 repo 是什么、核心模块有哪些,比目录有用。

8.5 "git commit rules" 这种高频动作要专门列出来

我自己的 CLAUDE.md 里专门有一节:

markdown 复制代码
## Git Commit Rules

When committing changes, **create separate commits per file**.
Do NOT bundle multiple file changes into a single commit.

为什么单列?因为这是每次都要做、做错就麻烦的动作。写在 CLAUDE.md 里比挂 hook 简单,效果也足够好。

8.6 别和 hooks 功能重复

如果你已经有个 PreToolUse hook 会拦截危险 Bash 命令,那 CLAUDE.md 里就不用再啰嗦"不要运行危险命令"。

心智区分 :CLAUDE.md 是知识 ,hooks 是强制。能用 hooks 强制执行的,不要再写进 CLAUDE.md------浪费 context,还容易冲突。


九、踩过的坑

9.1 CLAUDE.md 写太长,后半段不被遵守

第一次写 CLAUDE.md 我写了 500+ 行,结果项目运行时 Claude 完全不记得里面某些章节的规则。拆成 CLAUDE.md + .claude/rules/*.md 之后明显变好。200 行。

9.2 local vs project 配置混淆

.claude/settings.local.json 是 git-ignored 的个人覆盖------结果有人把团队 hook 配置写在这里,同步不到 git,其他队友根本拿不到。

记住 :想让队友拿到的配置 → settings.json;只在自己机器上用的 → settings.local.json。

9.3 sibling CLAUDE.md 不会加载

在 /monorepo/frontend/ 下跑 Claude Code,期待 /monorepo/backend/CLAUDE.md 里的约定也生效------不会的,sibling 永远不加载。

解决办法:把跨项目约定上提到根 CLAUDE.md,两个 sibling 共享。

9.4 managed settings 不能本地覆盖

有人在企业环境里发现自己的 settings.local.json 改了但没效果------没用 managed 在上面压着。disableAllHooks 在 local 里设也不能关掉 managed 部署的 hook(这是 v2.1.49 之后的官方行为)。

9.5 数组合并而不是替换,容易出现意外 allow

我曾经想"清空 allow 只保留一条",在 local 里写 "allow": ["WebSearch"] ------ 结果 project 和 user 里的 allow 还在,merge 出一个比我想的更宽的列表。

想删某条规则,不能 靠覆盖;数组是加法,不是替换。要么直接改上层文件,要么把要禁的写进 deny。


十、零件齐活了

memory 和 settings 这对分层系统,是 Claude Code 最底层的"它知道什么 "和"它能做什么"。

复盘一下------

  • memory 管"知识":CLAUDE.md 三层(user/project/local),monorepo 里上溯到根、下行 lazy 加载、sibling 不串门。想精确到某类文件用 .claude/rules/*.md + glob。
  • settings 管"规则":5 层优先级(managed > CLI > local > project > user),数组字段合并而非覆盖,deny 规则有全局最高优先级。企业场景用 managed 部署不可绕过的策略。
  • 分工:知识写 CLAUDE.md、强制走 hooks/settings、专题放 rules------别让三者职能重叠。

这 8 篇串起来,Claude Code 作为单机工具的内部机械基本拆完了:Commands(按钮)、Skills(工具)、Subagents(员工)、Hooks(挂钩点)、Memory(入职文档)、Settings(公司制度)。

零件都认完了,下一步是让它们一起跑起来。

03 篇里跑过一遍 release-notes 生成器------一个 /release-notes-crafter 带起一个 subagent、agent 预加载一个 skill 先跑 git log、再直接调另一个 skill 排版,最后写出 RELEASE_NOTES.md。那篇讲的是"怎么执行"。下一篇要讲的是"为什么这么编排"------Command / Agent / Skill 三者在一个工作流里是怎么分工的?能不能把 agent 内嵌另一个 agent?preload 的 skill 跟 Skill tool 调出来的 skill 有什么本质区别?同一件事"打开时间",在 command、agent、skill 三种实现里,Claude 最后会选哪一个?这些问题 03 篇只说了一半,下一篇来把它讲透。


参考资料

外部链接

Footnotes

  1. Boris Cherny on X - CLAUDE.md Loading Clarification --- 官方对 ancestor / descendant 加载机制的澄清 ↩

  2. Claude Code Settings Reference --- 官方 settings 层级与全部字段 ↩

相关推荐
独隅2 小时前
Claude API 实战教程:从入门到完整项目
android·java·数据库·claude·claude code
独隅5 小时前
Claude 高效使用指南与效果展示
claude·claude code
ZzT10 小时前
Claude Duet 安全设计拆解:替你回邮件、付账单的 agent,碰不到你的密码
ai编程·claude
小七-七牛开发者10 小时前
当 Agent 接手更多工作,我们还能把好关吗?
ai·openai·agent·claude
独隅11 小时前
Claude 高效使用指南深度评测
java·开发语言·claude·claude code
yjm00211 小时前
如何用 Claude Opus 5.5 做一支音乐 MV?代码逐帧渲染完整教程(2026)
ai编程·claude
独隅11 小时前
Claude 新手入门与高效调用指南
claude
独隅12 小时前
Claude 高效应用实战指南
android·java·开发语言·claude·claude code
技术小甜甜14 小时前
【Copilot】能选 Claude 和 GPT-6 了,Excel 分析该交给谁
gpt·excel·copilot·claude·microsoft365·gpt-6