Skip to content

fix(cooldown): 14003「模型繁忙」按模型级短窗口停车,不再整号冷却 600s - #234

Closed
Fromnowon wants to merge 1 commit into
linguo2625469:mainfrom
Fromnowon:fix/14003-model-busy
Closed

Fromnowon wants to merge 1 commit into
linguo2625469:mainfrom
Fromnowon:fix/14003-model-busy

Conversation

@Fromnowon

Copy link
Copy Markdown

问题

上游 429 code 14003(msg too many requests、displayMsg.zh =「模型繁忙,请换模型或稍后重试」)是模型级信号:同号换模型立刻可用,body 里也没有恢复时刻。但网关此前只把 6004 认成模型级,14003 掉进账号级软冷却。

线上形态:一个请求打中 14003 → 整号 CooldownSoftRate(soft_rate=600s);轮转 500ms 后换下一个号,上游是同一出口/同一模型的繁忙,新号也 14003 → 再罚 600s。4 个国际号 8 次命中,9 分钟内整池不可用 10 分钟(实测 11:27:52–11:36:48,4 个号各 2 次)。

改动

  1. internal/upstream/client.go
    • modelRateLimitCodes = "6004|14003",IsModelRateLimit 同时认两者
    • 新增 IsModelBusy(仅 14003),供 handler 选短窗口
  2. internal/pool/cooldown.go
    • CooldownSoftForModel 无重置时间时写 modelCooldowns[model](不再退化成账号级 until + soft_streak)
    • 新增 CooldownModelBusy:14003 独立短窗口 60s 起、按命中翻倍、封顶 3 分钟;窗口内不延长;已有更晚冷却不缩短
  3. internal/server/handler.go
    • 模型级先判;14003 无时间 → CooldownModelBusy;6004/14003 有墙钟或 Retry-After → CooldownSoftForModel
    • 其余 429 仍走账号级 soft_rate 阶梯
  4. README.md:错误处置表与 429 冷却语义同步

测试

go test ./...   # 全绿
go vet ./...    # 无输出

新增/更新用例:

  • TestIsModelRateLimit + 14003
  • TestIsModelBusy(14003 true / 6004 false / requestId 不误判)
  • TestChat14003StaysModelScopedShortWindow(账号不冷却、模型 ≤3m、换模型可用)
  • TestChat6004WithoutResetStaysModelScoped(原账号级退避用例改为模型级停车)
  • TestCooldownModelBusyShortWindow / TestCooldownModelBusyKeepsLaterCooldown

兼容性

  • state.json 结构不变(modelCooldowns 已有字段)
  • 行为变化:6004 无「将在 … 重置」时也不再罚账号,只停该模型(与 14003 同口径);真正的账号级 429 仍走 soft_rate

上游 429 code 14003(msg "too many requests"、displayMsg「模型繁忙,请换模型
或稍后重试」)此前只有 6004 被认成模型级,14003 落进账号级软冷却:soft_rate
600s 起、翻倍到 2h。一次请求轮转几个号,每个号都中 14003,几十秒内整池冷
10 分钟(国际版线上形态)。

- upstream: modelRateLimitCodes = "6004|14003",新增 IsModelBusy 区分二者
- pool: CooldownSoftForModel 无重置时间时写 modelCooldowns[model],不再退化
  成账号级;新增 CooldownModelBusy(60s 起、封顶 3m、窗口内不延长)
- handler: 模型级先判,14003 无时间时走 CooldownModelBusy
- README: 同步错误处置表与 429 冷却语义
- tests: 覆盖 14003 模型级短窗口、6004 无时间模型级、窗口不延长/封顶/保留更长冷却
@Fromnowon

Copy link
Copy Markdown
Author

推错目标仓库,关闭。本项目实际部署/维护的是 misakano7545/workbuddy2api-panel,同一修复已提交到那里:misakano7545/workbuddy2api-panel#37

@Fromnowon Fromnowon closed this Oct 20, 2026
Huiaei pushed a commit to Huiaei/workbuddy2api-panel that referenced this pull request Oct 25, 2026
…69#238)

上游停更(73a7560)后仍有三个 PR 挂在 linguo2625469 仓库上、因停更而未合
(linguo2625469#237 已关、linguo2625469#238 已关、linguo2625469#234 已关)。逐个核过落地性,结论如下:

采纳 linguo2625469#237(promo 折扣透出):
- 我方 ModelInfo 早有 PromoFactor,但它只在 discount.factor 机器可读时才有
  值。「错峰使用」类条目上游只有 hover 文案(如「周一至周五 09:00–12:00、
  14:00–18:00 属高峰原价,非高峰期积分5折」),factor 藏在文本里,我方一律
  留 nil ⇒ 客户端只拿到牌价 credits,错峰时段实付 x0.085 却显示 x0.17,
  选型被误导(对方实测 deepseek-v4-flash 差 2 倍)。
- 新增 internal/upstream/promo_note.go 从 hover 文案派生时段与折扣比例,
  派生值标记 PromoDerived=true 与上游机器可读字段区分置信度。
- /v1/models 增透 promo_* 一组字段(遵循空值省略约定)。

采纳 linguo2625469#238(试用/限免模型自动熔断)但改掉两处:
- 落盘原本是 tmp + os.Rename。Windows 上任何其他进程持有句柄时裸 Rename
  会返 ERROR_ACCESS_DENIED 而失败,状态从此写不进去 ⇒ 改走 internal/atomicfile。
- 默认监控名单原本硬编码 hy4-preview-f / step-5-preview / hy3——那是提交者
  自己环境里的三个模型,换台机器就是别人的模型,默认禁掉用户从没配置过的
  模型属静默误伤 ⇒ 改为留空,必须显式列 TRIAL_GUARD_WATCH 才生效。
- 新增 empty_watch_test.go 钉死「不配置 = 完全不动」。

不采纳 linguo2625469#234(14003 停车):我方 10e1353 已实现且更细——对方 60s 起/封顶 3m
且不区分瞬时与确定性;我方 10s 起/翻倍/封顶 1m,并按瞬时(14003/6004)与
确定性(11102/11158)分流末端语义。
Smirk1921 added a commit to Smirk1921/workbuddy2api-panel that referenced this pull request Oct 27, 2026
429 code 14003(too many requests / 模型繁忙)与 6004 一样是模型级信号:
- IsModelRateLimit 同时识别 6004/14003;新增 IsModelBusy 区分瞬时繁忙。
- 14003 无 Retry-After 走 CooldownModelBusy:只停 (账号, 模型),60s 起、按命中翻倍、
  封顶 3 分钟;窗口内不延长,已有更晚冷却不缩短,不写账号级 until。
- 6004 无重置时间也从账号级冷却改为只停 (账号, 模型),按 soft_rate 基数退避。
- 其余 429 仍走账号级 soft_rate 阶梯。
移植自上游 PR linguo2625469#234 / misakano7545#37(两者均被关闭,未进上游主线)。
新增/更新测试:IsModelBusy、CooldownModelBusy 短窗口、6004 无重置时间模型级、
14003 端到端换模型可用。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant