Codex CLI + 国产模型:一个零侵入的 AI 网关实践

OpenAI 的 Codex CLI 是一个强大的终端 AI 助手,但它默认只能使用 OpenAI 的模型。本文介绍如何通过自建 AI Gateway,让 Codex CLI 无需修改任何代码即可使用 DeepSeek、通义千问、Kimi、智谱 GLM 等国产大模型,并完整保留推理过程展示、工具调用、网络搜索等高级功能。

背景:为什么需要一个网关?

Codex CLI 是 OpenAI 推出的命令行 AI 编程助手,类似于 Claude Code,但它基于 OpenAI 的 Responses API 协议与模型通信。国产大模型普遍兼容的是 Chat Completions API,两者在请求格式、响应结构、流式事件、工具调用约定上存在显著差异。

让 Codex 直接调用国产模型?不行------协议不兼容。Fork Codex 改代码?维护成本太高。

最优雅的方案是中间加一层网关:Codex 以为自己在跟 OpenAI 通信,国产模型以为自己在服务一个普通的 Chat Completions 客户端。网关负责协议的双向翻译。

零侵入接入:只需两个环境变量

这是整个方案最优雅的地方------不需要 fork Codex,不需要改一行代码,只需要设置两个环境变量:

bash 复制代码
# 把 Codex 的请求指向本地网关
export OPENAI_BASE_URL=http://localhost:3000
# 用网关的 API Key 替代 OpenAI 的 Key
export OPENAI_API_KEY=gateway-your-api-key

# 正常启动 Codex
codex

Codex CLI 会把所有 /v1/responses 请求发到本地网关,网关翻译后转发给国产模型,再把响应翻译回 Responses API 格式返回。整个过程对 Codex 完全透明。

核心架构:协议翻译层

请求方向:Responses API → Chat Completions API

当 Codex 发送一个 Responses API 请求时,网关需要做以下转换:

Responses API 概念 Chat Completions API 概念
instructions 字段 system 角色消息
input 字符串 user 角色消息
input 结构化数组 按类型逐项映射为 messages
function_call_output 输入项 role: "tool" 消息
previous_response_id 从数据库查询历史消息并拼接
tools[].type: "function" 直接透传
web_search_preview 工具 拦截,触发网关内置搜索逻辑
computer_use_preview 工具 拦截,注入 Prompt 引导

其中 input 的结构化数组是最复杂的部分。Codex 的多轮对话会把历史消息以结构化数组的形式发送,网关需要正确识别每条消息的类型(用户消息、助手回复、工具调用、工具结果)并映射为对应的 Chat Completions 角色。

响应方向:Chat Completions API → Responses API

国产模型返回的响应同样需要翻译:

Chat Completions 字段 Responses API 字段
message.content output 中的 output_text
message.reasoning_content output 中的 reasoning 项(含 summary)
message.tool_calls output 中的 function_call
usage.prompt_tokens usage.input_tokens
usage.completion_tokens usage.output_tokens

流式响应的翻译

流式处理是最精巧的部分。Codex 期望的 SSE 事件序列与 Chat Completions 的 chunk 格式完全不同,网关需要实时翻译:

vbscript 复制代码
Chat Completions SSE chunk          →  Responses API SSE event
─────────────────────────────────────────────────────────────────
开始接收                              →  response.created
                                     →  response.output_item.added
delta.reasoning_content 出现          →  response.reasoning_summary_text.delta
delta.content 出现                    →  response.output_text.delta
delta.tool_calls 出现                 →  response.function_call_arguments.delta
单个输出项完成                         →  response.output_item.done
流结束                                →  response.completed(含 token 统计)

通过 ReadableStream 逐 chunk 读取、翻译、推送,实现了零延迟的流式透传。Codex 终端上能看到和国产模型原生 API 一样的逐字输出效果,包括推理过程的实时展示。

推理模型的特殊处理

DeepSeek R1 等推理模型会在响应中返回 reasoning_content 字段,记录模型的思考链路。网关的 DeepSeekAdapter 会:

  1. 非流式 :将 reasoning_content 提取为独立的 reasoning 输出项,包含 summary 文本
  2. 流式 :检测每个 chunk 中的 delta.reasoning_content,翻译为 response.reasoning_summary_text.delta 事件

这样在 Codex 终端中就能看到模型"正在思考"的过程,体验与使用 OpenAI o-series 模型一致。

高级功能:不只是翻译

Codex 支持 web_search_preview 工具来搜索网络,但国产模型不一定支持这个能力。网关的做法是拦截并代理

  1. 检测请求中包含 web_search_preview 工具
  2. 通过 MCP SDK 调用智谱的 webSearchPrime 搜索服务
  3. 取 Top 3 搜索结果,格式化后注入用户消息上下文
  4. 从工具列表中移除 web_search_preview(避免模型困惑)
  5. 将增强后的请求正常转发给国产模型

搜索结果带有 5 分钟内存缓存,相同的查询不会重复调用搜索服务。搜索失败也不阻塞请求------网关会优雅降级,直接将原始请求转发给模型。

Computer Use 桥接

Codex 的 computer_use_preview 工具允许模型操作用户电脑(截图、点击、输入等),但国产模型没有原生的 Computer Use API。网关采用 Prompt 注入法 桥接:

  1. 检测到 computer_use_preview 工具时,向 system 消息追加一段操作规范 Prompt
  2. Prompt 定义了 screenshot、click、scroll、type、key、wait 六种操作的 JSON 格式
  3. 国产模型按 Prompt 指示输出 JSON 格式的操作指令
  4. 网关通过正则检测模型输出中的操作 JSON,包装为 Responses API 的 computer_call 格式
  5. Codex 在本地执行操作后,将结果通过新的请求回传

