English ← MyDocs

文档索引

在此处获取完整文档索引:https://code.claude.com/docs/llms.txt 使用此文件发现所有可用页面,然后再进一步探索。

在 monorepo 或大型代码库中设置 Claude Code

为 monorepo 和大型单代码树配置 Claude Code,使用嵌套 CLAUDE.md 文件、稀疏工作树、代码智能和按包技能,使 Claude 专注于你正在使用的代码。

大型代码库可以是包含数百万行代码的单个仓库或包含许多包的 monorepo。Claude Code 可以在任何规模下工作,但随着代码库的增长,为较小项目调整的默认值可能会用与任务无关的指令和文件读取填满上下文窗口,消耗 token 并降低 Claude 的性能。

本指南展示个人开发者和工程团队如何将 Claude 的范围限定到任务涉及的代码库部分。每个部分都会说明设置是个人的还是提交到仓库的。

本指南涵盖内容

下方的表格列出了每个设置及其作用。其后的文件树是本页每个代码示例所引用的示例 monorepo。

本页设置

以下每个设置都是独立的。它们是分层的而非相互替代的,因此请应用适合你仓库的设置。选择启动 Claude 的位置决定了你的设置文件存放位置,请先阅读它。整合在一起展示了所有设置的组合。

我想要使用
仅加载你接触的代码的约定,而不是覆盖每个子系统的单个根文件按目录分层的 CLAUDE.md 文件
排除你不工作的包的 CLAUDE.md 文件claudeMdExcludes
阻止 Claude 打开构建输出、生成代码和供应商依赖permissions.deny 中的 Read 拒绝规则
通过语言服务器查找符号的定义或调用者,而不是扫描文件代码智能插件
当 Claude 创建工作树时仅检出任务需要的目录worktree.sparsePaths
从同一会话中读取和编辑兄弟包或另一个仓库--add-diradditionalDirectories
给 Claude 特定于某个区域的程序,仅在相关时加载按目录的技能
用一组每个人都安装的约定替换许多按目录的 CLAUDE.md 文件内部市场中的插件
Tip

关于在任何仓库中保持上下文小的工作流技术,例如在子代理中运行探索以便文件读取不会进入主对话,请参阅 Claude Code 最佳实践。要为组织中的每个开发者推出基线配置,请参阅为你的组织设置 Claude Code

示例 monorepo

本页的示例引用了一个包含三个包的 monorepo。相同的模式适用于大型单代码树:当示例使用 packages/api/ 时,替换为你自己的子系统目录,如 src/backend/lib/core/

monorepo/
  CLAUDE.md                     # root instructions
  packages/
    api/
      CLAUDE.md                 # API-specific instructions
      .claude/skills/
      src/
    web/
      CLAUDE.md                 # frontend-specific instructions
      .claude/skills/
      src/
    shared/
      CLAUDE.md                 # shared library instructions
      src/

选择启动 Claude 的位置

你启动 claude 的位置决定了 Claude 可以读取和编辑哪些文件(无需额外权限授予)、启动时加载哪些 CLAUDE.md 文件到上下文中,以及应用哪些项目设置。

从哪里启动文件访问启动时加载的 CLAUDE.md使用场景
仓库根目录每个文件仅根目录;子目录文件在 Claude 读取时按需加载任务跨越多个包或子系统
子目录仅该子树,直到你授予更多该目录加上每个祖先的工作范围限定在一个包或子系统

.claude/settings.json 中的项目设置仅从你的启动目录加载,不会像 CLAUDE.md 文件那样从父目录继承:仓库根目录的 .claude/settings.json 仅在你从根目录启动时适用。

以下每个部分都说明其设置文件是属于仓库根目录还是你启动的子目录,以及是提交的还是本地保留的。

按目录分层 CLAUDE.md 文件

在大型代码库中,仓库根目录的单个 CLAUDE.md 要么增长到涵盖每个子系统的约定(消耗与当前任务无关的指令上下文),要么保持过于通用而无用。将指令拆分到按目录的文件中意味着 Claude 加载仓库范围的规则加上仅你正在使用的代码的约定。

