上一篇我们聊了 Claude Code 的"指令文件"(CLAUDE.md),这篇接着讲它的另一半——“配置文件”(settings.json)。如果说指令文件是用大白话告诉 AI"该怎么干活",那配置文件就是用结构化的开关告诉它"用哪个模型、有什么权限、能调哪些工具"。本文以普通人视角,带你看懂三个配置文件分别是什么、它们之间怎么配合、放在哪、以及日常使用时真正需要注意的几点。
接着源码泄露系列往下讲。上一篇说的是指令文件CLAUDE.md——你用自然语言写给 AI 看的"工作须知"。这一篇讲的是配置文件settings.json——一份结构化的"参数表"。两者最大的区别:指令文件是写给 AI 读的"软约定",配置文件是写给程序读的"硬开关"。普通用户不需要会写代码也能用好它,关键是搞清楚有几个文件、谁管谁、放哪里
一、什么是配置文件
简单说,配置文件就是一份JSON 格式的"参数表",告诉 Claude Code 几件事:
默认用哪个模型(model,比如 Opus / Sonnet) 给 AI 多大的权限(permissionMode,能不能改文件、能不能跑命令) 注入哪些环境变量(env,比如数据库地址、API Key) 工具调用前后自动执行什么命令(hooks,生命周期钩子) 给 AI 装哪些"插件"(mcpServers,外部工具服务器) 是否开启沙箱隔离(sandbox,限制 AI 的系统访问范围) 以及认证(oauth)等
它和指令文件的分工可以这样记:
CLAUDE.md | settings.json | |
|---|---|---|
二、3个配置文件分别是什么
Claude Code 源码里其实定义了5 个配置文件的加载位置,但其中 2 个是旧格式兼容文件(~/.claude.json和/.claude.json),新用户根本不需要创建,可以直接忽略。
配置文件加载顺序(优先级从低到高):1. ~/.claude.json ← ⚠️ 旧格式兼容,新用户无需创建2. ~/.claude/settings.json ← ✅ 全局默认设置(所有项目通用)3. /.claude.json ← ⚠️ 旧格式兼容,新用户无需创建4. /.claude/settings.json ← ✅ 当前项目专属设置5. /.claude/settings.local.json ← ✅ 个人本地覆盖(最高优先级,不进 Git)
普通用户只需关注 3 个文件:
~/.claude/settings.json(全局)、<project>/.claude/settings.json(项目)、<project>/.claude/settings.local.json(个人覆盖)。标注 ⚠️ 的旧格式文件可忽略。
1. 全局配置 ~/.claude/settings.json
位置:你的用户主目录下(Windows 是C:\Users\<你的用户名>\.claude\) 作用范围:这台电脑上、你这个账户的所有项目都生效 适合放:你个人长期不变的默认偏好,比如默认模型、全局权限白名单、状态栏设置
2. 项目级配置 <项目>/.claude/settings.json
位置:某个具体项目文件夹里的.claude/目录下 作用范围:只对这一个项目生效,但对所有打开这个项目的人都生效 这个文件会进 Git——也就是说,团队成员 clone 下来就能直接用同一套设置 适合放:项目专属的东西,比如这个项目该用哪个模型、专属的 MCP 工具、自动跑 lint 的钩子 重要:绝对不要在这里写密码、API Key,因为它会被提交到 Git 仓库里
3. 个人本地覆盖 <项目>/.claude/settings.local.json
位置:和项目级配置同一个.claude/目录,只是文件名多了.local 作用范围:这一个项目 × 这台机器 × 你这个用户——最小、最私人 这个文件不进 Git(.local.json后缀会被自动忽略),只存在于你本地 适合放:你的私人 token、个人偏好(比如团队用 Sonnet 但你想用 Opus)、本机专属的绝对路径
它的优先级最高——存在时会覆盖项目级和全局的同名字段
全局管所有项目,项目级管一个项目所有人,本地覆盖只管你自己这台机器。范围越小,优先级越高。
三、3个配置文件之间的关系
这是最容易绕晕、也最关键的一节。三个文件不是"三选一",而是同时存在、层层叠加。
3.1 它们是怎么合并的:深度合并
Claude Code 有一套多层级配置合并系统。三个文件按优先级从低到高排列:
1. ~/.claude/settings.json ← 全局默认(优先级最低)2. <项目>/.claude/settings.json ← 项目级3. <项目>/.claude/settings.local.json ← 个人本地覆盖(优先级最高)
合并用的是深度合并(源码里叫deep_merge_objects)——意思是嵌套的内容会递归地合在一起,而不是简单地整个替换掉。
举个最直观的例子:假设你在全局配了 1 个 MCP 工具,又在项目级配了 1 个,再在本地配了 1 个。最终结果不是"只剩最后那 1 个",而是3 个工具都能用(合并叠加)。
3.2 三类字段,三种合并规则
不同类型的字段,合并方式不一样,记住这三条就够了:
| 标量字段 | modelpermissionMode、sandbox.enabled | 后者覆盖前者 |
| 对象字段 | envmcpServers | 递归合并 |
| 数组字段 | permissions.allowpermissions.deny |
深度合并(deep merge)VS 递归合并(recursive merge):
深度合并:用作整个三层配置合并机制的名字——它是个统称,里面其实包含三套子规则:标量覆盖、数组取并集、对象递归合并。合并会"深入"到嵌套的内层,与"浅合并(shallow merge,只合最外层)"相对
递归合并:专门用来描述其中对象字段那一档(env / mcpServers)的行为
不同的 key → 全部保留(这一点确实像并集) 相同的 key → 仍然按优先级覆盖(这一点不是并集) 真正发生"递归"动作的只有对象字段。标量字段(model)是直接覆盖、不往下钻;数组字段(hooks)是整体取并集、也不往 下钻。只有对象字段才会"进入内层、对相同 key 继续合并"——这一步才是字面意义上的递归
3.3 用"作用域"理解:一层套一层
如果你读过上一篇的指令文件,会发现配置文件其实是同一个套娃结构:
┌──────────────────────────────────┐│ 全局 / 所有项目 │ 优先级最低│ ┌──────────────────────────┐ ││ │ 项目级 / 一个项目 │ ││ │ ┌──────────────────┐ │ ││ │ │ 本地 / 你这台机器 │ │ │ 优先级最高│ │ └──────────────────┘ │ ││ └──────────────────────────┘ │└──────────────────────────────────┘局部覆盖全局,从外向内优先级递增
本质上就是"用户 / 项目 / 机器"三个维度被层层收窄。范围越小越靠内、优先级越高——更具体的设置会覆盖更通用的设置。
⚠️ 这里有一个和指令文件不同的细节**,值得普通用户特别注意:**
指令文件(CLAUDE.md)因为是塞进 Prompt 给大模型读的,存在"中间层最容易被忽略"的注意力特性。但配置文件完全没有这个问题——它的合并是确定性的程序代码逻辑,三层优先级严格线性递增,全局 → 项目 → 本地,不存在"中间塌陷"。所以"局部覆盖全局"这个宏观结论两类文件都成立;但"越中间越弱"只是指令文件的事,别套到配置文件上。
3.4 和电脑环境变量的类比
如果你用过 Windows 的"系统变量 / 用户变量 / 进程变量",会觉得很眼熟——都是层级配置 + 局部覆盖全局。可进行关联理解:
更具体的覆盖更通用的 全局放共性,局部放差异 敏感的个人配置走最局部的那一层 同名设置不生效时,从最局部往外排查
三处错位(不能直接套用):
中间层维度:Windows 用户变量 = “哪个登录账户”(身份维度);Claude 项目级 = “哪个目录树”(空间维度)。OS 不感知"项目"概念,最接近的对应物是git config --local。 嵌套语义:Windows 三层是平铺读取顺序,系统/用户变量不构成父子集;Claude 的"作用域 3 ⊂ 2 ⊂ 1"是真子集嵌套。 第三层维度:Windows 进程变量 = 时间维度(当前会话,退出即失);Claude.local.json= 空间维度(永久落盘但不入 git)。
四、配置文件实例
光说规则太抽象,下面用一个个人作品展示网站的例子(技术栈:Next.js + Python API + SQLite)把三个文件串起来看。
4.1 全局.claude/settings.json
注意:标准 JSON 不支持注释,以下 // 注释仅用于说明,实际文件中请删除注释行。
```json{"model": "claude-opus-4-6", // 默认使用的模型(可选 opus/sonnet 等)"permissionMode": "workspace-write", // 权限模式:read-only / workspace-write / danger-full-access"env": { "MY_API_KEY": "..." }, // 注入到环境变量中,AI 和工具可以读取的API KEY"hooks": { // 生命周期钩子:在工具调用前后自动执行的命令"PreToolUse": ["lint-check"], // 工具调用前 → 先运行 lint 检查"PostToolUse": ["auto-test"] // 工具调用后 → 自动运行测试},"mcpServers": { // MCP 外部工具服务器配置(给 AI 装"插件")"my-server": { // 工具名称(自定义,用于标识)"command": "uvx", // 启动命令(uvx = Python 工具运行器)"args": ["mcp-server-sqlite", "--db", "data.db"], // 启动参数(SQLite MCP 服务器 + 数据库路径)"env": { "TOKEN": "..." } // 传给该 MCP 服务器的环境变量}},"sandbox": { // 沙箱隔离配置(限制 AI 的系统访问范围)"enabled": true, // 是否启用沙箱"filesystemMode": "workspace-only", // 文件系统限制:只能访问当前工作区"networkIsolation": true // 网络隔离:禁止 AI 发起外部网络请求}}```
要点:
这个文件在你的用户主目录 ~/.claude/下,作用范围是这台机器上、你这个账户的所有项目——不属于任何单个项目,也不进 Git它是配置文件最常用、也最该先配好的一层:默认模型、全局权限白名单、状态栏这类"长期不变的个人偏好"都放这里 它的优先级最低,但角色是"兜底"——项目级 / 本地没配的字段,最终都会回落到这里生效 这里的 model、permissionMode是给所有项目的默认值:设成 Opus 后所有项目默认用 Opus,某个项目想换再去项目级 / 本地单独覆盖因为是"按需覆盖"模式,很多人其实只有这一个文件就够用了——普通项目没特殊需求时,根本不必再建项目级或本地配置 例子里 sandbox.enabled设为true,可以理解为给所有项目兜一条通用安全基线;信任的个人项目再在项目级把它关掉(见 4.2)
4.2 项目级 settings.json(会进 Git,团队共享)
```json{"model": "claude-sonnet-4-20250514", // 用 Sonnet 模型(更快更便宜,展示网站够用)"permissionMode": "workspace-write", // 日常开发标准权限"env": { // 项目级环境变量(会进 Git,不放敏感信息)"DATABASE_URL": "sqlite:///data/portfolio.db", // 数据库相对路径(团队通用)"NODE_ENV": "development" // Node.js 环境标识},"hooks": { // 生命周期钩子"PreToolUse": [], // 工具调用前:无额外操作"PostToolUse": ["npm run lint"] // 工具调用后:自动跑 ESLint 检查代码风格},"mcpServers": { // 项目专属的 MCP 工具"portfolio-db": { // 作品集数据库工具"command": "uvx", // 用 uvx 启动"args": ["mcp-server-sqlite", "--db", "data/portfolio.db"], // 指向项目内的 SQLite 文件"env": {} // 无额外环境变量}},"sandbox": { // 沙箱配置"enabled": false // 个人项目关闭沙箱(信任自己的代码)}}```
要点:
这个文件会进 Git,团队成员(或你换电脑后)clone 下来就能直接用model 用 Sonnet——更快更便宜,展示网站不需要 Opus 级别的推理能力permissionMode 选workspace-write,这是日常开发的标准选择mcpServers 配了一个 SQLite 工具,让 AI 能直接查询作品集数据库hooks 里配了npm run lint,AI 每次改完代码自动跑代码风格检查 这里不写任何密码、API Key,因为它会进 Git
4.3 个人本地覆盖 settings.local.json(不进 Git)
同一个项目,你的**个人本地配置**:```json{"model": "claude-opus-4-6", // 覆盖项目级的 Sonnet → 个人偏好用更强的 Opus"env": { // 个人私密环境变量(不进 Git,只在本地生效)"VERCEL_TOKEN": "my-vercel-deploy-token", // Vercel 部署令牌(用于自动部署展示网站)"GITHUB_TOKEN": "ghp_xxxxxxxxxxxx", // GitHub 个人访问令牌(用于 Issues/PR 操作)"DATABASE_URL": "sqlite:///D:/projects/portfolio/data/portfolio.db" // 覆盖为本机绝对路径},"mcpServers": { // 个人额外的 MCP 工具(会与项目级合并)"github-helper": { // GitHub 操作工具(管理 Issues、创建 PR)"command": "npx", // 用 npx 启动"args": ["-y", "@modelcontextprotocol/server-github"], // -y 自动确认安装"env": { "GITHUB_TOKEN": "ghp_xxxxxxxxxxxx" } // 传入 GitHub token},"vercel-deploy": { // HTTP 请求工具(用于调用 Vercel API 部署)"command": "npx", // 用 npx 启动"args": ["-y", "mcp-server-fetch"], // MCP fetch 服务器(通用 HTTP 请求能力)"env": {} // 无额外环境变量(Vercel token 已在上面的 env 中)}}}```
要点:
这个文件不进 Git,只存在于你本地model 覆盖成claude-opus-4-6——你个人偏好用更强的模型,但不影响团队设置env 里放了你的私人 token(Vercel 部署、GitHub),只在本地生效,安全DATABASE_URL 把项目级的相对路径覆盖成你本机的绝对路径多加了一个github-helperMCP 工具——这是你的个人需求,不是团队统一需求
4.3 三层叠加后,最终生效的是什么?
把全局 + 项目级 + 本地三层合并,最终结果是:
model = claude-opus-4-6 ← 标量字段:三层都有值,按优先级取最高 → 本地 Opus 覆盖项目级 SonnetpermissionMode = workspace-write ← 标量字段:本地没设,回落到「有值的最高层」→ 项目级生效(哪怕全局也设了也轮不到)mcpServers = { portfolio-db, github-helper, vercel-deploy } ← 对象字段递归合并:三个 key 互不重复 → 1(项目)+2(本地)=3 个全保留hooks = { PostToolUse: ["npm run lint"] } ← 数组字段:本例只有项目级配了 → 它是唯一有值的层,并未发生合并env = { VERCEL_TOKEN, GITHUB_TOKEN, DATABASE_URL(本地路径), NODE_ENV } ← 对象字段递归合并:不同 key 全保留,重复 key(DATABASE_URL)由本地覆盖
看明白这张表,你就真正理解了"深度合并":
model是单个值,本地的 Opus 把项目级的 Sonnet 覆盖掉了;
mcpServers是对象,项目级的 1 个 + 本地的 2 个 = 最终 3 个工具全部可用;
env同理,不同的 key 全保留,相同的 key(DATABASE_URL)由最高优先级的本地值胜出。
4.4 顺带说说 permissionMode(权限模式)
配置文件里有个字段叫permissionMode,它决定了 AI 默认能干多少事,普通用户只需掌握以下3个模式:
read-only | ||
workspace-write | 日常开发标准选择 | |
danger-full-access |
它和你平时点的弹窗按钮是配套的:
点“Allow Once”:只允许这一次,不写进任何文件; 点“Always Allow”:把这条命令加进白名单(写入settings.local.json的permissions.allow),以后不再弹窗。
可以这样理解:permissionMode是"默认能干什么"的天花板,permissions.allow是"白名单",可以通过预先声明哪些具体命令跳过弹窗直接放行。
五、配置文件放在哪里
下面这棵目录树标了 ★ 的就是你真正需要关心的文件:
```~/ ← 用户主目录(Windows: C:\Users\<name>)└── .claude/ ← Claude Code 用户级配置目录├── settings.json ← ★ 全局配置(管所有项目)├── CLAUDE.md ← 用户级指令文件├── plugins/ ← 用户级插件└── projects/ ← 会话历史等运行数据(自动管理,别动)<某个项目根目录>/├── .claude/│ ├── settings.json ← ★ 项目级配置(进 Git,团队共享)│ ├── settings.local.json ← ★ 本地覆盖(不进 Git,优先级最高)│ ├── CLAUDE.md ← 项目级指令文件│ └── commands/ agents/ hooks/ rules/├── CLAUDE.md ← 项目级指令文件(与 .claude/CLAUDE.md 二选一)├── CLAUDE.local.md ← 项目本地指令(不进 Git)└── .gitignore ← 必须包含 settings.local.json```
几个容易踩坑的点:
配置文件的本地版settings.local.json是在.claude/目录里面;而指令文件的本地版CLAUDE.local.md是在项目根目录——两者位置不一样,别记混。 凡是带.local的文件都不进 Git,需要在.gitignore里显式写一行.claude/settings.local.json把它排除掉。 用户级的~/.claude/settings.json是配置文件最常用的一层,模型、全局白名单这类长期偏好都放这里。 进阶:环境变量CLAUDE_CONFIG_HOME可以改掉~/.claude这个默认路径,一般人用不到。
六、普通人使用时需要关注的几点建议
以下是一些普通人可能需要关注的几个点:
1. 不是每个项目都要建配置文件。
Claude Code 是"按需覆盖"模式,不是"必须存在"模式。没有项目级配置,它会自动回落到用户级配置;没有本地配置,再往上回落。所以普通项目 + 用户级配置已经够用时,什么都不用加。只有在以下情况才值得新建配置文件:项目需要特定模型、项目有私密 token、项目有专属 MCP 工具、项目需要自动跑 typecheck/lint。
2. 密钥永远只放settings.local.json。
任何 API Key、token、密码——只能写在不进 Git 的本地文件里。项目级settings.json会被提交到仓库,写进去等于公开泄露。这是最重要的一条安全红线。
3. 一定要配好.gitignore。
在.gitignore里加上.claude/settings.local.json(和CLAUDE.local.md)。否则你的本地私密配置会不小心被提交上去。
4. 想临时换模型 / 权限,改settings.local.json最省心。
因为它优先级最高,在里面加一个字段就能临时覆盖;不想要了直接删掉那行,就自动回落到项目级或全局设置,随时可逆,不影响别人。
5. 日常开发用workspace-write就好。
别一上来就开danger-full-access。workspace-write已经能让 AI 自由读写项目文件,危险命令还会弹窗给你最后一道确认;遇到反复弹窗的常用命令,点"Always Allow"逐步攒白名单即可。
6. 全局放共性,局部放差异。
长期不变的个人偏好(默认模型、常用白名单)放全局~/.claude/settings.json;项目专属的东西放项目级;只属于你这台机器的东西放本地。一旦某个设置没生效,从最局部(本地)往外(全局)逐层排查同名字段被谁覆盖了。
小结:配置文件就是一份分三层的"参数表"——全局、项目、本地,范围越小优先级越高,三层会被深度合并成一份最终生效的设置。普通用户记住三件事就够了:密钥只进本地文件、本地文件别忘了写进 .gitignore、没特殊需求就不必新建配置文件。它和上一篇的指令文件一个管"硬开关"、一个管"软约定",配合起来才是完整的 Claude Code 使用姿势。
夜雨聆风