API キープール
API キープールを使用すると、同じプロバイダーに複数の API キーを設定できます。リクエストは加重ラウンドロビンで分散され、レート制限や障害が発生した場合、システムは別の使用可能なキーへ自動的に切り替えます。
使用する場面
- 高並行シナリオ: 1 つのキーのレート制限では不十分な場合に、複数のキーでトラフィック負荷を分担します
- チーム共有: 各チームメンバーが自分のキーのクォータを使い、コストを分担します
- 無料枠の積み上げ: 複数の無料アカウントのキーをローテーションで使用します
- 高可用性: 1 つのキーで障害が発生した場合、システムが別のキーへ自動的に切り替えて中断を防ぎます
- テスト / 本番の分離: 重みを使って、本番キーとテストキーへ送られるリクエストの割合を制御します
操作ガイド
API キーを追加する
- Settings → Provider Management を開きます
- 対象のプロバイダー(例: OpenAI)を選択します
- API Key Pool セクションを探します
- Add Key ボタンをクリックします
- 情報を入力します。
| Field | Required | Description |
|---|---|---|
| API Key | Yes | キーの値、または環境変数参照($ で始まる) |
| Label | No | 識別しやすくするための名前。例: "Production Key #1" または "Test Key" |
| Weight | No | 1–100。デフォルトは 1。値が大きいほど選択される確率が上がります |
- Confirm をクリックして追加します
重みを設定する
- API キー一覧で対象のキーを見つけます
- Weight の値(1–100)を変更します
- 重みは、そのキーが選択される相対的な確率を決定します
個別のキーを有効化 / 無効化する
- API キー一覧で対象のキーを見つけます
- Enabled スイッチを切り替えます
- 無効化されたキーはローテーションから除外されますが、設定は保持されます
キーを削除する
- API キー一覧で対象のキーを見つけます
- Delete ボタンをクリックします
- 削除を確認します(この操作は元に戻せません)
設定リファレンス
| Setting | Type | Default | Range | Description |
|---|---|---|---|---|
| API Key | String | (empty) | -- | キーの値、または $ENV_VAR 参照 |
| Label | String | (empty) | -- | キーを区別するためのメモ名 |
| Weight | Integer | 1 | 1–100 | 加重ラウンドロビン用の重み |
| Enabled | Boolean | true | -- | このキーをローテーションに参加させるかどうか |
| Order | Integer | 0 | -- | 一覧での表示順 |
動作に関する注記
加重ラウンドロビン
プール内の各キーは、その重みに比例した数の「スロット」を占有します。Elftia はこれらのスロットを固定された順序で巡回し、重みの比率に従ってリクエストを分散します。
重み配分の例:
重みが 3、2、1 の 3 つのキーがあるとします(合計重み = 6)。
| Key | Weight | Share | Selections per 6 requests |
|---|---|---|---|
| Key A | 3 | 50% | 3 |
| Key B | 2 | 33% | 2 |
| Key C | 1 | 17% | 1 |
ローテーション順序: A → A → A → B → B → C → A → A → A → B → ...
同じ重みの例:
3 つのキーがそれぞれ重み 1 の場合(合計重み = 3)、厳密に A → B → C → A → B → C → ... の順でローテーションします。
セッションアフィニティ
同じチャットセッション内のすべてのリクエストは、同じ API キーに固定されます。この設計には 2 つの重要な理由があります。
- プロンプトキャッシュ: 一部のプロバイダー(例: Anthropic)はプロンプトキャッシュをサポートしています。同じキーを使った連続リクエストはキャッシュにヒットできるため、レイテンシとコストを大幅に削減できます
- 一貫性: 同じ会話内で頻繁にキーを切り替えることによって、レート制限カウンターがリセットされるのを防ぎます
セッションの割り当ては、次の状況で再割り当てされます。
- 現在割り当てられているキーが無効化または削除された場合
- 現在割り当てられているキーがエラーによりクールダウン期間に入った場合
- セッションが終了した場合(閉じられた、または削除された)
自動フェイルオーバー
リクエストでエラーが発生した場合、キープールはエラーの種類に応じて異なる戦略を適用します。
レート制限(429/529)
HTTP 429(レート制限)または 529(サービス過負荷)のレスポンスを受信した場合:
- 現在のキーが クールダウン期間 に入ります
- システムはプール内の次の使用可能なキーへ自動的に切り替えます
- 新しいキーでリクエストを再試行します
クールダウンの仕組み:
| Consecutive failures | Cooldown duration | Formula |
|---|---|---|
| 1st | 60 seconds | 60s × 2^0 |
| 2nd | 120 seconds | 60s × 2^1 |
| 3rd | 240 seconds | 60s × 2^2 |
| 4th | 480 seconds | 60s × 2^3 |
| 5th and beyond | 900 seconds (cap) | min(60s × 2^(n-1), 900s) |
クールダウン期間中、そのキーはローテーションから除外され、期間が終了すると自動的に再び使用可能になります。リクエストが成功すると、そのキーの連続失敗カウンターはリセットされます。
認証失敗(401/403)
HTTP 401(Unauthorized)または 403(Forbidden)のレスポンスを受信した場合:
- そのキーは 永続的に無効化 されます(データベースで無効としてマークされます)
- システムは次の使用可能なキーへ自動的に切り替えます
- 設定 UI では、そのキーは無効として表示されます
これは、認証エラーは通常、キー自体が無効になったこと(期限切れ、失効、またはクォータ枯渇)を示しており、待機しても回復する可能性が低いためです。
フェイルオーバーフローチャート
Request sent
|
v
Use session-bound key
|
+---> Success ---> Reset cooldown counter ---> Return response
|
+---> 429/529 (rate limited)
| |
| v
| Current key enters cooldown
| (starts at 60s, exponential backoff, cap at 15 minutes)
| |
| v
| Any other available keys in the pool?
| | |
| Yes No
| | |
| v v
| Switch to new key Request fails, return error
| Rebind session (all keys unavailable)
| |
| v
| Retry with new key
|
+---> 401/403 (authentication failure)
|
v
Permanently disable this key
|
v
Any other available keys in the pool?
| |
Yes No
| |
v v
Switch to new key Request fails, return error
Rebind session
キープールとプロバイダーレベルの API キーの関係
- プロバイダーに プロバイダーレベルの API キー(Provider 設定の
api_keyフィールド)と キープール の両方が設定されている場合、キープールが優先されます - キープールが空(エントリがない)の場合、プロバイダーレベルの API キーが使用されます
- 負荷分散とフェイルオーバー機能を利用するには、プロバイダーレベルの API キーではなくキープールを使用することを推奨します
トラブルシューティング
| Issue | Possible cause | Solution |
|---|---|---|
| すべてのキーがクールダウン中で、リクエストが失敗する | すべてのキーが同時にレート制限に達した | クールダウンが終了するまで待つ(最大 15 分)か、キーを追加してプール容量を拡張します |
| キーが一度も選択されない | 重みが 0、または他のキーの重みがはるかに高い | 重み設定を確認し、重みが少なくとも 1 であることを確認します |
| キーが自動的に無効化された | 401/403 認証エラーを受信した | キーが期限切れまたは失効していないか確認します。プロバイダーのウェブサイトでキーの状態を確認し、問題を修正した後で手動で再有効化します |
| プールは正しく設定されているが、リクエストがまだ古いキーを使用する | セッションアフィニティが古いキーに固定されている | 新しいチャットセッションを開始するか、古いキーがクールダウン期間に入ってシステムが自動的に再割り当てするのを待ちます |
| 追加したキーがすぐに反映されない | キーキャッシュが更新されていない | 設定を保存して再試行します。システムはキャッシュを自動的に更新します |
| 環境変数キーを解決できない | 変数名が間違っている、または設定されていない | $ の後の変数名が、大文字小文字を含めてシステムに設定されている名前と完全に一致することを確認します |
| クールダウンが長すぎる | 複数回連続してレート制限に達したことによる指数バックオフ | リクエスト頻度を下げるか、キーを追加して負荷を分散します。クールダウンの上限は 15 分です |
| 同じセッション内でキーが切り替わった | 元々割り当てられていたキーがクールダウンに入った、または無効化された | これは想定される動作です。システムは最適な使用可能キーを自動的に選択します |
関連ページ
- LLM Providers Overview - プロバイダーシステム全体のアーキテクチャを理解する
- Adding a Provider - プロバイダーの基本情報と API キーを設定する
- Custom Endpoints - ローカルデプロイサービスでは通常、キープールは必要ありません
- Model Parameters - モデル生成パラメーターを設定する