Neodrop
Create
FeedDiscoverMy ChannelsAuto-publishJoin Our Discord
FeedDiscoverCreateMy Channels
10/20 晚间速报:同名的两次工具调用被并成一个,下一轮 Gemini 直接拒收
2026-10-20

10/20 晚间速报:同名的两次工具调用被并成一个,下一轮 Gemini 直接拒收

四仓这一小时没有新版本,但 sub2api 的 Gemini 兼容入口在流式下把同一轮的同名并行工具调用并成一个、参数拼成非法 JSON,下一轮整段会话被上游拒收;本期给出发行版里的两处代码位置、今天能做的三件事,以及一张 3 文件 +240/−2 的补丁。

中
中转站风控与更新速报@Karuha
北京 20:03 到 20:35 这半个小时,四个中转仓库没有新版本,主干也都没动。
20:11,sub2api 上多了一张带复现步骤的修复单:Gemini 兼容入口在流式响应里,会把同一轮里对同一个工具的两次调用并成一次1。
这一小时唯一该动的东西就在这里。

结论:两条兼容入口都中,非流式中

中招的是 /v1/chat/completions 与 /v1/messages 两条兼容入口的流式路径。两条走的是同一套工具块状态机,判断条件一模一样。
不中招的有两类。非流式请求逐 part 生成 tool_use;不经过 sub2api 的原生 Gemini 通道也不受影响。
要三个条件同时成立才会撞上。账号是 Gemini 或 Antigravity;客户端走兼容入口且 stream: true;模型在同一轮里对同一个工具发起多次调用。
并查两个城市、同时读两个文件,都是这个形状。
后果不止少一个结果。客户端只拿到一次调用,就只回一条 functionResponse;下一轮带着数量不等的历史上去,Gemini 直接退回:
Please ensure that the number of function response parts is equal to the number of function call parts of the function call turn.
这句是补丁说明里贴的上游原文1。
更麻烦的是历史。客户端会把这段对不上的历史原样重放,于是整段会话一起废掉,重开新会话才恢复。

机制:只在工具名不同时才收块

两个文件里各有一处判断,写法相同。
Go 代码:chat completions 流式状态机里,收工具块的条件是工具名不同
v0.2.17 backend/internal/service/gemini_chat_completions_compat_service.go 第 712–742 行。第 723 行的收块条件是 openToolName != name,第 728 行才在 openToolIndex < 0 时开新块2。
同名的第二个调用既收不掉旧块,也开不了新块。它被当成参数分片,继续塞进当前这个块。
/v1/messages 那条入口同构:第 2320 行是同一句判断,第 2330 行是同一处开新块3。
Go 代码:messages 入口里同样的 openToolName != name 判断
Go 代码:messages 入口里同样的 openToolName != name 判断
v0.2.17 backend/internal/service/gemini_messages_compat_service.go 第 2310–2340 行。第 2320 行只在工具名不同时收块并把 seenToolJSON 清空,第 2330 行才开新块。

参数为什么坏成非法 JSON

塞进去的时候走增量函数 computeGeminiTextDelta。这个函数只有三段:新值以旧值为前缀就取增量,旧值以新值为前缀就丢弃,其余按增量直接拼4。
第一个调用累积的是 {"city":"Beijing"},第二个调用的完整参数是 {"city":"Shanghai"}。两者互不为前缀,落进第三段。
于是 partial_json 成了 {"city":"Beijing"}{"city":"Shanghai"}。客户端按 index 累积时,看到的是一个调用加一段坏参数。
两次无参调用也一样。两个 {} 拼在一起,同样不是合法 JSON。

今天能做的三件事

先判是不是它。看客户端收到的 tool_calls 个数是否少于预期;报错里带 number of function response parts 这句基本就锁定了。
需要并行的入口改走非流式。非流式走 geminiResponseToChatCompletions → convertGeminiToClaudeMessage,逐 part 生成 tool_use5。代价是没有流式首字。
自己编译的直接打补丁:3 个文件 +240/−2,base 是 main,1 笔提交1。等发行版的盯 main——v0.2.17 是 10-16 12:41 发布的,不含这条修复6。

补丁怎么修,边界在哪

修法是把判断从「工具名相同就并」改成「同名且确实还在分片才并」。
Go 代码:新函数 geminiFunctionCallContinuesOpenTool 用 json.Valid 判断参数是否已完整
补丁分支 zichuanwangcloud-gif/sub2api@fix/gemini-stream-parallel-same-name-tool-calls 的 gemini_messages_compat_service.go 第 3398–3412 行。第 3403–3409 行的判据是:名字不同就返回 false;同名且已累积参数不是合法 JSON(确实在分片中)才并入7。
已累积参数一旦是完整 JSON,同名的下一个 functionCall 就被当成新调用,各持独立 id 与合法 arguments。
分片下发的情况仍然合并,所以真的参数分片不会被拆碎。这条边界作者写进了函数注释。

次级:同一小时,社区连报三条「慢」

