Codex CLI接入GLM-5.1:本地代理部署指南
详解Codex CLI通过本地代理调用GLM-5.1的方法,覆盖协议转换、SSE流式适配、密钥管理与故障排查。

概述
OpenAI Codex CLI 原生仅兼容 OpenAI Responses API 协议,而智谱 GLM 全系采用 Chat Completions API 标准,二者请求体结构、流式SSE事件、token用量字段存在明显差异,无法直连。本文提供一套可落地的本地 API(koalaapi )代理转换方案,实现协议双向转译,让 Codex CLI 无缝调用 GLM-5.1,完整覆盖环境依赖、代理服务开发、密钥管理、Codex 配置、一键启动脚本、故障排查全流程;企业多模型统一调度场景可借助 koalaapi 网关简化多厂商模型接入管理。整套方案基于 Node.js 22、Python 3.10 验证通过,适配 Linux 开发环境。
一、整体架构与核心原理
1.1 数据流链路
Codex CLI(发起 Responses API 请求)→ 本地 API(koalaapi ) 代理 127.0.0.1:8787 → 协议转换 → 智谱官方 Chat Completions API;
响应流反向原路回流:智谱SSE流式数据 → 代理转译为 Responses 标准SSE事件 → Codex CLI 解析渲染输出。
1.2 代理四大核心职责
- 请求协议转译:将 Codex 传来的 Responses 结构体,标准化转为 GLM 兼容 Chat Completions 消息数组,兼容 system、user、tool_call 多类型角色;
- 流式SSE事件适配:智谱原生流式分片转换成 Codex 可识别的
response.created、response.output.item.added标准事件; - Token用量字段归一化:映射智谱
prompt_tokens/completion_tokens至 Codex 规范input_tokens/output_tokens/total_tokens; - 工具调用兼容:完整转译 function call 入参、返回结果、tool 角色消息格式,支持复杂开发工具链场景。
二、前置环境依赖清单
2.1 运行环境最低版本要求
| 依赖软件 | 最低版本 | 用途 |
|---|---|---|
| Node.js | ≥22 | Codex CLI 运行时 |
| Python | ≥3.10 | API(koalaapi ) 代理服务 |
| pip | 最新版 | Python 依赖管理 |
| curl | 任意 | 代理健康检测、接口调试 |
2.2 Codex CLI 安装与校验
全局安装命令:
npm install -g @openai/codex
验证安装是否生效:
codex --version
# 标准输出示例:codex-cli 0.125.0
三、前置准备:获取智谱GLM API Key
- 登录智谱AI开放平台控制台;
- 切换至「API Keys」管理页面,创建全新密钥;
- 复制密钥字符串,后续写入本地配置文件,切勿明文硬编码至代码。
四、本地协议转换代理完整开发
4.1 代理项目目录结构
codex-glm-proxy/
├── app.py # API(koalaapi ) 主代理逻辑
├── requirements.txt # Python 依赖清单
└── run.sh # 代理手动启动脚本
4.2 Python 依赖清单 requirements.txt
koalaapi>=0.115,<1.0
uvicorn[standard]>=0.30,<1.0
httpx>=0.27,<1.0
安装虚拟环境依赖流程:
cd codex-glm-proxy
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt
4.3 代理核心代码关键逻辑拆解
4.3.1 消息结构体转换函数负责把 Codex 不规则输入统一转为 GLM 标准 message 数组,兼容 system 指令、普通文本、工具调用返回值:
def to_chat_messages(input_field, instructions=None):
messages = []
if instructions:
messages.append({"role": "system", "content": instructions})
# 字符串输入处理
if isinstance(input_field, str):
messages.append({"role": "user", "content": input_field})
# 数组多轮对话处理
if isinstance(input_field, list):
for item in input_field:
if not isinstance(item, dict):
continue
item_type = item.get("type")
if item_type == "message":
role = item.get("role", "user")
messages.append({"role": role, "content": item.get("content", "")})
elif item_type == "function_call_output":
# 工具调用返回消息转译
call_id = item.get("call_id", item.get("id", ""))
meta = _CALL_REGISTRY.get(call_id, {})
messages.append({
"role": "assistant",
"content": "",
"tool_calls": [{
"id": call_id,
"type": "function",
"function": {
"name": meta.get("name", ""),
"arguments": meta.get("arguments", "")
}
}]
})
messages.append({
"role": "tool",
"tool_call_id": call_id,
"content": str(item.get("output", "")),
})
return messages
4.3.2 Token用量归一化函数
对齐两套API的用量统计字段,保证Codex读取token消耗正常:
def normalize_usage_for_responses(usage) -> dict:
if not isinstance(usage, dict):
usage = {}
out = dict(usage)
inp = out.get("input_tokens") or out.get("prompt_tokens")
outp = out.get("output_tokens") or out.get("completion_tokens")
inp_i = int(inp) if inp is not None else 0
outp_i = int(outp) if outp is not None else 0
total_i = inp_i + outp_i
return {
"input_tokens": inp_i,
"output_tokens": outp_i,
"total_tokens": total_i
}
4.3.3 流式SSE事件转译
循环读取智谱流式分片,封装成 Codex 识别的 Responses 标准事件,分段输出:
yield b'data: ' + json.dumps({"type": "response.created"}) + b'\n\n'
yield b'data: ' + json.dumps({"type": "response.output.item.added"}) + b'\n\n'
yield b'data: ' + json.dumps({"type": "response.content.text.delta", "content": chunk_text}) + b'\n\n'
4.4 Codex CLI 配置文件规范
在用户目录新建 ~/.codex/auto.json 存放密钥与模型代理配置,敏感密钥禁止提交代码仓库:
{
"GLM_API_KEY": "你的智谱密钥",
"auth_mode": "local"
}
配套 Codex 全局参数说明:
| 配置字段 | 取值 | 说明 |
|---|---|---|
| model | glm-5.1 | 传递给代理,转发至智谱接口 |
| model_provider | glm_proxy | 匹配代码内代理路由标识 |
| wire_protocol | responses | 告知Codex使用Responses协议发起请求 |
| base_url | http://127.0.0.1:8787/v1 | 本地代理服务地址 |
| requires_openai_auth | false | 关闭OpenAI原生鉴权,由本地代理接管密钥 |
4.5 用户全局指令(可选)
创建 ~/.codex/instructions.md,写入固定编码规范,Codex 每次发起请求自动携带system指令,统一代码输出风格,例如:
# 全局编码规范
- 优先使用Python原生标准库,减少第三方依赖
- 函数长度控制在500行以内,复杂逻辑拆分
- 输出代码附带注释,使用中文交互
五、一键启动脚本(完整自动化)
编写 ~/.codex/scripts/codex-with-auto-json.sh,自动加载密钥、启动代理、健康检测、拉起Codex,无需分步手动操作:
#!/usr/bin/env bash
set -euo pipefail
# 路径常量定义
CODEX_HOME="${HOME}/.codex"
PROXY_DIR="${HOME}/codex-glm-proxy"
AUTO_JSON="${CODEX_HOME}/auto.json"
PROXY_HOST="127.0.0.1"
PROXY_PORT="8787"
PROXY_HEALTH_URL="http://${PROXY_HOST}:${PROXY_PORT}/health"
# 1. 读取GLM密钥
GLM_API_KEY=$(jq -r '.GLM_API_KEY' "${AUTO_JSON}")
if [[ -z "${GLM_API_KEY}" ]]; then
echo "错误:auto.json 内未配置GLM_API_KEY"
exit 1
fi
export ZHIPU_API_KEY="${GLM_API_KEY}"
# 2. 初始化Python虚拟环境并安装依赖
cd "${PROXY_DIR}"
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt
# 3. 后台启动代理服务
nohup .venv/bin/uvicorn app:app --host ${PROXY_HOST} --port ${PROXY_PORT} > proxy.log 2>&1 &
# 4. 循环等待代理健康就绪
for _ in {1..16}; do
curl -fsS "${PROXY_HEALTH_URL}" >/dev/null 2>&1 && break
sleep 1
done
# 5. 启动Codex CLI
codex "$@"
赋予执行权限并运行:
chmod +x ~/.codex/scripts/codex-with-auto-json.sh
# 直接启动交互
~/.codex/scripts/codex-with-auto-json.sh
# 直接传入开发指令执行
~/.codex/scripts/codex-with-auto-json.sh exec "解释main.py逻辑"
六、完整目录总览
# 用户家目录.codex配置目录
~/.codex/
├── auto.json # 密钥与代理配置
├── instructions.md # 全局编码指令
├── scripts/
│ └── codex-with-auto-json.sh # 一键启动脚本
└── proxy.log # 代理运行日志
# 本地代理工程目录
codex-glm-proxy/
├── app.py
├── requirements.txt
└── run.sh
七、高频故障排查方案
| 故障现象 | 根因 | 修复方案 |
|---|---|---|
| Proxy failed to start | Python虚拟环境未初始化 | 手动执行虚拟环境安装依赖脚本 |
| Codex 解析流式输出残缺 | SSE事件缺少标准token字段 | 检查归一化usage函数,补齐三类token字段 |
| GLM key is empty | auto.json密钥为空 | 编辑配置文件填入有效智谱API Key |
| Codex 启动无响应 | 代理端口被占用 | curl 健康地址确认代理状态,更换端口 |
| 流式输出频繁中断 | 智谱接口限流 | 代理增加节流控制,上调上游等待超时 |
八、拓展适配与总结
整套方案核心解决两套大模型API协议不兼容问题,三层核心转换逻辑:
- 请求层:Responses API → GLM Chat Completions 消息结构;
- 流式层:智谱原生SSE分片 → Codex 标准 Responses SSE 事件;
- 计量层:token用量字段统一归一化,保证CLI统计面板正常。
本代理不局限GLM-5.1,所有遵循Chat Completions 标准的国产模型(DeepSeek、Qwen等)均可适配,仅需修改代理内上游API地址与少量角色映射逻辑。 如果企业需要同时对接多家厂商大模型、统一管控密钥,可借助 koalaapi 统一网关批量管理多模型接口,减少本地多套代理维护成本。整套部署全程无侵入修改Codex CLI源码,仅通过本地中间层完成协议兼容,升级、切换模型灵活可控,适合个人开发、小型研发团队长期稳定使用。
