mode = "escalation" は llm_classifier の 3 つ目のモード
です。capability と custom がターンに必要なモデルを予測するのに対し、escalation は各
セッションを効率側のターゲットで始め、作業の進み具合をジャッジに読ませます — 予測ではなく、
効率側のモデルが実際に行った作業を見ます。
セッションが昇格するまで
まだ固定(ラッチ)されていないセッションのターンは weak_target で作って留め置きます。
そのあとジャッジが完成したターンを判定します。
- 辞退の判定は昇格の連続回数を 0 に戻します。
- 昇格の判定はその回数を増やします。連続回数が
confirmationsに満たないあいだは、留め 置いた効率側のターンを提供します。 confirmationsに達するとセッションが固定されます。そのターンの効率側の応答は捨ててstrong_targetがターンを提供し、以後そのセッションのすべてのターンはジャッジ呼び出しも バッファリングもなく、そのままstrong_targetへ行きます。
ジャッジはすでに存在するターンを判定するので、shunt は判定が出るまでそのターンを留め置き ます。再生が始まるまで応答ヘッダーを確定しないので、強力なターゲットへの切り替えはヘッダーを 送る前に起き、捨てられた効率側のターンをクライアントが見ることはありません。留め置いた ターンをどう提供するか、それに何のコストがかかるかは 留め置くターンで説明します。
設定する
[[models]]
id = "claude-escalate"
[models.router]
type = "llm_classifier"
mode = "escalation"
classifier_target = "claude-haiku-4-5"
strong_target = "claude-opus-4-8"
weak_target = "claude-sonnet-4-6"
# prompt = "…"
# max_output_tokens = 4096
[models.router.escalation]
confirmations = 2
# recent_turn_window = 28
# window_message_chars = 500[models.router.escalation] テーブルは任意です。省くと 3 つの既定値が使われ、これは上流が
ベンチマークした設定です。1 より大きい confirmations にはセッション id が必要です。
ないと毎ターンが 0 から始まり、セッションはいつまでも固定されません。ジャッジは直近の
recent_turn_window 件のメッセージを、それぞれ window_message_chars 文字までに切り詰めて
見ます。weak_target は classifier_target と同じ id でも構いません。
6 つの呼び出しごとの上限は
[models.router] に置き、そのうち 3 つの gated_* の上限が、留め置く効率側のターンに上限を
課します。classifier 形式の [models.subagents] オーバーレイは
引き続き mode = "custom" のみです。
資格情報
classifier_target と違い、weak_target は passthrough ルートでも構いません。効率側の
ターンはクライアント自身の応答なので、ライブのターンとまったく同じように呼び出し元の資格情報
を運びます。一方ジャッジ呼び出しは呼び出し元の資格情報をひとつも運びません。
ジャッジ呼び出しを参照してください。
プローブと固定
count_tokens プローブはジャッジ呼び出しも留め置く呼び出しも行いません。セッションが
固定されているあいだは strong_target で、そうでなければ weak_target で応答します。直前の
ターンが固定によって、または確定した昇格によって提供されていれば固定されたセッションです。
この固定はセッションの委譲された子と共有され、1 時間アイドルが続くと失効します。
クライアントから見えるもの
x-gateway-route-source が各ターンで何が起きたかを示します。
| ソース | 意味 |
|---|---|
escalation_weak |
ジャッジが効率側のターンを通し、それが再生されました |
escalation_latch |
このターンかそれ以前にセッションが固定されたため、強力なターゲットがターンをライブで提供しました |
escalation_fallback |
効率側のターンが失敗したか、切れたか、コンテキストウィンドウに対して長すぎるとして拒否されたため、強力なターゲットがジャッジを呼ばずにターンをライブで提供しました |
classifier_fail_open |
完成した効率側のターンのあとでジャッジが失敗したため、効率側のターンを提供しました |
gated_error |
留め置いたターンを提供できませんでした |
各ソースの正確な条件と、効率側のターン、そのアップストリーム、またはジャッジが失敗したときの
動作は設定リファレンスに
あります。ジャッジ呼び出しは shunt.router.judge_calls{algorithm="llm_classifier"} で
数えます。
コスト
escalation は固定前のすべてのターンでジャッジ呼び出しを 1 回行い、そうしたターンのそれぞれで、 効率側のターンが完成して判定されるまでクライアントは何も受け取りません。固定されるターンは、 捨てる効率側の呼び出しのコストも支払います。捨てた呼び出しも、アップストリームのクォータは すでに消費しています。