上一节我们把 Claude Code 的 Harness 拆成了七类机制:CLAUDE.md、Hooks、Skills、Plugins、LSP、MCP 和 Subagents。

本系列会优先展开最常用的前三层:CLAUDE.md、Hooks 和 Skills;其余四层放在后续扩展部分介绍。这一篇先处理第一层,并补上一个不属于扩展机制、却直接决定运行边界的基础配置:settings.json

这七类机制解释了 Claude Code 的能力从哪里来,但真正开始使用时,最先需要掌握的通常只有两个入口:

  • settings.json 决定 Claude Code 可以怎样工作,例如使用哪个模型、哪些命令可以直接执行、哪些文件禁止读取;
  • CLAUDE.md 告诉 Claude 在这个项目里应该怎样工作,例如项目约定、测试命令、架构边界和验收标准。

一个管理运行边界,一个提供长期上下文。把这两个文件写对,比堆叠复杂插件更能直接改善 Claude Code 的日常表现。

一、settings.json:配置 Claude Code 的运行边界

settings.json 是 Claude Code 的结构化配置文件。权限、模型、环境变量、Hooks、插件和沙箱等配置都可以写在这里。[1]

它与 CLAUDE.md 的差别很重要:

文件 主要作用 内容性质 典型问题
settings.json 配置工具、权限和运行行为 机器读取的 JSON “这条命令是否允许执行?”
CLAUDE.md 提供项目上下文和工作规则 模型读取的 Markdown “这个项目要求怎样修改和验证?”

如果某件事必须被技术上阻止,不要只在 CLAUDE.md 里写“禁止这样做”。CLAUDE.md 属于模型上下文,并不是强制访问控制;真正的安全边界应该放在权限规则、沙箱或 Hook 中。[2][3]

1. Claude Code 的四层配置

Claude Code 的配置不是只有一个文件,而是按使用范围分为四层:[1]

范围 典型位置 适合保存 是否共享
Managed 系统级 managed-settings.json、注册表或服务端策略 组织安全策略、合规要求、最低版本 由管理员统一下发
User ~/.claude/settings.json 个人模型偏好、通知、所有项目通用的工具权限
Project 项目内 .claude/settings.json 团队共享的权限、Hooks、插件和项目配置 是,通常提交到 Git
Local 项目内 .claude/settings.local.json 本机路径、个人实验和只对当前项目生效的覆盖项 否,通常加入 .gitignore

Windows 中的 ~/.claude 对应 %USERPROFILE%\.claude

同一个普通配置项出现在多个范围时,优先级依次是:

Managed > 命令行参数 > Local > Project > User

不过,权限规则不能简单理解成“高优先级覆盖低优先级”。各层权限会合并,并按 denyaskallow 的顺序判断;任意一层的 deny 都不能被另一层的 allow 抵消。[1][3]

这套结构解决的是“谁应该控制什么”:

  • 个人偏好放 User,不污染团队仓库;
  • 团队共识放 Project,让每个成员得到相同配置;
  • 机器差异放 Local,避免把本机路径提交到 Git;
  • 不允许绕过的安全规则放 Managed。

2. 一份可用的项目级配置

下面是一份偏保守的 .claude/settings.json 示例:

{
  "$schema": "https://json.schemastore.org/claude-code-settings.json",
  "model": "claude-sonnet-4-6",
  "permissions": {
    "allow": [
      "Bash(npm run lint)",
      "Bash(npm run test *)"
    ],
    "ask": [
      "Bash(git push *)"
    ],
    "deny": [
      "Read(./.env)",
      "Read(./.env.*)",
      "Read(./secrets/**)",
      "Bash(rm -rf *)"
    ]
  }
}

这段配置做了四件事:

  1. $schema 为支持 JSON Schema 的编辑器提供自动补全和字段校验;
  2. model 设置默认模型,临时切换仍可使用 /model
  3. allow 只放开明确、可验证的常用命令;
  4. ask 保留高影响操作的人工确认,deny 阻止敏感文件和明显危险的命令。

