从 OpenAI 官方切过来:迁移已有的集成

base URL、key、model id 三处改动。哪些原样能用、哪些要复查,以及怎么确认真的切过去了。

需要改的三处

把 SDK 的 base URL 指到 https://token-share.app,key 换成 token-share 的,model 换成本目录里的 id——就这三处。SDK 在这之外做的事(组请求、重试、流式迭代、解析 tool call)一行都不用动,因为线上协议就是它本来说的那套。

model id 这一步不能机械替换:这里没有 gpt-4o 也没有 o3。OpenAI 家的文本 id 是 gpt-5.6-sol、gpt-5.6-terra、gpt-5.6-luna、gpt-5.5、gpt-5.4、gpt-5.4-mini,图像是 gpt-image-2。别猜映射,读 GET /v1/models 看当前有哪些。

还有一个坑:走哪个端点由模型决定,不由你选。gpt-5.x 系列文本模型在 /v1/responses,Grok 与 Gemini 在 /v1/chat/completions。所以若你的代码是围绕 chat completions 写的,又想调 gpt-5.6-terra,那要改的是路由,不只是换个 id。

官方 openai 包接本网关:与直连相比,只有 baseURL、apiKey 和 model 不同。
import OpenAI from 'openai';

const client = new OpenAI({
  baseURL: 'https://token-share.app/v1',
  apiKey: process.env.TOKEN_SHARE_KEY,
});

// gpt-5.x text models answer on /v1/responses
const answer = await client.responses.create({
  model: 'gpt-5.6-terra',
  input: 'Explain what changed in this diff.',
});
console.log(answer.output_text);

// Grok and Gemini answer on /v1/chat/completions
const chat = await client.chat.completions.create({
  model: 'gemini-3-flash',
  messages: [{ role: 'user', content: 'Explain what changed in this diff.' }],
});
console.log(chat.choices[0]?.message?.content);

错误处理这块要预期什么

路由之后产生的错误会按你调用的那条路径的形态返回,所以 OpenAI 形态的调用方拿到的是 OpenAI 形态的错误对象。而在路由之前抛出的错误——key 不对、model 不认识、余额空了——用的是网关自己的结构,严格的 SDK 错误解析器可能认不出来。先按 HTTP 状态码分支,body 当诊断文本读。

状态码本身没什么特别:凭证问题 401,钱的问题 402 / 403,目录里没有的 model 是 400,容量不足 429,可用性问题 503,所有 provider 都失败是 502。SDK 自带的 429 与 5xx 重试在这里是对的行为。

每个响应都带 x-token-share-request-id。你要是本来就在记 OpenAI 的 x-request-id,把这个记在同一处就行——查请求靠它。

验证切换是否生效,以及成本变化

验证要看响应,不要看配置。从一次真实调用里读 x-token-share-request-id,有这个头就说明请求确实走了本网关。迁移「看起来做完了其实没有」,十有八九是容器里某个环境变量没更新。

计价方式是在官方每 token 单价上乘一个倍率,且逐模型不同,不是全目录一个数:低至 0.1 倍;Claude 0.25–0.35 倍;其余主流池内模型 0.2 倍。光 OpenAI 一家,就从 gpt-5.6-sol 的 0.1 倍到 gpt-5.6-luna 的 0.5 倍不等。做预算时,拿该模型自己的官方价乘它自己的倍率。

倍率对一个模型的各类 token 是一致的,所以账单结构不变——本来输出占大头的业务,切过来还是输出占大头。变的是绝对数值,所以你原本信得过的成本模型,乘上倍率就能继续用。

常见问题

要用 Responses API,就得把 chat completions 的代码重写吗?
只有那些确实在 Responses 上的模型才需要。gpt-5.x 文本 id 走 /v1/responses,所以要从 chat completions 的代码路径调它,就得改用 responses 方法。如果暂时不想动这段代码,Grok 和 Gemini 的 id 就在 /v1/chat/completions 上,结构不用改——这是「迁移工作量」与「能用哪些模型」之间实打实的权衡,自己掂量。
流式的行为一样吗?
一样,stream: true 照旧,迭代方式也照旧。响应体是直通转发而不是先缓冲,所以首 token 时延没有被牺牲。用量统计独立于你的客户端从流里读,所以中途 abort 并不会改变这次请求的费用。
同一份代码能同时对着 OpenAI 官方和本网关跑吗?
可以,前提是 base URL、key、model id 都是配置项而不是写死的字面量。协议一致,一个 client 配两套 profile 就够。注意把 model id 和 base URL 放进同一个 profile——把一边的 id 发到另一边,是最先会撞上的错。