レート制限を意識した AI API ゲートウェイ: 429 秒に達する前に RPM、TPM、バースト、テナントの公平性を調整する
カスケード LLM API 429 を防止するための実用的なゲートウェイ アーキテクチャ: プロバイダー制限の正規化、ディスパッチ前のトークン プレッシャーの推定、テナントごとのクォータの予約、トラフィック増加のスムーズ化、スロットリングの監査可能化。
LLM プロバイダからの 429 は、単なる再試行信号ではありません。運用環境では、多くの場合、アプリケーションがアドミッション、テナントの公平性、レイテンシー、またはプロバイダー固有のクォータ アカウンティングの制御をすでに失っているという証拠になります。
共通の修正である指数バックオフは必要ですが、不完全です。バックオフは、プロバイダーがトラフィックを拒否した後に反応します。レート制限を認識する AI API ゲートウェイ は、リクエストがシステムから送信される前にトラフィックを形成する必要があります。つまり、トークン プレッシャーを見積もり、クォータを予約し、テナントを分離し、適切な作業をキューに入れ、間違った作業を拒否し、プロバイダーの制限が変更されたときに適応します。
この記事では、統合された API を通じて複数の LLM プロバイダーに本番ワークロードを送信するチーム向けの実用的なゲートウェイ クォータ ガバナーについて説明します。
読者の問題: 429 は多次元です
多くのチームは、レート制限を 1 分あたりのリクエスト数であるかのように扱います。この前提は、LLM API を使用するとすぐに崩れます。
現在のプロバイダのドキュメントからの事実:
- OpenAI 制限が適用されるドキュメントは、公示されている 1 分あたりの制限よりも短い時間枠で適用される場合があるため、平均的な 1 分が安全に見える場合でも、ショート バーストは失敗する可能性があります。
- Azure OpenAI の割り当ては、サブスクリプション、リージョン、モデル、デプロイメント タイプごとに 1 分あたりのトークン数で割り当てられます。 TPM を展開に割り当てると、強制される推論 RPM 制限も決定され、RPM と TPM の比率はモデルによって異なります。
- Azure OpenAI は、レート制限トークンの計算はリクエストの受信時に推定され、最終的な請求トークン数と同じではないことにも注意しています。
- Anthropic では、1 分あたりのリクエスト数、1 分あたりの入力トークン数、1 分あたりの出力トークン数の制限を個別に文書化しています。制限を超えると、retry-after ヘッダーを含む 429 が返されます。
- Anthropic は、急激な交通量の増加により加速限界に達する可能性があることを警告し、段階的な増加を推奨します。
- ほとんどの Claude モデルでは、入力トークンをキャッシュ読み取りする Anthropic ドキュメントは、1 分あたりの入力トークンの制限にカウントされません。つまり、プロンプト キャッシュによって有効なヘッドルームが変化する可能性があります。
- Google Gemini API レート制限はプロジェクトの使用量階層に関連付けられており、より高い階層は請求設定、累積費用、支払いマイルストーン後の経過時間に応じて異なります。
運用上の教訓は明らかです。OpenAI 互換のリクエスト形式は、OpenAI 互換のクォータ動作を意味しません。マルチプロバイダー ゲートウェイには、「retry if 429」よりも豊富な内部割り当てモデルが必要です。
設計目標: アドミッション コントロールをゲートウェイの責任にする
レート制限を認識するゲートウェイは、リクエストをディスパッチする前に 5 つの質問に答える必要があります:
- リクエストを受け取るプロバイダー、モデル、デプロイメント、リージョン、プロジェクト、またはワークスペースはどれですか?
- どのくらいのリクエスト、入力トークン、出力トークン、同時実行能力を消費する可能性がありますか?
- どのテナント、チーム、API キー、顧客、またはワークロード クラスに共有容量に対して課金する必要がありますか?
- リクエストをすぐに承認するか、一時的にキューに入れるか、ダウングレードするか、別の場所にルーティングするか、または拒否する必要がありますか?
- プロバイダーが実際の使用量を返した後、予約はどのように調整されるべきですか?
ゲートウェイがクォータ ガバナーになります。プロバイダーの制限に代わるものではありません。これにより、プロバイダーの制限が可視化され、予測可能になり、独自のシステム内で公平になります。
正規化された割り当てモデルを構築する
まず、誤解を招くような 1 つのバケットに強制的に入れることなく、主要なプロバイダを表すことができる内部リミッター ディメンションを定義します。
推奨リミッター寸法
- RPM: リクエスト/分。
- 入力 TPM: 1 分あたりのプロンプト、メッセージ、ツール、およびコンテキスト トークン。
- 出力 TPM: 分あたりの完了トークン。ストリーミングと長い世代用に個別に予約されています。
- 合計 TPM: 複合トークン プレッシャーを公開するプロバイダーまたは展開に役立ちます。
- 同時実行数: アクティブなリクエスト、アクティブなストリーム、または実行中のジョブ。
- ストリーミング期間: 有効期間の長いストリームは、RPM が低い場合でも接続と出力トークンのヘッドルームを占有する可能性があります。
- プロバイダー固有のスコープ: Azure サブスクリプション/リージョン/デプロイ、Anthropic ワークスペース/モデル クラス、Google プロジェクト/層、または OpenAI 組織/プロジェクト/モデル グループ。
プロバイダー固有のディメンションを非表示にしないでください。それらを共通のスキーマに正規化しますが、後で拒否を説明するのに十分な詳細を保持します。
{
"provider": "provider_a",
"model_profile": "fast-chat",
"provider_scope": {
"project": "prod",
"region": "us-east",
"deployment": "chat-large-01"
},
"limits": {
"rpm": 1200,
"input_tpm": 800000,
"output_tpm": 250000,
"concurrency": 200
}
}
この内部オブジェクトは、モデル名だけから推測するのではなく、明示的に設定する必要があります。プロバイダーのダッシュボード、アカウント階層、地域展開、ワークスペース設定はすべて、同じモデル ファミリーの実効容量を変更する可能性があります。
ディスパッチ前にトークンプレッシャーを見積もる
プロバイダー側のレート制限は、最終的な請求使用量が判明する前に発生することがよくあります。ゲートウェイは、トラフィックを送信する前に、同様の保守的な見積もりを行う必要があります。
プリフライト予約の入力
- シリアル化されたプロンプトとメッセージの長さ。
- ロール、ツール、イメージ、または構造化出力命令のモデル固有のトークン化とオーバーヘッド。
max_completion_tokensまたは同等の出力上限- このエンドポイント、テナント、モデル プロファイル、リクエスト クラスの過去の完了率。
- プロンプト キャッシュが利用可能で測定可能な場合、予期されるキャッシュ読み取りトークン。
- ストリーミング フラグと予想されるストリーム期間。
多くの場合、単純な予約ルールで開始できます:
estimated_input_tokens = tokenize(request_messages) + model_overhead
estimated_output_tokens = min(
max_completion_tokens,
p95_historical_output_tokens_for_route
)
reserved_total_tokens = estimated_input_tokens + estimated_output_tokens
不明なルートの場合は、保守的なデフォルトを使用します。安定した生産ルートを実現するには、実際の使用量に基づいて推定値を継続的に更新します。
予約して調整
クォータ予約は永続的な料金にすべきではありません。保留のように扱います:
- 引用: 入力圧力と出力圧力を推定します。
- 予約: 発送前に関連するトークン バケットから差し引かれます。
- 解決: 可能な場合は、見積もりをプロバイダから報告された使用量に置き換えます。
- 返金または引き落とし: 必要に応じて、未使用の予約容量を返却するか、超過分を次の期間に請求します。
これは、長いコンテキストおよびストリーミング呼び出しの場合に最も重要です。ディスパッチ前に入力 TPM のみをチェックする場合、ストリームは正常に開始され、後で出力トークンのプレッシャーに遭遇する可能性があります。出力ヘッドルームを個別に予約すると、ストリーム途中の障害とストールのリスクが軽減されます。
テナントの公平性のために階層型トークン バケットを使用する
単一のグローバル リミッターはプロバイダー アカウントを保護しますが、テナントを相互に保護することはありません。 1 つのロングコンテキスト バッチ ジョブが共有 TPM を消費し、他のチームからのインタラクティブなリクエストが失敗する可能性があります。
階層型トークン バケットを使用する:
organization
└── tenant
└── team
└── api_key
└── model_profile
└── provider_deployment
リクエストは関連する各バケットを渡す必要があります。これにより、複数のポリシーを一度に適用できます:
- 組織はプロバイダーのキャパシティを超えることはできません。
- テナントは、契約したシェアを超えて消費することはできません。
- API キーは、意図された環境またはアプリケーションの制限を超えることはできません。
- バッチ モデル プロファイルは、インタラクティブ モデル プロファイルを枯渇させることはできません。
- プロバイダーのデプロイメントは、別のデプロイメントに予備の割り当てがある場合でも、過負荷になることはありません。
公平な共有と使用率
推奨事項: 制御されたバースト借用で重み付けされた公平な共有を使用します。
テナントごとの厳しい上限は説明が簡単ですが、未使用の容量が取り残される可能性があります。バースト借入により、テナントが共有プールからのアイドル クォータを一時的に使用できるようになり、使用率が向上します。トレードオフは複雑さです。ダッシュボードには、何が保証され、何を借りたのか、いつ借り入れが取り消されたのかを表示する必要があります。
実際的なルール:
- 各テナントに保証されたベースラインを与えます。
- 未使用の共有容量からのバースト借用を許可します。
- 優先度の高いトラフィックまたは保証されたトラフィックが発生した場合、借用した容量を再利用します。
- 借用したトラフィックによって、保証されたトラフィック用のプロバイダー レベルの 429 が作成されることを決して許可しないでください。
競合する前にトラフィック クラスを分離する
すべてのリクエストが同じキュー動作に値するわけではありません。トラフィックを別のキューと割り当てプールを使用してモデル プロファイルに配置します。
| トラフィッククラス | 典型的なポリシー | なぜ |
|---|---|---|
| インタラクティブなチャット | 短いキュー、低レイテンシの予算、フェイルファストまたは互換性のあるフォールバック | ユーザーはテール レイテンシーにすぐに気づきます |
| エージェントのワークフロー | 中程度のキュー、ツールを考慮した予算、出力ヘッドルーム | 複数ステップの呼び出しはトークンプレッシャーを増幅させる可能性があります |
| バッチジョブ | キューが長く、スケジュールされたスムージング、優先度が低い | 通常はレイテンシーに強く、トークンを大量に使用します |
| 評価 | 専用割り当て、インシデント中は一時停止 | 突然の人為的なスパイクを引き起こす可能性があります |
| 背景の要約 | キューまたは延期、厳格な TPM 上限 | 便利ですが緊急性は低い |
キューイングにより成功率は向上しますが、テール レイテンシは増加します。ゲートウェイはそのトレードオフを明示する必要があります。たとえば、対話型リクエストはクォータのために最大 300 ミリ秒待機し、その後フォールバックするか失敗する可能性があります。夜間のバッチ ジョブは 20 分間待機しても成功とみなされます。
429 を単一のエラー スキーマに正規化します
アドミッション コントロールが適切であっても、プロバイダー 429 は依然として発生します。制限は変更される可能性があり、プロバイダーの推定値がお客様の推定値と異なる場合があり、トラフィックが予想よりも急激に急増する可能性があります。
すべてのプロバイダー 429 をゲートウェイ エラー オブジェクトに正規化します:
{
"error": {
"type": "rate_limited",
"limiter": "output_tpm",
"provider": "provider_a",
"model_profile": "fast-chat",
"provider_model": "model-x",
"retry_after_ms": 2400,
"tenant_id": "tenant_123",
"api_key_id": "key_456",
"request_class": "interactive",
"estimated_input_tokens": 4200,
"estimated_output_tokens": 800,
"gateway_decision": "admitted_then_provider_rejected",
"fallback_allowed": false,
"trace_id": "trace_abc"
}
}
キー フィールドは gateway_decision です。ゲートウェイがリクエストを承認した後の 429 は、ディスパッチ前にゲートウェイがローカルで拒否したリクエストとは異なります。 1 つ目は、リミッターのキャリブレーションの問題を示します。 2 番目は意図的な保護を示します。
プロバイダー ヘッダーから適応しますが、それに依存しません
一部のプロバイダーは、再試行後や残存容量インジケーターなどの便利なヘッダーを返します。利用可能な場合は使用してください。
推奨事項: プロバイダー ヘッダーは、ローカル ガバナーを置き換えるのではなく、調整する必要があります。
理由:
- ヘッダーの利用可能性はプロバイダーとエンドポイントによって異なります。
- ヘッダーでは、すべてのリミッター ディメンションが公開されるわけではありません。
- Retry after は、次にどのテナントが容量を取得する必要があるかではなく、いつ再試行するかを示します。
- プロバイダ側のトークンの見積もりは、請求や内部会計と異なる場合があります。
堅牢な実装により、ヘッダーに基づいてローカル バケットの補充レートとクールダウンが更新されると同時に、ゲートウェイ内のテナント、API キー、トラフィック クラス、プロバイダーのデプロイ制限が強制されます。
移行およびスケジュールされたジョブ用にランプ ガバナーを追加
レート制限インシデントの多くは、あるモデルから別のモデルへの移行、プロバイダーの変更、新しいエージェント ワークフローの有効化、スケジュールされた評価実行の開始など、計画的な変更中に発生します。
推奨事項: トラフィックの増加を制御されたロールアウトとして扱います。
- テナント、ルート、またはトラフィックの割合ごとの機能フラグ モデルの移行。
- 新しいプロバイダーの導入に対して 1 分あたりの増加上限を設定します。
- すべてのトラフィックを即座に切り替えるのではなく、数時間かけて徐々にトラフィックをウォームアップします。
- 429 レート、ダウングレード レート、キューの深さ、または p95 レイテンシーがしきい値を超えた場合、ロールアウトを一時停止します。
- 単なる予備モデルではなく、互換性ポリシーを備えた緊急ロールバック ルートを保持します。
予測: プロバイダーのルーティング モード、優先順位、ワークスペース レベルの制御がより一般的になるにつれて、ランプ ガバナンスはインシデント対応スクリプトではなく標準のゲートウェイ機能になるでしょう。
フォールバックは単なる容量の決定ではなく、ポリシーの決定です
あるプロバイダーが 429 を返した場合、別のプロバイダーにルーティングするのが正しい答えである可能性があります。安全でない可能性もあります。
フォールバックは変更される可能性があります:
- 出力品質と指示は次のとおりです。
- コンテキストの長さ。
- ツール呼び出しの動作。
- 構造化された出力の信頼性。
- データの保持と常駐の姿勢。
- コストとレイテンシ。
クォータ ガバナーは、このリクエスト クラスに対してフォールバックが許可されているかどうかを互換性レイヤーに問い合わせる必要があります。そうでない場合は、セマンティクスをサイレントに変更するのではなく、キューに入れるか、明確なローカル レート制限応答で失敗する必要があります。
決定事項を説明する割り当てダッシュボードを公開
誰も理解できない割り当てシステムは回避されます。運用に関する質問に基づいてダッシュボードを構築します:
- RPM、入力 TPM、出力 TPM を最も多く消費しているテナントはどれですか?
- どのモデル プロファイルがキューに登録されているか、拒否されているか、またはフォールバックされていますか?
- ボトルネックとなっているプロバイダーの範囲は、プロジェクト、リージョン、デプロイメント、ワークスペース、モデルクラス、アカウント層のどれですか?
- ゲートウェイの見積もりがプロバイダーの使用状況と異なることがどのくらいありますか?
- プロバイダーおよびリミッター タイプ別の配布後の再試行とは何ですか?
- プロンプト キャッシュ読み取りによってどの程度の効果的なヘッドルームが作成されますか?
- バースト容量を借りているトラフィック クラスはどれですか?
顧客向けまたはパートナー向けの製品の場合は、安全なコントロールを公開します:
- キーごとのレート制限。
- チームごとのバースト制限。
- 顧客ごとの 1 日の上限。
- テナントまたはキーの緊急一時停止。
- 429 のスパイク、キューの増加、異常なトークン プレッシャーに関するアラート。
- パートナー API の再販業者割り当て管理用エンドポイント。
これにより、不可解なプロバイダー エラーによるレート制限が、チーム API ガバナンスの監査可能な部分に変わります。
実装チェックリスト
フェーズ 1: 観察と分類
- すべての呼び出しのプロバイダー、モデル、デプロイメント、リージョン、ワークスペース、プロジェクト、テナント、API キー、およびリクエスト クラスをログに記録します。
- 再試行後のメタデータと生のエラー メタデータを使用してプロバイダ 429 をキャプチャします。
- 推定された入出力トークンと実際の入出力トークンを別々に記録します。
- テレメトリでインタラクティブ、バッチ、評価、およびバックグラウンドのトラフィックを分離します。
フェーズ 2: ローカル アドミッション コントロール
- RPM、入力 TPM、出力 TPM、合計 TPM、同時実行性の内部リミッター オブジェクトを作成します。
- プリフライト トークンの推定を追加します。
- ディスパッチ前に割り当てを予約し、プロバイダの使用状況が到着した後に調整します。
- リクエストがテナントまたはプロバイダ バケットに適合しない場合は、ローカルで拒否します。
フェーズ 3: 公平性とキュー
- 組織からプロバイダーのデプロイメントに階層バケットを追加します。
- 保証されたテナント共有と制御されたバースト借入を割り当てます。
- トラフィック クラスごとに個別のキューを作成します。
- クラス固有の最大待機時間とフォールバック ルールを設定します。
フェーズ 4: 適応と運用
- プロバイダー ヘッダーを使用してクールダウンを調整し、仮定を補充します。
- 移行およびスケジュールされたジョブ用にランプ ガバナーを追加します。
- 割り当てダッシュボードとアラートを公開します。
- 推定エラーと滞った割り当てを毎週確認します。
実用的な結論
ゲートウェイが 429 秒のみを再試行する場合、ゲートウェイは失敗後も動作しています。運用グレードの AI API ゲートウェイ は、誰が、いつ、どのプロバイダの割り当てに対して何を送信できるかを決定することで、レート制限の失敗のほとんどを防ぐ必要があります。
正規化されたリミッター モデル、プリフライト トークン予約、トラフィック クラス キューから始めます。次に、階層テナントの公平性、プロバイダー ヘッダーの適応、およびランプ ガバナーを追加します。その結果は、単に 429 が減っただけではありません。これは、エンジニアリング、財務、カスタマー サポートのチームが実際に説明できる、より明確な容量割り当て、より予測可能な遅延、より安全な移行、およびレート制限の動作です。