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...

相关推荐
JJJennie77720 小时前
当AI开始学会欺骗
网络·人工智能
糖果店的幽灵20 小时前
大模型测评DeepEval快速入门-安全与通用指标详解
人工智能·安全·langgraph·大模型测评·deepeval
江畔柳前堤1 天前
roLabelImg 详细安装教程
开发语言·人工智能·后端·云原生
阿里云大数据AI技术1 天前
分链路差异化设计的DSP准实时数仓|钛动科技基于阿里云实时计算 Flink 版 + DLF Paimon + EMR Serverless StarRocks 的实践
人工智能·flink
陕西企来客1 天前
2026年7月AI智能搜索曝光趋势研判
大数据·人工智能·机器学习·ai智能搜索曝光
阿里云大数据AI技术1 天前
从算力到智能体,面向 Agentic AI 的基础设施演进
人工智能·agent
hangyuekejiGEO1 天前
GEO技术服务选型指南
大数据·人工智能·python
阿里云大数据AI技术1 天前
EMR Serverless Spark AI Function 的双维降本实践
人工智能·sql·spark
维基框架1 天前
GitHub源码处理提速 一趟扫描反而更慢
人工智能·github
冬奇Lab1 天前
代码库知识库系列(05):向量检索 vs 知识图谱——加了调用图并没有变更好
人工智能