コンテンツにスキップ

コンボ: フェイルオーバーとロードバランシング

コンボ は、実際のプロバイダー/モデル ターゲットの順序付きリストの先頭にある 1 つの仮想モデルです。クライアントは combo/<id> をリクエストします。 opencodex はターゲットを選択し、リクエストをその具体的な provider/model に書き換えます。最初のターゲットで再試行可能な障害が発生した場合は、別のターゲットを試行できます。

これは、次のいずれかが必要な場合に便利です。

  • フェイルオーバー: 1 つのモデルを推奨しますが、バックアップを準備しておいてください。
  • 負荷分散: 成功したリクエストを重み付けされたバッチでモデルまたはプロバイダー全体に分散します。

コンボは、通常のプロバイダー ルーティングの前に配置されます。 provider/model セレクターを初めて使用する場合は、まず モデルルーティング をお読みください。

この例では、最初に Anthropic、2 番目に OpenAI を使用して combo/main を作成します。両方のプロバイダーがすでに存在し、有効になっている必要があります。

Terminal window
ocx combo set main --targets anthropic/claude-opus-4-8,openai/gpt-5.6-sol

デフォルトの戦略はフェイルオーバーであるため、通常のリクエストは anthropic/claude-opus-4-8 に送信されます。その試行に再試行可能な失敗があった場合、opencodex は openai/gpt-5.6-sol にホップできます。

通常モデル ID を指定する場所であればどこでも仮想モデルを使用します。

{
"model": "combo/main",
"input": "Explain why the sky looks blue."
}

保存された定義を確認します。

Terminal window
ocx combo show main

ocx combo set <id> のコンボ ID は文字または数字で始まる必要があります。文字、数字、._、または - を合計 64 文字まで含めることができます。その正規モデル ID は常に combo/<id> です。たとえば、ID maincombo/main になります。

combo/ 名前空間は、コンボの構成中に予約されます。 combo という名前のプロバイダーはそれを占有することはできず、コンボ ID は構成されたプロバイダー名を複製することはできません。

オプションのエイリアスにより、コンボに別のパブリック モデル名が与えられます。別名:

  • ID と同じ文字を使用します。
  • daily-fast のように裸の場合もあれば、team/daily-fast のように / を 1 つ含む場合もあります。
  • combo にしたり、combo/ で始めることはできません。
  • 別のコンボ エイリアスを複製することはできません。そして
  • gpt-o1-o3-o4-、またはで始まる裸のネイティブ OpenAI ファミリ名は使用できません。 codex-

エイリアスが設定されている場合でも、正規の combo/<id> 形式は解決されます。正規ルックアップはエイリアスの一致の前に実行されるため、エイリアスが別のコンボの正規 ID を引き継ぐことはできません。

フェイルオーバー: 順序付けされたプライマリとバックアップ

Section titled “フェイルオーバー: 順序付けされたプライマリとバックアップ”

failover は、構成順序で最初の適格なターゲットを選択します。ターゲットは、プロバイダーが存在し、有効になっていて、クールダウン中でなく、特別なリクエスト制約を処理できる場合に適格となります。重みと stickyLimit はこの戦略に影響しません。

この順序を考慮すると、次のようになります。

  1. anthropic/claude-opus-4-8
  2. openai/gpt-5.6-sol
  3. google/gemini-3-pro

各リクエストは Anthropic で始まります。再試行可能な Anthropic エラーが発生すると、そのリクエストは OpenAI に移動します。再試行可能な OpenAI が失敗すると、OpenAI が Google に移される可能性があります。端末エラーは、残りのターゲットを試行する代わりに、ただちに停止します。

ラウンドロビン: スムーズな加重バッチ

Section titled “ラウンドロビン: スムーズな加重バッチ”

round-robin はスムーズな加重ラウンドロビンを使用します。ターゲットの重みが大きいほど、すべてのシェアを 1 つの長いブロックとして送信することなく、時間の経過とともにそのターゲットに大きなシェアが与えられます。 stickyLimit は、次の重み付けされた選択の前に、選択されたターゲットに残る成功したリクエストの数を制御します。

成功した 2 つのリクエストのバッチを含む 2:1 コンボを作成します。

Terminal window
ocx combo set balanced \
--targets anthropic/claude-opus-4-8:2,openai/gpt-5.6-sol:1 \
--strategy round-robin \
--sticky 2

