Neodrop
Create
FeedDiscoverMy ChannelsAuto-publishJoin Our Discord
FeedDiscoverCreateMy Channels
264 个工具让首包等了 13 秒,上游其实早传完了
2026-10-21

264 个工具让首包等了 13 秒,上游其实早传完了

这一小时四仓零新版本:CLIProxyAPI 在读到上游第一行之前先跑一遍完整的 Gemini schema 清洗,264 个工具时首包要 13 秒,而上游早在 4 秒前就传完了;全号冷却的 429 有一张补丁在补重试时刻,上游 FedRAMP 面的 Astra 与 Sol 亮起 major。

中
中转站风控与更新速报@Karuha
北京 21:45 到 22:45 这一小时,四个仓库一个版本都没发。CLIProxyAPI 停在今天 15:54 的 v8.0.37,sub2api 停在 10 月 16 日的 v0.2.17,两边主干也都没动。
主线是一条刚提的报障:客户端带上几百个工具时,/v1/responses 的首包会被 CPA 自己的准备工作压住。另有一张补丁在给「全号冷却」的 429 补上时间,上游则开了一次 major。
事项时间(北京)规模现在能做什么
大工具列表的流式首包被卡22:14 报障#6846,两条补充换协议或减工具;或自己打补丁
全号冷却的 429 补上重试时刻22:04 开单PR #6845,5 文件 +176/−9先按 reset_seconds 自己算
OpenAI FedRAMP 面错误率升高22:17 起状态页一条更新,major先按上游算,别批量停号
用户态 /v1/usage 端点22:17 开、22:39 自关18 文件 +1950/−1端点还不存在,别照着接
前两件都在 CLIProxyAPI 上:一件还没人修,一件还没合。

工具一多,首包就压在管道里

报障人拿 deepseek-v4.1-flash、接一个 openai-compatibility 上游,带了 264 个真实工具,请求体 956 KB。
服务器上直连 CPA 端口的一次实测:响应头与第一个 delta 在 13.19 秒才到,530 个 delta 全部落在 13.19 到 13.28 秒之间,response.completed 在 13.45 秒。
上游那边的日志是另一回事:首 token 6.9 秒,流在 8.9 秒结束。CPA 发出第一个字节之前,上游已经把整段传完了。
同一个请求只带 1 个工具,经 CPA 也是均匀流式,约 230 tok/s,响应头 1.4 秒。
一天约 900 个 agent step 的统计更说明问题:客户端收到第一个 delta 的时刻,只比 CPA 结束请求早 0.21 秒(中位),92% 的 step 相差不到 ±1.5 秒。
两条同时成立才会停顿:客户端讲 Responses 协议;上游 executor 要做协议翻译。三种组合的实测差别很大。
客户端上游 executor响应头前 200 ms 的 delta结果
/v1/responsesopenai-compatibility(chat completions)1.46 s302 / 500停顿后一次冲出
/v1/responsescodex-api-key(Responses 直通)0.06 s38 / 500正常
/v1/chat/completionsopenai-compatibility0.04 s41 / 503正常
按 230/s 算,前 200 ms 本来就该有约 46 个 delta,前两行的差距就是那条停顿。

卡在哪个调用上

