技術 約8分で読めます

TRACERはLLM分類APIのログから代理モデルを学習してparity gateで置き換える

いけさん目次

LLMを分類器として使う運用では、呼び出すたびに「入力テキスト + LLMが返したラベル」というペアがログに積み上がっていく。
このペアは課金済みの正解付き教師データそのものであり、放っておくだけで勝手に増えていく。
それを素直に訓練データとして吸い上げ、軽量な代理モデル(surrogate)へ徐々に置き換えていこうというのがAdam Ridaの論文TRACER: Trace-Based Adaptive Cost-Efficient Routing for LLM Classificationだ。
コードもオープンソースとして公開されている。

似た発想のカスケード構成はCloudflareがClient-Side SecurityのGNN+LLM検出で既に本番投入しており、軽量検出器で振り分けた上で怪しいものだけLLMに回す流れはすでに実績がある。
TRACERが面白いのは、振り分け器を「事前に設計したパイプライン」ではなく「本番ログから自動的に育つ後付けの代理モデル」として扱っている点、そして代理モデルを出すか出さないかをparity gateという形式的な合意率テストで決めている点だ。

何を解こうとしているのか

LLMをゼロショット分類器として使う案件は、手でラベルを貼らずに済むので導入が速い。
一方で、意図分類のような短いテキスト1本につきLLM 1回のコールが発生するので、トラフィックが増えると推論料金がじわじわ効いてくる。

分類タスクの多くは、ユーザー発話の大半が少数のよくある意図に偏っている。
つまり、全量をフル精度のLLMに投げ続けるのは明らかにオーバースペックで、「簡単な入力は小さなモデルに任せて、難しいものだけLLMに戻す」構造にできれば平均コストは一気に下がる。

問題はその「簡単な入力」の見極めだ。
差し替えが早すぎれば精度が落ちるし、差し替えを躊躇いすぎればコスト削減が進まない。
TRACERはこの判断を人間の勘ではなく、統計的なparity gateで機械的に決めさせる。

TRACERの全体像

TRACERの役割はざっくり3つに分かれる。

  • 本番ログ(trace)を教師データとして代理モデルを訓練する
  • 代理モデルがLLMとどれだけ一致するかをparity gateで測る
  • 合意率が閾値αを超えた領域だけ、LLMではなく代理モデルにルーティングする
flowchart TD
    A[本番リクエスト] --> B{ルーター}
    B -->|parity gate合格領域| C[軽量代理モデル]
    B -->|未カバー領域 / 低信頼| D[LLM 教師]
    D --> E[ラベル付きログ]
    C --> E
    E --> F[代理モデル再訓練]
    F --> G[parity gate評価]
    G -->|合格| B
    G -->|不合格| D

ここでポイントになるのは、代理モデルがLLMに追いついていない領域は自動的にLLMへ戻される(defer)ことだ。
カバレッジ(代理モデルが処理する割合)と一致率の両方を監視しながら、徐々に代理モデルが管轄する範囲を広げていく。

parity gateは「出すな」の判断にも効く

論文が一番強く主張しているのはparity gateの存在意義だ。
機械学習の評価でよく使われる精度・F1は「ラベル付きテストセット」があって初めて計算できるが、運用側が本当に欲しいのは「この代理モデルをLLMの代わりに出して大丈夫か?」という二択の答えである。

TRACERでは、代理モデルの予測がLLMの予測とどの程度一致するかを計測し、ユーザーが決めた閾値αを超えた場合だけ代理モデルの出力をエンドユーザーへ返す。
αはサービス品質要件そのもので、たとえば「95%一致していれば代理モデルで良い」と決めれば、α=0.95で運用する。

重要なのは、parity gateが「一致率が十分でないとき、デプロイを拒否する」という方向にも効く点だ。
NLI(自然言語推論)タスクの実験では、埋め込み表現だけでは信頼できる境界が引けないと判定され、parity gateが代理モデルのデプロイを拒否した。
これは「代理モデルを作ったのに性能が出ませんでした」という一般的な失敗ではなく、「その入力表現では原理的に無理なので出さないのが正解」という判断ができているということだ。
運用側にとっては、数字を信じて出したら事故ったという最悪パターンを未然に止めてくれる安全装置になる。

ベンチマーク結果のざっくりした読み方

論文では教師LLMにSonnet 4.6を据え、3種類のタスクでTRACERを評価している。

タスククラス数代理モデルのカバレッジ備考
意図分類ベンチA7783〜100%(αに依存)αを厳しくするとカバレッジが下がる
意図分類ベンチB150100%代理モデルが教師を完全に置換
NLIタスク-0%(デプロイ拒否)parity gateが適切に棄却

150クラス側で100%になっているのが特に印象的で、意図分類のように分布が偏るタスクでは「全量を代理モデルに吸わせた上でLLMはほぼ呼ばない」運用が現実に成立しうるとわかる。
一方で77クラス側はαを上げるにつれてカバレッジが落ちるのも当然の挙動で、許容できる品質基準ごとにコスト/精度のトレードオフが観察できる。

NLIの挙動は前節の通りで、「代理モデルにやらせてはいけないタスクである」と自らの口で言わせる設計になっているのが良い。

代理モデルが何を吸収し、何を諦めたのかを可視化する

TRACERは単に「代理モデルで置き換えられましたよ」という結果だけではなく、どの入力領域を代理モデルが処理しているのか、どこで頭打ちになっているのか、なぜdeferしているのかといった解釈用の成果物を出す。

