OpenAI Codex CLI 接入国产大模型(智谱 GLM 等)实战教程
在 Codex CLI 中使用 GLM-5.1 模型完整配置指南本文详细记录如何将智谱 GLM-5.1 模型接入 OpenAI Codex CLI涵盖代理服务搭建、配置文件编写、密钥管理与一键启动脚本助你在本地环境中无缝切换至国产大模型。1. 背景与原理Codex CLI 原生支持 OpenAI Responses API 协议而智谱 GLM 系列模型使用的是 Chat Completions API 协议。两者在请求/响应格式、流式事件结构上存在差异因此需要一个本地代理服务将 Codex 发出的 Responses API 请求转换为智谱兼容的 Chat Completions 请求并将响应转译回 Responses API 格式。整体架构如下Codex CLI ──(Responses API)──▶ 本地代理 (127.0.0.1:8787) ──(Chat Completions API)──▶ 智谱 API ◀──(SSE 流)── ◀──(SSE 流)──2. 环境要求依赖最低版本说明Node.js≥ 22Codex CLI 运行时Python≥ 3.10代理服务运行时pip最新Python 包管理curl任意健康检查与调试安装 Codex CLInpminstall-gopenai/codex验证安装codex--version# 期望输出类似codex-cli 0.125.03. 获取智谱 API Key访问 智谱开放平台注册并登录。进入「API Keys」页面创建新的 API Key。复制 Key 并妥善保管后续步骤将使用。4. 搭建本地代理服务4.1 项目结构codex-glm-proxy/ ├── app.py # FastAPI 代理主程序 ├── requirements.txt # Python 依赖 ├── run.sh # 手动启动脚本 └── README.md4.2 Python 依赖requirements.txtfastapi0.115,1.0 uvicorn[standard]0.30,1.0 httpx0.27,1.0安装依赖cdcodex-glm-proxy python3-mvenv .venv .venv/bin/pipinstall-rrequirements.txt4.3 代理核心逻辑app.py代理服务的核心职责请求转换将 Codex 发出的 Responses API 请求体转换为智谱 Chat Completions 格式流式转发将智谱返回的 Chat Completions SSE 流转译为 Responses API SSE 事件序列Usage 字段归一化将智谱的prompt_tokens/completion_tokens映射为 Codex 期望的input_tokens/output_tokens/total_tokensFunction Call 支持处理工具调用场景下的消息格式转换关键代码片段——请求体转换defto_chat_messages(input_field,instructionsNone):messages[]ifinstructions:messages.append({role:system,content:instructions})ifisinstance(input_field,str):messages.append({role:user,content:input_field})returnmessagesifisinstance(input_field,list):foritemininput_field:ifnotisinstance(item,dict):continueitem_typeitem.get(type)ifitem_typemessage:roleitem.get(role,user)ifroledeveloper:rolesystemmessages.append({role:role,content:_flatten_text(item.get(content,))})elifitem_typefunction_call_output:# 工具调用结果转译call_iditem.get(call_id,item.get(id,))call_meta_CALL_REGISTRY.get(call_id)ifcall_meta:messages.append({role:assistant,content:,tool_calls:[{id:call_id,type:function,function:{name:call_meta.get(name,),arguments:call_meta.get(arguments,{}),},}],})messages.append({role:tool,tool_call_id:call_id,content:str(item.get(output,)),})returnmessages关键代码片段——Usage 归一化def_normalize_usage_for_responses(usage)-dict:ifnotisinstance(usage,dict):usage{}outdict(usage)inpout.get(input_tokens)orout.get(prompt_tokens)outpout.get(output_tokens)orout.get(completion_tokens)inp_iint(inp)ifinpisnotNoneelse0outp_iint(outp)ifoutpisnotNoneelse0totout.get(total_tokens)tot_iint(tot)iftotisnotNoneelseinp_ioutp_i out[input_tokens]inp_i out[output_tokens]outp_i out[total_tokens]tot_ireturnout关键代码片段——流式事件转译# 将智谱 Chat Completions 的 SSE 事件转换为 Codex 期望的 Responses API 事件序列yielddata: json.dumps({type:response.created,...})\n\nyielddata: json.dumps({type:response.in_progress,...})\n\nyielddata: json.dumps({type:response.output_item.added,...})\n\nyielddata: json.dumps({type:response.content_part.added,...})\n\nyielddata: json.dumps({type:response.output_text.delta,delta:text,...})\n\nyielddata: json.dumps({type:response.output_text.done,...})\n\nyielddata: json.dumps({type:response.content_part.done,...})\n\nyielddata: json.dumps({type:response.output_item.done,...})\n\nyielddata: json.dumps({type:response.completed,response:response_obj})\n\nyielddata: [DONE]\n\n4.4 健康检查端点代理提供/health端点供启动脚本确认服务状态app.get(/health)asyncdefhealth():return{status:ok,has_key:bool(os.getenv(ZHIPU_API_KEY,).strip())}4.5 手动启动代理exportZHIPU_API_KEYyour_api_key_herecdcodex-glm-proxy../.venv/bin/python-muvicorn app:app--host127.0.0.1--port8787验证代理运行curlhttp://127.0.0.1:8787/health# 期望输出{status:ok,has_key:true}5. Codex CLI 配置5.1 主配置文件编辑~/.codex/config.toml# 模型设置 model glm-5.1 model_provider glm_proxy model_reasoning_effort medium # 自定义 Provider 定义 [model_providers.glm_proxy] name GLM Local Proxy base_url http://127.0.0.1:8787/v1 wire_api responses # 关键指定使用 Responses API 协议 requires_openai_auth false # 无需 OpenAI 认证配置项详解字段值说明modelglm-5.1传递给代理的模型名称代理会原样转发至智谱 APImodel_providerglm_proxy对应[model_providers.glm_proxy]的键名wire_apiresponses告知 Codex 使用 Responses API 格式发送请求base_urlhttp://127.0.0.1:8787/v1代理服务地址Codex 会在后面拼接/responsesrequires_openai_authfalse设为false后 Codex 不要求 OpenAI Key5.2 密钥管理创建~/.codex/auto.json存放智谱 API Key此文件不应提交至版本控制{GLM_API_KEY:your_zhipu_api_key_here,auth_mode:local}⚠️安全提示auto.json包含敏感凭据务必将其加入.gitignore。5.3 用户级指令可选编辑~/.codex/instructions.md可自定义 AI 行为偏好# User-level instructions ## Code and architecture - Use first-principles thinking when analyzing problems. - Follow DRY, KISS, SOLID, and YAGNI when coding. - Keep functions under ~500 lines; split when necessary. ## Language and communication - Communicate with the user in their preferred language.6. 一键启动脚本手动先启动代理再启动 Codex 比较繁琐推荐使用一键启动脚本~/.codex/scripts/codex-with-auto-json.sh#!/usr/bin/env bashset-euopipefailCODEX_HOME${CODEX_HOME:-$HOME/.codex}AUTO_JSON${CODEX_HOME}/auto.jsonPROXY_DIR$HOME/Project/codex_project/custdown_test/codex-glm-proxyPROXY_HOST127.0.0.1PROXY_PORT8787PROXY_HEALTH_URLhttp://${PROXY_HOST}:${PROXY_PORT}/healthPROXY_LOG$CODEX_HOME/log/proxy.logPROXY_AUTO_RESTART${PROXY_AUTO_RESTART:-1}# 1. 从 auto.json 加载 GLM_API_KEYif[[-f$AUTO_JSON]];thenGLM_KEY$(python3-cimportjson, os pos.path.expanduser(~/.codex/auto.json)try: with open(p,encodingutf-8)as f: djson.load(f)print((d.get(GLM_API_KEY)or).strip()) except Exception: print() ) if [[ -n $GLM_KEY ]]; then export GLM_API_KEY$GLM_KEY export ZHIPU_API_KEY$GLM_KEY fi fi # 2. 检查 Key 是否存在 if [[ -z ${ZHIPU_API_KEY:-} ]]; then echo GLM key is empty. Put GLM_API_KEY into ~/.codex/auto.json exit 1 fi # 3. 确保代理虚拟环境就绪 if [[ ! -x $PROXY_DIR/.venv/bin/python ]]; then python3 -m venv $PROXY_DIR/.venv $PROXY_DIR/.venv/bin/pip install -r $PROXY_DIR/requirements.txt fi # 4. 自动重启代理确保最新代码生效 if [[ $PROXY_AUTO_RESTART 1 ]]; then pkill -f uvicorn app:app--host$PROXY_HOST--port$PROXY_PORT /dev/null 21 || true ZHIPU_API_KEY$ZHIPU_API_KEY nohup $PROXY_DIR/.venv/bin/python -m uvicorn app:app \ --host $PROXY_HOST --port $PROXY_PORT --app-dir $PROXY_DIR \ $PROXY_LOG 21 # 等待代理就绪 for _ in {1..16}; do sleep 0.5 curl -fsS $PROXY_HEALTH_URL /dev/null 21 break done fi # 5. 设置环境变量后启动 Codex export GLM_PROXY_DUMMY_KEYok exec codex $使用方式chmodx ~/.codex/scripts/codex-with-auto-json.sh# 启动交互式会话~/.codex/scripts/codex-with-auto-json.sh# 或执行单条指令~/.codex/scripts/codex-with-auto-json.shexec解释 main.c 的逻辑可将该脚本路径加入PATH或创建 alias 以简化调用。7. 完整目录结构总览~/.codex/ ├── config.toml # 主配置模型 Provider ├── auto.json # 密钥GLM_API_KEY ├── instructions.md # 用户级 AI 指令 ├── AGENTS.md # 项目级 AI 指令 ├── scripts/ │ └── codex-with-auto-json.sh # 一键启动脚本 ├── log/ │ └── proxy.log # 代理运行日志 └── ... codex-glm-proxy/ ├── app.py # 代理服务主程序 ├── requirements.txt # Python 依赖 ├── run.sh # 手动启动脚本 ├── .venv/ # Python 虚拟环境 └── README.md8. 常见问题排查问题原因解决方案Proxy failed to startPython 虚拟环境未就绪手动运行python3 -m venv .venv .venv/bin/pip install -r requirements.txtProxy protocol self-check failed代理返回的事件格式不符合 Codex 解析预期检查app.py中response.completed事件是否包含input_tokens/output_tokens/total_tokensGLM key is emptyauto.json中缺少GLM_API_KEY编辑~/.codex/auto.json填入有效 KeyCodex 启动后无响应代理未运行或端口被占用运行curl http://127.0.0.1:8787/health确认代理状态流式输出中断智谱 API 限流代理内置 1.2s 节流必要时调大_throttle_upstream参数9. 总结通过搭建一个轻量的本地 FastAPI 代理我们实现了 Codex CLI 与智谱 GLM-5.1 模型的无缝对接。核心思路是协议适配Responses API ↔ Chat Completions API 双向转换流式转译智谱 SSE 事件 → Codex SSE 事件序列字段归一化Usage 字段名映射一键启动自动加载密钥、启动代理、验证健康状态这套方案不仅适用于 GLM-5.1也可扩展至任何兼容 Chat Completions API 的模型服务如 DeepSeek、Qwen 等只需修改代理中的上游 API 地址和模型名即可。本文基于 Codex CLI v0.125.0 与智谱 GLM-5.1 验证通过环境为 Linux / Node.js 22 / Python 3.10。