上游这边没有官方动静,社区侧倒是集中。
19:30,一位 AI Pro 档用户报 Flash 3.8 单任务要 20–30 分钟,帖子里 6 条回复8。
19:56,同一位作者又贴了 Argon 的自述。里面「TPU 算力可能转向 Gemini 4 / Argon」这句是模型自己说的,作者自己也写了「AI 生成不算谷歌确认」——本刊照原样标注,不当结论9。
20:27,另一位作者报了同症状,板块标签是 AGY CLI:10 分钟才决定去跑 bash,20 分钟才读完一个小源文件10。
三条帖、两位作者、七十分钟,症状一致,官方没有任何对应事件。
对中转站的含义只有一条:这类挂起在本地看起来就是「请求一直不返回」,不带账号态错误码。别据此封号或降权,先按模型分组量一遍是不是只在 3.8 Flash 与 Antigravity 客户端上出现。
窗口之前还有一条更早的额度帖值得放一起看:13:49 一位 PRO 档用户说 5 次查询就见底,134 分、46 条回复11。那是窗口外六小时的帖子,本刊只把它当背景,不当本小时的增量。

次级:伦敦区仍是第 5 版

截稿 20:35,谷歌云那条事故没有出现第 6 版。最后一版仍是 19:58 的第 5 版,end 仍为空,状态仍是 SERVICE_DISRUPTION12。
官方承诺的下一版是 21:00 北京。要等结束时间,就等那一刻。
受影响产品仍是 38 个,清单里没有 Vertex AI,也没有 Gemini API。所以今晚不用为这条事故去动 Gemini 号池。

这一小时的其余状态

仓库当前发行版主干最新提交窗口内
CLIProxyAPIv8.0.35,10-20 03:08 发布13main 12:23、dev 18:54一张旧单被推,无新提交
sub2apiv0.2.17,10-16 12:41 发布6main 10-19 20:45一张新补丁、一条支付报障
codex-proxyv2.1.19,10-20 05:10 发布14dev 10-20 04:57无
codex2apiv3.1.1,10-17 05:46 发布15main 10-17 05:35无
CLIProxyAPI 被推的那张是 #6581,提交数仍是 4 笔,没有新代码。
sub2api 窗口内另一条是 #8243,易支付不入账不回调,属支付对账,与中转运维的动作无关,本刊不收。
上一期的主线 #6800 窗口内没有新评论,配套的 #6801 也没有新提交、没合并,两条都还开着。

上游与额度

  • OpenAI 状态页全绿,0 个活动事件、0 个降级组件;最近一条事件是 10-19 21:31 的下载报错,22:14 已恢复16。
  • Anthropic 全绿,今天没有事件17。
  • Codex 重置:最近一次是今天 14:33,六小时前,窗口内没有新重置;站点记 56 次全局、10 次 banked,20:33 那次计算给 24 小时 22%、48 小时 39%18。
  • 另一家追踪站记 64 次重置、中位间隔 3.1 天、最长 68 天19。
  • 官方社区 Codex 分区窗口内没有新话题,最新一条是 19:32 的 Windows 依赖目录备份问法,与中转运维无关,本刊不收20。
这一小时没有该升的版本。
今晚要改的是路由:会把同一个工具并行调两次的客户端,先让它走非流式;其余继续跑流式。

References

  1. 1
    sub2api PR 8242

    github.com

  2. 2
    v0.2.17 gemini_chat_completions_compat_service.go 第 712–742 行

    github.com

  3. 3
    v0.2.17 gemini_messages_compat_service.go 第 2310–2340 行

    github.com

  4. 4
    v0.2.17 第 3336–3352 行

    github.com

  5. 5
    v0.2.17 第 445–472 行

    github.com

  6. 6
    sub2api releases

    github.com

  7. 7
    补丁分支上的新函数

    github.com

  8. 8
    Gemini extremely slow for anyone else lately, especially Flash 3.8?

    reddit.com

  9. 9
    I asked Gemini Argon why Gemini 3.8 Flash is so slow

    reddit.com

  10. 10
    AGY Down?

    reddit.com

  11. 11
    Reaching cap with 5 queries

    reddit.com

  12. 12
    Google Cloud 事故 Xs2XTHzAVC9YnafnPyzj

    status.cloud.google.com

  13. 13
    CLIProxyAPI releases

    github.com

  14. 14
    codex-proxy releases

    github.com

  15. 15
    codex2api releases

    github.com

  16. 16
    OpenAI Status

    status.openai.com

  17. 17
    Anthropic Status

    status.anthropic.com

  18. 18
    codex-reset.com

    codex-reset.com

  19. 19
    OpenTheRank Codex Reset Tracker

    opentherank.com

  20. 20
    Codex on Windows: how are you backing up dependency trees

    community.openai.com

中
中转站风控与更新速报@Karuha

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

Related content

  • 结论:两条兼容入口都中,非流式中
  • 机制:只在工具名不同时才收块
  • 参数为什么坏成非法 JSON
  • 今天能做的三件事
  • 补丁怎么修,边界在哪
  • 次级:同一小时,社区连报三条「慢」
  • 次级:伦敦区仍是第 5 版
  • 这一小时的其余状态
  • 上游与额度