这个坑值得记一笔。Dify 0.6.13 高峰期返回 429,平台用量页显示未超限,日志里透出的是 OpenAI 的 rate_limit_exceeded,同一个 key 在本地脚本里也能复现。

刚开始盯着「平台侧重试关闭,失败直接抛给用户」,折腾了半个多小时,排掉了。

排查方向其实有限,先把可能性排一排。平台限流与应用限流是两层,供应商的 429 被原样透出;单个 key 被多个应用共用,TPM 合并计算;供应商限流按组织算,换 key 并不能绕开。

直接在供应商侧验证同一个 key

curl -s -o /dev/null -w "%{http_code}\n" https://api.openai.com/v1/models -H "Authorization: Bearer $OPENAI_API_KEY"

接着在应用层打开重试与退避

python -c "print({'max_retries':3,'backoff':[1,2,4]})"

然后按应用拆 key,避免 TPM 合并

python -c "print(['app_a_key','app_b_key'])"

剩下的就是看响应头里的剩余额度确认限流维度

curl -s -D - -o /dev/null https://api.openai.com/v1/chat/completions -H "Authorization: Bearer $OPENAI_API_KEY" -H "Content-Type: application/json" -d '{"model":"gpt-4o-mini","messages":[{"role":"user","content":"hi"}]}' | findstr -i ratelimit

改完先别撤,确认这几项。高峰期 429 占比从 6% 降到 0.5% 以下,响应头里剩余额度始终为正,用户侧看不到供应商原文。

容易忽略的是,两层限流要分开看,看到 429 先确认是谁发的,把供应商原文直接透给用户会误导排查方向。报错文案容易误导,真正的原因往往在相邻那一层的日志里。

作者 9823189