ターゲットを A (重み 2) および B (重み 1) と呼ぶと、最初の 6 つの重み付き選択は A, B, A, A, B, A になります。 stickyLimit は 2 であるため、各選択は 2 つのリクエストが成功した場合にアクティブのままになります。

|リクエストが成功しました | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | | — | — | — | — | — | — | — | — | — | — | — | — | — | — | |ターゲット |あ |あ | B | B |あ |あ |あ |あ | B | B |あ |あ |

長期的なシェアは依然として2:1です。再試行可能な障害が発生すると、現在のスティッキー バッチが終了し、そのターゲットが冷却され、同じリクエストに対して別の適格なターゲットが選択されます。

ターゲットが失敗すると何が起こるか

Section titled “ターゲットが失敗すると何が起こるか”

コンボ障害は、ホップ 障害と ターミナル 障害に分類されます。

結果 行動
HTTP 401、403、404、408、429、または任意の 5xx ターゲットを冷却し、次の適格なターゲットに移動します。
機密認証、サブスクリプション、クォータ、レート制限、過負荷、またはアップストリーム サーバー エラー ステータスだけでは物足りない場合でもターゲットを冷やしてホップさせましょう。
クライアントのキャンセル (499)、origin_rejected、サイバー ポリシーの拒否、コンテキスト オーバーフロー、または無効なリクエスト 停止してエラーを返します。別のターゲットではリクエストは有効になりません。
その他の未分類のエラー 停止してエラーを返します。

ホップされたターゲットはデフォルトで 60 秒間のクールダウンに入ります。アップストリーム応答に有効な Retry-After 値が含まれている場合、opencodex は代わりにそれを使用します。秒数値と HTTP 日付値が受け入れられ、各クールダウンの上限は 10 分です。

現在のリクエストは、同じ試行ターゲットを再試行することはありません。以降のリクエストでは、クールダウンが期限切れになるまでスキップされます。適格なターゲットが残っていない場合、プロキシは error.code = "combo_unavailable" を含む HTTP 503 を返します。

defaultEffort は、次のすべてが当てはまる場合にのみ reasoning.effort を提供します。

  1. コンボには null 以外のデフォルトがあります。
  2. 呼び出し側は努力を設定しませんでした。そして
  3. 選択したターゲットのカタログは、その正確な取り組みを宣伝します。

リクエストに reasoning オブジェクトがない場合、opencodex はオブジェクトを作成します。 reasoningeffort プロパティなしで存在する場合、他のフィールドは保持され、デフォルトが追加されます。呼び出し元が提供した努力は決し​​て上書きされません。

ターゲットの機能が不明な場合、または設定されたエフォートが含まれていない場合、opencodex はデフォルトを省略し、ターゲット自体の動作を変更しないままにします。サポートされている値は、lowmediumhighxhighmax、および ultra です。このフィールドを省略するか、null に設定して、呼び出し元とターゲットに作業を完全に任せます。

暗号化された v2 サブエージェント タスク

Section titled “暗号化された v2 サブエージェント タスク”

Codex v2 サブエージェントには重要な制限が 1 つあります (第92号)。ネイティブの親は、新しく生成されたワーカーのタスクを、ネイティブ ChatGPT バックエンド用に作成された暗号文としてのみ送信できます。外部プロバイダーはそのペイロードを読み取ることができません。

このようなリクエストの場合、コンボは、再試行可能な失敗後も含め、対象となるターゲットを正規のネイティブ ChatGPT ルートにフィルタリングします。コンボに復号化可能なターゲットがない場合、opencodex はディスパッチ前に停止し、HTTP 400 を返します。

{
"error": {
"type": "invalid_request_error",
"code": "unreadable_encrypted_agent_task"
}
}

これにより、読み取り可能な命令を受け取らないプロバイダーにタスクが送信されることがなくなります。読み取り可能なプレーンテキストのタスクは、通常のコンボ戦略を使用します。

回復オプションは 4 つあります。

  1. 子用のネイティブ ChatGPT モデルを選択します。
  2. 正規のネイティブ ChatGPT ターゲットをコンボに追加します。
  3. さまざまなプロバイダー間の委任には v1 サーフェスを使用します。
  4. 呼び出し元を制御している場合は、タスクをプレーンテキスト v2 agent_message コンテンツとして再送信します。

