面试时 Codex 疯狂报错——CCX 接国产模型的 500 错误排查实录
面试时 Codex 疯狂报错——CCX 接国产模型的 500 错误排查实录
面试官让我用 Codex 做 AI Coding 环节,结果 API 一直报 500。我当场切模型,发现旧对话还是走老模型。那一刻的尴尬,希望你不用经历。
目录
那个面试下午
面试到 AI Coding 环节,面试官说"你用 Codex 写个 XX 功能吧"。我打开终端,启动 Codex,输入需求,等回复。
然后就看到一行红字:500 Internal Server Error。
我以为是偶发,重试了一下,还是 500。换了 gpt-5.4 的映射名,500。换成 codex,500。这时候面试官开始看我屏幕了。
我想着先切到 DeepSeek 救场,用 ccswitch 切了模型,显示"已激活"。但开新请求,还是 500——而且去 Mimo 的 API 控制台一看,请求量还在涨。ccswitch 说切了,CCX 根本没动。
更惨的是,我在旧对话里切模型,Codex 还是用的之前的模型名。得开新对话才生效。
那天面试的结果不重要。重要的是事后我把这个问题彻底搞清楚了,写下来,让你少踩几个坑。
CCX 是什么,为什么需要它
Codex CLI 是 OpenAI 的命令行 AI 编程工具,它默认只认 OpenAI 的 API 格式。但国内用 OpenAI 的 API 不太方便,大家更常用 DeepSeek、小米 Mimo、通义千问这些国产模型。
问题是:这些国产模型的 API 接口虽然大多兼容 OpenAI 格式,但细节上有差异——参数名不同、有些字段不支持、限流策略不一样。
CCX(CCProxy) 就是解决这个问题的。它是一个 API 网关,坐在 Codex 和模型供应商之间,做三件事:
- 协议转换:把 Codex 发出的 OpenAI 标准请求转成各供应商能认的格式
- 路由分发:按优先级把请求发到不同的供应商(比如 Mimo 优先,DeepSeek 备用)
- 参数适配:过滤掉供应商不支持的参数,避免报错
三件套的分工:Codex 负责写代码,CCX 负责转请求,国产模型负责生成。缺一环都不行。
问题长什么样
具体症状:
- 通过 CCX 发送的所有请求都返回
500 Internal Server Error - 涉及所有模型映射:
gpt-5.4、codex、mimo-v2.5-pro全挂 - CCX 日志显示连接成功,但在"首字生成"阶段失败
- 请求目标是
https://token-plan-cn.xiaomimimo.com
三个信息很关键:
- 所有模型都挂 → 不是某个模型的问题,是 CCX 转发层的问题
- 连接成功但生成失败 → 不是网络不通,是请求内容被拒绝
- 目标是小米的 API → 小米的参数校验可能比较严格
排查四步走
第一步:确认 API 本身没问题
先排除小米 API 自身的故障。直接绕过 CCX,用 curl 直接调小米的 API。
这里有个坑:Windows 下 curl 的行为和 Linux 不一样。
- CMD 不支持
\换行和单引号,命令会被拆成多行单独执行 - PowerShell 里
curl是Invoke-WebRequest的别名,参数语法完全不同 - Git Bash 最省事,完全兼容 Linux 语法
推荐用 curl.exe(加 .exe 后缀强制调原生 curl),整行粘贴:
curl.exe -X POST https://token-plan-cn.xiaomimimo.com/v1/chat/completions -H "Content-Type: application/json" -H "Authorization: Bearer tp-你的API密钥" -d "{\"model\": \"mimo-v2.5-pro\", \"messages\": [{\"role\": \"user\", \"content\": \"你好\"}], \"temperature\": 0.7}"
如果这条命令返回了正常的对话响应,说明小米 API 没问题,毛病在 CCX 的转发逻辑里。
第二步:定位 CCX 配置问题
API 没问题,那问题出在 CCX 转发请求时带了小米不认的参数。
CCX 默认会把 Codex 发来的所有 OpenAI 标准参数原样转发。但小米 Mimo 的 API 对参数校验很严格——它不认识的参数不会忽略,而是直接返回 500。
解决办法是用 CCX 的 stripParams 配置项,告诉 CCX “这些参数发给小米之前先剥掉”。stripParams 的意思是"剥离参数",即在请求转发到上游之前,删除指定的请求体字段。
需要剥掉的参数:
"stripParams": [
"stream_options",
"tools",
"function_call",
"max_tokens",
"presence_penalty",
"frequency_penalty",
"top_p",
"n",
"stop",
"logprobs",
"echo",
"store",
"output_config"
]
除了参数过滤,还要控制并发。小米免费套餐有 QPS(每秒请求数)限制,CCX 默认没有限流,多个请求同时打过去会触发小米的限流机制,也会返回 500。
"maxConcurrent": 2,
"qps": 1,
"retryCount": 1,
"retryDelay": 2000,
"disableTools": true
maxConcurrent: 2:最多同时 2 个请求在处理qps: 1:每秒最多 1 个请求retryCount: 1:失败重试 1 次retryDelay: 2000:重试间隔 2 秒disableTools: true:禁用工具调用,小米 API 暂不支持
第三步:修复 CCX 启动失败
改完配置文件,双击 ccx.exe,没反应。进程一闪就没了。
这种情况 99% 是配置文件的 JSON 语法有问题。几个常见原因:
JSON 里写了注释。标准 JSON 不支持注释,// 或 /* */ 都会导致解析失败。CCX 用的是严格 JSON 解析器,不接受任何注释。
排查步骤:
- 按
Ctrl+Shift+Esc打开任务管理器,结束所有ccx.exe和ccproxy.exe进程 - 用 VS Code 打开配置文件,看有没有红色波浪线报语法错误
- 或者去 jsonlint.com 粘贴配置内容,确认显示 “Valid JSON”
- 检查文件编码:用记事本打开 → 另存为 → 编码选 “UTF-8”(不要 UTF-8 BOM)
- 检查端口占用:
netstat -ano | findstr ":3000",如果有进程占了 3000 端口,先结束它 - 右键
ccx.exe→ 以管理员身份运行
第四步:密钥安全
排查过程中你可能把 API 密钥贴到了聊天记录、日志文件、甚至公开的论坛里。
如果密钥暴露过,立刻去小米 AI 开放平台重新生成。旧密钥删掉,新密钥妥善保存。API 密钥相当于你的钱包钥匙,谁拿到都能用你的额度调接口。
一份可以直接复制的完整配置
以下是经过验证的 CCX 标准配置。把 apiKeys 里的值换成你自己的密钥,其他字段直接用:
{
"upstream": [],
"responsesUpstream": [
{
"baseUrl": "https://api.deepseek.com",
"apiKeys": [
"sk-你的DeepSeek密钥"
],
"serviceType": "openai",
"name": "deepseek-o3mlh5",
"normalizeNonstandardChatRoles": true,
"priority": 2,
"status": "suspended",
"autoBlacklistBalance": true,
"normalizeMetadataUserId": true
},
{
"baseUrl": "https://token-plan-cn.xiaomimimo.com/v1",
"apiKeys": [
"tp-你的小米Mimo密钥"
],
"serviceType": "openai",
"name": "xiaomimimo-o1c0ll",
"modelMapping": {
"codex": "mimo-v2.5-pro",
"gpt": "mimo-v2.5-pro",
"gpt-5": "mimo-v2.5-pro",
"gpt-5.2": "mimo-v2.5-pro",
"gpt-5.2-codex": "mimo-v2.5-pro",
"gpt-5.3-codex": "mimo-v2.5-pro",
"gpt-5.4": "mimo-v2.5-pro",
"gpt-5.5": "mimo-v2.5-pro"
},
"reasoningParamStyle": "reasoning",
"textVerbosity": "medium",
"fastMode": true,
"normalizeNonstandardChatRoles": true,
"codexToolCompat": false,
"priority": 1,
"status": "active",
"autoBlacklistBalance": true,
"normalizeMetadataUserId": true,
"stripParams": [
"stream_options",
"tools",
"function_call",
"max_tokens",
"presence_penalty",
"frequency_penalty",
"top_p",
"n",
"stop",
"logprobs",
"echo",
"store",
"output_config"
],
"maxConcurrent": 2,
"qps": 1,
"retryCount": 1,
"retryDelay": 2000,
"disableTools": true
}
],
"geminiUpstream": [],
"fuzzyModeEnabled": true,
"stripBillingHeader": true
}
需要改的地方:
apiKeys里的sk-你的DeepSeek密钥和tp-你的小米Mimo密钥换成你自己的- DeepSeek 通道的
status是suspended(暂停),Mimo 是active(激活)。平时用 Mimo,Mimo 挂了再切 DeepSeek modelMapping里的映射关系按你实际需要调整
验证:确认一切正常
配置改好后,按顺序做这三步验证。
第一步:看启动日志
启动 CCX 后,控制台应该输出类似这样的信息:
INFO[0000] CCX started successfully on port 3000
INFO[0000] Loaded 2 upstream providers
INFO[0000] Active provider: xiaomimimo-o1c0ll
如果没看到这些,回头看第三步的排查。
第二步:检查模型列表
浏览器打开 http://localhost:3000/v1/models,确认页面返回的 JSON 里包含 mimo-v2.5-pro。
第三步:实际调用
curl.exe -X POST http://localhost:3000/v1/chat/completions -H "Content-Type: application/json" -d "{\"model\": \"gpt-5.4\", \"messages\": [{\"role\": \"user\", \"content\": \"你好\"}]}"
注意这里 model 填的是 gpt-5.4(Codex 会用这个名字发请求),CCX 会根据 modelMapping 转成 mimo-v2.5-pro 发给小米。如果返回了正常的对话响应,配置就对了。
你还会遇到的几个坑
切换模型要开新对话
在 Codex 里切模型后,旧对话还是走老模型。这是 Codex 的会话机制——每轮对话锁定创建时的模型名。切完模型记得开新对话,别在旧对话里继续聊。
偶发 500
如果大部分请求正常但偶尔报 500,大概率是并发限流没卡住。把 maxConcurrent 降到 1,qps 降到 0.5,进一步压低请求频率。
ccswitch 切了但 CCX 没动
ccswitch 改的是 Codex 配置文件(~/.codex/config.toml)里的 model 字段——这是一个模型名称字符串。CCX 路由看的是自己的通道 priority——这是一个数字优先级。两者不在一个维度上,ccswitch 切了模型名,CCX 的路由优先级纹丝不动。
这个问题的根因和解决思路,我在另一篇文章里详细写过:ccswitch 说切了,ccx 却没动——我给 Codex 国产模型切换造了一座桥。
标准排障清单
遇到问题时,按这个表从上往下排查:
| 问题现象 | 解决方案 |
|---|---|
| 所有请求返回 500 | 1. 确认 stripParams 配置完整;2. 检查 API 密钥是否正确;3. 用 curl 直接测试 API 可用性 |
| CCX 启动后秒退 | 1. JSON 不能有注释;2. 去 jsonlint.com 校验语法;3. 检查文件编码为 UTF-8 |
| 端口 3000 被占用 | 执行 netstat -ano | findstr ":3000" 找到 PID,在任务管理器中结束该进程 |
| 提示"API 密钥无效" | 重新生成密钥,确认配置文件中密钥没有多余空格或换行 |
| 偶发 500 | maxConcurrent 改为 1,qps 改为 0.5 |
| ccswitch 切换不生效 | 参考 CCX-Bridge 文章 |
紧急备用方案:切到 DeepSeek
如果小米 API 彻底不可用,临时切到 DeepSeek 救急:
- 把 DeepSeek 通道的
status从"suspended"改为"active" - 把 Mimo 的
priority改为2,DeepSeek 的priority改为1 - 重启 CCX
改完后所有请求自动走 DeepSeek,Mimo 变成备用。
排查这类问题的核心思路就一条:先确认问题在哪一层。是 API 本身挂了?是 CCX 转发的参数不对?还是配置文件语法有错?逐层排除,比盲目改配置有效得多。
更多推荐



所有评论(0)