Skip to content

fix: 避免中转 Key 按透传的 ChatGPT 周限额长期冷却 - #515

Merged
ranxi2001 merged 2 commits into
productionfrom
fix/apikey-chatgpt-quota-cooldown-20261022
Oct 21, 2026
Merged

ranxi2001 merged 2 commits into
productionfrom
fix/apikey-chatgpt-quota-cooldown-20261022

Conversation

@ranxi2001

Copy link
Copy Markdown
Owner

解决的问题与行为变化

  • 触发条件 / 原行为:OpenAI 平台中转 API Key 透传某个上游 ChatGPT 账号的 usage_limit_reached、resets_at 或 Codex 周窗口时,本地把这个窗口应用到整个 Key,造成余额仍可用的中转 Key 长期停调。fix: 区分 OAuth 与 API Key,避免上游套餐误标 Key #510 已修复套餐误标,但保留了这条冷却逻辑。
  • 修改后行为:普通 OpenAI API Key 的上游 429 使用现有可配置兜底冷却,默认 5 秒;不持久化透传的 Codex 使用率快照或长重置窗口。管理端 Key 测试也不再用 ChatGPT 429 更新调度状态。
  • 本次范围与仍未解决的问题:OAuth / Setup Token 真实配额窗口保持原逻辑;专用供应商配额、显式错误策略、池模式仍按已有优先级处理。不会自动清除历史长冷却;不合并、不发版、不部署。

关联记录与来源

复现与验收

  • 环境与基线:历史现象来自 2.14.0 / f3f72fa98;本 PR 从包含 fix: 区分 OAuth 与 API Key,避免上游套餐误标 Key #510 的 production / c2beea839 修复。以下为离线回归输入,尚未在本地执行,不声称重新复现生产。
  • 前置条件与操作:
    1. 构造 OpenAI API Key 账号 ID 42,关闭池模式,未设置自定义错误策略;模拟上游 HTTP 429。
    2. 返回下列错误体,或仅返回 x-codex-primary-used-percent: 100、x-codex-primary-reset-after-seconds: 604800、x-codex-primary-window-minutes: 10080。
  • 修复前观察:Key 冷却到错误体指定的远期时间,或按 Codex 七天窗口冷却;管理端测试也可写入长冷却。
  • 修复后验收:普通 Key 只按兜底设置冷却;禁用兜底时不新增本地冷却;不写入 Codex 快照。管理端 Key 测试不修改配额状态;OAuth 的真实窗口继续有效。
  • 回归位置:backend/internal/service/ratelimit_service_openai_apikey_quota_test.go;同步调整现有 API Key 套餐测试的冷却断言。覆盖绝对/相对重置时间、Codex/透传 Anthropic 头、普通 429、默认/自定义/禁用冷却、运行时调度阻塞和管理端测试。既有 OAuth / Ollama 等用例交由 CI 回归。
协议、调度或传输改动补充
  • 端点与类型:OpenAI 平台 API Key 的通用上游 429 处理与管理端账号测试;不修改模型映射、HTTP/SSE 解析或 WebSocket 协议。
  • 脱敏最小错误:{"error":{"type":"usage_limit_reached","plan_type":"pro","resets_at":4102444800}}。
  • 正常完成、超时、EOF、客户端取消的处理不变;仅调整上游 429 引发的本地冷却。上游 429 仍进入原有错误返回/故障转移路径。
  • HTTP 状态、最终业务错误、request ID、耗时及用量记录逻辑不变;新增兜底原因 openai_apikey_upstream_429,不增加正文或凭据采集。
  • 不新增重放或重试次数;请求已发送/流已开始后的策略、幂等与并发释放保持现有行为。
  • 调度运行时阻塞与数据库使用同一兜底期限,避免只修数据库而保留七天运行时阻塞;不自动清理已存在的历史冷却。池模式和显式策略保持优先。

实际验证

检查与执行目录 / 命令 结果 覆盖范围、证据或未运行原因
源码 worktree:gofmt -w backend/internal/service/ratelimit_service.go backend/internal/service/account_test_service.go backend/internal/service/ratelimit_service_openai_test.go backend/internal/service/account_test_service_openai_test.go backend/internal/service/ratelimit_service_openai_apikey_quota_test.go 通过 仅源码格式化,不代表编译或测试通过
源码 worktree:git diff --check / 暂存后 git diff --cached --check 通过 补丁空白检查
源码 worktree:人工审阅 git diff,核对 production 的贡献指南、PR 模板与 CI 配置 完成 核对范围、专用供应商分支优先级、OAuth 和管理端入口;不是运行验证
CI:make -C backend test-unit、make -C backend test-integration、lint、安全检查及构建 未运行 按任务要求直接提交 PR,交由 CI;本地未启动、未等待 CI
真实上游请求、生产验证、UI 截图 未运行 无 UI 改动,不发送可能计费请求,不操作生产

兼容性与运行影响

  • 配置 / API / 默认行为:不新增字段或设置;复用现有“429 兜底冷却”,默认启用且 5 秒,可自定义或关闭。普通 OpenAI Key 不再接受透传账号的远期重置时间,即使直接 Key 返回同类错误也适用;专用配额路径保持优先。
  • 数据库与回滚:无迁移;旧套餐误标由 fix: 区分 OAuth 与 API Key,避免上游套餐误标 Key #510 处理展示。已持久化长冷却不自动清除,应核实后通过管理端恢复。回退二进制可再次写入旧式长冷却,不撤销已经写入的短冷却。
  • 权限、凭据与日志:权限不变,不采集或修改 Key、Token、ticket/state;日志只使用既有账号 ID、平台及兜底原因。
  • 计费与资源:不改变计费或并发上限,不新增 goroutine 或定时任务;持续真实 429 时短冷却可能比七天停调产生更多后续尝试,依然受现有请求重试预算和调度控制约束。
  • 灰度 / 回滚与残余风险:合并后另行发布部署;用中转 Key 的 429 与正常请求观察冷却和调度。无法仅凭中转错误区分背后单账号耗尽或整个 Key 配额耗尽,持续错误场景可使用已有显式错误策略;不宣称上游一定可恢复。

文档与用户可见变化

README 增加中转 API Key 429 的短冷却语义、专用路径例外和历史状态处理说明。无 UI、API schema 或 i18n 变化;PR 合并不等于已上线。

Agent 使用声明

  • Agent 名称与参与范围:Codex;问题分析、源码与回归用例编写、文档与 PR 正文、提交推送;未使用子 Agent。
  • 模型名称:GPT-6(运行环境仅提供系列名称;完整模型 ID 未公开,未知)。
  • 推理强度:未知,运行环境未公开实际配置值。

提交前自查

  • base 分支和改动范围正确,没有夹带无关修改。
  • 正文、提交、测试数据和附件不含凭据、ticket/state 或真实用户敏感信息。
  • 实际验证结果已列出,失败、未运行和未覆盖的部分已说明。
  • 已检查配置默认值、权限、兼容性及相关文档;不适用项已说明。
  • Bug 修复有针对性回归验证,执行结果待 CI。
  • 已填写全部实际 Agent、模型与推理强度的信息边界。

@ranxi2001
ranxi2001 merged commit cf2bca0 into production Oct 21, 2026
18 checks passed
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