教程2026年7月10日8,793 浏览约 6 分钟阅读

Codex CLI接入GLM-5.1:本地代理部署指南

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

Codex CLI接入GLM-5.1:本地代理部署指南

概述

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 代理四大核心职责

  1. 请求协议转译:将 Codex 传来的 Responses 结构体,标准化转为 GLM 兼容 Chat Completions 消息数组,兼容 system、user、tool_call 多类型角色;
  2. 流式SSE事件适配:智谱原生流式分片转换成 Codex 可识别的 response.createdresponse.output.item.added 标准事件;
  3. Token用量字段归一化:映射智谱 prompt_tokens/completion_tokens 至 Codex 规范 input_tokens/output_tokens/total_tokens
  4. 工具调用兼容:完整转译 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

  1. 登录智谱AI开放平台控制台;
  2. 切换至「API Keys」管理页面,创建全新密钥;
  3. 复制密钥字符串,后续写入本地配置文件,切勿明文硬编码至代码。

四、本地协议转换代理完整开发

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协议不兼容问题,三层核心转换逻辑:

  1. 请求层:Responses API → GLM Chat Completions 消息结构;
  2. 流式层:智谱原生SSE分片 → Codex 标准 Responses SSE 事件;
  3. 计量层:token用量字段统一归一化,保证CLI统计面板正常。

本代理不局限GLM-5.1,所有遵循Chat Completions 标准的国产模型(DeepSeek、Qwen等)均可适配,仅需修改代理内上游API地址与少量角色映射逻辑。 如果企业需要同时对接多家厂商大模型、统一管控密钥,可借助 koalaapi 统一网关批量管理多模型接口,减少本地多套代理维护成本。整套部署全程无侵入修改Codex CLI源码,仅通过本地中间层完成协议兼容,升级、切换模型灵活可控,适合个人开发、小型研发团队长期稳定使用。

标签Codex CLIGLM-5.1智谱AI本地代理API协议转换
Koala API · 一站式大模型 API 中转

把博客读到的,落地到你的下一个项目

国内直连 · 兼容 OpenAI SDK · GPT / Claude / Gemini 等主流模型聚合

延伸阅读

免费注册