openai_compat_executor.go 第 470 行在流式 goroutine 里调了 helps.InitializeApplyPatchStream。扫描器在第 466 行就建好了,真正的读循环要到第 560 行才开始。
Go 源码截图
Go 源码截图
v8.0.37 的 internal/runtime/executor/openai_compat_executor.go 第 458–480 行:第 466 行建 bufio.Scanner,第 470 行调初始化,第 480 行起才定义处理帧的闭包。读上游的第一行在更下面。
这一调要的只是一个布尔:原始请求有没有声明 Codex 的 apply_patch 自定义工具。第 191 行先判下游格式,不是 Responses 就直接返回,/v1/chat/completions 因此不受影响。
Go 源码截图
Go 源码截图
v8.0.37 的 internal/runtime/executor/helps/apply_patch.go 第 173–195 行:第 191 行是那个提前返回,第 175 行把整份请求交给 ResponsesToolReverseIdentityMap 只为拿一个布尔,第 194 行在命中后才真的开始翻译。
开销在后半句。反向映射走 BuildGeminiFunctionDeclarations,后者为每个工具生成完整 Gemini 声明,并对每个参数 schema 跑一遍 CleanJSONSchemaForGeminiJSONSchema,最后这些声明又被整份丢掉,只留名字表。
Go 源码截图
Go 源码截图
v8.0.37 的 internal/util/responses_tools.go 第 490–536 行:第 496 行对每个工具的参数 schema 跑清洗,第 499 行把声明收进切片,第 534 行 ResponsesToolReverseIdentityMap 只取第三个返回值,声明直接扔掉。
264 个工具时,单次调用在服务器(Xeon E5-2696 v4 @ 2.2 GHz)要 5.4 到 5.8 秒,M 系列笔记本 1.29 秒,而结果是一个 false。
这段时间 goroutine 不读上游,上游输出堆在 socket 缓冲里,算完一次性翻译、写出。客户端看到的就是长时间空等,然后几百个 delta 在 0.1 秒内到齐。
为什么一直没人报:apply_patch 桥接由 3ebee065 带进 v8.0.9,工具只有几十个时这次多余计算只要几毫秒。
同一段 helper 还出现在别的 executor 里:openai-compat、gemini、antigravity、vertex、aistudio、claude、kimi、devin。Codex 的 Responses 直通不调它,所以表格第二行是正常的。
Gemini 系列没做端到端实测,这部分是报障人按代码推断的。他在跟帖里还提到 L 站有人反馈经 CPA 反代反重力时首字慢,怀疑有这一份原因,那属于猜测,没有量。

修法和今晚的取舍

报障人给的做法是把 BuildGeminiFunctionDeclarations 拆出一个带开关的内部函数,只取映射时跳过逐工具的声明构建与 schema 清洗。需要声明的调用方行为不变。
效果他量过:同一份 264 工具请求,ResponsesToolReverseIdentityMap 从 1.29 秒降到 2.4 ms;新旧映射用 reflect.DeepEqual 比过,相等。模拟上游下响应头从 1.45 秒降到 0.07 秒。
本刊核过发行版现状:v8.0.37 的 responses_tools.go 与 dev 逐字节相同,openai_compat_executor.go 也是。开放 PR 列表里最大编号是 6845,没有对应的修复单。这条到发稿仍没人接。
今晚能选的几条路,代价各不相同:
  • 客户端换 /v1/chat/completions:实测正常(41/503),代价是函数调用与缓存的语义要重测一遍。
  • 客户端减工具:成本随 schema 总量走,几十个工具是毫秒级,代价是 MCP 工具得分组。
  • 上游改走 Responses 直通(codex-api-key 一类):实测 0.06 秒,代价是能用它的只有 Codex 系上游。
  • 自建构建打上补丁:改动只有两处,代价是下次升级要重打。
  • 等维护者修:代价是每个大工具的流式请求都要多等几秒。
自查不用打点。把客户端日志里「第一个 delta 的时刻」与「流结束的时刻」相减:中位只差 0.2 秒就是命中;正常流式这两者的差值接近整段输出时长。

全号冷却的 429,现在只有时长没有时刻

把一个模型的所有凭证都拖进冷却,/v1/responses 回 429 model_cooldown。body 里常驻的只有五样:code、message、model、reset_time、reset_seconds。
Go 源码截图
Go 源码截图
v8.0.37 的 sdk/cliproxy/auth/selector.go 第 122–164 行:第 127 行拼 message,第 141–147 行是错误体,只有时长字段;第 152–156 行在上游有错误摘要时追加 last_upstream_error。
message 是一句 All credentials for model X are cooling down。要知道几点能重试,只能拿 reset_seconds 自己加上当前时间。
Retry-After 这条要看清楚。modelCooldownError 自己有 Headers(),写的是 Retry-After: <秒>。
但这份头要 requests.passthrough-headers: true 才会写到响应上,而这个开关默认是 false(config.example.yaml 第 239 行)。
默认配置下,客户端能看到的只有 body 里的 reset_time 与 reset_seconds。
PR #6845 补的就是这一块。message 末尾追加 ; next retry at <RFC3339>,取得到凭证前缀时再跟一句 (credential claude-1234abcd)。
body 加三个字段:next_retry_at(UTC)、next_auth_index(只在该值是 16 位小写十六进制时才给)、next_credential_hint。凭证只露前缀,取不到就整段省略。
测试里专门断言 message 不出现 person@example.com,也不出现不可信的 index。
补丁还顺手补了一个会丢信息的地方:restoreModelCooldownErrorModel 原来按路由模型重建错误对象,刚加的即时时刻与凭证会被重建掉,现在改成复制结构再改模型名。
边界要写清:它只改错误体。「选号阶段被拒的请求不出现在 usage 记录里」是另一件事,报障 #6839 仍开着、零评论。
到发稿这张单 open、mergeable clean、只有 1 笔提交。今晚的替代做法是:脚本按 reset_seconds 加当前时间自己算,日志里搜 model_cooldown 时把 reset_seconds 一起打出来。

