Claude Code从入门到精通(3)-settings.json 与 CLAUDE.md
上一节我们把 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、插件和项目配置是通常提交到 GitLocal项目内.claude/settings.local.json本机路径、个人实验和只对当前项目生效的覆盖项否通常加入.gitignoreWindows 中的~/.claude对应%USERPROFILE%\.claude。同一个普通配置项出现在多个范围时优先级依次是Managed 命令行参数 Local Project User不过权限规则不能简单理解成“高优先级覆盖低优先级”。各层权限会合并并按deny、ask、allow的顺序判断任意一层的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 *) ] } }这段配置做了四件事$schema为支持 JSON Schema 的编辑器提供自动补全和字段校验model设置默认模型临时切换仍可使用/modelallow只放开明确、可验证的常用命令ask保留高影响操作的人工确认deny阻止敏感文件和明显危险的命令。这里没有直接允许所有Bash、Write或git *。权限规则越宽确认次数确实越少但误操作和提示词注入的影响范围也越大。更稳妥的方式是从最小权限开始把反复确认且在当前环境中确实安全的命令逐条加入允许列表。还要注意两个细节标准 JSON 不支持//注释正式配置文件中不要照搬带注释的 JSON 示例Bash 字符串规则不是完整的安全沙箱复杂命令可能通过变量、重定向或其他程序间接产生副作用。高风险环境还应启用沙箱或组织级策略。[3]草稿中原有的autoCompactThreshold并不是当前官方settings.json的公开配置项。Claude Code 会自动管理上下文压缩需要主动压缩时使用/compact需要清空无关上下文时使用/clear。[4]3. 修改后何时生效Claude Code 会监听配置文件变化。权限、Hooks 等大多数设置修改后会在当前会话中重新加载model等少数设置需要通过对应命令切换或在下一次启动时生效。[1]不确定某个字段是否有效时可以按下面的顺序检查在配置中加入官方$schema查看编辑器的字段提示运行claude doctor检查无效配置回到官方 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.mdCLAUDE.md没有强制模板。Markdown 语法不是难点难点是只留下能改变 Claude 行为的内容。1. 两种官方入口在项目根目录启动 Claude Code 后运行/init/init会分析当前代码库生成一份项目级CLAUDE.md起点如果文件已经存在它会提出改进建议而不是直接覆盖。项目已有构建脚本、测试和目录结构时生成结果通常更有参考价值。[2]需要查看当前会话加载了哪些指令文件时运行/memory/memory可以列出并打开CLAUDE.md、CLAUDE.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.这份文件包含五类信息项目是什么只写模型无法稳定推断的技术和架构边界命令怎么跑给出可复制的构建和验证命令任务怎么做规定修改前、修改中和修改后的工作流程什么不能碰写清依赖、迁移和公开接口等边界怎样算完成把“完成”转换成测试、类型检查和结果汇报。标题用于分组列表用于表达独立规则反引号用于标记命令和路径。相比长段落这种 Markdown 结构更容易被人维护也更容易被模型扫描。3. 把空话改成可验证规则模糊写法更有效的写法保持代码整洁不要重构或格式化与当前任务无关的文件做好测试Bug 修复必须增加回归测试并运行受影响模块的测试遵循项目架构HTTP handler 只负责协议转换业务规则放在src/domain/注意安全不读取.env*不在日志中输出 token 和用户凭据完成后检查一下运行pnpm typecheck和pnpm lint并汇报命令结果越具体的规则越容易验证也越容易在失效时定位原因。4. 向优秀实践学习但不要整份照抄Claude Code 作者 Boris Cherny 公开分享过一种很实用的维护方式团队把CLAUDE.md提交到 GitClaude 在项目中犯错或代码审查暴露出它本应知道的规则时就把结论补进文件。这样单次纠正会变成后续所有会话都能复用的项目知识。[5]另一个广泛传播的案例是社区项目andrej-karpathy-skills。它不是 Andrej Karpathy 本人发布的官方配置而是维护者根据 Karpathy 对 LLM 编程问题的观察整理出的四条原则[6]编码前先暴露假设和不确定性用最少的代码解决已经提出的问题只修改任务直接涉及的范围把任务改写为可以验证的成功标准。这些原则值得借鉴但不应成为每个仓库都复制一遍的长篇宣言。更有效的做法是把它们改写成项目动作例如## 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 MemoryClaude Code 自己维护的项目笔记如果说CLAUDE.md是你主动写给 Claude 的项目规则那么 Auto Memory 就是 Claude 在工作过程中为后续会话保存的笔记。二者是互补关系不是“第一优先级”和“第二优先级”的简单关系[2]维度CLAUDE.mdAuto 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.md、api-conventions.md等主题文件由 Claude 在需要时读取。[2]同一 Git 仓库的不同子目录和 worktree 会共享这份 Auto Memory但不同机器和云端环境不会自动同步。2. 它会记住什么Auto Memory 没有草稿中user、feedback、project、reference四种固定类型。官方当前描述的是更灵活的项目知识例如构建和测试命令调试过程中发现的非显然原因架构和接口约定代码风格偏好反复出现的工作流习惯你明确要求 Claude 记住的项目事实。Claude 不会在每个会话中机械地写入内容而是判断某条信息是否可能对未来任务有用。3. Auto Memory 仍然需要审查Auto Memory 是普通 Markdown 文件可以随时查看、修改或删除。这一点很重要由模型总结的经验可能过时也可能把一次性的现象误判为长期规律。维护时可以采用下面的分工团队必须遵守的稳定规则人工确认后写入CLAUDE.mdClaude 自己发现、仍需观察的经验暂时留在 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参考资料Claude Code DocsClaude Code settingsClaude Code DocsHow Claude remembers your projectClaude Code DocsConfigure permissionsClaude Code DocsBest practices for Claude CodeInfoQInside the Development Workflow of Claude Codes CreatorGitHubKarpathy-Inspired Claude Code Guidelines