言語モデル API では、1 分あたりに送信する要求の数 (RPM) と 1 分あたりに使用するトークンの数 (TPM) という 2 つの方法でトラフィックが制限されます。 いくつかの長いプロンプトがトークンの予算を使い切ったため、リクエスト上限を大幅に下回っていても、それでもスロットリングされる可能性があります。 いずれかの制限に達すると、API は 429 Too Many Requests を返し、アプリは待機する必要があります。
OpenAI、Azure OpenAI、Anthropic でのカウント方法
| Provider | 制限される項目 | 知っておくべきこと |
|---|---|---|
| OpenAI | RPM、1日あたりのリクエスト数、TPM、1日あたりのトークン数など(組織ごと、プロジェクトごと、モデルごと) | 先に達した方の制限が適用されます。 トークン制限の場合、リクエストは max_tokens とその文字数に基づく見積もりのうち大きい方でカウントされます。 失敗した要求の数もカウントされます。 |
| Azure OpenAI | 各デプロイに割り当てる TPM に加えて、それに比例して設定された RPM 制限 | RPM は 1 秒または 10 秒のウィンドウでチェックされるため、1 分あたりの合計が問題ない場合でもバーストは 429 になります。 トークンの見積もりには max_tokensが含まれます。 |
| Anthropic | RPM、1 分あたりの入力トークン (ITPM)、出力トークン/分 (OTPM)、モデルごと | 容量の補充が継続的に行われ、1 秒あたり 1 要求として 60 RPM が適用される場合があります。 ほとんどのモデルにおいて、キャッシュされた入力トークンは ITPM の計算対象外であり、max_tokens は OTPM の計算対象外となります。 |
max_tokensを 4,000 に設定し、200 個のトークンを取得すると、OpenAI と Azure OpenAI は引き続き制限に対して 4,000 をカウントします。 このようにして、使用量の指標がクオータを大幅に下回っているように見えても、429 エラーが発生する場合があります。
429 が各プロバイダーにとって何を意味するか
待てば解消する429ばかりではありません。
| Provider | 待機して再試行する | 停止して誰かに伝える |
|---|---|---|
| OpenAI | 要求またはトークンに関する 429、429 slow_down (制限範囲内であってもトラフィックの増加が急激すぎる)、503 server_is_overloaded。
Retry-Afterが存在する場合は待機します。 |
error.code に 429 と、credit_balance_exhausted、organization_spend_limit_exceeded、project_spend_limit_exceeded、organization_usage_limit_exceeded が含まれている場合。 再試行してもアクセスは復元されません。 |
| Azure OpenAI | 429: 展開の TPM または RPM、システム容量、またはレート制限の一時的な引き下げに関するエラーです。
retry-after-msを待ってください。 |
承認されたクォータを下回っているにもかかわらず、運用環境で 429 エラーが継続して発生している。 展開の TPM 割り当てを確認してから、サポート リクエストを送信してください。 |
| Anthropic | ヘッダー retry-after がついた 429 rate_limit_error には、利用が急増した後の加速制限が含まれており、529 overloaded_error も含まれます。 |
月間利用上限は 429 です。
retry-after ヘッダーがなく、error.details.error_code は enforced_spend_limit_reached であり、アクセスが再開されるまで失敗し続けます。 |
LLM レート制限を処理する方法
- 表示された 429 を確認してください。 課金、支出、クォータのエラーには、再試行ではなく人が必要です。
- API が要求する限り待ちます。 OpenAI と Anthropicは、数秒で
retry-afterを送信します。 Azure OpenAI は、ミリ秒単位でretry-after-msを送信します。 ヒントがない場合は、ランダムジッターで指数関数的にバックオフし、試行回数と合計時間の両方を制限します。 - SDK が既に行うことを把握しましょう。
OpenAI と Anthropic の Python SDKs は、接続エラー、および
408、409、429、5xx の各応答について、既定で 2 回再試行します。 独自の再試行ループを追加する場合は、たとえば Python ではmax_retries=0を使用して、Azure OpenAI が推奨するように SDK の再試行を無効にします。そうしないと、再試行回数が増えてしまいます。 - 重要なものを絞り込みます。 OpenAI と Azure OpenAI で、
max_tokensを、予想される応答サイズに近い値に設定します。 Anthropicでは、システム命令などの繰り返しコンテンツをキャッシュします。 - 徐々に増やしてください。 トラフィックが急増すると、たとえ設定した制限の範囲内であっても、OpenAI の
slow_downおよび Anthropic の処理速度制限が発動します。 OpenAI は、1 分あたり 100 万個の入力トークンに達したら、15 分ごとの増加率を 50% 以下に抑えることを推奨しています。 - 既に使用したストリームを再生しないでください。 ストリームの開始後に発生したエラーは、ストリーム イベントとして通知される場合があるため、出力を処理した後に要求を自動的に再送信はしないよう、OpenAI が推奨しています。
- スピナーを表示するのではなく、要求が 429 でストールしたときにユーザーに知らせます。
アプリが LLM レート制限を処理することをテストする方法
| Approach | 見つけたもの | 欠落しているもの |
|---|---|---|
| テストで SDK クライアントをモックするか、コーディング エージェントにモックを記述させる | エラー ブランチが実行されるかどうか | プロバイダーの実際の状態コード、エラー コード、ヘッダー、SDK 独自の再試行処理。 アプリでは、モックに到達するためにテスト専用のスイッチも必要です。 |
| 調整がかかるまで、実際の API を呼び出す | 実際の動作 | トークンは 1 つごとに料金が発生し、slow_down やオーバーロード、消費上限を任意のタイミングで発動できません |
| アプリの実際のトラフィックをインターセプトしてプロバイダーのエラーを返すか、アプリで使用するトークンに基づいてスロットルする | 実際の URL、SDK の再試行ポリシー、プロバイダーのエラー本文、ユーザーが指定した制限 | お使いのコードは孤立しています。 それ用に単体テストを取っておいてください。 |
アプリで試す
Dev Proxy は、アプリから言語モデル API への要求をインターセプトし、プロバイダー独自のエラーを返す一方で、アプリ自体は引き続き実際の URL を呼び出し続けます。 OpenAI の場合は、プリセットをダウンロードし、それを使用して開発プロキシを起動します。
devproxy config get openai-throttling
devproxy --config-file "~dataFolder/configs/openai-throttling/.devproxy/devproxyrc.json"
openai-throttling プリセットでは、slow_down へのリクエストの 90% が、TPM または RPM の場合は credit_balance_exhausted、server_is_overloaded、rate_limit_exceeded、または 503 https://api.openai.com/* というランダムなエラーで失敗します。
anthropic-throttling プリセットは、RPM、入力トークン、出力トークン、加速度について、https://api.anthropic.com/* に対して同様の処理を行い、429s および 529 overloaded_error となります。 どちらのプリセットにも RetryAfterPlugin が含まれており、429 エラーが発生した際に、retry-after の時間が経過する前にアプリが API を再度呼び出したタイミングを通知します。 503 と 529 の応答を確認しません。
アプリが実際に使用するトークンに基づいてスロットルするには、LanguageModelRateLimitingPlugin を使用します。 各応答が報告するプロンプト トークンと完了トークンをカウントし、アプリが設定した制限を超えると retry-after を付けて 429 を返します。 Azure OpenAI とローカル モデルを含む、OpenAI と互換性のある API で動作します。
{
"$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v3.3.1/rc.schema.json",
"plugins": [
{
"name": "LanguageModelRateLimitingPlugin",
"enabled": true,
"pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll",
"configSection": "languageModelRateLimitingPlugin"
}
],
"urlsToWatch": [
"https://api.openai.com/*",
"https://*.openai.azure.com/openai/deployments/*/chat/completions*"
],
"languageModelRateLimitingPlugin": {
"$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v3.3.1/languagemodelratelimitingplugin.schema.json",
"promptTokenLimit": 1000,
"completionTokenLimit": 500,
"resetTimeWindowSeconds": 60
}
}
プラグインは、 max_tokens 見積もりを再現しません。 そのデフォルトの 429 本文では、insufficient_quota コードが使用されています。 アプリが想定するレート制限のエラー本文を返すには、 whenLimitExceeded を Custom に設定し、 customResponseFile を独自の応答にポイントします。 Dev Proxy をインストールするには、「Dev Proxy のセットアップ」を参照してください。
次のステップ
参照
Dev Proxy