这里没有直接允许所有 BashWritegit *。权限规则越宽,确认次数确实越少,但误操作和提示词注入的影响范围也越大。更稳妥的方式是从最小权限开始,把反复确认且在当前环境中确实安全的命令逐条加入允许列表。

还要注意两个细节:

  • 标准 JSON 不支持 // 注释,正式配置文件中不要照搬带注释的 JSON 示例;
  • Bash 字符串规则不是完整的安全沙箱,复杂命令可能通过变量、重定向或其他程序间接产生副作用。高风险环境还应启用沙箱或组织级策略。[3]

草稿中原有的 autoCompactThreshold 并不是当前官方 settings.json 的公开配置项。Claude Code 会自动管理上下文压缩;需要主动压缩时使用 /compact,需要清空无关上下文时使用 /clear。[4]

3. 修改后何时生效

Claude Code 会监听配置文件变化。权限、Hooks 等大多数设置修改后会在当前会话中重新加载;model 等少数设置需要通过对应命令切换,或在下一次启动时生效。[1]

不确定某个字段是否有效时,可以按下面的顺序检查:

  1. 在配置中加入官方 $schema
  2. 查看编辑器的字段提示;
  3. 运行 claude doctor 检查无效配置;
  4. 回到官方 Settings 文档确认当前版本是否支持该字段。

二、CLAUDE.md:把项目共识交给每一次会话

每次启动 Claude Code 都会获得一个新的上下文窗口。模型不会天然记得上一个会话里你解释过的项目约定,CLAUDE.md 的作用就是把这些长期有效的信息稳定带入新会话。[2]

适合写进 CLAUDE.md 的内容通常包括:

  • Claude 无法从代码中可靠推断的构建、测试和检查命令;
  • 与语言默认习惯不同的代码风格;
  • 项目特有的架构边界和技术决策;
  • 分支、提交、PR 和代码审查约定;
  • 环境中的非显然限制;
  • 反复出现的踩坑和禁止事项;
  • 完成任务时必须提供的验证证据。

不适合写进去的内容包括:

  • 读取仓库就能得到的信息;
  • 语言和框架的常识;
  • 经常变化的进度或临时任务;
  • 大段 API 文档和逐文件说明;
  • “写出高质量代码”这类无法验证的空泛要求。

一个简单的判断标准是:

删掉这一行,Claude 是否更容易在后续会话中犯错?

如果答案是否定的,这一行大概率不必占用每次会话的上下文。[4]

1. CLAUDE.md 可以放在哪里

当前 Claude Code 支持组织、用户、项目、本地和目录级指令:[2]

范围 路径 作用 适合写什么
组织级 系统目录中的 CLAUDE.md 组织内统一生效 公司编码规范、安全和合规要求
用户级 ~/.claude/CLAUDE.md 你的所有项目 个人工作习惯、通用沟通偏好
项目级 ./CLAUDE.md./.claude/CLAUDE.md 当前项目和团队 架构、命令、规范、工作流
本地级 ./CLAUDE.local.md 当前项目、仅本机 本地测试数据、个人沙箱地址
目录级 子目录中的 CLAUDE.md 读取该目录文件时按需加载 模块特有约定和局部限制

CLAUDE.local.md 应加入 .gitignore。需要团队共享的项目级 CLAUDE.md 则应该提交到 Git,让规则和代码一起接受审查。

2. 多层文件是组合加载,不是简单覆盖

草稿中“文件夹级 > 项目级 > 全局级”的说法容易让人误以为只有最具体的一层生效。实际行为是:Claude Code 会把发现的文件组合进上下文,而不是像 CSS 一样用下级文件彻底覆盖上级文件。[2]

假设从 repo/services/payment/ 启动 Claude Code,它会沿目录向上查找相关指令:

~/.claude/CLAUDE.md
repo/CLAUDE.md
repo/services/CLAUDE.md
repo/services/payment/CLAUDE.md
repo/services/payment/CLAUDE.local.md