v1/base/v2 モードと完全な暗号化タスクのワークフローについては、サブエージェントサーフェス を参照してください。

ローカル ダッシュボードを開き、コンボを選択します。ワークスペースはコンボを作成、編集、名前変更、削除し、そのターゲット ピッカーは無効なモデルとネストされたコンボを除外します。

主なコマンドは次のとおりです。

Terminal window
ocx combo list
ocx combo show <id>
ocx combo set <id> --targets provider/model[:weight],...
ocx combo remove <id> --yes

set は、--strategy--sticky--effort--alias、および --rename-from も受け入れます。そのフィールドをクリアするには、--effort または --alias の値として - を使用します。 create および update は、set のエイリアスです。 deleteremove のエイリアスです。同じサブコマンドが ocx route combo で使用できます。

ヘッドレス クライアントは、/api/combos 上の GETPUT、および DELETE を使用します。 GET は正規化されたコンボ定義をリストし、PUT は 1 つを作成または置換し (名前を変更できます)、DELETE は id クエリ パラメーターを受け取ります。認証と要求/応答の詳細は 管理 API リファレンス にあります。

永続化された設定全体については、「構成」を参照してください。

コンボは、コンボ ID をキーとして、最上位の combos オブジェクトに保存されます。

{
"combos": {
"balanced": {
"targets": [
{ "provider": "anthropic", "model": "claude-opus-4-8", "weight": 2 },
{ "provider": "openai", "model": "gpt-5.6-sol", "weight": 1 }
],
"strategy": "round-robin",
"stickyLimit": 2,
"defaultEffort": "high",
"alias": "team/balanced"
}
}
}
フィールド 必須 デフォルト ルール
targets はい 構成された { provider, model, weight? } ターゲットの空でない順序付けされた配列。重複するプロバイダーとモデルのペアは拒否されます。
targets[].weight いいえ 1 1 ~ 10,000 の整数。ラウンドロビンで使用されます。フェイルオーバーによって無視されます。
strategy いいえ "failover" "failover" または "round-robin"
stickyLimit いいえ 1 ラウンドロビン選択ごとの成功したリクエストの数は 1 ~ 100 の整数です。
defaultEffort いいえ null lowmediumhighxhighmax、または ultra;呼び出し元が努力を省略し、ターゲットがサポートをアドバタイズした場合にのみ適用されます。
alias いいえ なし オプションのトリミングされたパブリック モデル ID。上記のエイリアス ルールを使用します。空の値はエイリアスなしで保存されます。

combo/<id> が 404 を返すのはなぜですか?

Section titled “combo/<id> が 404 を返すのはなぜですか?”

コンボIDは不明です。応答はタイプ invalid_request_error の HTTP 404 です。 ocx combo list を実行し、スペルと大文字小文字を確認して、モデル要求を受信する同じ実行中の opencodex インスタンスに管理コマンドが書き込まれたことを確認します。

combo_unavailable が発生するのはなぜですか?

Section titled “combo_unavailable が発生するのはなぜですか?”

現在、すべてのターゲットは不適格です。たとえば、プロバイダーが無効になっている、冷却中である、このリクエストに対してすでに試行されている、暗号化された v2 タスクによってターゲットが除外されているなどです。ターゲットプロバイダーの状態と最近のアップストリームエラーを確認してください。クールダウンの場合は、デフォルトの 60 秒またはアップストリームの Retry-After 期間(10 分を超えないでください)待ってから、再試行してください。

私のエイリアスが拒否されたのはなぜですか?

Section titled “私のエイリアスが拒否されたのはなぜですか?”

まず、エイリアスの文法と予約名を確認してください。重複したエイリアスまたは無効な形状は、HTTP 400 として拒否されます。最初のセグメントが構成済みの Codex アカウント名前空間であるスラッシュ付きエイリアスは、HTTP 409 として拒否されます。別のエイリアス名前空間を選択してください。 CLI とダッシュボードには、サーバーの正確な検証メッセージが表示されます。

最初のエラーの後にフェイルオーバーが停止したのはなぜですか?

Section titled “最初のエラーの後にフェイルオーバーが停止したのはなぜですか?”

このエラーはターゲット固有のものではなく、最終的なものでした。無効な入力を修正し、大きすぎるコンテキストを削減し、ポリシーの拒否を処理し、拒否されたリクエストの送信元を修正します。コンボはそのような場合には機能しません。