メインコンテンツへスキップ
組み込み戦略 —— cheapest, quality, balanced, adaptive —— は価格と品質でモデルを選びます。Routing DSL はその下のティアで、 適切な モデルがリクエストの実際の中身に依存する場合のためのものです: 長いエージェント的コーディングのターン、安価な分類呼び出し、ビジョン リクエスト、テスト失敗後のリトライなど。ルールを書けば、ゲートウェイが リクエストごとに評価し、それに従ってルーティングします。 これは名前付きルーターdsl 戦略です —— アプリは引き続き orcarouter/{name} を呼び出し、ルーティングロジックは ダッシュボードに置かれ、再デプロイなしにバージョン管理・編集できます。

DSL を使うべきとき

「最安のライブモデル」や「最高品質」で意図が表現できるなら組み込み戦略を 使ってください。リクエストの内容やコンテキストにルーティングが依存する 場合に DSL を使います:
  • タスク特化 —— コードはコーディングモデルへ、ビジョンはビジョン モデルへ、安価なチャットは安価なモデルへ送る。
  • 難易度を意識したルーティング —— 難しいリクエストだけを高価なモデル へエスカレートし、簡単なものは安く保つ。
  • エージェントを意識したルーティング —— セッション状態 (エージェント がどのツールを使ったか、テストが今失敗したか、何ターン目か) に基づいて 異なるルーティングを行う。
  • 時間 / テナント / ヘッダのルール —— 時間帯、ユーザーグループ、または リクエストヘッダによる異なるルーティング。

有効化

ダッシュボードの Routing でルーターを開き、その StrategyDSL に設定します。これでこのルーター用の DSL エディタが現れます。 ルーターに関するその他のすべては引き続き適用されます —— Allowed models の glob、Default model のセーフティネット、orcarouter/{name} での 呼び出しです。

エディタ

エディタは、意図から動作するルールセットへ素早く到達できるように 作られています:
  • テンプレートあなたのワークスペースの実モデルでシードされます (一度きりのティアマッピングダイアログ経由)。空のファイルから始めたり 「未知のモデル」の壁にぶつかることはありません。
  • Insert —— 識別子を手で打つ代わりに、オートコンプリートから ModelRouter (orcarouter/<name>)、Pool を挿入します。
  • Generate —— 欲しいルーティングを平易な言葉で記述すると、あなたの 実モデルに基づいた、コンパイル済みでリント済みの DSL が返ってきます。
  • Explain —— 現在のルールセットが何をするかの平易な英語による言い換え。
  • インラインリント —— すべてのエラーが {line, column, message} を 報告し、すべてのリントコードに ? の説明があります。優先順位 (first-match-wins) と一般的な CEL パターンがその場で示されます。

ファイル構造

ルールセットは 3 つのトップレベルキーを持つ YAML です:
version: 1              # required — currently must be 1
rules: [...]            # required — 1 to 30 rules, evaluated in order
default: {...}          # required — the effect when no rule matches
ルールは when: 条件と use: 効果です:
rules:
  - id: hard_code              # required: ^[a-z][a-z0-9_]{0,39}$, unique
    when: |                    # optional CEL boolean; absent ⇒ always matches
      task_class == "code" && difficulty > 0.6
    use:
      model: "anthropic/claude-sonnet-4-6"
default:
  delegate: balanced           # fall back to a built-in strategy
ルールは上から下へ評価され、when: が真になる最初のルールが勝ちます。 どれもマッチしない場合は default: が適用されます。ルールは最も具体的な ものから順に並べてください —— 早い位置にある広範なルールは、その下の すべてを覆い隠してしまいます。

when: —— 条件

条件は CEL (Common Expression Language) で記述します: 設計上安全です —— ループなし、 I/O なし、マイクロ秒での評価、RE2 正規表現のみ。次の 6 つのパターンが 実際のルールの大半をカバーします:
PatternExample
Field accesstask_class == "agent"
Numeric comparedifficulty > 0.6 && request.input_tokens < 50000
Boolean logicagent_state.has_edited && !agent_state.has_run_tests
List membership"Edit" in agent_state.tools_used
Regex macrosystem_prompt_matches("(?i)planning agent")
Tool macrotool_calls_present_any(["Edit","Write","apply_patch"])

変数

