最近把 Claude Code 从“裸奔”状态升级成了一套正经的配置体系,前后折腾了两个晚上,最大的感受是:这工具默认状态能用,但你要是不把配置捋明白,每次开新会话都要重新跟它解释项目背景、技术栈、代码规范,效率低到怀疑人生。后来我把配置拆成三层来看,一切就顺了,这三层就是标题里说的 settings.json、CLAUDE.md 和 memory。很多刚接触的人会困惑:这三个东西到底什么区别?优先级谁高谁低?改哪个文件干什么事?这篇文章就把我实际调试过程中踩过的坑和最终沉淀下来的方案完整记录下来,给那些正在用或者准备用 Claude Code 的朋友一个可以直接抄作业的参考。
先说结论:settings.json 管的是“能不能做”,CLAUDE.md 管的是“该怎么做”,memory 管的是“记得怎么做”。理解了这个分工,你就不会被一堆文档绕晕。
1. 先把三个配置文件的关系理清楚
1.1 三张配置表解决的是同一个问题的三个侧面
拿一个真实团队来类比。settings.json 相当于公司的 IT 管理制度,规定谁能访问哪台服务器、哪些操作需要审批、哪些命令被禁止,它是运行环境和行为边界的定义。CLAUDE.md 则相当于项目组的操作手册,告诉新来的同事这个项目是干什么的、代码放哪、构建命令是什么、有没有什么历史遗留的坑。memory 则像老员工脑子里的经验积累,他记得上次那个线上事故是怎么修复的、这个客户偏好什么风格、那个模块为什么当初那么设计。
这三者缺一不可。只配 settings.json,Claude 知道能执行什么命令,但不知道你的项目要什么;只写 CLAUDE.md,它知道项目规则,但每次会话都要重新加载;只有 memory 而没有前两者,记忆没有约束,容易跑偏。我见过不少人的配置只有 settings.json,CLAUDE.md 是空的,memory 也没概念,结果就是 Claude Code 像一台配置完好的服务器,却没有任何业务逻辑在上面跑。
1.2 一个会话里三个文件是怎么被读取的
我实测下来的加载顺序是这样的:启动 Claude Code 时,它先读取 settings.json 确定运行环境,包括 API 密钥、模型选择、权限规则、钩子脚本;然后加载各层级的 CLAUDE.md,把这些内容作为会话的系统指令注入,Claude 在回答任何问题之前就“知道”了你的项目背景和规则;memory 则是在整个对话过程中动态累积的,它既包括 JSON 配置文件和 CLAUDE.md 里静态写入的长期记忆,也包括会话进行中你明确让它记住的内容。
理解这个顺序很重要,因为它决定了你的配置策略。你在 settings.json 里修改的环境变量,会在 CLAUDE.md 加载之前生效;你在 CLAUDE.md 里写的规则,会先于你对话中的临时指令被遵守——但如果你在对话里明确说“这次忽略 CLAUDE.md 里的某某规则”,它的优先级又会更高。所以不要指望着用一个配置文件解决所有问题,三层配置分开管理,才是长期可维护的姿势。
1.3 推荐的上手顺序
如果你现在是一个新项目要从零配置,我建议按这个顺序来。第一,先把 settings.json 搞定,把环境变量、权限、模型选择配置好,保证 Claude Code 能在你的终端里稳定跑起来。第二,写一份项目级的 CLAUDE.md,不用追求大而全,先把项目概述、技术栈、常用命令、代码规范写进去,这几项就能让 Claude 的回复质量上一个台阶。第三,随着使用慢慢沉淀 memory,把你在对话中反复强调的偏好、踩过的坑、团队的决策记录进去。
不少新手一上来就照着网上的大而全模板写了几百行 CLAUDE.md,结果 Claude 反而被各种互相矛盾的规则搞糊涂。我的经验是:配置是迭代出来的,不是一次写出来的。先跑起来,再加规则,遇到问题再改规则,这才是正路。
2. settings.json:全局行为的控制中心
2.1 配置文件到底放在哪里
settings.json 有两层:用户级和项目级。用户级的全局配置在~/.claude/settings.json,它影响你机器上所有项目里的 Claude Code 会话。项目级的配置在项目根目录下的.claude/settings.json,只对当前项目生效。两份文件都存在时,项目级配置会覆盖用户级配置里的同名项,这一点和 Git 的 local 配置覆盖 global 配置的逻辑是一样的。
我推荐的做法是:用户级 settings.json 只放跟账号、模型、全局权限相关的内容,比如 API Key 的环境变量、默认模型、允许全局执行的命令白名单。项目级 settings.json 则放跟项目相关的权限开关,比如这个项目允许 Claude 直接修改哪些目录下的文件、允许执行哪些包管理命令。如果你把项目特定的权限写进用户级配置,另一个项目可能也会用到,不小心就会造成权限越界。
2.2 值得你仔细看的几个配置项
{ "model": "claude-sonnet-4-20250514", "env": { "ANTHROPIC_API_KEY": "sk-xxxx", "ANTHROPIC_MODEL": "claude-sonnet-4-20250514", "ANTHROPIC_BASE_URL": "https://api.example.com" }, "permissions": { "allow": [ "Bash(npm run test)", "Read(~/Projects/MyApp/**)" ], "deny": [ "Bash(git push)", "Edit(.env)" ], "ask": [ "Bash(rm -rf **)" ] }, "hooks": { "PreToolUse": [ { "matcher": "Edit", "command": "node .claude/hooks/lint-check.js" } ] }, "includeCoAuthoredBy": false, "cleanupPeriodDays": 30 }上面这个 JSON 是我实际在用的一个精简版本,字段名可能会随版本更新变化,但核心思路不变。env是最常用的字段,用来设置环境变量,比如 API Key、模型名、API 网关地址。注意两个坑:一个是在 shell 里 export 的环境变量和 settings.json 里的env字段是两套体系,当 settings.json 里有值时,它会覆盖 shell 里同名的变量;另一个是env字段里不要写没有引号的注释,JSON 标准不允许注释,写错了整个文件都会解析失败。
permissions是权限控制的重点。它分成 allow(允许)、deny(禁止)、ask(询问)三类。Claude 执行任何敏感操作之前,会先检查这个列表。如果不在任何列表里,默认会弹窗问你“是否允许”。如果你觉得每次都被打断,就把那些日常必须的命令和文件路径加进 allow;如果某些操作绝对不想让 Claude 做,就加进 deny。优先级是 deny 最高,allow 次之,ask 最后。也就是说即使某条规则同时出现在 allow 和 ask 里,只要它在 deny 里,就一定会被拒绝。
有人可能会问,为什么不直接把所有命令都加进 allow,省得烦?这里我要提醒一句:Claude Code 的权限设计本质上是安全边界,特别是Bash类操作,一旦允许了 rm、git push、生产环境部署这类命令,它可能在你没来得及反应的时候执行完。我个人的底线是:读操作放开,写操作按目录控制,破坏性命令永远放在 ask 里。
2.3 hooks 钩子机制的作用
hooks 是 settings.json 里容易被忽视但又特别强大的能力。它的作用是在 Claude 执行 Tool 调用的前后触发你自定义的命令。
举个例子,我在项目配置里加了一个 hook:在 Claude 准备修改代码(Edit 操作)之前,跑一遍 ESLint 规则检查,如果代码风格有问题,就阻止它的修改。这等于在 Claude 和你的代码库之间加了一道自动化质检。我用的心思是,把这次检查的脚本放在项目里的.claude/hooks/目录下,让团队所有人都能共用这个质量门槛。
另一个实用场景是 PostToolUse。Claude 执行完命令之后,把输出结果追加到日志文件,方便你事后复盘它做了什么、为什么这样做。调过复杂任务的人应该深有体会:对话轮次多了之后,你根本记不清它中间执行了什么命令。有了钩子的日志,出了问题就能快速定位是哪一步操作导致的。
2.4 第三方模型接入配置
现在圈子里的玩法早就不仅限于官方模型了。通过设置ANTHROPIC_BASE_URL和ANTHROPIC_MODEL这类环境变量,可以把 Claude Code 接到兼容 OpenAI/Anthropic 接口的第三方模型上,比如 DeepSeek、Qwen、GLM 等。社区里还有人做了 cc switch 这类便捷工具,专门用来快速切换不同的模型供应商。
我的建议是不要把模型相关的配置写死在用户级 settings.json 里。因为你会经常切换,写死就意味着每次切换都要编辑 JSON,非常容易出错。更优雅的方式是在 shell 配置文件里定义几个环境变量别名,或者干脆用 cc switch 这样的工具来管理多套供应商配置。如果确实要在 settings.json 里写,也尽量写成注释清楚、结构简单的形式,并且做好备份。
3. CLAUDE.md:项目规则的载体
3.1 CLAUDE.md 的本质是“给 Claude 的入职手册”
settings.json 告诉我怎么跑,那么 CLAUDE.md 告诉它“你在这个项目里是什么角色”。每一个 Claude Code 会话启动时,它会自动读取项目根目录下的 CLAUDE.md,并把它当作最高优先级的上下文进行理解。这相当于每次面试之前,先给候选人一份公司手册,让他大概了解业务方向和工作规则。
CLAUDE.md 在官方设计里有多个层级:用户级(~/.claude/CLAUDE.md)存放个人偏好,比如你希望 Claude 用中文回复、注释风格用 JSDoc 等等;项目级(项目根目录的CLAUDE.md)存放项目相关的背景和规则;本地私有级(CLAUDE.local.md)存放只对你自己生效、不想提交进版本库的内容。多层级之间会合并生效,项目级覆盖用户级,本地私有级再覆盖项目级。用 Git 管理项目时,CLAUDE.md 要提交到仓库里,这样团队成员都能共享同一套规则;CLAUDE.local.md 则加入 .gitignore。
3.2 一份可以直接抄下来的模板
下面这个模板是我根据自己维护的几个项目总结出来的,删减了很多花哨的东西,只留核心。你可以拿去直接改:
# 项目名称:XXX 管理平台 ## 项目概述 这是一个面向小微企业的多租户订单管理系统。 前端使用 React + TypeScript + Vite,后端使用 Spring Boot + MySQL。 核心业务模块包括:订单、库存、对账、权限。 ## 常用命令 - 安装依赖:npm install - 启动开发服务:npm run dev - 运行测试:npm run test -- --watch - 构建生产包:npm run build - 数据库迁移:npx prisma migrate dev ## 代码风格约定 - 组件文件使用 PascalCase 命名,工具函数使用 camelCase。 - 所有接口调用必须经过 `src/api/` 下的封装模块,禁止在组件里直接 fetch。 - 注释使用中文,关键逻辑必须写明为什么这么实现。 - 新加的依赖必须说明用途,并同步更新 README。 ## 架构与目录说明 - `src/pages/`:页面级组件 - `src/components/`:可复用组件 - `src/store/`:状态管理 - `src/server/`:后端接口 ## 常见陷阱 - 订单号在创建后不可修改,任何涉及订单号的更新操作都要先确认是否有历史关联数据。 - 库存扣减必须在事务内执行,同时更新乐观锁版本号,防止并发超卖。 - 导出报表的接口耗时较长,前端要处理超时重试,不要盲目加大 axios timeout。这个模板的核心逻辑是:让它知道你项目的背景(概述)、怎么跑(命令)、怎么写(风格)、在哪写(架构)、别踩什么(陷阱)。这几项内容能覆盖 Claude 日常协作 80% 以上的需求。
3.3 规则书写的两个核心原则
第一个原则是“具体到可以被执行”,第二个是“给正面例子而不是抽象口号”。
“要写出高质量代码”这种话就是典型的抽象口号,Claude 无法把“高质量”变成具体的操作,写了一句等于没写。但“所有接口调用必须通过 src/api/ 封装,禁止在业务代码里直接 fetch”就是一条可执行规则,Claude 在写代码时会真的去检查自己有没有违反。
我在实际过程中发现,规则里配上正面和反面的例子效果最好。比如你可以写“建议使用 async/await 而不是 .then 链式调用,反例见本项目 git history 中重构前的提交记录”。Claude 能根据这个例子判断自己的写法是否符合预期。
还有一点:CLAUDE.md 会随着项目演进而过时。我见过有人写了一年没更新过的 CLAUDE.md,里面还写着已经废弃的构建命令,结果 Claude 每次跑命令都报错,它还一脸茫然地重试。我的习惯是每两周左右翻一次 CLAUDE.md,把过时的命令、改动的架构、新踩的坑同步进去。这个动作看起来不起眼,却是配置体系长期有效的重要保障。
3.4 利用 @ 语法搭建项目知识库
CLAUDE.md 还有一个容易被忽略的扩展能力:在文件里通过@语法引用其他文档。比如在 CLAUDE.md 里写:
## 接口设计规范 详细接口设计规范见 @docs/api-design.md ## 数据库设计 ER 图和字段说明见 @docs/database.md这样 Claude 会自动加载docs/目录下的相应文档作为上下文。它的意义在于:你不需要把所有内容都塞进一个 CLAUDE.md 文件,而是可以像维护技术文档一样,把规则、设计文档、说明文档分门别类放在项目里,然后在 CLAUDE.md 里建立索引。当 Claude 需要相关上下文时,再通过@语法按需引入,避免了单个文件过于臃肿导致上下文被稀释。
实测下来,把 CLAUDE.md 保持在 300 行以内,剩余细节全部用@引用,Claude 的理解准确率最高。超过 500 行以后,规则之间的优先级和冲突就开始变得频繁,Claude 会偶尔遗漏某些条款。
4. memory:跨会话记忆的正确姿势
4.1 记忆到底存在哪
很多人一听到 memory,第一反应是“是不是有一个数据库或者向量索引”。实际在 Claude Code 的体系里,记忆的承载形式主要是文件:用户级 CLAUDE.md、项目级 CLAUDE.md、以及你在对话中明确要求记录下来的内容。它更像是一个结构化的“长期记忆仓库”,而不是一个自动学习的向量库。如果你需要语义检索级别的记忆能力,可以借助 MCP 记忆服务器或者维护独立的 knowledge 目录,但那属于扩展玩法,入门阶段先把文件层次的记忆用明白就行。
我把 memory 拆成三种类型:偏好记忆、项目记忆、决策记忆。偏好记忆记录你喜欢什么,比如“回复用中文”“函数注释必须写清参数说明”;项目记忆记录项目的背景和约定,本质上就是项目级 CLAUDE.md;决策记忆记录的是“为什么”,比如当初为什么要用 A 方案而不是 B 方案,它可以帮助 Claude 在未来面临相似选择时做出和你一致的判断。
4.2 三层记忆目录搭建方案
我给自己设定的三层记忆结构是这样的:
第一层是用户级~/.claude/CLAUDE.md,只放跨项目的通用偏好。比如语言偏好、编码风格偏好、常用工具的配置习惯。因为它是全局的,所以内容要克制,不能把项目特有的东西放进去。
第二层是项目级 CLAUDE.md 加上项目内的docs/claude/目录。项目 CLAUDE.md 放高度浓缩的核心规则和索引,docs/claude/目录放完整的架构决策记录、踩坑记录、API 文档、会议总结之类的详细内容。通过@语法在 CLAUDE.md 里按需引用。
第三层是运行期的隐性记忆。当我在对话里跟 Claude 说“记住:这个项目的部署流程是……”,它会在当前会话内记忆。为了让这个记忆在下一次会话也有效,我养成了一个习惯:每次会话结束前,把有效的结论追加到项目 CLAUDE.md 或 docs 目录下的对应文档里。这一步很多人会忽略,相当于你让 Claude 记住了,但没让它形成长期记忆,下次还是得重新讲。
4.3 知识库文件的维护节奏
记忆体系不是一次搭完就完事的。我给自己的维护节奏是:日常随手记,每周整理一次。日常中遇到 Claude 反复问同样的问题,或者我在对话中纠正了它某个错误认知,就顺手记到临时文件里。每周抽十分钟,把这些零散的记录整理进 docs/claude 和 CLAUDE.md。
这样做的好处很明显:随着时间推移,Claude 对你的项目理解会越来越深,新开一个会话也能带着之前的“经验”进入状态,而不是每次冷启动。这和你带一个新同事的曲线差不多,最开始需要反复交代,越到后面越省心。
4.4 记忆安全:别什么都往里面写
记忆体系里最容易忽略的是安全问题。我见过有人把数据库密码、云服务密钥直接写进 CLAUDE.md,然后推送到公共仓库,这种事故一旦发生就是灾难。凡是密钥、Token、内网地址,一律不要出现在记忆文件里,建议通过环境变量注入。
另外,最近圈子里讨论比较多的 AgentPoison 这类研究表明:攻击者可以通过向智能体的记忆或知识库中投毒内容,诱导它在后续决策中按照攻击者意图行动。也就是说,如果你的 CLAUDE.md 或知识库里有一些恶意或误导性内容,Claude 有可能把这些内容当作可信规则执行。所以我给自己定了一条规矩:所有写进记忆体系的内容必须是自己审核过的可信信息;如果是团队协作,别人修改 CLAUDE.md 后要先 review 再合入,不能任由不明来源的内容混进来。
5. 常见问题与排查技巧
5.1 配置不生效的排查清单
我遇到最多的反馈是“我改了 settings.json,但 Claude Code 根本没反应”。这里有一个排查顺序,按这个顺序走,能解决绝大部分问题。
第一,确认文件位置对不对。用户级配置必须在~/.claude/目录下,项目级配置必须在当前工作目录的.claude/目录下或项目根目录下。注意 Claude Code 启动时的当前目录,你以为是项目根目录,实际上可能是在子目录里启动的,那么它加载的就不是你改的那份配置。
第二,确认 JSON 格式合法。settings.json 里多加了一个逗号、少了一个引号,整个文件都会被忽略,而且很多情况下报错信息并不显眼。可以用jq . ~/.claude/settings.json这类命令快速验证格式。
第三,确认配置项名称是否是当前版本支持的。Claude Code 升级频率很高,某些配置字段会改名或者迁移。我在升级后都会跑一个简单测试,看看claude --version和官方 changelog,如果发现配置项被废弃,及时更新。
第四,确认 CLAUDE.md 是否被正确加载。在会话里直接问 Claude:“CLAUDE.md 里写了些什么?”它如果答不上来或者答错了,说明加载顺序或文件位置有问题。我测试过,CLAUDE.md 的位置放错一级,加载结果就是完全不同的两份内容。
5.2 权限弹窗和多模型切换问题
权限弹窗太频繁是很常见的问题。解决办法是把自己日常允许的操作写进 settings.json 的 permissions.allow 列表。比如Bash(npm run dev)、Read(~/MyProject/**),注意权限规则的路径用 glob 通配符的时候要谨慎,写宽了就等于放开整个目录的读取权限。
多模型切换不生效的问题,十有八九是环境变量被某个位置的配置覆盖了。检查顺序是:系统环境变量 → shell 配置里的 export → settings.json 的 env 字段 → 命令行传入的参数。优先级从低到高,也就是说命令行参数最高。如果 cc switch 这种工具切了没生效,大概率是它的配置只改了 shell 环境变量,但 settings.json 里还写死了旧值。删掉 settings.json 里对应的 env 项,让外部变量透传进来,问题就解决了。
5.3 安装与 VSCode 集成相关
安装本身不复杂,通过 npm 全局安装@anthropic-ai/claude-code就行,前置条件是 Node.js 版本满足要求。macOS 和 Ubuntu 的安装步骤基本一致,但要注意 PATH 环境变量是否包含了 npm 全局安装目录。VSCode 集成则在插件市场搜索 Claude Code 插件,安装后在 IDE 里打开命令面板就能呼出 Claude Code 面板。VSCode 插件的配置和 CLI 共享同一套配置文件,你改 settings.json 和 CLAUDE.md 后,重启插件让配置生效即可。
如果是在 Ubuntu 这类 Linux 环境下遇到报错,我见过的最多的问题是 Node 版本太低。建议先node -v确认版本,低了就升级,不要直接硬跑。
5.4 我的几个避坑心得
最后说几个很难从官方文档里直接读到的东西。
一个是 CLAUDE.md 里写“中文要求”的细节。如果你想让它用中文回复,直接写“请用中文回复”就行,但如果你的项目里有大量英文技术术语,建议配套写一句“专业术语保留英文原文”,否则它可能会把 API、DTO、Repository 全都强行翻译成中文,看着非常别扭。
另一个是日志目录和输出量的问题。Claude Code 会在运行过程中产生大量的会话日志,默认情况下的自动清理周期也许并不适合你。我在~/.claude目录下见过好几个 G 的日志文件,如果你机器的磁盘空间紧张,记得在 settings.json 里设置cleanupPeriodDays或者定期手动清理。
还有一个是 hooks 脚本的运行权限。在 Linux 和 macOS 上,hook 指定的脚本如果没有可执行权限,Claude Code 会静默失败,看起来像是 hook 没配置成功,实际上只是缺了一个chmod +x。这个坑我踩过,排查了很久才发现是权限问题。
我自己的体会是,配置文件这东西,一次性搞大而全反而容易出错。先把 settings.json 和 CLAUDE.md 的最小功能跑通,再在日常使用中慢慢补 memory,等三轮迭代之后,你就能拥有一套完全贴合自己工作流的配置体系。那之后你再去对比刚上手时裸奔的体验,会明显感觉 Claude Code 像换了一个人在帮你干活。