接入教程

OpenAI 兼容 Base URL 该填什么:四种典型填错方式与一条验证命令(2026)

Kenji Watanabe

每一家 OpenAI 兼容的服务商都会给你一个 base URL,然后默认你知道该拿它怎么办。接入第一天遇到的失败,大多既不是鉴权问题也不是模型名问题,而是 base URL 差了一个路径段或一个斜杠——却报出一个指向完全别处的错误信息。

能解决其中绝大部分的一条规则是:base URL 就是 SDK 会在其后面拼接自己那段固定路径的部分。 其余所有细节,都由「你的客户端到底拼了什么」推导出来。

base URL 替换的是哪一段

OpenAI SDK 构造请求 URL 的方式是把一个 base 和一段固定路由拼起来:

<base_url> + /chat/completions

官方客户端的默认 base 是 https://api.openai.com/v1。注意那个结尾的 /v1 属于 base,不属于路由。所以最终 URL 是 https://api.openai.com/v1/chat/completions

这一个事实就决定了你该往配置里粘什么。如果服务商文档写的端点是 https://example.com/v1/chat/completions,那么你的 base URL 是:

https://example.com/v1

不是 https://example.com,也不是那条完整的端点路径。

四种典型的填错方式

1. SDK 不会补 /v1,而你把它漏了。 用 OpenAI 的 Python 或 Node SDK 填 https://example.com,请求会打到 https://example.com/chat/completions——通常是 404,有时返回的是一个 HTML 错误页,于是你的客户端抛出的是 JSON 解析错误而不是干净的 HTTP 错误。识别特征:报错里出现 unexpected token 或 invalid JSON,而不是状态码。

2. 客户端已经会补 /v1,而你又填了一遍。 镜像问题,在封装了 SDK 的工具里更常见。结果是 https://example.com/v1/v1/chat/completions。特征是 404 的报错里能看到重复的路径段——要读错误里的完整 URL,而不是只看状态码。

3. 结尾多了一个斜杠。 https://example.com/v1/ 拼上 /chat/completions 会得到 //chat/completions。有的网关会归一化,有的会路由到另一个处理器,有的直接 404。去掉结尾斜杠没有任何代价,所以去掉它。

4. base URL 设在一处,环境变量设在另一处。 OPENAI_BASE_URL(以及更老的 OPENAI_API_BASE)是在构造客户端时被 SDK 读取的。代码里显式传入的 base URL 会覆盖环境变量;而在一个并非运行你进程的 shell 里 export 的 base URL 则完全不起作用。当终端里和应用里的表现不一致时,先确认正在运行的进程实际看到的是哪一个。

各类客户端分别期望什么

客户端

填在哪里

需要带 /v1

openai Python SDK

OpenAI(base_url=...)OPENAI_BASE_URL

需要,由你提供

openai Node SDK

new OpenAI({ baseURL })

需要,由你提供

LangChain(OpenAI 封装)

openai_api_base / base_url

需要

curl / HTTP 客户端

你自己写完整 URL

整条路径都由你写

Claude Code / Codex 这类 CLI

服务商配置项或环境变量

通常需要——查该工具文档是否自行补版本段

当某个工具的文档写得含糊时,最快的解决办法不是去读更多文档,而是发一次请求,看服务端到底收到了什么。

一条命令完成验证

在把它接进应用之前,先直接请求 SDK 会构造出的那条路由:

curl -sS https://example.com/v1/chat/completions \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"<model-id>","messages":[{"role":"user","content":"ping"}],"max_tokens":8}' \
  -w '\nHTTP %{http_code}  final=%{url_effective}  redirects=%{num_redirects}\n'

输出里有三样东西和响应体同样重要:

  • HTTP 状态码。 200 说明 base URL 和路由都对。404 说明路径错了,是 base URL 的问题。401 说明路径是对的、问题在密钥——这是进展,不是倒退。
  • redirects 大于 0 意味着你打到的是一个会跳转的 URL。有些客户端在跳转时会丢掉 Authorization 头,表现出来就是一个让人困惑的 401。把跳转终点当作你的 base。
  • final 读它,看有没有重复的 /v1//

这条 curl 返回 200 之后,把该 URL 中 /chat/completions 之前的全部内容设为你的 base URL。

从报错反推病因

你看到的现象

最可能的原因

404,URL 里路径段重复

/v1 填了两遍

404,路径里缺版本段

base 里漏了 /v1

JSON 解析错误 / unexpected token <

打到了 HTML 页面而非 API,通常是路径错

原本可用的路由突然 401

跳转把鉴权头丢了,或密钥与 base 不匹配

连接被拒 / DNS 失败

base URL 的主机写错,或有代理拦截

返回 200 但响应来自意料之外的模型

base URL 没问题,是模型别名在上游被重映射

比路由更上一层的问题——URL 正确但参数被静默忽略——见 OpenAI 兼容性问题:所谓「兼容」到底覆盖了什么。如果请求已经到达服务端却被拒绝,见 Anthropic API Key 不可用?先读状态码。想跑通第一次端到端调用,见 如何使用 Claude API

常见问题

OpenAI 的 base URL 要不要带 /v1?

如果你的客户端只拼接 /chat/completions,那就要带——/v1 属于 base。官方 Python 和 Node SDK 都是这样。发一次 curl、读一下最终 URL 即可确认。

OPENAI_BASE_URL 和 OPENAI_API_BASE 有什么区别?

OPENAI_API_BASE 是较老的变量名,OPENAI_BASE_URL 是现代 SDK 中的当前写法。有些工具仍然只读旧的那个。如果 base URL 看起来没生效,两个都设,或者直接在代码里显式传入(代码里的优先级最高)。

为什么 curl 能通、SDK 却报 404?

几乎总是因为你的 curl 用的是完整端点路径,而 SDK 是从你的 base 拼出了另一条路径。把 curl 打到的 URL 和 SDK 报错里的 URL 对照一下,差异之处就是要改的地方。

base URL 结尾的斜杠有影响吗?

可能有。base/ 拼上 /chat/completions 会产生双斜杠,部分网关的路由行为会因此不同。去掉结尾斜杠。

一句话总结

base URL 就是 SDK 会在其后拼上 /chat/completions 的那一段——通常是服务商的主机加 /v1,结尾不带斜杠。用一条 curl 验证它,读状态码、跳转次数和最终 URL:404 是路径问题,401 说明路径已经对了,而 JSON 解析错误意味着你打到的是一个网页而不是 API。