什么是 OpenAI 兼容 API?端点、客户端与切换方法
OpenAI 兼容 API 到底是什么
OpenAI 兼容 API指的是:任何一个推理接口,只要它接受与 OpenAI Chat Completions 相同的 HTTP 请求结构、并返回相同结构的响应,就叫「OpenAI 兼容」。它不是 OpenAI 的产品,也不代表与 OpenAI 存在任何关系,它只是一份约定——服务端接受 POST /v1/chat/completions,请求里带 model、messages 数组和 Bearer token,响应里给出 choices[].message.content,那么所有为 OpenAI 写的客户端就能直接跑在它上面。
这份约定之所以成为事实标准,原因很朴素:它是第一个被广泛采用的格式,于是生态里的工具都先适配了它。今天大多数推理服务(vLLM、llama.cpp、Ollama、Together、Groq、OpenRouter,以及 ROIBest AI 这类网关服务)都对外暴露这套接口,不管背后跑的是什么。
由此得到的实际结论,也是本文的重点:换服务商是改配置,不是重写代码。
兼容接口都包含哪些端点
「OpenAI 兼容」是个程度问题,不是一张认证证书。下表前两行几乎所有服务商都实现,越往下支持度越稀薄。
|
端点 |
用途 |
实际支持度 |
|---|---|---|
|
|
主力端点——多轮对话、流式、工具调用 |
通用 |
|
|
列出该端点接受的模型 ID |
接近通用 |
|
|
向量嵌入 |
常见,但模型 ID 各不相同 |
|
|
旧版单 prompt 补全 |
常有,但很少还需要 |
|
|
OpenAI 较新的有状态 API |
OpenAI 之外罕见 |
|
|
语音与图像生成 |
各家自行决定 |
当有人说「把它指向一个 OpenAI 兼容端点」,几乎总是指一个提供 /v1/chat/completions 的 base URL。其余端点属于附加项,应当逐个验证,不要默认存在。
怎么把现有客户端指过去
官方 OpenAI SDK 都提供 base URL 覆写。需要改的只有两样:API key 和 base URL。
Python
from openai import OpenAI
client = OpenAI(
api_key="YOUR_KEY",
base_url="https://your-endpoint.example/v1",
)
resp = client.chat.completions.create(
model="服务商列表里的模型 ID",
messages=[{"role": "user", "content": "用一句话打个招呼。"}],
)
print(resp.choices[0].message.content)Node.js
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
baseURL: "https://your-endpoint.example/v1",
});
const resp = await client.chat.completions.create({
model: "服务商列表里的模型 ID",
messages: [{ role: "user", content: "用一句话打个招呼。" }],
});
console.log(resp.choices[0].message.content);环境变量
大多数命令行工具和 IDE 插件会直接读这两个变量,这意味着很多时候你根本不用改代码:
export OPENAI_BASE_URL="https://your-endpoint.example/v1"
export OPENAI_API_KEY="YOUR_KEY"兼容通常在哪里断掉
兼容性出问题时很少是戏剧性的崩溃,基本逃不出下面六种,大致按出现频率排列:
/v1多了一层或少了一层。 有的 SDK 自己会补/v1,有的不会。https://host/v1/v1/chat/completions返回的 404 看起来很像鉴权失败。先看实际请求路径,再看别的。- 模型 ID 不通用。
gpt-4o是 OpenAI 的标识符;兼容端点只认它自己公布的名字。调GET /v1/models从返回列表里复制,别靠猜。 - 可选参数不被支持。
seed、logprobs、response_format、logit_bias以及n > 1是重灾区。有的服务端静默忽略,有的直接 400。静默忽略更危险——你以为拿到了确定性,其实没有。 - 工具调用存在真实方言差异。
tools/tool_calls的结构普遍实现了,但并行工具调用、流式传输中的参数分片、严格 JSON Schema 校验,各家差别很大。要用你的 agent 真实依赖的那套定义去测,而不是玩具示例。 - 流式分块的细节。 大家都发
data: {...}的 SSE 行、以data: [DONE]收尾,但最后是否带usage分块、是否有空的保活行、finish_reason挂在哪一个 delta 上,都不一样。写死了某一种排列的解析器就会崩。 - 用量与限流元数据。
usage.prompt_tokens一般都有;x-ratelimit-*响应头经常没有。任何靠这些响应头来安排重试的代码,都需要准备兜底逻辑。
三条 curl 验证一个端点
在把兼容端点接进应用之前,先在终端确认一遍。下面三条调用一分钟就能跑完,而且能把鉴权、推理、流式三件事互相隔离开。
# 1. 鉴权 + 模型发现
curl -s https://your-endpoint.example/v1/models \
-H "Authorization: Bearer $OPENAI_API_KEY"
# 2. 一次非流式往返
curl -s https://your-endpoint.example/v1/chat/completions \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"MODEL_ID","messages":[{"role":"user","content":"ping"}]}'
# 3. 同一请求,改成流式
curl -N -s https://your-endpoint.example/v1/chat/completions \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"MODEL_ID","messages":[{"role":"user","content":"ping"}],"stream":true}'第 1 条通、第 2 条挂,问题在模型 ID。第 2 条通、第 3 条卡住不出字,说明你和端点之间有东西在缓冲响应——可能是代理、负载均衡器,或者客户端库自己开了缓冲。
哪些工具在讲这套方言
正因为有这层兼容面,同一个端点才能同时服务形态差别很大的工具:编码类 CLI 和 IDE 插件、LangChain / LlamaIndex 这类编排框架、自建的聊天前端,以及各种一次性脚本。它们要的都只是一个 base URL 加一个 key。
有两类集成值得单独点名,因为问的人最多。Codex 读取标准的 base URL 与 key 配置,逐步配置过程见将 Codex 接入 ROIBest AI。而按 Anthropic 消息格式构建的客户端——Claude Code 属于此类——并不原生讲这套方言,需要在前面加一层协议转换;该机制见Claude API 中转原理。
常见问题
OpenAI 兼容 API 就是 OpenAI 的 API 吗? 不是。它只复制了请求与响应格式,好让现有客户端能直接跑。模型、价格、限流、数据处理方式、可用参数,完全由该服务商自己决定。
必须改应用代码吗? 通常只改 base URL、key 和模型 ID 三处。如果你的代码读限流响应头、依赖 seed 的确定性、或者手写了流式分块解析,就要留时间把这三处核一遍。
函数 / 工具调用能用吗? 基础的 tools 请求与 tool_calls 响应普遍支持。分歧集中在并行调用和严格 schema 校验上——请用 agent 真实使用的工具定义去验证,别用示例代码。
怎么知道一个端点提供哪些模型? GET /v1/models 是该端点的权威答案。文档会过期,模型列表不会。
一个 key 能同时服务多个工具吗? 可以。这正是它最实际的好处:一个 base URL、一个 key,配置在 CLI、编辑器和脚本里,不必为每个工具单独做一套集成。
小结
OpenAI 兼容 API 是一种结构,不是一个品牌。先用 GET /v1/models 确认 base URL 能通,从返回列表里取模型 ID,跑一次流式和一次非流式请求,再核对你代码真正依赖的那几个可选参数。这几步过了,剩下的技术栈本来就已经兼容。
ROIBest AI 在 https://ai.roibest.com 提供 OpenAI 兼容端点,可用于 OpenAI 官方 SDK、兼容格式的 CLI,以及任何允许自定义 base URL 的客户端;各工具的具体配置见集成指南。