1. 先把三大配置体系的分工搞清楚
Claude Code 这工具,怎么说呢,第一次用的时候很容易被它的“能干活”震撼到——命令行里敲几句,它就能自己读代码、跑命令、改文件。但用久了你会发现,真正决定这个工具是“聪明助理”还是“莽撞实习生”的,恰恰是那些不起眼的配置文件。
好多人上来就问“怎么让 Claude Code 更懂我的项目”,答案就藏在这三样东西里:settings.json、CLAUDE.md、memory。一句话总结它们的分工:settings.json 管的是“行为边界”,CLAUDE.md 管的是“工作准则”,memory 管的是“跨会话记忆”。三者各管一摊,又互相配合,缺一个都会让体验大打折扣。
先别急着改配置,我先说说我为什么特别推荐把这三样东西当成一个整体来看。市面上聊 Claude Code 配置的文章不少,但绝大多数只盯着某一个文件讲,结果就是你在 settings 里开了权限,却忘了在 CLAUDE.md 里告诉 Agent 你的代码规范;或者你费劲调好了项目记忆,重启一次会话又全忘了——其实是因为记忆文件放错了位置。这篇我就把三者的完整玩法串起来,不论你是刚装好 Claude Code 的新手,还是已经被 Agent 气到血压升高的老用户,都能找到对号入座的那一部分。
1.1 三条配置管的事完全不一样
先说settings.json。这个文件是 Claude Code 的运行时配置,相当于发动机的 ECU 调校,控制的是工具的“硬件参数”:模型选哪个、能不能自动执行命令、哪些目录不能碰、环境变量怎么传、hooks 怎么挂。你在这个文件里做的是“开关设置”,它决定的是 Claude Code 的“权限边界”和“运行模式”。
再说CLAUDE.md。这个名字容易被误解,其实是 Claude 的“项目说明书”,更像公司里的《员工手册》。你在里面写的是:这个项目是什么、代码风格怎么定、哪些命令不能用、遇到什么情况要先问而不是直接动手。它不是技术参数,而是给 Agent 的“行为准则”。Claude Code 每次启动、每次处理任务前都会自动读取这个文件,把它当作最高优先级的工作指引。
最后是memory。这个词在 Claude Code 里有两层含义:一层是指全局记忆文件(通常放在用户主目录下的~/.claude/CLAUDE.md),另一层是项目内的记忆目录(比如.claude/目录里存的各种长期状态)。它的核心作用是解决“会话失忆”的问题——新开一个会话,Claude Code 默认是不记得上一次聊了什么的,但通过记忆文件,你可以把关键信息“钉”住,让 Agent 跨会话地记住你的偏好、项目进展、历史决策。
1.2 为什么不能只靠一套配置打天下
很多人一开始图省事,只写一个settings.json把所有东西都往里塞,结果越写越乱。我见过有人把项目规范写进 settings 的env字段里,也见过有人试图用 CLAUDE.md 控制模型参数——方向全错了。
核心原因是它们的作用域和生效层级不同。settings.json是分层的:有用户级(~/.claude/settings.json)、项目级(.claude/settings.json)、本地级(.claude/settings.local.json),越靠后的越具体,能覆盖前面的配置。CLAUDE.md也有层级:全局的放在用户主目录,项目级的放在项目根目录,还有嵌套子目录的CLAUDE.md会被当作子项目的局部指南。memory则贯穿在会话上下文里,更像是一个自动维护的“便签本”。
打个比方:settings 是“宪法”,规定了什么能做;CLAUDE.md 是“部门规章”,规定了具体事情怎么做;memory 是“工作日志”,记着上次干到哪、负责人是谁。三者的配合关系是:settings 决定权限边界 → CLAUDE.md 在授权范围内做约束 → memory 保证这种约束能跨会话延续。
提示:如果你刚接触 Claude Code,建议先花 10 分钟把三者的文档各通读一遍,再动手改配置。顺序搞反了,后面排查问题会非常痛苦。
2. settings.json:运行时行为的“总开关”
2.1 文件放哪、优先级怎么算
先解决最基础的问题:settings.json 到底有几个、都在哪。官方设计的继承机制是这样的,按优先级从低到高排列:
- 用户级配置:
~/.claude/settings.json(Windows 下是C:\Users\<用户名>\.claude\settings.json) - 项目级配置:
<项目根目录>/.claude/settings.json - 本地个人配置:
<项目根目录>/.claude/settings.local.json
低优先级的配置会被高优先级覆盖,但注意是“按字段合并”,不是整个文件替换。也就是说,用户级配置了model: "claude-sonnet-4-20250514",项目级也配置了model字段,那就以项目级的为准;但如果项目级只配置了permissions,那model仍然沿用用户级的。
这个继承机制特别适合团队协作的场景:用户级配置你个人习惯,项目级配置团队统一的规范,settings.local.json则放“只属于你本机”的东西,比如个人 API Key、本机调试参数。我见过不少团队把个人密钥写进项目级配置然后提交到 Git 仓库的,这是非常危险的习惯。正确做法是密钥类的东西一律进.local文件,并且把.claude/settings.local.json加进.gitignore。
2.2 高频参数:真正用得上的就这几个
settings.json支持的字段不少,但我实际用下来,日常真正会碰的就这几类,先给一个可以直接“抄作业”的最小示例:
{ "model": "claude-sonnet-4-20250514", "permissions": { "allow": [ "Read(//)", "Edit(//)", "Bash(git status)" ], "deny": [ "Bash(rm -rf *)", "Write(./secrets/**)" ] }, "env": { "NODE_ENV": "development", "HF_ENDPOINT": "https://hf-mirror.com" }, "hooks": { "PreToolUse": [ { "matcher": "Bash", "command": "node scripts/check-command.js" } ] }, "apiKeyHelper": [ "echo $ANTHROPIC_API_KEY" ] }分别说一下我为什么推荐这几个字段:
model 字段:直接指定用哪个模型。别小看这一步,不同模型在长任务里的表现差距极大,用 agent 模式跑批量重构的话,选错模型可能让你反复返工。
permissions 字段:这是设置权限边界,我强烈建议新手上路就配置好。allow列表里写的是 Agent 可以直接做的事,deny列表里写的是绝对禁止做的事。一个常见误区是allow只写一个超大范围的Bash(//),等于把终端完全交给了 Agent,真正出问题的时候你会后悔的。我是建议把常用命令写进 allow,比如Bash(git *)、Bash(npm *),把危险操作写进 deny,例如强制删除、强制推送、生产环境操作等。
env 字段:注入环境变量。这里有个实用技巧:可以用${VAR}引用系统已有的环境变量,也可以直接写死。但注意别把 API Key 这种敏感信息写进会被提交到仓库的配置里,要么放.local文件,要么用apiKeyHelper动态获取。
hooks 字段:挂钩子。这个功能很适合做“安全闸门”,比如在PreToolUse阶段拦截危险命令,或者在PostToolUse阶段自动跑一遍 lint。我自己的做法是挂了一个脚本检查所有即将执行的命令,命令里包含rm -rf或者git push --force就直接拦下并让 Agent 换方案。
2.3 权限配置的三个实战细节
permissions的配置格式看着简单,实际坑不少,我总结三条经验:
第一,路径匹配不是只能写死。支持通配符模式,但要注意匹配范围和实际作用的对应关系。比如Write(./dist/**)表示可以写 dist 目录下的所有文件,Read(//)表示可以读取所有路径(/ 代表任意路径)。建议用最细粒度的规则,越细越不容易误伤。
第二,deny 列表的优先级高于 allow。也就是说,就算你在 allow 里写了Bash(//),只要 deny 里有Bash(rm -rf *),Agent 执行带这个模式的命令时依然会被拦。这个机制其实是给你留了一个“兜底闸门”,我建议所有人都把deny的至少三条万能规则加上:危险删除、强制推送、curl 下载执行脚本。
第三,临时放行别靠改配置文件。实际使用中,Agent 经常会请求一个你没预料到的权限。很多人这时候就去改 settings.json,改完还要让 Agent 重新读取配置,非常打断心流。其实 Claude Code 在会话里会弹出权限确认,你可以在会话中直接批准确认,临时授权本次执行,不需要动配置文件。如果你发现某个权限经常被请求,再把它固化进 settings.json 也不迟。
注意:改完 settings.json 后,通常需要重启会话或执行
/doctor让配置重新加载。我自己试过,直接在会话里Ctrl+C再重新启动 Claude Code 是最保险的,不要指望 Agent 能“立刻看到”新配置。
3. CLAUDE.md:项目的“灵魂与边界”
3.1 生效机制:为什么它在项目里“无处不在”
CLAUDE.md 最有价值的地方在于,它不是一份给你看的文档,而是一份给 Agent 看的“启动引导”。Claude Code 在每次会话开始、每切换到一个新文件、每准备执行任务的时候,都会自动检索并读取相关的 CLAUDE.md。
它的检索是有层级和就近原则的:
- 全局层:
~/.claude/CLAUDE.md,包含你对所有项目通用的偏好,比如“回复用中文”“代码用 TypeScript”“不要随意删文件”。 - 项目层:项目根目录下的
CLAUDE.md,包含这个项目的整体说明、架构约定、常用命令。 - 子目录层:子目录里的
CLAUDE.md,只对那个子目录生效,比如你可以在backend/CLAUDE.md里规定后端代码的规范,在frontend/CLAUDE.md里写前端的构建命令。
这里有个很重要的理解:CLAUDE.md 是“被自动读取”的,不是“需要你提醒”的。很多新手把重要的规范写在聊天上下文里,结果新开会话全忘了。正确的做法是把那些“每次都要重复一遍”的规则全写进 CLAUDE.md,让 Agent 每次启动时自动加载,这样你就不用反复解释了。
我在实际项目中发现的另一个经验是:CLAUDE.md 里的内容不宜过多。太长的话,Agent 在判断“该读哪一段”时反而容易漏掉关键规则。项目级文件控制在适度范围以内,超过就可以考虑拆分到子目录或独立文档里引用。
3.2 一份高质量 CLAUDE.md 的模板
不给你空谈方法论,直接上一份我目前在用的项目级CLAUDE.md模板,你拿回去改改就能用:
# 项目指南 ## 项目简介 这是一个微服务架构的订单系统,包含订单服务、支付服务、库存服务三个模块。 技术栈:Python 3.11 / FastAPI / PostgreSQL / Redis / Docker ## 开发规范 - 代码风格遵循 black + isort,提交前必须格式化 - 所有接口必须包含类型注解和单元测试 - 错误信息统一使用中文,但代码注释用英文 - 禁止在业务代码中直接 print,一律用日志模块 ## 常用命令 - 启动本地环境:docker compose up -d - 运行测试:pytest -x - 打包镜像:docker build -t order-service:latest ./order_service ## 关键目录说明 - /order_service:订单服务主代码 - /order_service/tests:单元测试目录 - /deploy:部署编排文件,不建议直接改动 ## 工作约束 - 未经确认不得修改数据库表结构 - 不得直接执行 npm install 之外的包安装命令 - 涉及支付金额的计算,必须同时检查精度处理逻辑 - 遇到不确定的需求,先列出方案询问我,而不是直接动手这个模板的核心设计思路是:先让 Agent 知道“项目是什么”,再告诉它“该怎么做”,最后划出“绝对不能碰的红线”。前几部分决定它能多高效,最后一部分决定你多省心。
另外我特别推荐一个进阶用法:在 CLAUDE.md 里用变量占位区分不同环境的规则。比如写:
## 环境相关 - 研发环境可执行:migration - 生产环境必须只读,禁止任何写操作配合settings.json里的env字段注入APP_ENV=production,你甚至可以让同一份 CLAUDE.md 在不同环境下产生不同的约束效果。
3.3 容易踩的三个坑
第一个坑:把 CLAUDE.md 写得像散文。Agent 是阅读能力很强,但处理“模糊描述”的方式是猜。你写“尽量别动那些核心文件”,它可能真的会给你整一个巨大的重构方案。写规则时要用“明确的动作 + 明确的对象”,比如“不要修改 /core 目录下的任何文件”就比“核心文件要慎重”好得多。
第二个坑:规则之间互相矛盾。最常见的是全局 CLAUDE.md 说“所有回复用中文”,项目级 CLAUDE.md 又说“代码注释用英文”。这不算冲突,但如果你在项目级写“不要用 TypeScript”,而全局说“默认 TypeScript”,那就会让 Agent 进入一个两难状态。建议每次改完 CLAUDE.md 都做一个“冲突自查”,看看和上层的全局规则有没有矛盾。
第三个坑:忘了 CLAUDE.md 是给 Agent 看的,不是给同事看的。我见过有人把很文绉绉的项目愿景写进去,占大量篇幅却对行为约束毫无帮助。CLAUDE.md 的价值在于“能用一句话让 Agent 少犯一个错”,而不是“写得漂亮”。建议定期翻看 CLAUDE.md,如果某个段落没法概括成一个明确的行为规则,那它就是冗余的。
4. memory:让 Agent 拥有跨会话的“长期记忆”
4.1 memory 的存储机制与两层结构
很多人误以为 memory 是 Claude Code 自动维护的某个黑盒数据库,其实不是。它本质上还是“文件系统上的文本记忆”,只是被设计成按一定规则自动读取和更新。搞清楚这一点,你就能自己掌控记忆的内容和边界。
Claude Code 的 memory 我习惯分成两层:
- 全局记忆层:就是
~/.claude/CLAUDE.md,它承担“你是谁、你常用什么工具链、你有哪些固定偏好”的记忆。 - 项目记忆层:项目目录下
.claude/里维护的记忆文件(包括项目 CLAUDE.md 和进入会话后动态产生的记忆内容),它承担“这个项目当前进展到哪、上一步决定是什么、哪个模块谁在负责”的记忆。
全局记忆层的使用姿势,就是把那些“换一个项目也通用”的东西沉淀下来。比如我是个重度 TypeScript 用户,我就在全局 CLAUDE.md 里固定写一条“新建前端项目时默认使用 pnpm + TypeScript”。这样不管我进入哪个新项目,Claude Code 都能自动带上这个偏好,不需要我每次重新声明。
项目记忆层的价值则在“连贯性”。你可能会发现,同一个项目里,上一个会话你让 Agent 改了一组 API 接口的定义,新开一个会话之后,它又试图把接口改成别的样子——因为它“不记得”上一个会话的决策了。这时候如果你把关键决策写进项目记忆,就能避免这种“反复横跳”。
4.2 怎么把关键信息“钉”进记忆
我在实际使用里总结了一套三步记忆法,操作简单,效果好:
第一步,会话开始时就加载记忆。在聊天开头直接说“请读取项目记忆和全局记忆,我们继续上一轮的工作”。Claude Code 会自动从.claude/目录读取相关的记忆文件。
第二步,在关键决策发生时主动要求记录。比如刚确定了某个模块的接口方案,就补一句“请把本轮的接口决策追加到项目记忆文件中”。这里我建议你稍微有点耐心,明确指定“写到哪个文件、大概什么格式”,而不是笼统说“记住这个”。比如:
请将以下决策记录到 .claude/project-memory.md: - 订单服务的支付接口变更:payOrder 新增 refundAmount 字段 - 取消原定于 5 月的库存同步改造第三步,会话收尾时过一遍记忆。结束时你可以说“请总结本次会话完成的事项、遗留问题、下一步计划,并更新记忆文件”。执行完这一步,下次开会话你就有了一个“自动续传”的起点。
这套方法最重要的是“主动记录”。我一开始指望 Agent 自动记住所有东西,实测下来发现它只在上下文窗口内可靠,一旦上下文被截断或者会话重启,记忆就会丢。把关键决策落盘到文件,才是最稳的。
4.3 目录结构与清理技巧
Claude Code 的记忆相关文件,我习惯统一放在.claude/目录下,典型结构长这样:
.claude/ ├── settings.json ├── settings.local.json ├── CLAUDE.md ├── project-memory.md └── archives/ ├── 2024-06-week2.md └── 2024-05-orders-refactor.md这个结构的思路很简单:CLAUDE.md放“稳定的行为规则”,project-memory.md放“动态的项目状态”,archives/放“已经过期的历史记录”。
关于清理,我有一条建议:项目记忆不是越大越好。文件太大会吃上下文空间,而且让 Agent 在读取时“抓不住重点”。我一般每周做一次“记忆瘦身”:把已经完成的事项移到archives/,把已经稳定的规则升级到 CLAUDE.md,把待办事项精简到最多几条。这个习惯帮我避免了不少“Agent 被旧信息带偏”的麻烦。
5. 三大配置协同实战:一个典型场景
5.1 场景设定与配置组合
纸上谈兵再多,不如跑一遍真实场景。我拿最近做的一个小工具项目举例:一个用 Python 写的命令行 JSON 处理工具,代码量不大,但涉及文件读写、命令执行、依赖管理。
我落地这套配置时做了三件事:
第一,在用户级settings.json里定下通用规则:
{ "model": "claude-sonnet-4-20250514", "permissions": { "deny": [ "Bash(rm -rf *)", "Bash(git push --force)" ] }, "env": { "PYTHONPATH": "src" } }第二,在项目根目录写了一份项目级 CLAUDE.md,核心内容是:技术栈说明、常用测试命令、约定“所有 CLI 输出必须有 --quiet 参数”、以及“禁止修改 src/parsers 目录下的解析器接口”。这份文件的效果立竿见影——Agent 不再动不动就掏出pytest tests/,而是直接跑我约定的python -m pytest -q,也不会擅自改接口。
第三,我在project-memory.md里记录了当时的一个关键状态:上一个会话刚确定了“JSON 合并命令采用深度合并策略,保留数组中的重复项”。这个记忆让新会话里的 Agent 没有推翻之前的决定,而是沿着既定方案继续开发。
5.2 验证这套组合是否生效
配置完不是万事大吉,我建议跑一个“三连测试”来验证:
- 测试一:在项目目录启动 Claude Code,问一句“当前项目的测试命令是什么”。如果它回答
python -m pytest -q,说明 CLAUDE.md 被正确读取了。 - 测试二:让 Agent 执行一个危险命令,比如
rm -rf src(可以先用一个临时目录测试),看它是否被权限拦截。 - 测试三:关掉当前会话,重新启动,然后问“上次确定的 JSON 合并策略是什么”。如果它能准确回答“深度合并、保留重复项”,说明 memory 链路是通的。
这三个测试分别针对 settings、CLAUDE.md、memory 的效果,任何一个挂了,你都能立刻定位是哪一环出了问题。我在团队里推广这套配置方案后,基本就靠这个三连测试来判断一个项目“有没有配置到位”。
6. 常见问题与排查技巧实录
最后把你最可能遇到的一批问题集中列出来,先看现象,再给解决办法。
| 现象 | 大概率原因 | 解决办法 |
|---|---|---|
| 修改 settings.json 后行为没变化 | 配置未重新加载 | 重启会话或执行 /doctor,确认当前生效配置 |
| 项目级 settings 和用户级冲突 | 优先级理解反了 | 弄清项目级覆盖用户级,不要在多个层级重复设置矛盾字段 |
| Agent 不遵守 CLAUDE.md 里的规范 | 规则写得太“散文” | 改成“动作 + 对象”的明确句式,删掉模糊表达 |
| 新会话总是忘掉历史决策 | 项目记忆没落盘 | 会话结束前主动要求把状态写入 project-memory.md |
| 权限配置太宽松,Agent 乱跑命令 | allow 列表范围过大 | 收敛到最小必要权限,危险命令统一进 deny |
| 全局 CLAUDE.md 太啰嗦,干扰项目行为 | 全局规则过载 | 全局只留跨项目通用项,项目特定规则挪到项目级 |
| 配置文件被提交进 Git 仓库 | settings.local.json 未忽略 | 将 settings.local.json 和 .claude 下的本地密钥文件加入 .gitignore |
| 项目记忆文件越来越大,影响效率 | 缺少归档机制 | 定期把旧记录移入 archives/,只保留当前有效信息 |
补充一个我反复踩过的细节:settings.json里的permissions.allow写路径时,很多人把Read(//)当成“读取当前目录”,其实//是任意路径的意思。如果你只想让 Agent 读取项目内文件,应该写成Read(./**)或者在项目级配置里用相对路径。这个细节一旦搞错,Agent 可能连蒙带猜地读取了项目之外的系统文件,对安全敏感的项目来说是个不小的隐患。
另一个非常实用的小技巧:在 CLAUDE.md 里写“不要做的事”时,一定要和 deny 权限配合。单靠文本规约,Agent 有可能在上下文压力下“忘掉”约束;而只要在 settings 里做硬拦截,它就物理层面无法执行。文本约束负责“引导”,权限配置负责“兜底”,这是我一直坚持的双保险思路。
我个人的体会是,Claude Code 的配置体系其实和学习任何一套工具一样,最忌讳的就是“想一步到位”。你先只配一个 settings.json 跑几天,再加 CLAUDE.md 约束行为,最后把 memory 用起来,每一步都能感受到明显的效果差异。等你把这三件套跑顺了,再回头看那些“为什么别人的 Agent 那么懂事”的帖子,答案其实就在这三个文件里。