DeepDojo.AI发布 2026-11-12English
Claude Code 多份配置冲突时,哪个生效?
你的用户配置里写着 "model": "sonnet",项目配置写着 "opus"。项目里还有一条拒绝读取 .env 的规则,你在本地配置里写了一个空的 deny 数组,想把它清掉。打开新会话,模型变成了 opus,.env 依旧读不了。
Claude Code 的设置可以同时来自好几份文件:你的用户配置、团队提交的项目配置、你本机的本地配置,有时还有组织统一下发的托管配置。只打开其中一份 JSON,很难解释整个会话最后用的是什么。
真正让人困惑的是,不同字段的合并方式不一样:
- 只取一个值的字段,比如模型名称,高优先级来源直接替换低优先级;
- 环境变量这类对象,各层按键合并;
- 权限规则这类列表,各层的条目汇集在一起,谁也删不掉谁的。
开头那个空数组之所以清不掉拒绝规则,原因就在第三条。处理办法分三步:先找齐这次会话加载了哪些来源,再按字段类型逐个推算结果,最后用 /status、/permissions 等命令对照实际状态。
01 先按共享范围选文件
先决定设置影响谁,再选文件。个人偏好、团队规范和本机差异需要不同的共享范围:
| 范围 | 文件位置 | 影响对象 | 常见用途 |
|---|---|---|---|
| 用户 | ~/.claude/settings.json | 你在所有项目中的会话 | 主题、默认模型、个人插件和通用偏好 |
| 项目 | .claude/settings.json | 当前仓库的所有协作者 | 团队权限、Hooks、共同插件和统一工具行为 |
| 本地 | .claude/settings.local.json | 当前仓库中的你 | 本机差异、个人试验和不应共享的配置 |
组织还可以由管理员部署 Managed Settings,统一安全和合规要求。它优先级最高,个人或项目设置无法覆盖。普通用户先查组织已有策略即可,/status 的 Setting sources 一行会列出适用于你的托管来源。
例如,团队检查 Hook 放项目配置并提交 Git,本机特殊端口放本地配置;组织强制策略交给 Managed Settings。手动创建本地配置后检查 .gitignore,避免把本机配置带进提交。
02 同一个字段写在多处时的优先级
位置选对以后,仍可能有多个文件写着同一个字段。先看只取一个值的字段,也就是标量,比如 model。这时按下面的来源顺序选择:
Managed Settings
↓
命令行(启动时用 --settings 传入的配置)
↓
.claude/settings.local.json
↓
.claude/settings.json
↓
~/.claude/settings.json顺序从高到低:同一标量由项目覆盖用户,本地又可覆盖项目。Claude Code 的设置文档给出的是同一个顺序:托管设置、命令行、项目本地、共享项目、用户,高一层设置的键会覆盖下面各层的同一个键。
命令行这一层只影响当前会话,适合临时切换。--model 这类单项参数也能在本次会话覆盖文件里的默认模型,不过官方说明它们按各自的键处理,不属于上面这个层级。Managed Settings 属于组织策略,你自己的文件和 --settings 都覆盖不了托管的键。
还有一类容易漏掉的来源:环境变量。官方文档特别说明,环境变量不在这个层级里,它和设置键谁优先要逐对看。例如在 shell 里导出的 ANTHROPIC_MODEL,会压过任何文件里的 model。
03 三类字段,三种合并方式
配置逐字段解析。高优先级文件不会整份替换其他文件,还要区分字段类型:
| 字段类型 | 怎样得到结果 |
|---|---|
| 标量(如模型名称) | 高优先级来源的值直接替换低优先级 |
| 对象(如环境变量字典) | 各层按键合并 |
| 规则数组(如权限列表) | 汇集各层来源的全部条目,再去重保留 |
官方文档把列表的规则写得很明确:同一个列表键出现在多份文件里时,Claude Code 会把列表合并,而不是挑一份,所以每份文件都只能添加条目,删不掉别的文件里的条目。少数存放模型列表的键有自己的规则,日常用到的权限列表都按合并处理。
先找齐加载来源,再逐字段计算。权限数组合并后还要检查匹配结果;新增 allow 不能解除已命中的 deny。