運用側から見ると、これは費用対効果の議論をする上でかなり効く。
「全体の◯%を代理モデルに吸わせてコストが◯%下がりました」だけだと次のアクションが取れないが、「このクラスはまだLLMに返している」「このクラスは代理モデルが飽和している」というクラス別の内訳が出れば、次に追加学習するデータの優先度や、代理モデルのモデル容量を増やすべきかどうかの判断につながる。

また、deferの理由(信頼度が低い、境界近傍、未観測のクラスなど)を明示することで、「ブラックボックスのルーターが勝手に切り替えている」状態にはならない。
本番運用でのデバッグ体験はむしろ「LLM単体+ログ」で回していた時より上がる可能性が高い。

蒸留との違い、そしてカスケードとの違い

「LLMの出力をログから吸って小さいモデルを鍛える」という部分だけ切り出すと、これはナレッジディスティレーション(蒸留)そのものに見える。
実際、Claudeの大規模不正蒸留とSWE-benchの崩壊で話題になったように、教師モデルの出力を使って小型生徒モデルを訓練する手筋自体は長い歴史がある。

TRACERが蒸留と違うのは、
「生徒モデルを訓練してチェックポイントを出して終わり」ではなく、「parity gateと解釈可能性のレイヤーを挟んで、代理モデルをどの範囲までデプロイして良いかを運用的に決める」ところまで含めて設計されている点だ。
蒸留は学習時の技法、TRACERは運用時のルーティング制御だと切り分けると頭に入りやすい。

また、事前に構造を決め打ちしたGNN+LLMカスケード(CloudflareのClient-Side Securityが代表的)と比べると、TRACERは本番ログだけを入力にゼロから代理モデルを組み上げる。
カスケードは「軽量側の検出器を人間が設計する」のに対して、TRACERは「軽量側の検出器は本番ログが育てる」。
どちらが良いかは状況次第で、固定スキーマで回るタスク(意図分類など)ではTRACER流のほうが楽に立ち上げられるが、検出対象が日々変わる攻撃検知のようなドメインでは、Cloudflareがやっているような手設計のGNN側のほうが耐性が高い可能性もある。

実運用で効きそうなポイント

論文の主張をそのまま信じるとして、自分の用途に持ち込むなら以下が効きそうだ。

  • すでにLLM分類APIを運用しているなら、ログを訓練データとしてそのまま再利用できる。追加のラベル作業は不要
  • parity gateがあるので「代理モデルを出すタイミング」を感覚で決めなくて済む。αを経営的なSLO(サービス品質目標)とそのまま紐付けられる
  • 一致率が十分でない領域は黙ってLLMに戻るので、「差し替えたら性能が落ちた」リスクを引き受けずに済む
  • 代理モデルがカバーする領域と諦めた領域がそれぞれ可視化されるので、次に改善するべきデータセット領域の優先度付けがしやすい

逆に気をつけるべき点もある。
本番ログ=教師LLMのラベルなので、教師LLMがもともと間違えているケースは代理モデルも間違えたまま学習する(教師の誤りはそのままコピーされる)。
parity gateは「LLMと一致しているか」を測る仕組みなので、LLMが間違えているドメインでは一致率が高くても品質は保証されない。
品質要件が厳しい分類器をTRACERでコスト最適化する場合、LLM側の評価と代理モデル側の評価は独立に走らせ続けるのが安全だ。

自前の分類器運用(かなチャット)と重ねて読む

TRACERの話を読んでいて、自分で回しているLLM分類器の運用とほぼ同じ問題意識だな、と思った。
かなチャット(手元のアシスタント)でも入力の振り分けに分類器を挟んでおり、かなチャット アーキテクチャ v1 の時点ではHaiku単体でインテント分類していた。
このときの「LLM 1回でルーティングする」構成は、まさにTRACERが「高コストな教師LLMに毎回問い合わせる」と呼んでいる出発点そのままだ。

その後 かなチャット アーキテクチャ v2 で、プライマリモデル(gpt-5.3-codex-spark)で一旦分類し、confidence が 0.84 未満のときだけフォールバックモデル(gpt-5.4-mini)で再分類する2段構えに組み替えた。
これはTRACERの「代理モデルの信頼度が閾値を下回ったらLLMにdeferする」という挙動とまったく同じ発想で、自分は運用の中で体で覚えて閾値を 0.84 に決めたが、TRACERはそれをparity gateという形式的な仕組みで扱えるようにしている。

ここを突き詰めると、かなチャット側の問題は2つに分けられる。
1つは「プライマリの出力をそのまま信じて良い領域はどこまでか」という境界設定、もう1つは「境界の外に出たら、何に聞けば安全か」というフォールバック設計だ。
いま自分が0.84という数字で手当てしている前者は、TRACER流に考えれば本番ログから代理モデルを育てて parity gate で自動判定する対象にできる。
後者は結局「教師LLMを残しておく」しかなく、これもTRACERが defer 用に教師LLMを温存する設計と揃っている。

つまりTRACERは、自分が運用でアドホックに作った2段分類を、ログドリブンに学習+評価のサイクルとして回すための道具立てとして読める。
意図分類のように分布が偏るタスクでは、0.84のような手設定の閾値を parity gate に置き換えるだけでも、運用負荷はだいぶ下がりそうだ。