Claude Code 配置:分几层、怎么合并、凭据该放哪一层
Claude Code 的配置不止一个地方,而且这些地方的行为并不相同。大多数「我明明改了、可是没生效」的情况,根因不是配置文件写错了,而是值确实设上了,只是设在了一个会被覆盖的层。
这篇讲清楚:配置一共分哪几层、它们怎么合并、每一层该放什么、以及怎么确认一次改动真的生效——而不是假设它生效了。
配置有两条通道,不是一条
配置通过两条互相独立的通道进入工具。
环境变量读自启动工具的那个 shell。换端点靠的就是它——ANTHROPIC_BASE_URL 是接收请求的地址,ANTHROPIC_AUTH_TOKEN 是那个地址认的凭据。设好这两个,所有请求就发往别处,客户端其余部分一行都不用改。这个机制本身、以及换过去之后哪些能力还在,写在Claude Code 换用其他模型那篇。
设置文件是 JSON,文件名 settings.json,分布在几个作用域上。它承载那些反复手动导出很别扭的东西:权限规则、hooks、默认模型,以及一个 env 块——可以把环境变量固定下来,不再依赖「碰巧是哪个 shell 启动了会话」。
第二条通道可以喂给第一条。原本要写进 shell 配置里去 export 的东西,都可以写进设置文件的 env 块;一套配置一旦不再是临时试验,通常就该这么做。
作用域的层级
设置文件存在于几个作用域,而且它们是一起读的,不是互相取代:
- 用户级——
~/.claude/settings.json。对本机所有项目生效,适合放个人默认值。 - 项目级——仓库里的
.claude/settings.json。设计上是要提交进 git 的,让整个团队继承同一套。 - 项目本地级——
.claude/settings.local.json,和上一个放在一起,但不提交。任何跟本机相关或者私密的东西都归这里。 - 托管策略——由管理员下发的文件,位于以上全部之上,项目内部无法覆盖。
顺序只朝一个方向:越具体、越本地的作用域越后应用;托管策略压过一切。
它们按「键」合并,不是按「文件」替换
这是最容易让人意外的一点:更具体的文件不会整体替换掉更泛的那个,合并是逐个键发生的。
一台在用的机器上的实例:用户级文件里有 permissions、hooks 和一个 sandbox 块;紧挨着的项目本地文件里只有 permissions。结果是用户级的 hooks 与 sandbox 在那个项目里依然生效——它们没有被一个压根没提到它们的本地文件清空。只有本地文件点名了的键,才是它覆盖的键。
实际好处是:一个小而专注的本地文件是安全的。为了改一条权限规则,你不需要把整份用户配置抄进项目里。
而它的镜像后果才是真正咬人的那一面:同一个键如果在两层里都设了,更本地的那层会静默取胜,而你去读自己刚改的那个文件,完全看不出哪个值是活的。
每一层该放什么
|
层 |
适合放 |
不该放 |
|---|---|---|
|
shell 环境变量 |
一次性试验、只在这一次会话里换个端点 |
任何明天还要能复现的东西 |
|
用户级 |
个人默认值:模型选择、自己的权限基线、常用网关的 |
队友也需要的东西 |
|
项目级 |
全队规则:本仓库的权限策略、约束工作流的 hooks |
凭据。永远不放。没有例外 |
|
项目本地 |
你自己在这个项目用的凭据、本机相关路径、按项目覆盖的端点 |
应该全队共享的规则 |
|
托管策略 |
组织级、不允许本地覆盖的约束 |
任何需要按人不同的东西 |
值得背下来的只有一条:凭据只能放在 git 看不见的层。项目级是被设计成要提交的,所以它恰恰是最不该放的地方;而这个错误特别容易犯,因为它看起来正是「项目相关设置」最该去的那一层。
你真正会碰的那几个键
model——会话的默认模型。某个项目需要跑在与个人默认值不同的模型上时用它。env——应用到会话的环境变量表。想把 base URL 与凭据固定住而不是每次手动 export 时,就写这里。permissions——allow、deny、ask三个列表,外加defaultMode。这是最常被按项目定制的一层,也是合并起来最干净的一层,因为这些列表在语义上是叠加的。hooks——在会话的特定时点触发的命令。因为它们会被执行,所以一个提交进仓库的 hooks 块,应当按对待仓库里任何一个可执行文件的标准来审。sandbox——隔离相关设置,包含出站访问的网络白名单。
MCP 服务器是另一套系统
Model Context Protocol 服务器不通过 settings.json 配置。它有自己的文件——项目根目录下的 .mcp.json,设计上要提交,好让所有人拿到同一份服务器清单——外加用户级与本地级作用域,运作方式与设置文件的作用域一致。
改了没反应的时候,请先记住这个分界:改 settings.json 永远不会影响加载哪些 MCP 服务器,反过来也一样。两套系统、两个文件、两个要去看的地方。
凭据那条规则在这里力度更大,因为 MCP 服务器定义里经常带着它所连服务的 token。一份提交进 git、里面还带着活 token 的 .mcp.json,就等于一次凭据泄漏。
把工具指向网关
对于走中转或网关端点的人,配置问题其实退化成了「放哪一层」,而不是「用哪个变量」。变量本身已经定了——base URL 与 auth token,见上文;如果对面的协议格式不同,相邻情况在什么是 OpenAI 兼容 API里写过。
层的选择直接对应这套安排有多长久:
- shell 里 export——用来试端点。终端一关就没了,而在你还没定下来的阶段,这是优点不是缺点。
- 用户级
settings.json的env块——一个你在所有项目里默认都走的网关。 - 项目本地
settings.local.json——某一个仓库要用与其余工作不同的端点、或权限范围不同的凭据时。当某个项目的凭据有自己的轮换节奏时,这也是正确的形状,参见API 密钥轮换最佳实践。
如果卡点根本不在配置、而在能不能拿到官方端点本身,那么Anthropic Claude API 接入权限里的路线对比更对症。
怎么确认改动真的生效
什么都别假设。本文开头那个失效模式——改在了错误的层——不会产生任何报错,所以验证必须是正向的,不能拿「没人抱怨」当通过。
三道检查,可信度递增:
- 确认文件能解析。 多一个逗号、少一个花括号,这份设置文件就是无效 JSON,而无效文件一个键都贡献不了。这是最便宜的排除项,也是意外常见的真因。
- 确认这个值是活的,而不只是被写下了。 去看会话实际生效的配置,而不是回头再读一遍你刚改的那个文件。两层设了同一个键时,只有这一步能告诉你谁赢了。
- 确认行为变了。 换端点的话,对面那个端点应该看得到流量;改权限规则的话,它管的那个动作现在应该真的被放行或被拦下。行为是唯一一道无法被「设了但不起作用的值」蒙混过去的检查。
常见问题
为什么我的设置没生效?
按可能性从高到低:同一个键在更本地的层里也设了,正在覆盖你改的那个;文件不是合法 JSON,所以整份都没应用;你改的是设置文件,但你想要的东西在 MCP 配置里(或者反过来);会话是在改动之前启动的,仍在用启动时读到的那份。
项目设置会替换掉我的个人设置吗?
不会,它们按键合并。项目文件没提到的键,保留你用户级文件里的值——这也是为什么一个只包含权限块的项目文件,不会动到你的 hooks 和其他设置。
API 凭据该放在哪?
放在 git 不跟踪的层:用户级设置文件、项目本地设置文件,或者 shell 环境变量。绝不放进会提交的项目级设置文件,也绝不放进会提交的 MCP 配置。
不同项目可以用不同端点吗?
可以,项目本地作用域就是干这个的。把 base URL 与凭据写进该仓库的 .claude/settings.local.json,在那里启动的会话就用它,其他地方仍然走你的默认值。
MCP 服务器是在 settings.json 里配的吗?
不是。它用自己的配置文件、自己的一套作用域。改其中一个对另一个没有任何影响。
一句话总结
配置从环境变量与设置文件两条通道进来;设置文件分用户级、项目级、项目本地级与托管策略四种作用域;它们按键合并而不是互相替换;凭据只能待在不会被提交的层;MCP 服务器是单独配的;而一次改动在你去核实生效值(而不是你刚编辑的那个文件)之前,都不算确认。
ROIBest AI 在一个同时兼容 OpenAI 与 Anthropic 协议的端点上提供 Messages API 形状,也就是说本文描述的这套配置面就是接入的全部内容——一个 base URL 加一个凭据,放进与你希望这套安排有多长久相匹配的那一层。