这个方案虽然不如原生 API 优雅,但在实践中证明是可行的------国产模型的指令遵循能力足以支撑这种结构化输出。

工具调用的双向透传

Codex 的 function tools(如 exec_command 等)可以直接透传给国产模型,因为国产模型普遍支持 Chat Completions 的 function calling 格式:

scss 复制代码
Codex 发送 tools (Responses API 格式)
  → 网关透传 tools (Chat Completions 格式)
  → 国产模型返回 tool_calls
  → 网关翻译为 function_call (Responses API 格式)
  → Codex 执行工具,发送 function_call_output
  → 网关翻译为 role: "tool" 消息
  → 国产模型继续生成

整个循环对 Codex 和国产模型都是透明的,双方都以为自己正在与原生 API 通信。

多模型负载均衡与故障转移

生产环境中,单一模型提供商可能不够可靠。网关内置了加权负载均衡 + 自动故障转移

负载均衡 :在网关的管理后台中,可以为同一个 OpenAI 模型名配置多个国产模型映射。例如 gpt-4o 可以映射到 DeepSeek、通义千问和 Kimi,各自带有权重。网关按权重加权随机选择。

故障转移:网关维护每个 provider 的健康状态。在 60 秒窗口内连续失败 3 次的 provider 会被标记为不健康,自动排除在候选列表外。窗口过期后自动恢复。

markdown 复制代码
请求 → 获取所有候选 provider
     → 过滤掉不健康的
     → 按优先级逐个尝试
     → 成功:记录成功,返回响应
     → 失败:记录失败,尝试下一个
     → 全部失败:返回 502

这意味着即使某个国产模型 API 完全不可用,Codex 用户也不会感知到任何中断。

会话管理

Codex 通过 previous_response_id 实现多轮对话。网关在 SQLite 中维护会话表:

  • 每次请求完成后,将 response_id 和完整消息列表存入数据库
  • 下次请求携带 previous_response_id 时,网关查询历史消息并拼接到上下文中
  • 会话默认 7 天过期
  • 服务重启后会话数据不丢失(SQLite 持久化)

这个设计让网关无状态化------网关本身不持有对话状态,所有持久化都交给数据库,方便水平扩展。

技术实现细节

整个网关用 TypeScript 编写,基于 Bun 运行时和 Elysia Web 框架:

  • Bun:提供高性能 HTTP 服务和内置 SQLite,单二进制部署
  • Elysia:类型安全的路由定义,自动请求体验证
  • OpenAI SDK:用 OpenAI 自家的 SDK 调用国产模型(因为它们兼容 Chat Completions API),省去自己写 HTTP 客户端
  • Zod:请求体校验,确保进入网关的 Responses API 请求格式正确
  • SQLite:零额外依赖的持久化,单文件部署

前端管理后台用 React + Bun HTML bundler,不需要单独的构建步骤。通过管理后台可以可视化管理提供商、模型映射、API Key 和查看调用日志。

部署与使用

bash 复制代码
# 1. 启动网关
pnpm dev

# 2. 初始化数据库
bun src/db/migrate.ts

# 3. 通过管理后台添加提供商和模型映射
# 打开 http://localhost:3000

# 4. 配置 Codex
export OPENAI_BASE_URL=http://localhost:3000
export OPENAI_API_KEY=your-gateway-key
codex

总结

这个 AI Gateway 的核心价值在于:用协议翻译替代代码修改。通过在 Codex CLI 和国产模型之间加一层智能翻译层,实现了:

  • 零侵入:Codex 不需要任何改动
  • 全功能:推理过程、工具调用、流式输出、网络搜索、Computer Use 全部支持
  • 高可用:多模型负载均衡 + 自动故障转移
  • 可观测:调用日志、token 统计、管理后台

对于想用国产模型但又被 Codex 等 OpenAI 生态工具绑定的开发者来说,这是一个实用且低成本的方案。同样的思路也可以应用到 Cursor、Copilot 等其他基于 OpenAI API 的工具上------只需把 OPENAI_BASE_URL 指向网关即可。

代码仓库 : github.com/BoltDoggy/a...

相关推荐
财经资讯数据_灵砚智能1 小时前
基于全球经济类多源新闻的NLP情感分析与数据可视化(日间)2026年5月11日
大数据·人工智能·python·信息可视化·自然语言处理
java1234_小锋1 小时前
Spring AI 2.0 开发Java Agent智能体 - 会话记忆(Chat Memory)
java·人工智能·spring
数字护盾(和中)1 小时前
终端安全破局:银狐木马防御的 EDR 核心能力详解
网络·人工智能·安全
Promise微笑1 小时前
AI搜索时代的流量重构:Geo优化精细化运营标准与实战路径
大数据·人工智能·重构
SmallBambooCode1 小时前
【人工智能】【Python】离线环境下huggingface预训练权重导入流程
开发语言·人工智能·python
qiyongwork1 小时前
智能项目管理信息系统的未来图景:AI赋能下的全链路革新与生态重构
大数据·人工智能·重构
wanhengidc1 小时前
云手机的兼容性与稳定性
大数据·运维·服务器·网络·人工智能·智能手机
昇腾CANN1 小时前
5月12日直播丨Ascend 950 HiF8模型量化技术的训推实践
人工智能·昇腾·cann
winlife_1 小时前
AI 怎么验证 Unity PlayMode 行为:截图 + 输入模拟的完整闭环
人工智能·unity·游戏引擎·ai编程·claude·playmode