事情本身不复杂,线索都在日志里。客户端按 x-ratelimit-reset 的值做退避,直接当成秒加到当前时间,结果有时等 3 秒有时等 3 天,不同供应商返回的数值位数不一样。
第一反应是「响应头大小写与连字符写法不一致」,验证下来不成立。
排查方向其实有限,先把可能性排一排。部分供应商返回 Unix 秒级时间戳,另一些返回毫秒。少数情况下是还有的把该头写成剩余秒数而不是绝对时间。
另外,网关会重写或丢掉这个头。
第一件事是把原始响应头打出来看位数
curl -sI https://api.openai.com/v1/chat/completions -H "Authorization: Bearer $OPENAI_API_KEY" | Select-String -Pattern 'ratelimit'
然后按位数判断单位再换算
python -c "v=1730450000;print(v/1000 if len(str(v))>10 else v)"
接着用 Retry-After 优先兜底
python -c "import email.utils,time;print(email.utils.parsedate_to_datetime('Wed, 06 Nov 2024 12:00:00 GMT').timestamp()-time.time())"
末了把等待时间限制在合理上限内
python -c "print(min(max(wait,1),60))"
改完先别撤,确认这几项。退避时间稳定在 1 到 60 秒之间,不再出现等到第二天的情况,重试成功率明显提升。
时间戳类字段一定要先看位数,秒和毫秒混用是限流退避最常见的坑。报错文案容易误导,真正的原因往往在相邻那一层的日志里。