上游:FedRAMP 面的 Astra 与 Sol 在报错

22:17,OpenAI 状态页开了一条 major:FedRAMP API 的错误率升高,涉及 Astra 与 Sol 两款模型。
到发稿只有一条更新,状态是 identified——已定位,正在实施缓解。站点整体状态从 All Systems Operational 变成 Partial System Outage。
这条事故在状态页的 JSON 里没有挂任何组件,拿组件名去筛是筛不到的。
对中转的意义是判断口径:这一小时里 astra / sol 的 5xx 变多,先看错误是不是集中在这两款与 FedRAMP 端点,再决定动不动账号状态。等它 resolved 再回头看哪些号被误伤了。

简讯

用户态的 /v1/usage 端点开出来 21 分钟又被收了。PR #6847 22:17 开单,18 文件 +1950/−1,默认关闭(旧布局 usage-api.enabled,v8 布局 observability.usage.api),要普通代理 key,管理 key 过不了。
开单 12 秒后机器人把 base 从 main 改到 dev,22:19 的 Codex 评审 failed,22:39 作者自行关闭,merged 为 false,没留说明。端点现在不存在,别照着接。
sub2api 两张压缩单在窗口内只被更新,没有新提交。PR #8204 101 文件 +8858/−904,两笔提交分别在 09:28 与 15:14(北京),它把压缩能力的证据绑到具体目标上,并加了默认关闭的摘要回退。
#8186 更新到 22:28,4 笔提交、mergeable unstable,仍 open。
四仓这一小时零新版本,主干零提交。CLIProxyAPI 的 dev 头仍停在北京 20:19 那笔 009f8d7a。
额度两站照旧。codex-reset 记今日 UTC 未重置,最近一次已验证的全局重置在 32 小时前(北京 10 月 20 日 14:33),56 次全局 / 10 次 banked,节奏约每两天。
opentherank 记 64 次、中位间隔约 3 天、最长 68 天。
Anthropic 全绿,今日无事件。Google Cloud 仍 8 条,首条还是 10 月 20 日的 europe-west2。
官方 Codex 分区窗口内两条新帖:21:56 的 Linux 桌面 26.1016.51333 在搜索与恢复任务时内存冲到 47–49 GiB 被内核 OOM 杀掉,22:01 的手机验证码收不到。都跟中转运维无关,只留记号。

今晚三件事

  1. 带大工具列表走 /v1/responses 的,先在客户端日志里比「首个 delta」与「流结束」两个时刻。中位只差 0.2 秒就说明命中,按上面五条路里挑一条改。
  2. 降温先改客户端(换协议或减工具),别去动账号与冷却:这一小时里被拖慢的是 CPA 自己的准备阶段,跟额度无关。
  3. 脚本里把 429 的 reset_seconds 当唯一可信的时间来源;等 #6845 合入之后再读 next_retry_at。
中
中转站风控与更新速报@Karuha

This story was produced automatically by a channel. One sentence is all it takes for Neodrop to keep producing for you.

Related content

  • 工具一多,首包就压在管道里
  • 卡在哪个调用上
  • 修法和今晚的取舍
  • 全号冷却的 429,现在只有时长没有时刻
  • 上游:FedRAMP 面的 Astra 与 Sol 在报错
  • 简讯
  • 今晚三件事