范围更广的内容先出现,离当前工作目录更近的内容后出现。当前工作目录以下的 CLAUDE.md 不会全部在启动时加载;Claude 读取对应子目录中的文件时,才会加载那里的指令。

后出现不等于能够可靠消除冲突。官方明确提醒:如果不同文件中的规则互相矛盾,Claude 可能任意选择其中一条。因此,正确做法不是依赖“优先级”制造覆盖关系,而是避免让多层指令互相冲突。

3. CLAUDE.md 与强制规则的边界

CLAUDE.md 会影响模型判断,但不能保证每条指令都百分之百执行。下面三句话看起来相似,约束强度却完全不同:

- 不要修改数据库迁移文件。
{
  "permissions": {
    "deny": [
      "Edit(./migrations/**)"
    ]
  }
}
PreToolUse Hook 检查目标路径,命中 migrations/ 时拒绝写入。

第一种是上下文提示,适合表达工作约定;后两种才是执行层约束。凡是涉及生产环境、密钥、迁移文件和不可逆操作,都不应只依赖 Markdown 中的一句提醒。

三、怎样写一份真正有用的 CLAUDE.md

CLAUDE.md 没有强制模板。Markdown 语法不是难点,难点是只留下能改变 Claude 行为的内容。

1. 两种官方入口

在项目根目录启动 Claude Code 后运行:

/init

/init 会分析当前代码库,生成一份项目级 CLAUDE.md 起点;如果文件已经存在,它会提出改进建议,而不是直接覆盖。项目已有构建脚本、测试和目录结构时,生成结果通常更有参考价值。[2]

需要查看当前会话加载了哪些指令文件时运行:

/memory

/memory 可以列出并打开 CLAUDE.mdCLAUDE.local.md.claude/rules/ 和 Auto Memory。修改后建议在新会话中检查加载结果,避免把“文件已经保存”误当成“当前上下文已经按预期更新”。

2. 一份项目级示例

下面这份示例刻意保持简短,并把每条规则写成可以观察或验证的动作。命令和目录只是示例,不能原样复制到所有项目。

# Project overview

- This is a Node.js 22 and TypeScript 5 service managed with pnpm.
- HTTP handlers live in `src/api/`; business rules belong in `src/domain/`.
- Keep transport, domain, and persistence logic in their existing layers.

## Common commands

- Install dependencies: `pnpm install`
- Run one test file: `pnpm test -- <test-file>`
- Type-check: `pnpm typecheck`
- Lint changed code: `pnpm lint`

## Workflow

- Before editing, inspect the relevant implementation, tests, and call sites.
- For bug fixes, add or update a test that reproduces the failure.
- Prefer the smallest change that satisfies the request.
- Do not refactor unrelated code or reformat untouched files.

## Constraints

- Do not edit files under `migrations/`.
- Do not add or upgrade dependencies without asking first.
- Do not change public API response fields without updating `docs/api.md`.

## Completion criteria

- Run the narrowest relevant tests after each change.
- Before finishing, run `pnpm typecheck` and `pnpm lint`.
- Report changed files, commands executed, and any checks that could not run.

这份文件包含五类信息:

  1. 项目是什么:只写模型无法稳定推断的技术和架构边界;
  2. 命令怎么跑:给出可复制的构建和验证命令;
  3. 任务怎么做:规定修改前、修改中和修改后的工作流程;
  4. 什么不能碰:写清依赖、迁移和公开接口等边界;
  5. 怎样算完成:把“完成”转换成测试、类型检查和结果汇报。

标题用于分组,列表用于表达独立规则,反引号用于标记命令和路径。相比长段落,这种 Markdown 结构更容易被人维护,也更容易被模型扫描。

3. 把空话改成可验证规则

模糊写法 更有效的写法
保持代码整洁 不要重构或格式化与当前任务无关的文件
做好测试 Bug 修复必须增加回归测试,并运行受影响模块的测试
遵循项目架构 HTTP handler 只负责协议转换,业务规则放在 src/domain/
注意安全 不读取 .env*,不在日志中输出 token 和用户凭据
完成后检查一下 运行 pnpm typecheckpnpm lint,并汇报命令结果