Claude Code 在启动时从你的工作目录和每个父目录加载每个 CLAUDE.md 文件,然后在读取子目录中的文件时按需加载该子目录的文件。根文件设置仓库范围的规则,每个子目录添加自己的规则。

常见的拆分是两级:

  • CLAUDE.md:适用于所有地方的指令,如编码标准、提交约定和仓库布局
  • 按子目录 CLAUDE.md:特定于该区域技术栈的约定。在 monorepo 中是每个包一个。在大型单树中是每个子系统一个,如 src/db/src/api/

将这些文件提交到仓库,以便队友继承。每个目录的所有者通常维护其文件。

CLAUDE.md 让 Claude 了解仓库结构:

This is a monorepo with three packages under packages/:

- packages/api: Node.js REST API with Express, TypeScript, and PostgreSQL
- packages/web: React frontend with Vite, TypeScript, and TailwindCSS
- packages/shared: shared TypeScript utilities used by both api and web

Run commands from the package directory, not the monorepo root.
Each package has its own tsconfig.json, package.json, and test suite.

每个子目录的 CLAUDE.md(这里是 packages/api/CLAUDE.md)添加特定于该区域技术栈的上下文:

This package is the REST API server.

- Run tests: `npm test` (uses Vitest)
- Run dev server: `npm run dev` (port 3001)
- Database migrations: `npm run migrate`
- Environment variables: copy `.env.example` to `.env`

API routes are in src/routes/. Each route file exports an Express router.
Database queries use Knex in src/db/. Never write raw SQL strings in route handlers.

当你从 packages/api/ 启动 Claude 时,它同时加载 packages/api/CLAUDE.md 和根 CLAUDE.md。Claude 看到本地指令和仓库范围的规则,上下文中没有来自 packages/web/ 的指令。对于非 monorepo 树中的任何子目录也是如此。

保持文件随代码库和模型变化的几种方法:

  • 在拉取请求中审查:像对待其他文档变更一样对待 CLAUDE.md 编辑,使约定跟踪代码
  • 在主要模型发布后重新审视:围绕旧模型限制工作的指令可能在新模型自行处理该情况后成为开销。例如,强制单文件重构的规则一旦限制消失就可以删除
  • 添加一个提议更新的 Stop 钩子Stop 钩子在 Claude 完成响应时接收会话转录的路径,因此脚本可以在差距暴露时审查会话并提议 CLAUDE.md 更新

有关 CLAUDE.md 文件如何加载和交互的更多信息,请参阅内存和项目指令

选择按目录 CLAUDE.md 还是路径范围规则

按目录的 CLAUDE.md 文件和 .claude/rules/ 下的路径范围规则都允许你将指令定向到树的某一部分。它们在文件位置和加载时间上有所不同。

方法文件位置加载时机使用场景
按目录 CLAUDE.md在目录内,与其代码一起从该目录启动时在启动时加载,或在 Claude 读取该目录中的文件时按需加载目录所有者维护自己的约定;指令与代码一起版本控制
.claude/rules/ 中的路径范围规则仓库根目录的中央 .claude/当 Claude 处理与规则的 paths: glob 匹配的文件时你希望所有约定在一个地方,或相同的规则适用于许多分散的路径

有关包括技能在内的比较,请参阅比较类似功能

排除不相关的 CLAUDE.md 文件

当你从仓库根目录启动 Claude 时,每个子目录的 CLAUDE.md 会在 Claude 读取该目录中的文件时加载。claudeMdExcludes 设置按路径或 glob 模式跳过特定文件,使它们永远不会加载。

对于你从不工作的目录使用此设置,例如其他团队的包、遗留代码或供应商子树。排除列表是静态的,不是按任务切换的。要今天专注于一个包,明天专注于另一个包,从该包的目录启动 Claude 而不是编辑排除项。

如果你只想对自己应用这些排除项,将设置放在 .claude/settings.local.json 中,该文件被 gitignore 且不提交。模式使用 glob 语法匹配绝对文件路径,因此以 **/ 开头的相对风格模式匹配树中的任何位置。以下示例排除其他团队拥有的包:

{
  "claudeMdExcludes": [
    "**/packages/admin-dashboard/**",
    "**/packages/legacy-*/**"
  ]
}

