本指南涵盖的内容
下面的表格列出了每个设置及其作用。之后的文件树是本页面每个代码示例所引用的示例 monorepo。本页面的设置
下面的每个设置都是独立的。它们相互叠加而不是相互替换,因此应用适合你的存储库的任何设置。选择从哪里启动 Claude 决定了你的设置文件的位置,所以先阅读它。将其整合在一起 展示了所有这些设置的组合。示例 monorepo
本页面的示例引用了一个包含三个包的 monorepo。相同的模式适用于大型单树代码库:其中示例使用packages/api/,替换为你自己的子系统目录,例如 src/backend/ 或 lib/core/。
选择从哪里启动 Claude
你启动claude 的位置决定了 Claude 可以读取和编辑哪些文件而无需额外权限授予、在启动时加载哪些 CLAUDE.md 文件,以及哪些项目设置适用。
.claude/settings.json 中的项目设置不像 CLAUDE.md 文件那样从父目录继承。关于会话读取哪个目录的 .claude/settings.json,请参阅 Claude Code 查找每个文件的位置。
下面的每个部分都说明其设置文件应该位于存储库根目录还是你启动的子目录中,以及它是提交的还是保持本地的。
按目录分层 CLAUDE.md 文件
在大型代码库中,存储库根目录的单个 CLAUDE.md 往往要么增长到覆盖每个子系统的约定,在与当前任务无关的指令上浪费上下文,要么保持太通用而无用。将指令分散在按目录的文件中意味着 Claude 加载存储库范围的规则加上仅你正在处理的代码的约定。 Claude Code 在启动时从你的工作目录和每个父目录加载每个 CLAUDE.md 文件,然后当它在那里读取文件时按需加载每个子目录的文件。根文件设置存储库范围的规则,每个子目录添加自己的规则。 常见的分割是两个级别:- 根
CLAUDE.md:适用于任何地方的指令,例如编码标准和提交约定 - 按子目录
CLAUDE.md:特定于该区域堆栈的约定。在 monorepo 中,这是每个包一个。在大型单树中,它是每个子系统一个,例如src/db/或src/api/
/doctor 检查。根 CLAUDE.md 包含在每个包中适用的规则:
CLAUDE.md
CLAUDE.md,这里是 packages/api/CLAUDE.md,添加特定于该区域的约定:
packages/api/CLAUDE.md
packages/api/ 启动 Claude 时,它加载 packages/api/CLAUDE.md 和根 CLAUDE.md。Claude 看到本地指令与存储库范围的规则一起,上下文中没有来自 packages/web/ 的指令。对于非 monorepo 树中的任何子目录也是如此。要确认加载了哪些文件,请运行 /context 并检查 Memory files 下的列表。
保持文件随着代码库和模型变化而最新的几种方法:
- 在拉取请求中审查:像对待任何其他文档更改一样对待 CLAUDE.md 编辑,以便约定跟踪代码
- 在主要模型发布后重新访问:适用于较旧模型限制的指令一旦较新模型自己处理该情况,可能会变成开销。例如,强制单文件重构的规则一旦限制消失就可以删除
- 添加一个 Stop hook 来提议更新:
Stophook 在 Claude 完成响应时接收会话记录的路径,所以脚本可以审查会话并在暴露的差距仍然新鲜时提议 CLAUDE.md 更新
在按目录 CLAUDE.md 和路径范围规则之间选择
按目录的CLAUDE.md 文件和 .claude/rules/ 下的路径范围规则都允许你将指令定向到树的一部分。它们在文件位置和加载时间上有所不同。
有关也涵盖 skills 的比较,请参阅比较相似功能。
排除不相关的 CLAUDE.md 文件
当你从存储库根目录启动 Claude 时,每个子目录的 CLAUDE.md 在 Claude 读取该目录中的文件时立即加载。claudeMdExcludes 设置按路径或 glob 模式跳过特定文件,以便它们永远不会加载。
对你从不处理的目录使用此功能,例如其他团队的包、遗留代码或供应商子树。排除列表是静态的,不是按任务的开关。要今天专注于一个包,明天专注于另一个包,从该包的目录启动 Claude 而不是编辑排除。
如果你只想为自己排除这些,将设置放在 .claude/settings.local.json 中。Claude Code 在保存设置时会将该文件添加到你的全局 gitignore。由于你在这里手动创建它,请将其添加到你的 gitignore。模式使用 glob 语法与绝对文件路径匹配,所以以相对样式模式开头的 **/ 以在树中的任何地方匹配。下面的示例排除其他团队拥有的包:
.claude/settings.local.json
"**/packages/*/CLAUDE.md":排除每个包的 CLAUDE.md,同时保留根目录"**/packages/legacy-*/**":排除每个名称与 glob 匹配的包,包括规则"/home/user/monorepo/legacy/CLAUDE.md":按绝对路径排除一个特定文件
claudeMdExcludes:用户、项目、本地或托管。数组在范围内合并,所以团队可以设置项目级别的默认值,同时个人添加本地覆盖。
有关完整的排除文档,请参阅排除特定 CLAUDE.md 文件。
减少 Claude 读取的内容
指令只是最终进入 Claude 上下文的一部分。文件读取是另一个随着代码库增长而增加的成本。下面的设置阻止读取不相关的路径,并用语言服务器查找替换详尽的文件扫描。阻止读取生成的和供应商代码
Claude 的内容搜索默认尊重.gitignore,所以已列在其中的路径,例如 node_modules/、dist/ 和 build/,无需额外配置就会保持在搜索结果之外。
对于已检入的路径,例如供应商 SDK 或提交的生成代码,在 permissions.deny 中添加 Read 拒绝规则以阻止 Claude 打开这些文件。
拒绝规则可以覆盖在存储库中工作的每个人、仅你自己或机器上的每个会话,具体取决于你将它们放在哪个设置文件中:
- 在存储库中工作的每个人:将规则提交到
.claude/settings.json,位于存储库根目录(如果你从那里启动 Claude),或位于每个包的.claude/(如果你从子目录启动)。与本页面的其他项目设置一样,该文件不会从父目录继承。 - 仅你自己:使用位于存储库根目录的
.claude/settings.local.json,它在存储库内的每个 CLI 会话中加载,无论启动目录如何,除了 Claude Code 不使用存储库根目录的情况,例如在 Windows 上。相对模式(如示例中的Read(./**/vendor/**/*))仍然锚定在会话的当前工作目录而不是存储库根目录,所以如果你从子目录启动会话,请在此文件中将规则写为//绝对路径,例如Read(//absolute/path/to/repo/**/vendor/**/*)。在 v2.1.211 之前,.claude/settings.local.json也仅从启动目录加载。 - 每个人,在每个会话中强制执行:在托管设置中设置规则,用户和项目设置无法覆盖。
/**/* 而不是 /** 结尾,以便每个规则覆盖目录内的所有内容,但不覆盖目录本身。Claude 仍然可以列出这些目录或进入它们,例如使用 ls dist 或 cd build。
.claude/settings.json
cat、head、grep 和 find,当拒绝的路径作为参数出现时,以及重定向的目标,例如 < file。Claude Code 还尽力尝试将拒绝的路径排除在内置 Grep 和 Glob 工具的结果之外。对包含拒绝文件的目录进行的 Bash 搜索(例如 grep -r 或 find)仍然会在其输出中包含它们。
拒绝规则不涵盖自己打开文件的子进程。有关完整的模式语法,请参阅 Read 和 Edit 权限规则。
使用代码智能减少文件读取
在大型代码库中,查找符号的定义或使用位置可能需要许多文件读取和 grep 调用。代码智能插件将 Claude 连接到语言服务器,以便它可以跳转到定义、查找引用和直接显示类型错误,而不是扫描树。 官方市场有 TypeScript、Python、Go、Rust 和其他常见语言的插件。在 Claude Code 会话内运行下面的命令来安装 TypeScript 插件:Marketplace "claude-plugins-official" not found:使用/plugin marketplace add anthropics/claude-plugins-official添加市场,然后重试安装。- 插件在市场中找不到:检查插件名称。
enabledPlugins 项目设置。
代码智能插件需要每个开发者机器上的语言的语言服务器二进制文件。查看每种语言需要哪个二进制文件。从官方市场安装需要网络访问 GitHub,市场在那里托管。在受限网络上,从内部 Git 主机或本地路径添加市场。
这与上面的 claudeMdExcludes 和 Read 拒绝规则配对良好。那些保持不相关的内容不进入上下文,代码智能保持 Claude 不读取剩余的内容来定位定义。
范围 worktrees 和文件访问
这些设置控制 worktrees 中磁盘上的内容以及 Claude 可以读取和写入的超出启动点的目录。仅检出你需要的目录
--worktree 标志在新的 git worktree 中启动会话,以便更改与主检出隔离。默认情况下,它检出整个存储库。在大型存储库中,worktree.sparsePaths 设置使用 git sparse-checkout 仅将列出的目录加上根级文件写入磁盘,以便 worktrees 启动更快并使用更少空间。
如果在此目录中工作的每个人都需要相同的路径,将设置提交到 .claude/settings.json。要为自己添加路径,使用 .claude/settings.local.json:列表在范围内合并,所以本地文件可以向提交的列表添加路径但不能删除它们。
本页面上的 JSON 示例一次显示一个设置。如果你的 .claude/settings.json 已经包含其他键,例如上面的 permissions.deny 规则,请在它们旁边添加 worktree 键,而不是替换文件。将其放在一起显示组合结果。
下面的示例显示提交的文件:
.claude/settings.json
.claude/、packages/api/ 和 packages/shared/ 而不是完整树。sparsePaths 中的路径相对于存储库根目录,无论你从哪个子目录启动 Claude。任何目录路径都可以在这里工作,不仅仅是包根。
这对于子代理 worktree 隔离特别有用。子代理是为子任务生成的并行 Claude 实例,每个在 worktree 中运行的都获得轻量级检出而不是完整树。会话中的所有 worktrees 共享相同的 sparsePaths,所以如果一个子代理需要 packages/api/ 而另一个需要 packages/web/,列出两者。
在 sparsePaths 中列出目录,而不是单个文件。根级文件如 package.json、tsconfig.base.json 和锁文件始终与你列出的目录一起检出。根级目录不是,所以如果你想要存储库根目录的 .claude/settings.json、.claude/rules/ 或 .claude/skills/ 在 worktree 内可用,请在列表中包含 .claude。
Sparse checkout 需要 git 在存在 sparse worktree 时在存储库的共享 .git/config 中启用 extensions.worktreeConfig。Claude Code 在删除最后一个 worktree 后会删除该条目,但仅当 Claude Code 添加了它时。它永远不会删除你自己设置的值。在 v2.1.207 之前,该条目在删除最后一个 worktree 后仍然存在,基于 go-git 的工具(如 tea)无法打开存储库,直到你运行 git config --unset extensions.worktreeConfig。
要避免在 worktrees 中复制大型目录如 node_modules,将 sparsePaths 与同一 .claude/settings.json 中的 symlinkDirectories 配对:
.claude/settings.json
node_modules/ 回到主存储库副本的符号链接,而不是在磁盘上复制它。
sparsePaths 和 symlinkDirectories 设置在创建 worktree 之前从你的启动目录读取。创建后,会话的工作目录是 worktree 根,而不是你启动的子目录。因此,worktree 内的项目设置从 worktree 根的 .claude/settings.json(存储库根文件的检出副本)加载。将你在 worktrees 内需要的任何其他设置(例如权限规则或 hooks)放在存储库根的 .claude/settings.json 中。跨包或存储库授予访问权限
当你从子目录启动 Claude 时,或当任务跨越多个检出时,本部分适用。如果你在单个大型树中从存储库根目录启动,Claude 已经可以访问每个文件,你可以跳过此部分。 当你从packages/api/ 启动 Claude 时,它可以读取和写入该目录内的文件。如果任务需要跨包更改,例如更新 api 和 web 都导入的共享类型,你需要授予对同级目录的访问权限。相同的机制授予对单独检出的存储库的访问权限。
.claude/settings.json 中的 additionalDirectories 设置给 Claude 访问工作目录外的目录。下面的示例授予对两个同级包的访问权限:
packages/api/.claude/settings.json
packages/api/ 工作时读取和编辑 packages/shared/ 和 packages/web/ 中的文件。
你也可以在运行时不编辑设置而授予访问权限,通过在启动 Claude 时传递 --add-dir:
.claude/rules/ 文件和 skills 是否也加载取决于你如何添加它:
要从使用
--add-dir 或 /add-dir 添加的目录加载 CLAUDE.md 和规则文件,设置 CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD 环境变量:
additionalDirectories 设置中列出的目录没有影响。详见从其他目录加载。
对于此区域中的每个人都需要的同级目录,将 additionalDirectories 提交到 .claude/settings.json。对于个人选择或一次性访问,使用 .claude/settings.local.json 或在启动时传递 --add-dir。
添加按目录 skills
任何子目录都可以定义skills范围限于其自己的堆栈。skill 在 Claude 确定其相关时按需加载,所以 API 特定的工具在前端工作期间不会消耗上下文。 Skills 位于目录内的.claude/skills/ 下。将它们与该区域的代码一起提交,以便克隆存储库的任何人都能获得它们。在 monorepo 中,这可以是每个包一套 skills。在大型单树代码库中,它是每个子系统一套,例如 src/db/.claude/skills/。
在子目录内创建一个 skill 目录:
SKILL.md,这里是 packages/api/.claude/skills/api-testing/SKILL.md。此示例教 Claude API 包的测试模式:
packages/api/.claude/skills/api-testing/SKILL.md
packages/web/.claude/skills/component-patterns/ 描述前端的组件约定而不是测试。当 Claude 处理 packages/api/ 中的文件时,它加载 api-testing skill。当它在 packages/web/ 中工作时,它加载 component-patterns 代替。在另一个的任务期间,两个目录的 skills 都不加载。
你也可以按文件模式而不是按位置范围 skill。paths frontmatter 字段采用 glob 模式,Claude 仅在处理匹配文件时自动加载 skill。对于位于存储库根目录的 .claude/skills/ 中但仅适用于某些文件(无论它们出现在哪里)的 skill,使用此功能,例如范围限于 **/migrations/** 的数据库迁移 skill。
有关创建和组织 skills 的更多信息,请参阅 Skills。
保持 skills 可发现
随着 skills 分散在许多目录中,Claude 选择的列表可能会增长很大。Claude 通过读取每个发现的 skill 的名称和描述来选择 skill,只有选定的 skill 的完整内容加载到上下文中。本部分涵盖如何保持该列表较小。 哪些 skills 在范围内取决于你从哪里启动 Claude:- 从子目录如
packages/api/:来自该目录、每个父目录直到存储库根目录以及用户和企业级别的 skills - 从存储库根目录:根 skills,加上来自 Claude 在会话期间接触的每个子目录的 skills,可能累积到数百个
- 在使用
--add-dir添加同级后:该同级的 skills 也加载。additionalDirectories设置仅授予文件访问权限,不加载 skills
packages/api/ 中编写或修改测试”。
对于许多目录共享的 skills,例如 PR 约定或部署检查清单,将它们放在存储库根目录的 .claude/skills/ 中,以便从任何启动目录加载。当共享 skills 需要自己的版本历史或必须跨存储库工作时,改为将它们打包为插件。插件 skills 使用 plugin-name:skill-name 命名空间,所以它们永远不会与按目录的 skills 冲突。平台团队可以在一个地方对它们进行版本化和更新。
要查找哪些 skills 未被使用,启用 OpenTelemetry 日志导出器并设置 OTEL_LOG_TOOL_DETAILS=1 以便 skill 名称被逐字记录而不是被编辑。skill_activated 事件在其 skill.name 属性中记录每个调用,invocation_trigger 记录命令、Claude 或嵌套 skill 是否调用它,这告诉你要合并或停用什么。
当分层停止扩展时集中约定
随着代码库的增长,按目录的 CLAUDE.md 文件可能变得难以管理。约定漂移,文件变得陈旧,没有人拥有根目录。解决这个问题通常落在维护存储库 Claude Code 设置的团队身上,而不是在自己的区域中工作的每个开发者。 将约定和参考内容从始终加载的 CLAUDE.md 移出到按需加载的机制中:- Skills:Claude 仅在与任务相关时加载的参考材料
- Plugins:平台团队集中拥有的 skills、hooks 和命令的版本化包
- MCP servers:如果你的组织已经在存储库上运行代码搜索或 RAG 索引,将其公开为 MCP 工具,以便 Claude 查询它而不是直接读取文件
在会话启动时推荐正确的插件
一旦约定位于插件中,在树的陌生部分启动 Claude 的队友就没有关于该区域所有者维护哪个插件的信号。SessionStart hook 可以弥补这个差距,因为 hook 打印到 stdout 的任何内容都会在第一个提示之前添加到 Claude 的上下文中。
例如,你可以编写一个脚本,从hook 输入读取启动目录,在提交到存储库的路径到插件映射中查找它,并打印建议供 Claude 在其第一个回复中中继。查看使用 hooks 自动化操作来编写和注册 hook。
将其整合在一起
下面的组合配置使用 monorepo 布局。相同的文件适用于大型单树中的任何子目录。每个子目录的.claude/settings.json 必须是自包含的而不是分层在根文件上。
示例在 .claude/settings.json 中提交 worktree、additionalDirectories 和 Read 拒绝规则,以便 packages/api/ 中的每个开发者获得相同的同级访问、稀疏路径和排除。下面的文件是 packages/api/ 的提交的按区域设置:
packages/api/.claude/settings.json
packages/api/ 启动,同级包的 CLAUDE.md 文件已经超出范围,所以这里不需要 claudeMdExcludes。如果你也从根目录启动会话,改为将其添加到存储库根目录的 .claude/settings.local.json。
additionalDirectories 条目在你直接从 packages/api/ 启动 Claude 时适用。在从此会话创建的 worktree 内,工作目录是 worktree 根,所以此设置文件不加载。同级包已经在 worktree 内可达而无需它,但拒绝规则需要在存储库根目录的 .claude/settings.json 中的第二个副本,以便 worktree 会话获取它们,如worktree 设置注释所述:
.claude/settings.json
packages/api/ 启动 Claude:
- 加载根 CLAUDE.md 和
packages/api/CLAUDE.md,跳过packages/web/CLAUDE.md - 可以读取和编辑
packages/api/和packages/shared/中的文件 - 跳过
packages/api/中dist/和build/下的构建输出读取 - 有 api-testing skill 按需可用
- 创建包含
.claude/、packages/api/、packages/shared/和根级文件的 worktrees,拒绝规则从根设置文件应用于整个 worktree
范围和计划跨包的更改
上面的配置控制 Claude 看到的内容。当单个更改涉及多个包时,例如更新共享类型以及使用它的每个调用站点,你如何范围和排序任务也会影响结果。 两种技术帮助保持跨包更改的一致性:- 在一个会话中给 Claude 整个更改:将共享编辑及其调用站点一起交付保持每个编辑背后的决策一致,而不是按包重新推导它们
- 在编辑前计划:先计划在 plan mode 中,Claude 将计划写入文件。长的跨包会话在进行中压缩其上下文。Claude Code 在每次压缩后重新注入计划文件,所以计划在对话历史可能不会的地方幸存
后续步骤
一旦此配置就位,你可以细化它:- 使用 hooks 在 Claude 编辑文件后运行按目录的 linters 或类型检查器
- 查看有效管理成本以了解代码库大小如何影响 token 使用以及如何在更广泛推出前设置支出限制
- 在 Claude 博客上阅读Claude Code 如何在大型代码库中工作,了解组织推出模式和所有权模型,这些模型位于本页面的按存储库配置之上