リクエストの形状
VariableType
modelstring
request.input_tokensint
request.output_max_tokensint
request.streambool
request.visionbool
request.message_countint
request.has_system_promptbool
request.has_toolsbool
分類 (ゲートウェイがリクエストごとに計算)
VariableTypeMeaning
task_classstringchat / code / agent / vision / audio / rag / creative
difficultydouble0.01.0
code_keyword_densitydouble0.01.0
reasoning_cue_countintプロンプト内で検出された推論の手がかり数
tool_countintリクエスト上の個別のツール定義数
エージェントセッション (agent_state.*、会話をまたいで永続化)
VariableType
agent_state.turnint
agent_state.tools_usedlist<string>
agent_state.files_readlist<string>
agent_state.has_editedbool
agent_state.has_run_testsbool
agent_state.last_test_failedbool
agent_state.consecutive_errorsint
agent_state.elapsed_secondsint
agent_state.models_triedlist<string>
コンテキスト
VariableType
headers["x-foo"]string
user.id / user.groupint / string
token.id / token.nameint / string
time.hour / time.weekdayint (UTC)
workspace.idint

マクロ

一般的な「リクエストの中身を見る」チェックのために登録された CEL 関数:
MacroReturns
system_prompt_matches(regex)結合されたシステムメッセージに対する RE2
user_message_matches(regex)最後のユーザーメッセージに対する RE2
tool_definitions_include(name)あるツールがリクエスト上で宣言されている
tool_calls_present_any(list)リクエストがこれらのツール呼び出しのいずれかを含む
tool_results_from_any(list)リクエストがいずれかからの tool ロールメッセージを持つ
header_matches(name, regex)ヘッダ値に対する RE2

use: —— 効果

use: ブロックは destination (ちょうど 1 つ) と、任意の数の オプションの呼び出し単位の knob を指定します。

Destination

use:
  model:    "anthropic/claude-sonnet-4-6"   # one upstream model
  models:   ["openai/gpt-4o-mini", "..."]   # load-balance across a list
  pool:     "@pool:<name>"                   # an admin-curated pool
  delegate: balanced                         # hand off to a built-in
                                             #   strategy: cheapest |
                                             #   quality | balanced |
                                             #   linucb | gated_adaptive
delegate: dsl は拒否されます (再帰してしまうため)。特定のチャネルへの 固定 (channels: / @channel:) は現在利用できず、未対応としてリントされ ます —— 代わりに modelmodelspool でルーティングしてください。

呼び出し単位の knob

任意の destination と組み合わせて上流呼び出しを形作ります:
use:
  reasoning_effort:       low | medium | high     # OpenAI o-series, Gemini
  thinking_budget_tokens: 1024..64000             # Claude / Gemini thinking
  samples:                1..16                    # the n parameter
  temperature:            0.0..2.0
  param_override:         { ... }                  # merged into upstream params
  header_override:        { ... }                  # merged into upstream headers
  reason_tag:             "<[a-z0-9_]+>"           # shows up in logs/telemetry
  affinity_ttl:           "5m"                      # channel stickiness window
  model_rewrite:          "<upstream-model>"       # send under a different name
param_overrideheader_override はデニーリストを強制します —— modelmessagesstreamtools、認証ヘッダなどはオーバーライド できません (それらは課金、監査、エージェント状態を覆してしまうため)。

信頼度カスケード & アンサンブル (高度)

2 つの高度な効果により、ルールが弱い最初の回答に反応したり、複数の モデルにファンアウトしたりできます。他のどのルールとも同じように記述 します。 カスケード —— 低信頼度シグナルでより強力な効果へリトライします:
rules:
  - id: code_with_repair
    when: task_class == "code"
    use:
      model: "openai/gpt-4o-mini"
    on_low_confidence:
      signals: [patch_invalid, self_doubt, next_turn_test_failed]
      use:
        model: "anthropic/claude-sonnet-4-6"   # repair attempt
アンサンブル —— 複数のレッグを並列に発行し、アービターに選ばせます:
use:
  parallel:
    - { model: "anthropic/claude-sonnet-4-6" }
    - { model: "openai/gpt-4o-mini", samples: 2 }
  arbiter:
    strategy: best_of_n        # or majority | first | tests_pass
    model:    "anthropic/claude-sonnet-4-6"   # judge (best_of_n only)
  max_latency_ms: 120000
アンサンブル / カスケードのランタイムはゲートされており、既定では オフです。 各並列レッグと各カスケード修復はそれぞれ独立した呼び出しと して課金されるため、レッグ単位の課金が検証されるまで、ファンアウト ランタイムはサーバーフラグの背後にあります。オフの状態では、parallel: ルールは最初のレッグのみを提供し、カスケードはシグナルを記録するものの 再ディスパッチはしません —— ルールセットは引き続き通常どおりリント・ 保存され、その主効果をルーティングします。ワークスペースでアンサンブル ランタイムを有効化するにはお問い合わせください。

安全にロールアウトする