越具体的规则越容易验证,也越容易在失效时定位原因。

4. 向优秀实践学习,但不要整份照抄

Claude Code 作者 Boris Cherny 公开分享过一种很实用的维护方式:团队把 CLAUDE.md 提交到 Git;Claude 在项目中犯错,或代码审查暴露出它本应知道的规则时,就把结论补进文件。这样,单次纠正会变成后续所有会话都能复用的项目知识。[5]

另一个广泛传播的案例是社区项目 andrej-karpathy-skills。它不是 Andrej Karpathy 本人发布的官方配置,而是维护者根据 Karpathy 对 LLM 编程问题的观察整理出的四条原则:[6]

  1. 编码前先暴露假设和不确定性;
  2. 用最少的代码解决已经提出的问题;
  3. 只修改任务直接涉及的范围;
  4. 把任务改写为可以验证的成功标准。

这些原则值得借鉴,但不应成为每个仓库都复制一遍的长篇宣言。更有效的做法是把它们改写成项目动作,例如:

## Change discipline

- If the request has multiple plausible interpretations, ask before editing.
- Every changed line must be traceable to the requested task.
- For a bug fix, first add a failing regression test, then make it pass.

通用原则只有在落到当前仓库的命令、目录和验收标准上时,才会真正改善结果。

5. 把维护变成固定循环

CLAUDE.md 不应该一次写完后永久不动。可以在下面几种事件发生时更新:

触发事件 处理方式
Claude 第二次犯同类错误 把原因和正确动作写成一条具体规则
代码审查发现项目隐含约定 补充到项目级文件,并提交 Git
命令、目录或架构发生变化 在同一个 PR 中更新对应说明
某条规则长期没有实际作用 删除,避免稀释重要指令
文件接近 200 行 拆到目录级规则、路径规则或 Skill
两条规则互相矛盾 删除旧规则,保留唯一事实来源

Anthropic 当前建议单个 CLAUDE.md 尽量控制在 200 行以内。这个数字不是硬限制,而是上下文成本和遵循度的经验边界:文件会被完整加载,越长越容易让真正重要的规则埋在噪声里。[2]

四、Auto Memory:Claude Code 自己维护的项目笔记

如果说 CLAUDE.md 是你主动写给 Claude 的项目规则,那么 Auto Memory 就是 Claude 在工作过程中为后续会话保存的笔记。

二者是互补关系,不是“第一优先级”和“第二优先级”的简单关系:[2]

维度 CLAUDE.md Auto Memory
谁写 用户和团队 Claude
主要内容 指令、约定和边界 Claude 发现的经验、偏好和模式
共享范围 可提交 Git,团队共享 当前机器上的仓库记忆
加载方式 相关文件完整加载 MEMORY.md 的前 200 行或 25 KB 启动时加载
适合保存 “必须怎样做” “上次发现了什么”

Auto Memory 需要 Claude Code v2.1.59 或更高版本,当前默认开启。可以用下面的命令检查版本:

claude --version

在会话中输入 /memory 可以开启或关闭 Auto Memory,也可以打开它的目录。还可以在项目配置中显式关闭:

{
  "autoMemoryEnabled": false
}

1. Auto Memory 存在哪里

每个仓库默认拥有一个独立目录:

~/.claude/projects/<project>/memory/
├── MEMORY.md
├── debugging.md
├── api-conventions.md
└── ...

MEMORY.md 是简短索引。它的前 200 行或前 25 KB(以先达到者为准)会在会话开始时加载;更详细的内容可以放进 debugging.mdapi-conventions.md 等主题文件,由 Claude 在需要时读取。[2]

同一 Git 仓库的不同子目录和 worktree 会共享这份 Auto Memory,但不同机器和云端环境不会自动同步。

2. 它会记住什么

