从模型直连到统一 AI 网关:多模型 API、Codex 与 Claude Code 接入实践
过去一年,我在不同项目里接过多家大模型:有的使用 OpenAI 风格接口,有的使用自有 SDK,有的鉴权头不同,还有的流式事件格式完全不一样。

只接一个模型时,这些差异不算麻烦。但当项目需要同时使用 GPT、Claude、Gemini、DeepSeek、Qwen 等模型,或者想在 Codex、Claude Code 和业务服务之间复用同一套模型资源时,问题就会逐渐暴露:
- 每增加一家供应方,都要维护一套 SDK 和环境变量;
- 模型切换会侵入业务代码;
- 超时、重试、限流和日志散落在各个调用点;
- 多个控制台的余额、账单和调用记录难以统一;
- AI 编程工具与业务程序往往还使用不同的协议。
这篇文章不比较哪个模型“最强”,而是讨论一个更工程化的问题:如何用统一 AI 网关降低应用与模型供应方之间的耦合,并让同一套 API 同时服务于代码、Codex 和 Claude Code。
一、为什么不建议让业务代码直接绑定模型厂商
最常见的接入方式,是在业务层直接调用厂商 SDK:
业务服务 -> 厂商 SDK -> 模型 API
它的优点是链路短,也能第一时间使用厂商的专属能力。但当模型数量增加后,业务层很容易按 OpenAI、Anthropic、Google 等供应方堆叠条件分支。真正麻烦的并不是分支本身,而是它们背后的差异:
| 关注点 | 可能存在的差异 |
|---|---|
| 鉴权 | Bearer Token、自定义请求头、项目凭据 |
| 请求结构 | messages、contents、system 字段的位置 |
| 流式响应 | SSE 数据块、事件名称、结束标记 |
| 工具调用 | 参数结构、调用 ID、并行工具调用能力 |
| 错误语义 | HTTP 状态码、错误码、是否适合重试 |
| 用量统计 | 输入、输出、缓存、推理 Token 的口径 |
如果这些差异散落在 Controller、定时任务、Agent 和脚本中,后续想换模型时,改动范围通常比预期大。
更稳妥的做法,是在业务和模型供应方之间增加一个稳定的抽象层:
业务服务 / AI 编程工具 | v统一 AI 网关├─ API Key 鉴权├─ 协议适配├─ 模型路由├─ 超时与有限重试├─ 限流与配额└─ 日志与用量统计 | v OpenAI / Anthropic / Google / 其他模型服务
客户端只需要关心三个配置:
- Base URL;
- API Key;
- Model ID。
模型供应方发生变化时,客户端接口尽量保持稳定,差异由网关内部消化。
二、统一接口不等于抹平所有协议
OpenAI 兼容接口已经成为很多 AI 工具事实上的通用接入方式。例如对话请求通常采用以下结构:
{"model": "模型 ID","messages": [{ "role": "system", "content": "你是一名编程助手" },{ "role": "user", "content": "解释这段代码" }]}
只要网关提供兼容端点,大量 SDK 和客户端就可以通过修改 Base URL 完成迁移,业务代码不必重新实现一遍。
但“兼容”需要有边界。OpenAI、Anthropic 与 Google 的协议并非完全等价,至少有三类能力需要单独处理:
1. 流式事件
不同协议的事件名称、增量字段和结束方式不完全相同。网关不能只转发原始字节,还需要保证客户端能正确识别文本增量、工具调用和结束事件。
2. 工具调用
工具定义、工具选择和调用结果回传的结构可能不同。简单对话可以统一,复杂 Agent 场景则要验证目标模型与兼容层是否完整支持工具调用。
3. 厂商专属参数
推理强度、缓存、视觉输入、结构化输出等能力,可能只在特定协议或模型中存在。好的抽象不是强行取交集,而是让通用能力保持一致,同时允许高级调用显式选择原生协议。
因此,一个实用的网关通常会同时提供 OpenAI、Anthropic 或 Google 兼容入口,而不是把所有请求都压成一种格式。
三、用 Node.js 调用 OpenAI 兼容接口
下面给出一个通用的 OpenAI 兼容接口示例。代码只使用 Node.js 18+ 自带的 fetch,没有第三方依赖,并包含环境变量校验、30 秒超时、HTTP 错误和响应结构检查。接口地址、密钥和模型都从环境变量读取,因此可以用于官方接口、自建网关或其他兼容服务。
const apiKey = process.env.AI_GATEWAY_API_KEY;const model = process.env.AI_GATEWAY_MODEL;const baseUrl = (process.env.AI_GATEWAY_BASE_URL || '').replace(//$/, '');if (!apiKey) {console.error('请先设置 AI_GATEWAY_API_KEY');process.exit(1);}if (!model) {console.error('请先设置 AI_GATEWAY_MODEL');process.exit(1);}if (!baseUrl) {console.error('请先设置 AI_GATEWAY_BASE_URL,例如兼容服务的 /v1 地址');process.exit(1);}async function createChatCompletion() {const controller = new AbortController();const timeoutId = setTimeout(() => controller.abort(), 30_000);try {const response = await fetch(`${baseUrl}/chat/completions`, {method: 'POST',headers: {Authorization: `Bearer ${apiKey}`,'Content-Type': 'application/json'},body: JSON.stringify({model,messages: [{role: 'system',content: '你是一名严谨的 Ja vaScript 助手。'},{role: 'user',content: '请用三句话解释什么是事件循环。'}],temperature: 0.3}),signal: controller.signal});const responseText = await response.text();if (!response.ok) {throw new Error(`请求失败:HTTP ${response.status} ${responseText}`);}const data = JSON.parse(responseText);const content = data.choices?.[0]?.message?.content;if (!content) {throw new Error(`响应中没有可读取的文本:${responseText}`);}console.log(content);} catch (error) {if (error.name === 'AbortError') {console.error('请求超时:30 秒内未收到完整响应');} else {console.error(error instanceof Error ? error.message : String(error));}process.exitCode = 1;} finally {clearTimeout(timeoutId);}}createChatCompletion();
保存为 chat.js 后,先设置密钥和模型:
export AI_GATEWAY_BASE_URL="https://vsoui.com/v1"export AI_GATEWAY_API_KEY="sk-你的密钥"export AI_GATEWAY_MODEL="your-model-id"node chat.js
把示例地址和模型 ID 替换成实际服务提供的配置。可用模型不应该长期写死在代码里;如果兼容服务实现了模型列表接口,可以通过环境变量查询:
curl "$AI_GATEWAY_BASE_URL/models" -H "Authorization: Bearer $AI_GATEWAY_API_KEY"
这里有两个容易忽略的细节:
- Base URL 已经包含
/v1,代码里只需追加/chat/completions; - 错误响应也可能是 JSON,但排查阶段保留原始响应文本往往更有用。
四、Codex 和 Claude Code 本质上也在配置网关
AI 编程工具的界面不同,底层配置思路却很接近:告诉工具使用哪个协议、请求地址是什么、密钥从哪里读取,以及默认使用哪个模型。
Codex:OpenAI Responses 协议
Codex 支持自定义模型供应方。一个典型的 ~/.codex/config.toml 配置如下:
model_provider = "custom_gateway"model = "your-model-id"model_reasoning_effort = "high"[model_providers.custom_gateway]name = "custom_gateway"base_url = "https://vsoui.com/v1"env_key = "OPENAI_API_KEY"wire_api = "responses"
至于密钥,处理方式没有变化,依然是通过环境变量注入:
export OPENAI_API_KEY="sk-你的密钥"codex
这段里真正需要盯紧的,其实是 wire_api = "responses"。很多业务代码平时走的是 /chat/completions,但到了新版 Agent 工具,调用的很可能就是 Responses API。也就是说,配置兼容网关时,不能只看一句“兼容 OpenAI”就算了,更关键的是要进一步确认:它到底支不支持当前客户端实际使用的那个端点。
base_url 和 model 是配置模板,使用时替换为目标服务的实际地址和模型 ID。
Claude Code:Anthropic 协议
Claude Code 更适合走 Anthropic 兼容入口,核心配置可以通过环境变量表达:
export ANTHROPIC_AUTH_TOKEN="sk-你的密钥"export ANTHROPIC_BASE_URL="https://vsoui.com"export ANTHROPIC_MODEL="your-model-id"claude
这里使用的是 Anthropic 兼容协议,而不是上一节的 OpenAI 兼容协议。不同网关对路径前缀的约定可能不同,Base URL 和模型名称都应以目标服务的接口说明为准。
如果同时使用 Codex、Claude Code、OpenCode 等工具,可以借助配置管理工具切换供应方;不过无论界面如何封装,最终都要检查四件事:
- Base URL 是否与协议匹配;
- 密钥读取的环境变量名是否正确;
- 客户端使用 Chat Completions、Responses 还是 Anthropic Messages;
- 所选模型是否支持工具调用、视觉或推理等所需能力。
五、一个统一模型网关真正需要解决什么
把请求成功转发,只完成了最基础的一步。用于真实项目时,还需要重点处理下面几类问题。
1. 超时分层
连接超时、首 Token 超时和完整响应超时应该分别观察。推理模型可能首 Token 较慢,如果只有一个很短的总超时,会把正常的深度推理误判为故障。
2. 有限重试
可以考虑重试网络错误、429 和部分 5xx,但不要无条件重试所有请求:
400一般是参数错误,重试没有意义;- 流式响应已向用户输出部分内容后,自动重试可能产生重复文本;
- 带工具副作用的 Agent 请求,需要幂等键或业务去重。
推荐采用有限次数的指数退避,并为单次请求设置总时间预算。
3. 模型路由与降级
路由不只是“模型 A 失败就换模型 B”。两个模型的上下文长度、工具调用、视觉能力和输出风格可能不同。降级策略应该按能力标签配置,例如:
代码任务 -> 代码模型主路由 -> 同能力模型备用路由视觉任务 -> 支持图片输入的模型集合批处理-> 低成本模型 + 更严格的并发限制
4. 日志脱敏
建议记录请求 ID、模型、耗时、状态码、Token 用量和错误类型,但不要默认保存完整 Prompt。API Key、Authorization 头、用户隐私和上传文件信息必须脱敏。
5. 密钥隔离
生产密钥不应写在前端代码、仓库或截图中。至少应按环境和应用拆分密钥,并支持轮换、吊销、额度限制和异常用量告警。
6. 成本可观测
仅看请求次数不够。不同模型的输入、输出、缓存和推理 Token 价格可能不同,网关需要统一记录用量口径,才能回答“哪个功能、哪个用户、哪个模型消耗最多”。
六、统一网关并不适合所有项目
统一网关能降低接入成本,但它不是所有系统的默认答案。以下场景更应该认真评估官方直连或企业级专线方案:
- 对数据驻留地区有明确要求;
- 处理医疗、金融、政务等敏感数据;
- 依赖某家厂商刚发布、尚未被兼容层支持的专属能力;
- 需要与厂商签署单独的 SLA、DPA 或审计协议;
- 调用规模足够大,值得直接谈企业合同和专属配额。
无论选择官方接口、自建网关还是第三方兼容服务,都建议先用非敏感数据进行验证,测试模型可用性、流式响应、工具调用、超时、错误码和用量记录,再决定是否进入正式环境。
总结
多模型时代,真正值得稳定下来的不是某个具体模型名,而是应用与模型之间的接口边界。
一个实用的统一 AI 网关,至少应该做到:
- 用稳定入口隔离上游变化;
- 明确处理不同协议的兼容边界;
- 统一超时、重试、限流、日志和用量;
- 让业务代码和 AI 编程工具复用同一套接入方式;
- 对安全、合规和厂商专属能力保留清晰边界。
当接入规模扩大后,还可以继续把模型能力标签、动态路由、请求幂等和成本归因拆成独立模块。这样即使上游模型持续变化,业务层仍然可以维持稳定、可测试的调用边界。
接入地址是:https://vsoui.com/
-
下载
-
- 关于柯南的沙雕网名有哪些
- 角色扮演 | 1
- 网名
-
- 最新中性名字男女通用网名有哪些
- 角色扮演 | 1
- 网名
-
- 关于蓝色说唱的网名有哪些
- 角色扮演 | 1
- 网名
-
- 我好喜欢你是什么梗?
- 角色扮演 |