这会跳过这些包下的每个 CLAUDE.md 和规则文件。根 CLAUDE.md 和你工作的包仍然正常加载。

这些模式涵盖其他常见情况:

  • "**/packages/*/CLAUDE.md":排除每个包的 CLAUDE.md 同时保留根
  • "**/packages/web/**":排除 web 包下的所有内容,包括规则
  • "/home/user/monorepo/legacy/CLAUDE.md":按绝对路径排除一个特定文件

托管策略 CLAUDE.md 文件无法排除,因此组织范围的指令始终适用。你可以在任何设置范围设置 claudeMdExcludes:用户、项目、本地或托管。数组跨范围合并,因此团队可以设置项目级默认值,而个人添加本地覆盖。

有关完整排除文档,请参阅排除特定 CLAUDE.md 文件

减少 Claude 的读取量

指令只是 Claude 上下文的一部分。文件读取是另一项随代码库增长的成本。以下设置阻止读取不相关的路径,并用语言服务器查找替换详尽的文件扫描。

阻止读取生成代码和供应商代码

Claude 的内容搜索默认遵守 .gitignore,因此已列出的路径(如 node_modules/dist/build/)无需额外配置即可排除在搜索结果之外。

对于已检入的路径,如供应商 SDK 或已提交的生成代码,在 permissions.deny 中添加 Read 拒绝规则以阻止 Claude 打开这些文件,即使搜索列出了它们。

要为仓库中的每个人应用这些排除项,将它们提交到 .claude/settings.json。要保留为个人的,使用 .claude/settings.local.json。像本页上的其他项目设置一样,这些文件仅从你的启动目录加载。如果你从仓库根目录启动,将它们放在那里;如果从子目录启动,放在每个包的 .claude/ 中。要在每个会话中强制执行相同的拒绝规则(无论启动目录),在托管设置中设置它们,用户和项目设置无法覆盖。

以下示例阻止构建产物和供应商 SDK:

{
  "permissions": {
    "deny": [
      "Read(./**/dist/**)",
      "Read(./**/build/**)",
      "Read(./**/*.generated.*)",
      "Read(./vendor/**)"
    ]
  }
}

拒绝规则覆盖 Claude 的内置文件工具和识别的 Bash 文件命令,包括 catheadgrepfind,当被拒绝的路径作为参数传递时。它们不会从递归搜索的输出中过滤被拒绝的路径,也不会覆盖自行打开文件的任意子进程。有关完整的模式语法,请参阅Read 和 Edit 权限规则

使用代码智能减少文件读取

在大型代码库中,查找符号的定义或使用位置可能需要许多文件读取和 grep 调用。代码智能插件将 Claude 连接到语言服务器,使其可以直接跳转到定义、查找引用和显示类型错误,而不是扫描树。

官方市场有适用于 TypeScript、Python、Go、Rust 和其他常见语言的插件。以下示例安装 TypeScript 插件:

/plugin install typescript-lsp@claude-plugins-official

要为仓库中的每个人启用插件而不是自行安装,将其添加到 enabledPlugins 项目设置

代码智能插件需要每台开发者机器上的语言服务器二进制文件。参见每种语言需要哪个二进制文件。从官方市场安装需要访问 GitHub 的网络,市场托管在那里。在受限网络上,从内部 Git 主机或本地路径添加市场

这与 claudeMdExcludes 和上面的 Read 拒绝规则配合良好。这些将不相关内容排除在上下文之外,代码智能防止 Claude 阅读剩余内容来定位定义。

限定工作树和文件访问

这些设置控制工作树中磁盘上的内容以及 Claude 可以在起点之外读写哪些目录。

仅检出你需要的目录

--worktree 标志在新的 git 工作树中启动会话,使更改与你的主检出隔离。默认情况下它检出整个仓库。在大型仓库中,worktree.sparsePaths 设置使用 git 稀疏检出仅将列出的目录加上根级文件写入磁盘,因此工作树启动更快且使用更少空间。

如果在此目录中工作的每个人都需要相同的路径,将设置提交到 .claude/settings.json。要为自己添加路径,使用 .claude/settings.local.json:列表跨范围合并,因此本地文件可以向已提交的列表添加路径但不能移除。以下示例显示已提交的文件:

