省流:一句 prompt 让 Claude Code 自己配好
点开复制这段 prompt,粘进 Claude Code 主会话,它会反问你要 base_url 和 token,其他都不用管
帮我在 ~/.zshrc 里加一个 claudex 别名,用来调用 claude 时强制走中转站的 GPT 模型。先问我要中转站的 base_url 和 token,其他配置都用下面这份写死,不用再问我: alias claudex='CLAUDE_CODE_SUBAGENT_MODEL=gpt-5.6-sol \ CLAUDE_CODE_ALWAYS_ENABLE_EFFORT=1 \ CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY=3 \ ENABLE_TOOL_SEARCH=false \ claude --settings "{\"env\":{\"ANTHROPIC_BASE_URL\":\"<base_url>\",\"ANTHROPIC_AUTH_TOKEN\":\"<token>\",\"ANTHROPIC_MODEL\":\"gpt-5.6-sol\",\"ANTHROPIC_DEFAULT_SONNET_MODEL\":\"gpt-5.6-sol\",\"ANTHROPIC_DEFAULT_OPUS_MODEL\":\"gpt-5.6-sol\",\"ANTHROPIC_DEFAULT_HAIKU_MODEL\":\"gpt-5.6-terra\"}}" \ --model gpt-5.6-sol' 把 <base_url> 和 <token> 换成我告诉你的值后写进 ~/.zshrc,不要修改 ~/.claude/settings.json。这么做是因为 settings.json 里已有的 env 块优先级比 shell 导出的环境变量高,直接用 VAR=value claude 这种前缀写法传 base_url/token 不会生效,必须走 --settings 内联 JSON。
想看清楚为什么非要走 --settings 不可,继续往下读。
背景
我平时 claude 命令走的是中转站(~/.claude/settings.json 的 env 块里配了 ANTHROPIC_BASE_URL / ANTHROPIC_AUTH_TOKEN)。想加一个 claudex 命令,专门切到中转站上的 GPT 模型(gpt-5.6-sol 当主模型,haiku 位置本想用 gpt-5.6-luna,但调不通,改用 gpt-5.6-terra),但不想动 settings.json 里正在用的主配置。
第一版思路很直觉:写个 zsh alias,用环境变量前缀覆盖:
alias claudex='ANTHROPIC_BASE_URL=https://your-proxy.example.com \
ANTHROPIC_AUTH_TOKEN=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \
ANTHROPIC_MODEL=gpt-5.6-sol \
claude --model gpt-5.6-sol'看起来没问题——shell 里 VAR=value command 这种前缀写法,理论上应该只在这一次调用里生效,覆盖掉继承来的环境变量。
问题
实测下来,claudex 发出去的请求用的还是 settings.json 里原来的 token,新 token 完全没生效。
排查后发现:Claude Code 启动时会把 ~/.claude/settings.json 里 env 字段的内容主动写回自己的进程环境,而且是无条件覆盖,不只是”没设置才补全”。也就是说:
- 你在 shell 里
export或者用前缀语法传的ANTHROPIC_AUTH_TOKEN/ANTHROPIC_BASE_URL - 会先被继承进
claude进程 - 但紧接着又被
settings.json的env块原样覆盖回去
这是有意为之的设计(大概率是为了让企业/团队的策略配置始终优先,不被本地 shell 环境意外顶掉),但对我这种”临时切一下模型”的场景就很不友好——shell 层面的覆盖直接失效。
修复思路
claude --help 里有个 --settings <file-or-json> 参数,专门用来在启动时额外加载一份设置,优先级比用户级 settings.json 高。把中转站的 base_url、token、模型相关的 env 都塞进这份内联 JSON,而不是塞进 shell 环境变量:
alias claudex='CLAUDE_CODE_SUBAGENT_MODEL=gpt-5.6-sol \
CLAUDE_CODE_ALWAYS_ENABLE_EFFORT=1 \
CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY=3 \
ENABLE_TOOL_SEARCH=false \
claude --settings "{\"env\":{\"ANTHROPIC_BASE_URL\":\"https://your-proxy.example.com\",\"ANTHROPIC_AUTH_TOKEN\":\"sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\",\"ANTHROPIC_MODEL\":\"gpt-5.6-sol\",\"ANTHROPIC_DEFAULT_SONNET_MODEL\":\"gpt-5.6-sol\",\"ANTHROPIC_DEFAULT_OPUS_MODEL\":\"gpt-5.6-sol\",\"ANTHROPIC_DEFAULT_HAIKU_MODEL\":\"gpt-5.6-terra\"}}" \
--model gpt-5.6-sol'其中 gpt-5.6-sol 是 sonnet/opus 都对应的主模型,haiku 本来想配 gpt-5.6-luna,但中转站上这个模型调不通,退而求其次用 gpt-5.6-terra,成本也没上升多少——具体用哪个模型名,看你中转站上暴露的模型别名,替换掉即可。
要点:
CLAUDE_CODE_SUBAGENT_MODEL/CLAUDE_CODE_ALWAYS_ENABLE_EFFORT这类不属于settings.jsonenv 覆盖范围的变量,还是可以用普通 shell 前缀传,只影响这一次调用。- 真正会被
settings.json抢回去的(ANTHROPIC_BASE_URL、ANTHROPIC_AUTH_TOKEN、ANTHROPIC_MODEL及三个ANTHROPIC_DEFAULT_*_MODEL),一律走--settings内联 JSON。 ~/.claude/settings.json本身完全不用动,平时的claude命令行为不受影响。
验证
source ~/.zshrc后alias claudex确认定义生效。- 新终端跑
claudex,进去用/status看当前 base URL 和 model——应该显示中转站地址和目标模型,而不是settings.json里的默认值。 - 另开一个终端跑普通
claude,确认还是走原来的 token 和默认模型,没被claudex的配置污染。
题外话
这类”我传的环境变量为什么没生效”的坑,本质都是优先级链路不透明:CLI 参数、shell 环境变量、用户级配置文件、项目级配置文件之间到底谁盖谁,得靠 --help 或实测才能确认,不能想当然地认为”离执行最近的赋值优先级最高”。遇到类似问题,先想办法验证优先级(比如故意传一个能观察到的值),再决定往哪一层写配置。