Skip to content

Orchestrators

カスケードや並列+合成のオーケストレーションを自分で設計し、単一の仮想モデルとして model:"orch/<slug>" で呼び出せます。

オーケストレーターは複数のモデルを 1 つの仮想モデルに束ねるルーティング規則です。既存の 4 タイプ (fallbackweightedlatencyauto)に加えてカスケード並列+合成のアーキタイプが追加され、すべてのポリシーを "model": "orch/<slug>" で呼び出せます(従来の policy/<slug> もそのまま動作します)。ダッシュボードのオーケストレーターページのフォームで作成するか、高度タブで JSON DSL を直接編集してください。

カスケードと並列はベータです — 運用フラグ routing.orchestrators_enabled がオフの間、この 2 タイプの呼び出しは 400 エラーになります(保存・CRUD はゲートに関係なく常に可能)。既存 4 タイプはこれまで通り routing.policies_enabled に従います。

アーキタイプ#

fallback・weighted・latency・auto — 既存のルーティングポリシーと同じ動作です。詳細は ルーティングポリシー文書を参照してください。

cascade — エントリを低価格 → 高性能のティア順で登録すると、リクエストの難易度に合うティアから始まり、失敗時に 1 段階上へエスカレーションします。易しいリクエストは低価格モデルで完了し、難しいものだけ強力なモデルへ上がるため平均コストが下がります。

parallel — ワーカー(エントリ)を同時に呼び出し、合成モデルが成功した回答を批判的に検証して 1 つの最終回答へ統合します。

カスケード — 難易度によるティア・エスカレーション#

開始ティア判定は 2 つの信号を組み合わせます。① hard_categories — 純正規表現のインテント分類(外部送信なし・コスト 0)で一致するリクエストは最上位ティアから開始。② judge_model — 設定すると安価なモデル 1 回の呼び出しで開始ティアを判定します(子呼び出しとして通常課金)。judge が失敗するか数字を答えない場合は ① へフォールバックします。

エスカレーションは 2 つの信号で起こります。ティア呼び出しが失敗したら次のティアへ。また response_check を有効にすると、成功したが空の回答(空白テキスト・コンテンツフィルタ)でも次のティアへ上がります。破棄された呼び出しも精算済みのため、usage・コストは最終応答に合算して報告されます(正直な使用量報告)。

ストリーミングでは最初のトークン之前にティア判定(ヒューリスティック + judge)を終え、選ばれたティアから順にストリーミングします。応答ベースの再判定(response_check)は非ストリーミング呼び出し専用です。

並列+合成 — 多数のワーカー、1 つの回答#

ワーカーが 2 件以上成功すると synthesis.model が候補回答を検証・統合します(synthesis.prompt でトーンや基準をカスタマイズ可能、未指定なら既定の指示を使用)。合成モデル未設定・失敗時は最初に成功したワーカーの回答を返します。成功ワーカーが 1 件のみの場合も合成なしでそのまま返します。

deep_categories を設定すると一致するインテントのみ並列実行し、それ以外は最初のワーカー 1 回の呼び出しで処理します(fast-path)。未設定ならすべてのリクエストを並列実行します。

合成が終わるまで最終回答が確定しないため、parallel はストリーミング非対応です stream=true で呼び出すと SSE 開始前に 400 エラーが返ります。

呼び出しと課金#

通常のチャット呼び出しで "model": "orch/<slug>" を指定するだけです。どの OpenAI SDK でも plm_ キーでそのまま動作します。組織に共有されたオーケストレーターは、同じ組織のメンバーなら誰でも自分のキーで呼び出せます。

invoke orchestrator
curl https://apirouter.pleum.ai/v1/chat/completions \
  -H "Authorization: Bearer plm_..." \
  -H "Content-Type: application/json" \
  -d '{
    "model": "orch/prod-cascade",
    "messages": [
      {"role": "user", "content": "Summarize this document."}
    ]
  }'

課金は実際に実行された子呼び出しごとに定価パススルーで行われ、応答の usage・コストは全子呼び出しの合計です — judge・破棄ティア・合成呼び出しも含みます。オーケストレーション自体の追加料金はありません。

暴走防止のため 2 つの上限を設定できます。limits.max_total_attempts(1〜10、グローバル上限 6 をさらに狭める)と limits.max_cost_krw — 子呼び出しの累積実費がこの値を超えるとそれ以上エスカレーションしません。

routing_prefs で子呼び出しのプロバイダー設定(sortignoremax_price など)を固定できます。リクエスト本文の provider オブジェクトが常に優先されます。

組織共有#

オーケストレーターを組織に共有すると、メンバー全員が呼び出せます。編集・削除は作成者と組織の owner/admin が行えます(admin はメンバーの個人用オーケストレーターも管理可能)。非共有なら作成者のみアクセスできます。

JSON DSL#

ダッシュボードの高度タブと /v1/routing-policies API は同じ JSON 構造を受け付けます — フォームと DSL が同じスキーマを共有するため、JSON をコピーしてチームに渡せます。エントリは 1〜10 件の実在する有効な課金モデルで、他のオーケストレーター(orch/…policy/…)や仮想ルーティング親は参照できません。

create cascade (API)
curl -X POST https://apirouter.pleum.ai/v1/routing-policies \
  -H "Authorization: Bearer <JWT>" \
  -H "Content-Type: application/json" \
  -d '{
    "slug": "prod-cascade",
    "display_name": "Production cascade",
    "policy_type": "cascade",
    "entries": [
      {"model": "gpt-5-mini"},
      {"model": "claude-fable-5"}
    ],
    "config": {
      "cascade": {
        "hard_categories": ["code"],
        "judge_model": "gpt-5-mini",
        "response_check": true
      },
      "routing_prefs": {"sort": "latency", "ignore": ["slow-provider"]},
      "limits": {"max_total_attempts": 4, "max_cost_krw": 3000}
    }
  }'
parallel config (JSON)
{
  "slug": "review-panel",
  "policy_type": "parallel",
  "entries": [{"model": "claude-fable-5"}, {"model": "gpt-5.5"}, {"model": "gemini-3.1-pro"}],
  "config": {
    "parallel": {
      "deep_categories": ["code", "reasoning"],
      "synthesis": {
        "model": "claude-fable-5",
        "prompt": "Verify the answers like a senior reviewer and merge the strongest parts."
      }
    }
  }
}