{
  "worktree": {
    "sparsePaths": [
      ".claude",
      "packages/api",
      "packages/shared"
    ]
  }
}

当 Claude 创建工作树时,它仅检出 .claude/packages/api/packages/shared/ 而不是完整树。sparsePaths 中的路径相对于仓库根目录,无论你从哪个子目录启动 Claude。任何目录路径都有效,不仅是包根目录。

这对于子代理工作树隔离特别有用。子代理是为子任务生成的并行 Claude 实例,每个在工作树中运行的实例获得轻量级检出而不是完整树。会话中的所有工作树共享相同的 sparsePaths,因此如果一个子代理需要 packages/api/ 而另一个需要 packages/web/,请列出两者。

sparsePaths 中列出目录,而不是单个文件。根级文件如 package.jsontsconfig.base.json 和锁文件始终与你列出的目录一起检出。根级目录不会,因此如果你想在工作树中使用仓库根目录的 .claude/settings.json.claude/rules/.claude/skills/,请在列表中包含 .claude

要避免在工作树之间复制 node_modules 等大目录,在同一 .claude/settings.json 中将 sparsePathssymlinkDirectories 配对:

{
  "worktree": {
    "sparsePaths": [
      ".claude",
      "packages/api",
      "packages/shared"
    ],
    "symlinkDirectories": [
      "node_modules"
    ]
  }
}

这会从每个工作树的 node_modules/ 创建指向主仓库副本的符号链接,而不是在磁盘上复制它。

Note

sparsePathssymlinkDirectories 设置在创建工作树之前从你的启动目录读取。创建后,会话的工作目录是工作树根目录,而不是你启动的子目录。工作树内的项目设置因此从工作树根目录的 .claude/settings.json(仓库根目录文件的检出副本)加载。将工作树内需要的任何其他设置(如权限规则或钩子)放在仓库根目录的 .claude/settings.json 中。

有关完整的工作树设置参考,请参阅工作树设置

授予跨包或跨仓库访问权限

当你从子目录启动 Claude 或任务跨越多个检出时,此部分适用。如果你从单个大型树的仓库根目录启动,Claude 已经可以访问每个文件,你可以跳过此部分。

当你从 packages/api/ 启动 Claude 时,它可以读取和编辑该目录中的文件。如果任务需要跨包更改,例如更新 apiweb 都导入的共享类型,你需要授予对兄弟目录的访问权限。相同的机制授予对单独检出的仓库的访问权限。

.claude/settings.json 中的 additionalDirectories 设置使 Claude 可以访问工作目录之外的目录。以下示例授予对两个兄弟包的访问权限:

{
  "permissions": {
    "additionalDirectories": [
      "../shared",
      "../web"
    ]
  }
}

相对路径根据你启动 Claude 的目录解析。使用此配置,Claude 可以在从 packages/api/ 工作时读取和编辑 packages/shared/packages/web/ 中的文件。

你也可以在启动 Claude 时通过传递 --add-dir 在运行时授予访问权限,无需编辑设置:

claude --add-dir ../shared

无论你如何添加目录,Claude 都可以读取和编辑其中的文件。目录的 CLAUDE.md、.claude/rules/ 文件和技能是否也会加载取决于你如何添加它:

添加方式加载 CLAUDE.md 和规则加载技能
additionalDirectories 设置从不从不
--add-dir 标志或 /add-dir 命令仅在设置以下环境变量时

要从使用 --add-dir/add-dir 添加的目录加载 CLAUDE.md 和规则文件,设置 CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD 环境变量:

CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1 claude --add-dir ../shared

该环境变量对 additionalDirectories 设置中列出的目录无效。详见从附加目录加载

对于此区域中每个人都需要的兄弟目录,将 additionalDirectories 提交到 .claude/settings.json。对于个人选择或一次性访问,使用 .claude/settings.local.json 或在启动时传递 --add-dir

添加按目录技能

任何子目录都可以定义限定于其自身技术栈的技能。技能在 Claude 确定其相关时按需加载,因此特定于 API 的工具不会在前端工作期间消耗上下文。