04 把开头的例子算一遍
用一个例子看看怎样判断。假设当前有这三份配置,先找出来源,再计算各字段的结果:
~/.claude/settings.json
model: "sonnet"
permissions.allow: ["Bash(pnpm lint)"]
.claude/settings.json
model: "opus"
permissions.allow: ["Bash(pnpm test *)"]
permissions.deny: ["Read(./.env)"]
.claude/settings.local.json
permissions.deny: []逐字段算这个例子:
| 字段 | 最终结果 | 原因 |
|---|---|---|
model | opus | 本地没写,项目值优先于用户的 sonnet |
permissions.allow | lint 和 test 两条 | 两个来源的规则累积 |
permissions.deny | 保留 .env 读取拒绝 | 本地空数组清不掉已有条目 |

算完再打开 /permissions,对照实际合并结果。若对不上,先回头查有没有漏掉来源。只把一份 JSON 读明白,还解释不了整个会话的配置。
权限列表合并之后,每条调用还要按拒绝、询问、允许的顺序去匹配,这一步的细节在Claude Code 明明允许了,为什么还拒绝里展开。
05 用命令核对实际状态
手动编辑 JSON 便于团队审查和版本管理,内置命令用于核对最终状态。
| 命令 | 主要用途 |
|---|---|
/config | 打开设置界面;也支持用 key=value 修改单项配置 |
/model | 切换当前会话模型,选择会保存为新会话的默认值 |
/status | 查看当前加载了哪些 Settings 来源 |
/permissions | 查看最终合并后的权限规则及各自来源 |
/hooks | 查看当前生效的 Hook |
/context | 查看哪些内容占用了上下文 |
/doctor | 检查安装和配置问题,并在确认后提出修复 |
claude doctor | 不进入交互会话,直接输出只读诊断结果 |
排查配置的官方文档也是用这几条命令来定位问题的:/permissions 显示当前生效的允许和拒绝规则,/status 显示生效的设置来源,以及是否有托管设置在起作用。
改完文件,再看设置怎样生效。官方文档说明,Claude Code 会监视设置文件,大多数修改无需重启就会应用到正在运行的会话,包括权限、Hooks 和 apiKeyHelper 这类凭证辅助配置。文件保存了,还要核对实际结果。
06 配置没生效时的排查顺序
配置没有生效时,从实际加载来源开始检查,避免同时改多个参数。按加载、校验、优先级和解析结果依次排查:
- 用
/status确认用户、项目、本地或 Managed Settings 是否真正被加载。 - 用
/doctor或claude doctor检查 JSON 语法、字段类型和无效配置。 - 搜索更高优先级范围中是否定义了同名字段。
- 检查命令行参数和环境变量是否覆盖了文件值。
- 对权限、Hooks、MCP 使用对应命令查看解析后的结果。
错误和警告的影响范围不同:
| 结果 | 例子与下一步 |
|---|---|
| Settings Error | 多余逗号使 JSON 解析失败,整份文件可能不加载;先修语法,再核对其他设置 |
| Settings Warning | Bashh(pnpm lint) 等无效条目会被跳过;修正后用 /permissions 等命令确认,同一文件里的其他有效配置仍然生效 |
设置文档对这两类结果的描述是:Settings Error 指文件 JSON 无效或有值被 schema 拒绝,交互会话启动时会弹出对话框,让你修复、退出或在不加载这份文件的情况下继续;Settings Warning 指个别条目失败,Claude Code 跳过这些值,文件其余部分照常生效。
修正拼写并消除警告后,仍要在 /permissions 等对应命令中查到条目,再复测依赖它的行为。/status 只证明来源加载,官方也说明它不显示每个键来自哪份文件,不能单独证明某条设置生效。
先找齐来源,再逐字段算,最后用命令核对。每项设置记下用途和来源,下次再有配置“改了没用”,就能直接从这几步查起。字段本身该怎么挑、怎么写,可以接着看settings.json 常用配置项逐个讲清。