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

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

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

答案藏在两种东西里:

  • 记忆 (memory):CLAUDE.md.claude/rules/*.mdAGENTS.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.jsonmanaged-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 层级与全部字段

相关推荐
洛卡卡了3 小时前
缓解token焦虑,Mac Docker 搭建 CPA 配合 cc switch 使用 Codex
人工智能·openai·claude
DO_Community18 小时前
DigitalOcean VPC 网络故障排查 Runbook 实战指南
人工智能·aigc·claude·deepseek
yezannnnnn1 天前
AI Agent又删我数据库?我直接写了个安全拦截器(附项目源码)
安全·agent·claude
jerrywus1 天前
别再陪 AI 调 iOS 了:用 cmux + baguette,让 Claude 在你的模拟器里"自己动手"
前端·ios·claude
Niubility1 天前
你大概率没用对 Claude Code 的五大能力
agent·ai编程·claude
星浩AI1 天前
Claude Code 白嫖接入 DeepSeek V4 教程
llm·claude·vibecoding
码流怪侠1 天前
【GitHub】Claude-Mem 深度解析:为 Claude Code 装上"永久记忆脑"
程序员·github·claude
solo_991 天前
安装 Claude Code 并接入 deepseek v4
claude
MacroZheng1 天前
狂揽34k star!一款AI编程必不可少的神器,和Claude Code/Codex绝配!
人工智能·后端·claude