技能位于目录内的 .claude/skills/ 下。将它们与该区域的代码一起提交,以便克隆仓库的任何人都能获得它们。在 monorepo 中,这可以是每个包一组技能。在大型单代码树中,是每个子系统一组,如 src/db/.claude/skills/

在子目录内创建技能目录:

mkdir -p packages/api/.claude/skills/api-testing

然后在该目录内写入 SKILL.md,这里是 packages/api/.claude/skills/api-testing/SKILL.md。此示例教 Claude API 包的测试模式:

---
name: api-testing
description: Testing patterns for the API package. Use when writing or modifying tests in packages/api/.
---

## Test structure

Tests are in `src/__tests__/` mirroring the `src/` directory structure.
Each route file has a corresponding `.test.ts` file.

## Running tests

- All tests: `npm test`
- Single file: `npm test -- src/__tests__/routes/users.test.ts`
- Watch mode: `npm test -- --watch`

## Test utilities

- `src/__tests__/helpers/db.ts`: provides `setupTestDb()` and `teardownTestDb()` for database tests
- `src/__tests__/helpers/auth.ts`: provides `createTestUser()` and `getAuthToken()` for authenticated endpoints

## Patterns

- Use `supertest` for HTTP assertions, not raw fetch
- Always wrap database tests in a transaction that rolls back
- Mock external services in `src/__tests__/mocks/`

不同的子目录以相同方式拥有不同的技能:packages/web/.claude/skills/component-patterns/ 描述前端的组件约定而不是测试。当 Claude 处理 packages/api/ 中的文件时,它加载 api-testing 技能。当它在 packages/web/ 中工作时,它加载 component-patterns。两个目录的技能都不会在对方的任务期间加载。