新しいルールセットは、保存した瞬間にトラフィックを引き継ぐわけでは ありません:
  • シャドウモード —— 最初の保存後の一定期間、DSL は評価されますが 使われません: 以前の戦略が引き続きトラフィックを処理し、その間に ゲートウェイは DSL が行ったであろうことを記録します。ダッシュボードは 差分レポートを表示します —— ルートが異なる割合、予測されるコスト差分、 ルール別の発火回数、default: に落ちた頻度です。ルールを信頼する前に これを読んでください。
  • カナリア —— DSL をライブトラフィックの一定割合 (5 → 25 → 50 → 100) に段階投入し、スライス別メトリクスを監視しながら、 割合を 0 にスライドすることで即座にロールバックできます。
また、エディタ内で合成リクエスト (タスククラス、難易度、エージェント 状態、リクエスト形状) に対してルールセットを dry-run し、トレースと マッチしたルールを確認することもできます —— トラフィックなし、何も 永続化されません。

制限と検証

すべての保存で厳格なリントが実行され、無効なルールセットは {line, column, message, rule} とともに拒否されます:
  • スキーマ —— 必須キー、正しい型/列挙、未知のフィールドなし。
  • サイズ —— ルール ≤ 30、YAML ≤ 16 KiB、when: 1 つあたり ≤ 200 文字。
  • CEL —— パースされ、変数環境に対して型チェックされ、未知の識別子が なく、when:bool に評価される必要があります。
  • 効果 —— use: ブロックごとにちょうど 1 つの destination; すべての model / models / @pool: 参照がワークスペース内で解決できること。
  • knob の範囲 —— thinking_budget_tokens ∈ [1024, 64000]temperature ∈ [0, 2]samples ∈ [1, 16]
  • 予約 —— _ で始まるルール id は予約済み; ルール id としての default は拒否されます (トップレベルの default: ブロックを使用)。
すべての保存とロールバックは監査行を書き込みます; 同時編集は検出され、 2 番目の保存は最新の状態に対してリトライするよう求められます。

完全な例

version: 1
rules:
  - id: vision
    when: request.vision
    use: { model: "openai/gpt-4o" }

  - id: cheap_chat
    when: task_class == "chat" && difficulty < 0.3
    use: { delegate: cheapest }

  - id: hard_code
    when: task_class == "code" && difficulty > 0.6
    use:
      model: "anthropic/claude-sonnet-4-6"
      thinking_budget_tokens: 8000
      reason_tag: hard_code

  - id: agent_after_failed_test
    when: agent_state.last_test_failed && agent_state.consecutive_errors >= 2
    use:
      model: "anthropic/claude-sonnet-4-6"
      reason_tag: repair

default:
  delegate: balanced
リクエストがどのモデルに解決されたかを確認するには、X-Orca-RouterX-Orca-Resolved-Modelレスポンスヘッダ を読みます。

API リファレンス

DSL はルーター単位で管理されます; 書き込みには Developer+ が必要です。
Method & pathRolePurpose
GET /api/user/routers/:id/dslMemberソース + バージョン + シャドウ/カナリア状態。
PUT /api/user/routers/:id/dslDeveloper+リント + 保存 (新バージョン、監査対象)。
POST /api/user/routers/:id/dsl/lintMemberドラフトをリント → {errors:[…]}
POST /api/user/routers/dsl/lintMemberステートレスなリント (ルーター id なし)。
POST /api/user/routers/:id/dsl/dryrunMember合成リクエストを評価 → トレース + マッチしたルール。
GET /api/user/routers/:id/dsl/historyMemberバージョン履歴、新しい順。
POST /api/user/routers/:id/dsl/rollback/:versionDeveloper+再リントして古いバージョンを復元。

FAQ

これ戦略です —— cheapest / quality / balanced / adaptive と並ぶ dsl オプションです。他の戦略は価格と品質で選びますが、DSL は リクエストの形状、分類、エージェント状態に対してあなたが書いた ルールで選びます。ルールの効果として、またはデフォルトとして、 引き続き組み込み戦略へ delegate: できます。
トップレベルの default: 効果が適用されます。これは必須なので、 常に定義された結果があります —— 一般的には delegate: balanced か 特定のセーフティネットモデルです。
はい。CEL は標準ライブラリ関数のみのサンドボックス、数ミリ秒の評価 デッドライン、RE2 正規表現 (線形時間、ReDoS なし)、データベース・ ネットワーク・ファイルシステムへのアクセスなし、で実行されます。 変数環境はスカラとリストの固定セットです。
3 つの方法があります: エディタ内で合成リクエストに対して dry-run する、シャドウモードのままにして差分レポートを読む、その後 100% へ段階投入する前にライブトラフィックの小さな割合へ カナリア する、です。