Claude Code 怎么改成用自己的 API:只设 Base URL 不算切换
最常见的误解是以为设了 ANTHROPIC_BASE_URL 就切到自己的 API 了。官方文档写得很明确:只设这一个变量不会替换订阅登录,请求确实走了网关,但用的仍是你原来的 claude.ai 账号,额度和计费也还算在它头上。凭据必须一起设,而且要和网关认证头对上——bearer token 用 ANTHROPIC_AUTH_TOKEN,API key 用 ANTHROPIC_API_KEY,选错了会直接 401。建议先用临时环境变量加一条 curl 验证通过,再写进配置文件。
先讲结论:只改 Base URL 不算切换
这是配置自己的 API 时最常踩的一个坑,先把它写在最前面。
官方文档说得很直接:只设 ANTHROPIC_BASE_URL、不设凭据,并不会替换掉你的订阅登录。请求确实是发到你的网关了,但当前生效的凭据仍然是你保存的 claude.ai 登录,额度和计费也还算在它头上。
所以完整的切换是两件事:
ANTHROPIC_BASE_URL:请求发到哪里- 凭据变量:用什么身份认证
两个都设上,才算真的换成了自己的 API。
还没装的先看《Claude Code 安装教程》。
先分清两种凭据
第二个坑在凭据变量选错。这不是随便选一个都行——两个变量走的是不同的 HTTP 头,选错了网关根本读不到,直接返回 401。
| 凭据放在 | 什么时候用 | 实际发送的请求头 |
|---|---|---|
ANTHROPIC_AUTH_TOKEN |
对方说的是「bearer token」或「Authorization 头」 | Authorization: Bearer <值> |
ANTHROPIC_API_KEY |
对方说的是「API key」或「x-api-key」 | x-api-key: <值> |
apiKeyHelper |
凭据会轮换,或者要从密钥库里取 | 两个头都发 |
如果对方没说清楚是哪种,官方建议先用 ANTHROPIC_AUTH_TOKEN,后面的验证步骤会告诉你要不要换。
用 Anthropic 官方 API 的情况更简单:不用改 Base URL,只设 ANTHROPIC_API_KEY 就行。
先用临时环境变量试
强烈建议先用临时环境变量跑通,再写进配置文件。这样出问题时排查范围小,不用怀疑是配置文件没生效还是凭据不对。
Bash 或 Zsh:
export ANTHROPIC_BASE_URL=https://llm-gateway.example.com
export ANTHROPIC_AUTH_TOKEN=sk-gateway-key
PowerShell:
$env:ANTHROPIC_BASE_URL = "https://llm-gateway.example.com"
$env:ANTHROPIC_AUTH_TOKEN = "sk-gateway-key"
如果你的 API 要的是 x-api-key,把 ANTHROPIC_AUTH_TOKEN 换成 ANTHROPIC_API_KEY。
这里的地址和 Token 都是假的,换成你自己的。另外提醒一句:写教程、发截图、发群里求助的时候,务必把真实凭据遮掉。
要注意 shell 里 export 的变量只对当前这个终端和从它启动的程序有效。从 Dock 或开始菜单点开的编辑器读不到。
验证第一步:直接打接口
先别开 Claude Code,用一条 curl 直接打网关。这样如果失败,问题一定在网关或凭据上,跟 Claude Code 无关。
curl -X POST "$ANTHROPIC_BASE_URL/v1/messages" \
-H "Authorization: Bearer $ANTHROPIC_AUTH_TOKEN" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{"model": "claude-sonnet-5", "max_tokens": 1, "messages": [{"role": "user", "content": "."}]}'
如果你的网关用 x-api-key,把 Authorization 那一行换成 -H "x-api-key: $ANTHROPIC_API_KEY"。
怎么看结果:
- 返回的 JSON 以
{"id":"msg_开头、带"content":[...],说明地址和凭据都对 - 报错说模型不存在,也算通过。网关是先认证再检查模型名的,能报到这一步说明认证已经过了,不用特意去找你的网关支持哪个模型
- 返回
401,说明凭据被拒。如果你刚才是猜的变量,换成另一个再试一次
max_tokens 设成 1 是故意的,这条验证请求只花极少的 token。
验证第二步:在 Claude Code 里确认
从刚才那个终端启动 claude(要同一个终端,否则读不到环境变量),发一条消息,然后运行:
/status
在 Status 里看两行:
Anthropic base URL显示的是不是你自己的地址。如果这一行根本没有,说明变量没传进这个会话- 有没有一行
Auth token或API key指向你设的那个变量。有,才说明当前用的是你的凭据,而不是保存的 claude.ai 登录
两行都对,再发一条普通消息能正常返回,就算通了。
通过之后再写进配置文件
临时变量关掉终端就没了。确认可用之后,写进配置文件让它长期生效。
推荐写到用户级配置:
- macOS / Linux:
~/.claude/settings.json - Windows:
%USERPROFILE%\.claude\settings.json
内容是一个 env 块:
{
"env": {
"ANTHROPIC_BASE_URL": "https://llm-gateway.example.com",
"ANTHROPIC_AUTH_TOKEN": "sk-gateway-key"
}
}
只想让某个项目用的,写到 .claude/settings.local.json,并且先确认它已经在 gitignore 里。
有一条红线:不要把凭据写进项目的 .claude/settings.json。那个文件是要提交的,会跟着仓库分发给每个 clone 的人。
配置文件和 shell 变量同时设了同一个变量时,配置文件的值生效。拿不准当前用的是哪个,跑 /status 看。
每个客户端怎么换地址
这一点最容易被忽略:**不是所有入口都读同一套配置。**在终端里配好了,不代表 VS Code 和桌面 App 也跟着变。
| 客户端 | 在哪里配 |
|---|---|
| 终端 CLI | shell 环境变量,或 ~/.claude/settings.json 的 env 块 |
| VS Code / Cursor 扩展 | VS Code 自己的用户设置里的 claudeCode.environmentVariables |
| 桌面 App | App 内的第三方推理配置界面,不读 ANTHROPIC_BASE_URL 和 settings.json |
| 网页版和云端会话 | 由运行环境管理连接,本地这些变量不生效 |
VS Code 和 Cursor
用命令面板打开 Preferences: Open User Settings (JSON),加上:
{
"claudeCode.environmentVariables": [
{ "name": "ANTHROPIC_BASE_URL", "value": "https://llm-gateway.example.com" },
{ "name": "ANTHROPIC_AUTH_TOKEN", "value": "sk-gateway-key" }
]
}
为什么不能只靠 ~/.claude/settings.json:扩展在拉起进程之前会自己检查一次凭据,settings.json 里的值能传给它拉起来的进程,但过不了它自己那道检查。所以凭据要放在这个设置里。
桌面 App
桌面 App 走的是完全不同的一套机制,不读 ANTHROPIC_BASE_URL,也不读 settings.json。
路径是:Help → Troubleshooting → Enable Developer Mode,App 会重启并多出一个 Developer 菜单,然后 Developer → Configure Third-Party Inference,在里面填服务地址。
如果 App 提示 Gateway was unreachable,说明它启动时连不上你填的地址,先用前面那条 curl 复现一下。
一个省事的做法
如果你几个入口都用,最省事的顺序是:
- 先把变量写进
~/.claude/settings.json的env块,终端就都覆盖了 - 再在 VS Code 的用户设置里配一遍
- 桌面 App 单独在界面里填
配完每个入口都跑一次 /status 或发一条消息确认,别假设配了就生效。
怎么换模型
先记住一句:**ANTHROPIC_BASE_URL 只决定请求发到哪里,不决定用哪个模型。**这两件事是分开配的。
会话里临时换
进会话直接敲:
/model
会打开模型选择器。在选择器里按回车是切换并存为默认,按 s 是只对本次会话生效。
也可以直接指定:/model opus、/model sonnet。
启动时指定
claude --model opus
claude --model claude-opus-5
只对这一次会话生效,不会存成默认。
长期设定
写进 ~/.claude/settings.json:
{
"model": "opus"
}
或者用环境变量。这里有两个变量,作用不一样:
ANTHROPIC_MODEL:只对当前会话生效,优先级高于设置文件ANTHROPIC_DEFAULT_MODEL:新会话的默认值,只在没有--model、没有ANTHROPIC_MODEL、设置文件里也没写model时才生效
优先级从高到低是:/model 命令 → --model 参数 → ANTHROPIC_MODEL → 设置文件的 model → ANTHROPIC_DEFAULT_MODEL → 账号或组织默认值。
搞不清当前用的是哪个,/status 里能看到。
网关或第三方服务的模型名
用别名(opus、sonnet、haiku)的前提是对方认这些名字。接自建网关或第三方服务时,模型名往往是对方自己定的,这时候有三种做法。
第一种,直接写全名:
claude --model 服务商给的模型名
第二种,把它加进模型选择器,这样每次不用手敲:
export ANTHROPIC_CUSTOM_MODEL_OPTION="my-gateway/custom-model"
export ANTHROPIC_CUSTOM_MODEL_OPTION_NAME="网关模型"
export ANTHROPIC_CUSTOM_MODEL_OPTION_DESCRIPTION="通过自建网关路由"
它会作为一个额外条目出现在内置选项后面。
第三种,开启网关模型发现,让它启动时自己去问网关有哪些模型:
export CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1
发现到的模型会作为额外条目出现在 /model 列表里。想确认有没有跑成功,用 claude --debug 启动,在 ~/.claude/debug/ 的日志里找 [gatewayDiscovery] 开头的行。
如果你想彻底替换掉选择器里的选项,用设置里的 modelPicker:
{
"modelPicker": [
{ "label": "网关 Opus", "model": "my-gateway/custom-opus" },
{ "label": "快速", "model": "my-gateway/custom-fast" }
]
}
别把模型名写死在教程和脚本里
这一条是经验:模型迭代比文档更新快,写死某个版本号,过几个月就是错的。
实际做法是用别名(opus、sonnet)或者进 /model 看当前有什么可选,而不是记住某个具体名字。接第三方服务时,以对方文档为准。
接国内模型服务
前面讲的配置方式不只用于公司自建网关。国内已经有模型服务商适配了 Anthropic 的调用协议,可以直接用国内地址接进 Claude Code,不需要 Anthropic 账号。
配置方式和前面完全一样,只是地址和凭据换成服务商给的:
export ANTHROPIC_BASE_URL=https://服务商给的地址
export ANTHROPIC_AUTH_TOKEN=你的-API-Key
以智谱的开放平台为例,公开资料里给出的兼容地址是 https://open.bigmodel.cn/api/anthropic,凭据放 ANTHROPIC_AUTH_TOKEN。具体地址、可用模型名和计费方式以服务商自己的文档为准,这类信息变动比教程快。
模型名按上一节的做法处理:先按服务商文档填,或者进 /model 看有哪些可选。
换了模型之后有两件事会不一样
**第一,框架能力不变,模型表现会变。**读文件、跑命令、Skill、MCP、权限审批这些都在框架层,换模型不影响。但多步任务的规划能力、长上下文的处理、工具调用的准确度,不同模型差别不小。建议拿一个你熟悉的活先跑一遍再决定。
第二,有两个功能仍然会去连 api.anthropic.com。
- WebFetch 工具的域名安全预检。这一步不走你配的 Base URL,所以在连不上 Anthropic 的网络里,WebFetch 会卡住。要关掉的话,在设置里把
skipWebFetchPreflight设为true - 快速模式的可用性检查也走这个地址,同样不跟随 Base URL
其余的模型请求都会正常发到你配的地址。这两个点不提前知道的话,很容易误判成「配置没生效」。
认证优先级和计费
这部分直接关系到钱,值得单独看。
- 凭据变量优先于订阅登录。设了之后,你保存的 claude.ai 登录还在,但处于不用的状态
ANTHROPIC_AUTH_TOKEN立刻生效;ANTHROPIC_API_KEY在交互模式下会先问你一次是否使用这个 Key,确认过才接管。非交互模式(-p)下只要设了就直接用- 用网关凭据的时候,不消耗 Claude 订阅额度。费用按 token 算在凭据所属的账号上——可能是你们公司的 Console 账号,也可能是网关背后的云账号
- 想切回订阅,把变量清掉即可
Bash / Zsh:
unset ANTHROPIC_BASE_URL
unset ANTHROPIC_AUTH_TOKEN
unset ANTHROPIC_API_KEY
PowerShell:
Remove-Item Env:ANTHROPIC_BASE_URL -ErrorAction SilentlyContinue
Remove-Item Env:ANTHROPIC_AUTH_TOKEN -ErrorAction SilentlyContinue
Remove-Item Env:ANTHROPIC_API_KEY -ErrorAction SilentlyContinue
如果启动时看到同时存在两个凭据来源的警告,说明网关凭据和保存的登录都在:要么清掉变量用登录,要么跑 /logout 清掉登录只留凭据。
常见问题
| 症状 | 优先检查 |
|---|---|
| 启动后仍然要求登录 | 凭据变量没进到当前进程。放到 shell export 或 ~/.claude/settings.json 的 env 里,项目级配置在首次信任目录之前不生效 |
401 |
凭据无效,或者放错了变量。对照上面的凭据表换另一个再试 |
| 连不上、连接被拒 | 地址写错,或者 VPN、防火墙挡住了。先用上面那条 curl 复现 |
| HTTP 200 但响应为空或格式不对 | 网关或中间代理返回了非 API 内容,常见是 HTML 错误页或登录页 |
/model 里看不到网关的模型 |
模型名不在内置列表里,开 CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1,或用 ANTHROPIC_CUSTOM_MODEL_OPTION 手动加一条 |
| 终端换了模型,VS Code 里没变 | 两个入口读的配置不同,VS Code 要在 claudeCode.environmentVariables 里配 |
桌面 App 提示 Gateway was unreachable |
App 启动时连不上你填的地址,先用 curl 复现 |
/status 里没有自定义地址 |
变量没被当前会话读到 |
设了 ANTHROPIC_API_KEY 却没反应也没提示 |
交互模式下需要一次性批准,之前拒绝过就不会再问。到 /config 里打开 Use custom API key |
| 明明有订阅却按 API 计费 | 正常。凭据变量优先级高于订阅登录 |
| 终端能用但 VS Code 不行 | VS Code 扩展要单独在 claudeCode.environmentVariables 里配 |
| 模型请求正常,但 WebFetch 卡住 | WebFetch 的域名预检仍走 api.anthropic.com,不跟随 Base URL。设 skipWebFetchPreflight: true |
| 证书或 TLS 报错,但 curl 正常 | 公司做了 TLS 拦截,设 NODE_EXTRA_CA_CERTS 指向 CA 证书包 |
配完之后跑一个最小测试
光看 /status 还不够,跑一遍真实任务更放心。建一个测试目录,放一份虚构的商品 CSV:
mkdir claude-ecommerce-test
cd claude-ecommerce-test
claude
然后输入:
读取当前目录的商品 CSV,汇总产品数量和价格区间,生成一份 Markdown 报告。不要修改原始文件。
这一步同时验证三件事:API 通了、它能读到本地文件、它能生成成果物。三件事都成立,才算真的可以开始干活。
配置完成检查表
claude --version正常- Base URL 已配置
- 凭据变量和网关认证头对得上
- curl 验证返回正常或只报模型名错误
/status显示自己的地址和凭据来源- 普通消息能正常返回
- 商品 CSV 测试跑通
- 凭据没有提交到 Git,也没有出现在截图里




