Claude Code 配 ANTHROPIC_BASE_URL 后 404?检查 /v1/messages 是否重复

Claude Code 已经能启动,settings.json 里也写了 ANTHROPIC_BASE_URL,第一条消息却返回 404,最容易先改的是模型名或 API Key。这个顺序不一定对:404 可能发生在请求还没有进入模型路由之前,真正的问题是客户端和 Base URL 各自拼了一次 /v1

本文只解决一个问题:Claude Code CLI 接自定义 Anthropic Messages 端点时,怎样确认 Base URL 的边界,以及怎样从实际请求路径判断是不是 /v1/v1/messages。实测环境是 Claude Code 2.1.219 (Claude Code),服务端是只监听 127.0.0.1 的合成夹具,没有请求线上 Anthropic 或第三方 provider。

先按最小路径跑一次

适用环境

适用于已经安装 Claude Code CLI、目标服务声称兼容 Anthropic Messages,并且你能查看网关访问日志的 macOS/Linux 环境。Windows 可以把用户设置路径替换成 %USERPROFILE%\\.claude\\settings.json;项目级文件仍放在项目目录的 .claude/ 下。

1. 先确认你改的是哪一层

Claude Code 当前 CLI 帮助列出了 userprojectlocal 三类 settings source。不要同时改三份文件后再猜优先级,先只读确认路径:

ls -l ~/.claude/settings.json
ls -l .claude/settings.json 2>/dev/null || true
ls -l .claude/settings.local.json 2>/dev/null || true

如果需要完全隔离一次验证,可以把环境变量放进一个临时 JSON,再用 --settings 明确加载。下面的 URL 是占位符,不要把真实 Key 写进仓库、截图或 shell history:

{
  "env": {
    "ANTHROPIC_BASE_URL": "https://your-anthropic-compatible-endpoint.example",
    "ANTHROPIC_AUTH_TOKEN": "<REDACTED>",
    "ANTHROPIC_MODEL": "provider-model-id"
  }
}

这里最重要的是 ANTHROPIC_BASE_URL 的末尾。本文的 Claude Code 版本会自己补 /v1/messages,因此先填服务文档规定的 API 根地址;不要因为网上某个 OpenAI 示例写了 /v1,就原样复制到 Anthropic Messages 配置。

2. 用一次最小命令观察成功信号

claude --bare \
  --settings /tmp/claude-path-check.json \
  --tools "" \
  --print "hello"

成功信号不是“CLI 启动了”,而是网关访问日志出现一条 POST /v1/messages,并且命令能读到一个正常的 Anthropic Message 响应。失败信号是访问日志出现 POST /v1/v1/messages 或者网关直接返回 404。只看网页首页能否打开,不能证明消息路径正确。

Base URL 到底应该写到哪里

把“服务根地址”和“资源路径”分开看:

ANTHROPIC_BASE_URL = https://gateway.example
Claude Code       + /v1/messages
实际请求            https://gateway.example/v1/messages

如果把同一个端点写成 https://gateway.example/v1,当前版本会继续追加资源路径:

ANTHROPIC_BASE_URL = https://gateway.example/v1
Claude Code       + /v1/messages
实际请求            https://gateway.example/v1/v1/messages

这两条 URL 不是同一个资源。很多网关对未知路径直接返回 404,所以你会误以为模型不存在。只有当目标服务文档明确要求“Base URL 已经包含 /v1,且客户端不会再追加”时,才按它的约定填写;不要把 OpenAI Chat Completions 的经验套给 Anthropic Messages 客户端。

本机回环实测:200 和 404 的分界

内容包中的夹具只绑定 127.0.0.1,执行:

python3 06-evidence/probe_claude_base_url.py

本次脱敏输出如下:

CLAUDE_VERSION=2.1.219 (Claude Code)
ROOT_SETTINGS_EXIT=0
ROOT_SETTINGS_SIGNAL=fixture path success
DUPLICATE_V1_EXIT=1
DUPLICATE_V1_SIGNAL=404_expected
SHELL_OVERRIDE_EXIT=1
SHELL_OVERRIDE_SIGNAL=settings_value_won
REQUESTS=[
  {"path":"/v1/messages?beta=true","status":200},
  {"path":"/v1/v1/messages?beta=true","status":404}
]
SUMMARY=pass root_200 duplicate_v1_404 settings_env_precedence_observed
ONLINE_PROVIDER_REQUEST=NO

这里的 200 只说明当前 Claude Code 把根地址拼成了 /v1/messages,不是某个线上 provider 已经兼容。404 分支则证明了路径重复时错误发生在路由层。夹具只记录路径、合成模型名、认证类别和状态码,不记录任何凭据。

Claude Code Base URL 重复路径实测结果

三个容易误判的失败路径

1. Base URL 末尾多了 /v1

这是本文的主问题。把配置从 https://gateway.example/v1 改为 https://gateway.example 后,重新启动一次 Claude Code,再看访问日志是否恢复为 /v1/messages。不要只改模型名,也不要用无限重试掩盖 404;相同路径重复失败时,重试不会改变路由。

2. shell 环境变量没有覆盖 settings.json

我在同一次实测中让 settings 文件写入错误的 .../v1,同时在启动进程里导出正确的根地址。结果仍然请求 /v1/v1/messages,命令退出码为 1,说明在这次 --settings 运行里,settings env 的值胜过同名 shell 变量。

这不是让你背一条永久优先级,而是提醒你不要同时维护两套值。先选一个来源,再用访问日志确认最终地址:

env | grep '^ANTHROPIC_BASE_URL=' || true
python3 -m json.tool /tmp/claude-path-check.json

如果两处值不同,先清掉临时 shell 变量或改正 settings 文件,再重启会话。不要把完整 Key 打到 env 输出或诊断截图里。

3. 把 Anthropic Messages 和 OpenAI Chat Completions 混在一起

Anthropic Messages 的资源路径是 /v1/messages,请求体和响应结构也不同于 /v1/chat/completions。如果目标服务只实现 OpenAI 兼容接口,把 URL 改成 /v1 并不会让 Claude Code 自动获得协议兼容;此时可能得到 404、405、协议解析失败或网关统一错误。先查服务文档,再用最小消息请求确认协议,不要把“域名可访问”写成“API 已兼容”。

排查顺序

  1. 记录 CLI 版本:claude --version
  2. 确认实际生效的 settings source,不要同时编辑 user、project、local 三份配置。
  3. ANTHROPIC_BASE_URL 只保留服务根地址,除非目标文档明确要求带版本路径。
  4. --bare --settings 做最小请求,关闭工具、插件和额外上下文干扰。
  5. 查看脱敏访问日志,确认实际路径是 /v1/messages,再判断 401、403、404 或响应结构问题。
  6. 只有路径正确且协议响应可读后,才进入认证、模型 ID 或流式事件排查。

安全边界

示例中的 <REDACTED>provider-model-id 和本地 fixture 值都不是可用凭据。真实 API Key 不应出现在仓库、截图、Issue 或 shell history;项目级 settings 也不要提交明文密钥。本文没有请求线上 Anthropic 或任何第三方 provider,回环结果不能替代你对目标服务当前文档和脱敏日志的核验。

总结

Claude Code 配自定义 Anthropic 端点遇到 404 时,先确认请求路径,再换模型或 Key。对当前 2.1.219,根 Base URL 会生成 /v1/messages;Base URL 末尾再加 /v1 会生成 /v1/v1/messages,夹具返回 404。把配置收敛到一个 settings source,用 --bare --settings 做最小复现,并以访问日志中的真实路径作为成功信号,才能把路由错误和模型、认证问题分开。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