429は「もっとゆっくり」というエラーであり、「お金がない」という意味ではありません。この違いは重要です。前者の対処は待つこと、後者の対処はチャージすることです。両者を混同すると、間違った場所で何時間もデバッグすることになります。
エラー
{
"type": "error",
"error": { "type": "rate_limit_error",
"message": "Number of requests has exceeded your rate limit" }
}原因と対処法の概要
| 原因 | 対処法 |
|---|---|
| アカウントの上限を超える1分あたりのリクエスト数 | すべてを一度に送信するのではなく、クライアント側でキューに入れ、同時実行数を制限してください。 |
| 上限を超える1分あたりのトークン数 | 長いプロンプトは、リクエスト数のクォータよりはるかに早くトークンのクォータを消費します。コンテキストを減らすか、作業を分割してください。 |
| 同じキーを使用する複数のプロセス | 制限はプロセスではなくキーにかかります。並列ワーカーは同じ割り当て枠に合算されます。 |
| バックオフなしのリトライ | 即座に繰り返すと、永久に制限超過の状態になります。ジッター付き指数バックオフが必須です。 |
retry-afterを尊重する
応答にretry-afterヘッダーが含まれる場合、それは提案ではありません。その時間が経過した後にリクエストが再び受け付けられる正確な時刻です。短く待つと、必ず別の429になります。
import time
from openai import APIStatusError
try:
resp = client.chat.completions.create(model=MODELO, messages=msgs)
except APIStatusError as e:
if e.status_code == 429:
espera = float(e.response.headers.get("retry-after", 5))
time.sleep(espera)
resp = client.chat.completions.create(model=MODELO, messages=msgs)
else:
raise発生源で同時実行数を制限する
最も一般的な原因は総量ではなく急激な集中です。同じ瞬間に送られた20件のリクエストは、1分間に分散した60件では超えない制限を超えます。セマフォは、リトライだけでは解決できない問題を解決します。
import asyncio
LIMITE = asyncio.Semaphore(4) # no máximo 4 chamadas simultâneas
async def chamar(msgs):
async with LIMITE:
return await client.chat.completions.create(
model=MODELO, messages=msgs)制限なのか残高なのか確認する
429はクレジット不足を意味しません。それは402です。ログに両方が混在している場合は、調査前にステータスで分けてください。429の対策はタイミング調整、402の対策はチャージです。402を繰り返しても常に失敗します。
Kunavo経由で呼び出している場合
Kunavoでは制限がキー単位で、残高は別のプリペイドウォレットです。そのため両者は異なるステータスで表示されます。429はレート制限、402は残高不足であり、一方が他方に偽装されることはありません。拒否されたリクエストには課金されません。 各リクエストが残高から消費するトークン単価は、 Claude APIの料金ガイド.
よくある質問
429はクレジットを使い切ったという意味ですか?
いいえ。残高不足は402です。429は速度に関するもので、短時間にリクエストまたはトークンを送りすぎた状態です。待てば解決します。
どのくらい待つべきですか?
retry-afterヘッダーがあれば、その時間ぴったり待ちます。なければ1~2秒からジッター付き指数バックオフを開始し、30~60秒を上限にします。
制限を引き上げれば解決しますか?
量が本当に多い場合は役立ちますが、429の多くは短時間の集中によるものです。同時実行数を制限すれば、制限自体を変更せずに解決できることがよくあります。