Auto Memory 没有草稿中 userfeedbackprojectreference 四种固定类型。官方当前描述的是更灵活的项目知识,例如:

  • 构建和测试命令;
  • 调试过程中发现的非显然原因;
  • 架构和接口约定;
  • 代码风格偏好;
  • 反复出现的工作流习惯;
  • 你明确要求 Claude 记住的项目事实。

Claude 不会在每个会话中机械地写入内容,而是判断某条信息是否可能对未来任务有用。

3. Auto Memory 仍然需要审查

Auto Memory 是普通 Markdown 文件,可以随时查看、修改或删除。这一点很重要:由模型总结的经验可能过时,也可能把一次性的现象误判为长期规律。

维护时可以采用下面的分工:

  • 团队必须遵守的稳定规则,人工确认后写入 CLAUDE.md
  • Claude 自己发现、仍需观察的经验,暂时留在 Auto Memory;
  • 已经失效的调试结论及时删除;
  • 涉及密钥、令牌和个人隐私的信息不要存入记忆文件。

五、自建参考文档:让上下文按需展开

随着项目变大,不可能把所有品牌规范、API 约定和业务知识都塞进根目录的 CLAUDE.md。更合理的结构是让根文件只保留入口和路由,详细内容放在专项文档中。

例如:

docs/
├── brand-visual.md
├── copywriting-style.md
└── api-conventions.md

然后在 CLAUDE.md 中写清触发条件:

## Reference documents

- Before changing colors, typography, or spacing, read `docs/brand-visual.md`.
- Before writing UI copy or user-facing messages, read `docs/copywriting-style.md`.
- Before adding or changing an API, read `docs/api-conventions.md`.

这里故意给路径加了反引号,而没有写成 @docs/api-conventions.md

原因是 @path 属于导入语法。被导入的文件会在启动时展开到上下文中,它适合拆分和组织文件,但不会节省启动上下文。如果目标是真正的渐进式披露,应让 Claude 在触发条件出现时主动读取文档,或使用官方的路径规则和 Skill。[2]

1. 用 .claude/rules/ 按文件路径加载

当规则与明确的代码路径对应时,可以创建 .claude/rules/api.md

---
paths:
  - "src/api/**/*.ts"
  - "tests/api/**/*.test.ts"
---

# API rules

- Read `docs/api-conventions.md` before changing an endpoint.
- Validate all external input at the transport boundary.
- Keep the public error response compatible with the existing schema.

只有 Claude 处理匹配路径时,这份规则才会进入上下文。它比在根 CLAUDE.md 中长期加载所有 API 细节更节省空间,也比单纯希望模型“想起来再读”更可靠。[2]

2. 用目录级 CLAUDE.md 管理模块约定

如果某个子系统拥有独立边界,可以把规则放在模块目录:

src/
└── payment/
    ├── CLAUDE.md
    ├── service.ts
    └── service.test.ts

当 Claude 读取 src/payment/ 下的文件时,这份 CLAUDE.md 会按需加载。它适合支付、认证、数据迁移等具有明确目录边界的模块。

3. 用 Skill 承载复杂知识和流程

如果内容不仅是一组规则,还包含完整步骤、脚本或参考资料,更适合做成 Skill。例如“发布版本”“处理线上事故”“新增 API”都不是每次会话必须加载的上下文,可以在任务需要时再调用。

可以用一个简单判断选择承载方式:

内容 更适合放在哪里
每个任务都要遵守的少量原则 根目录 CLAUDE.md
只对某个模块生效的规则 子目录 CLAUDE.md
只对特定文件路径生效的规则 .claude/rules/
需要按需查阅的详细规范 docs/,由规则指向
多步骤、可复用的专业工作流 Skill
必须强制执行的安全限制 settings.json、Sandbox 或 Hook

参考资料

  1. Claude Code Docs:Claude Code settings
  2. Claude Code Docs:How Claude remembers your project
  3. Claude Code Docs:Configure permissions
  4. Claude Code Docs:Best practices for Claude Code
  5. InfoQ:Inside the Development Workflow of Claude Code's Creator
  6. GitHub:Karpathy-Inspired Claude Code Guidelines
Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