你也可以通过文件模式而不是放置位置来限定技能范围。paths frontmatter 字段接受 glob 模式,Claude 仅在处理匹配文件时自动加载技能。对于位于仓库根目录 .claude/skills/ 但仅适用于特定文件的技能使用此方式,例如限定为 **/migrations/** 的数据库迁移技能。

有关创建和组织技能的更多信息,请参阅技能

保持技能可发现

当技能分布在多个目录中时,Claude 从中选择的列表可能变得很大。Claude 通过读取每个发现的技能的名称和描述来选择技能,只有被选中的技能的完整内容才会加载到上下文中。本节介绍如何保持该列表小以及编写能经受缩短的描述。

哪些技能在范围内取决于你启动 Claude 的位置:

  • 从子目录(如 packages/api/)启动:来自该目录、每个父目录直到仓库根目录以及用户和企业级别的技能
  • 从仓库根目录启动:来自会话期间 Claude 接触的每个子目录的技能,可能累积到数百个
  • 使用 --add-dir 添加兄弟目录后:该兄弟目录的技能也会加载。additionalDirectories 设置仅授予文件访问权限,不加载技能

名称始终加载,但描述在有很多时会被缩短,这可能会去除 Claude 用于决定技能是否适用的关键词。保持描述简短,并以请求中会包含的词开头,如"writing or modifying tests in packages/api/"。

对于许多目录共享的技能,如 PR 约定或部署检查清单,将它们放在仓库根目录的 .claude/skills/ 中,以便从任何启动目录加载。当共享技能需要自己的版本历史或必须跨仓库工作时,将它们打包为插件。插件技能使用 plugin-name:skill-name 命名空间,因此它们永远不会与按目录的技能冲突。平台团队可以在一个地方进行版本控制和更新。

要查找哪些技能未使用,启用 OpenTelemetry日志导出器并设置 OTEL_LOG_TOOL_DETAILS=1,以便技能名称按字面记录而不是被编辑。skill_activated 事件在其 skill.name 属性中记录每次调用,invocation_trigger 记录是命令、Claude 还是嵌套技能调用了它,这告诉你需要整合或淘汰什么。

当分层停止扩展时集中化约定

按目录的 CLAUDE.md 文件在代码库增长时可能变得难以治理。约定漂移、文件过时,没有人拥有根文件。解决这个问题通常落在维护仓库 Claude Code 设置的团队身上,而不是在各自领域工作的每个开发者身上。

将约定和参考内容从始终加载的 CLAUDE.md 移到按需加载的机制:

  • 技能:Claude 仅在与任务相关时加载的参考材料
  • 插件:技能、钩子和命令的版本化包,由平台团队集中拥有
  • MCP 服务器:如果你的组织已经在仓库上运行代码搜索或 RAG 索引,将其公开为 MCP 工具,以便 Claude 查询它而不是直接读取文件

参见服务器管理或端点管理的设置了解平台团队如何集中执行这些设置。

在会话开始时推荐正确的插件

一旦约定存在于插件中,在树中不熟悉的区域启动 Claude 的队友就没有关于该区域所有者维护哪个插件的信号。SessionStart 钩子可以弥合这一差距,因为钩子打印到 stdout 的任何内容都会在第一个提示之前添加到 Claude 的上下文中。

例如,你可以编写一个脚本,从钩子输入中读取启动目录,在提交到仓库的路径到插件映射中查找它,并打印建议供 Claude 在其第一个回复中传达。参见使用钩子自动化工作流编写和注册钩子。

整合在一起

下面的组合配置使用 monorepo 布局。相同的文件适用于大型单树中的任何子目录。项目设置仅从你启动 Claude 的目录加载,因此每个子目录的 .claude/settings.json 必须是自包含的,而不是分层在根文件上。

该示例将 worktreeadditionalDirectoriesRead 拒绝规则提交在 .claude/settings.json 中,以便 packages/api/ 中的每个开发者获得相同的兄弟访问权限、稀疏路径和排除项。以下是 packages/api/ 的已提交按区域设置:

{
  "worktree": {
    "sparsePaths": [
      ".claude",
      "packages/api",
      "packages/shared"
    ],
    "symlinkDirectories": [
      "node_modules"
    ]
  },
  "permissions": {
    "additionalDirectories": [
      "../shared"
    ],
    "deny": [
      "Read(./**/dist/**)",
      "Read(./**/build/**)"
    ]
  }
}

因为此会话从 packages/api/ 启动,兄弟包的 CLAUDE.md 文件已经在范围之外,所以这里不需要 claudeMdExcludes。如果你也从根目录启动会话,请将其添加到仓库根目录的 .claude/settings.local.json 中。

additionalDirectories 条目在你直接从 packages/api/ 启动 Claude 时适用。在此会话创建的工作树内,工作目录是工作树根目录,因此此设置文件不会加载。兄弟包在工作树内无需它即可访问,但拒绝规则需要在仓库根目录的 .claude/settings.json 中有第二个副本,以便工作树会话可以获取它们,如工作树设置说明所述:

{
  "permissions": {
    "deny": [
      "Read(./**/dist/**)",
      "Read(./**/build/**)"
    ]
  }
}

设置完成后,仓库具有以下布局:

monorepo/
  CLAUDE.md
  .claude/settings.json                           # deny rules for worktree sessions
  packages/
    api/
      CLAUDE.md
      .claude/settings.json                       # worktree, additionalDirectories, deny rules
      .claude/skills/api-testing/SKILL.md
    web/
      CLAUDE.md
      .claude/skills/component-patterns/SKILL.md
    shared/
      CLAUDE.md

使用此设置,从 packages/api/ 启动 Claude:

  • 加载根 CLAUDE.md 和 packages/api/CLAUDE.md,跳过 packages/web/CLAUDE.md
  • 可以读取和编辑 packages/api/packages/shared/ 中的文件
  • 跳过 packages/api/dist/build/ 下的构建输出读取
  • api-testing 技能按需可用
  • 创建包含 .claude/packages/api/packages/shared/ 和根级文件的工作树,拒绝规则从根设置文件应用到整个工作树

限定和计划跨包更改

上述配置控制 Claude 看到的内容。当单个更改涉及多个包时,例如更新共享类型及其所有调用点,你如何限定和排序任务也会影响结果。

两种技术有助于保持跨包更改的一致性:

  • 在一个会话中给 Claude 完整的更改:将共享编辑及其调用点一起交给 Claude 保持每个编辑背后的决策一致,而不是按包重新推导
  • 在编辑前将计划保存到文件先计划并要求 Claude 将计划写入仓库中的 markdown 文件。长时间的跨包会话会压缩其上下文,保存的计划在对话历史可能不复存在时仍然保留

后续步骤

配置就位后,你可以进行细化: