
环境:new-api v1.0.0-rc.24 / 智谱 GLM Coding Plan / 2026-08
公司最近在推广 Codex。之前我用 new-api 搭了一套 token 中心给团队用,只开了 chat 和 Claude 两种协议——那是 Claude Code 专用的年代,大家拿着令牌走 /v1/messages,岁月静好。
现在要接 Codex,就得让网关支持 OpenAI Responses 协议(/v1/responses)。上游是智谱 GLM Coding Plan,官网上明晃晃写着它支持三种接入方式:
协议类型 | Base URL |
|---|---|
Anthropic Message 协议 |
|
OpenAI Chat Completion 协议 |
|
OpenAI Response 协议 |
|
看起来是个半小时的活儿。实际折腾了一圈,踩了三个坑,其中一个坑的成因可以说是相当搞笑。记录下来,方便后来人。
按直觉,智谱的渠道应该选「ZhipuV4」类型吧?加渠道、填 Key、保存,然后让同事请求 /v1/responses——直接报错。
翻源码发现,ZhipuV4 渠道适配器的 Responses 转换函数是个摆设(relay/channel/zhipu_4v/adaptor.go:104):
func (a *Adaptor) ConvertOpenAIResponsesRequest(...) (any, error) {
// TODO implement me
return nil, errors.New("not implemented")
}它只会把请求往 /api/paas/v4/chat/completions 上发。也就是说,渠道类型选 ZhipuV4,Responses 协议必挂,没有降级转换。
改用 OpenAI 类型的渠道。它的 URL 拼接规则是「渠道 Base URL + 客户端原始请求路径」的纯字符串拼接(relay/common/relay_utils.go:27),请求体原生透传,流式/非流式响应都有专门的 handler。
所以 Base URL 这样填(注意不要带 /v1,它会自己拼):
类型: OpenAI
Base URL: https://open.bigmodel.cn/api
密钥: 你的 Coding Plan Key拼出来的效果:
https://open.bigmodel.cn/api + /v1/responses
= https://open.bigmodel.cn/api/v1/responses ← 正好是 Coding Plan 的 Responses 端点配置完,先点个「测试」按钮验证一下——好戏开场了。
点下测试按钮,返回:
bad response status code 403, message: No permission to access model: glm-5.2,
body: {"error":{"code":"model_access_denied","message":"No permission to access model: glm-5.2","type":"model_access_denied"}}model_access_denied?没权限?我拿着同一把 Key 直接 curl 官方端点:
curl https://open.bigmodel.cn/api/v1/responses \
-H "Authorization: Bearer <你的CodingPlanKey>" \
-H "Content-Type: application/json" \
-d '{"model":"glm-5.2","input":"hi","max_output_tokens":16}'
# HTTP 200,正常出字同一把 Key、同一个模型、同一个端点,curl 是 200,网关测试是 403。 这时候人已经开始怀疑人生了。
用这把 Key 把各种可能的端点全打了一遍:
端点 | 结果 |
|---|---|
| ✅ 200 |
| ✅ 200 |
| 429 余额不足(错误格式是数字 code) |
| ❌ 403 model_access_denied,一字不差 |
最后一行就是元凶。而智谱 Coding Plan 的 /api/v1 这个 Base,只开放 Responses 协议——chat completions 打过去就是这个 403。
那网关为什么去打 /api/v1/chat/completions?读 controller/channel-test.go,真相令人捧腹:
// controller/channel-test.go:116
requestPath := "/v1/chat/completions" // 测试按钮默认按 chat 协议测
// controller/channel-test.go:145
// responses-only models
if strings.Contains(strings.ToLower(testModel), "codex") {
requestPath = "/v1/responses" // 模型名里含 "codex" 才改测 Responses
}渠道测试按钮默认按 chat completions 协议测试;只有当"测试模型名"里包含 codex 字样时,才切换成 /v1/responses。
我当时把渠道命名为「测试codex」——没用,它查的是模型的身份证,不看渠道的户口本。测试模型是 glm-5.2,于是老老实实走了 chat 协议,一头撞上"该端点不开放"的 403。
也就是说:渠道配置从头到尾都是对的,这个 403 是个假阴性——测试按钮用错了协议去测一个只支持另一种协议的端点。
顺带一提:渠道测试不写 relay 日志,所以数据库 logs 表里这个渠道一条记录都没有,这也一度干扰了排查方向。
明白了测试按钮的坑之后,把模型名改成带 codex 的,测试立刻通过。但这里必须澄清一个容易误解的点(我自己也一度搞混):
模型名带不带 codex,只影响"测试按钮"用哪个协议测;真实流量的协议由请求路径决定——客户端请求 /v1/responses,网关就按 Responses 协议处理,跟模型名没有任何关系。
真实流量的问题在别处:new-api 选渠道只看「分组 + 模型名 + 优先级」,与请求协议无关(model/channel_cache.go)。而我们这套 token 中心里已经有一堆 Claude 时代的 Anthropic 类型渠道,模型列表里都有 glm-5.x,优先级 100;新渠道优先级 0。于是:
同事请求 /v1/responses (model: glm-5.2)
→ 在优先级 100 的池子里随机挑一个 Anthropic 渠道
→ Responses 请求被"好心"地转成 Claude 格式
→ 发到 /api/anthropic/v1/messages,用的是那个渠道里别人的 Key
→ 碰到没权限的 Key → 403 model_access_denied同一个报错,两个完全不同的成因——这也是这次排查最迷惑的地方。日志表里 glm-5.2 的流量均匀分布在十几个渠道上,而新渠道是 0 条,坐实了"流量根本没来过我这"。
一步到位的方案:给 Responses 专用渠道起独占的模型名,并且名字里带 codex。一举两得——路由独占,测试按钮也自动走 Responses 协议。
配置项 | 值 |
|---|---|
渠道类型 | OpenAI |
Base URL |
|
密钥 | Coding Plan 的 API Key |
模型 |
|
模型重定向 |
|
状态 | 启用 |
再在「运营设置 → 模型固定价格/倍率」里给这两个新名字配上与 glm-5.2/glm-5.3 相同的价格——计费按客户端请求的模型名查价,不配会报价格未配置。
调用方这样用:
curl https://你的网关地址/v1/responses \
-H "Authorization: Bearer sk-你的newapi令牌" \
-H "Content-Type: application/json" \
-d '{"model":"glm-5.2-codex","input":"hi"}'原有的 chat / Claude 协议渠道完全不受影响,Claude Code 的团队继续用 /v1/messages + glm-5.2,互不干扰。
如果不想改模型名,也可以用独立分组方案:新建一个分组(如 responses),把新渠道归进去,给 Codex 用户发该分组的令牌——令牌分组同样能实现确定性路由,只是测试按钮依旧是假阴性。
千万不要图省事把新渠道优先级调到全场最高:那会把所有 glm-5.2 流量(包括团队的 Claude 流量)都抢过来,转成 OpenAI 格式打到一个不开放的端点上,而且全部消耗你这一个 Key 的配额。
/v1/responses, Responses 协议要用 OpenAI 类型渠道 + Base URL https://open.bigmodel.cn/api 实现。codex 才测 Responses——在只开放 Responses 的端点上,测试报 403 model_access_denied 恰恰说明渠道配对了,别被假阴性骗了。以及一条隐性经验:报错是上游给的,不代表流量走的是你以为的那条路。先查日志里这条请求到底用了哪个渠道,再谈别的。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。