2026年8月18日 公開

ロスターはルーターではない:独自のツールを選ぶ脳を構築する
先週、NeMoCoについて書きました。NeMoCoは、脳が世界を分類するのと同じように、生のラベルなし経験から、カテゴリを教えられることなくニューラル構造を分類する方法を学ぶ自己教師ありシステムです。私は同じフレーズに何度も戻ってきました:labels are a shortcut, structure is what matters.
今週、そのアイデアのもう半分を、私が実際に働いている分野で構築しました。私は個人用AIアシスタント——Aura——を運営しており、これはメモリを管理し、タスクをルーティングし、セッションをまたがって本当に役立とうとしています。このアシスタントはモデルのフリート上で動作します:本番コーディング用のClaude、研究と設計用のいくつかのクラウドモデル、そして何も消費しないローカルモデルです。問題はNeMoCoが解決するものと同じですが、逆になっています。NeMoCoは生データから構造を学びます。私は構造——各エージェントが仕事を持つエージェントのロスター——を持っていました。そして、システムにdecide which model should do which task, live, under a budget that runs out.が必要でした。
この意思決定エンジンこそが今週私が構築したものです。3つの部分からなります:タスクを読み取ってどのような仕事かを判断するclassifier、ライブクォータに基づいて最適なモデルチェーンにマッピングするrouter、そして全体を生きている鼓動する脳として描写するdashboardです。これは技術的な書き上げです——各部分が何をするのか、なぜその形になっているのか、そして設計を強制した失敗について——。
問題点:ロスターはルーターではない
ナイーブなセットアップは静的な表です:このエージェントはこのモデルを実行し、あのエージェントはあのモデルを実行します。これは単純で、かつ間違っており、その理由は3つあります。
まず、the budget runs out. Claudeは週次クォータandローリングセッションクォータで動作し、これらは独立して変動します。ある日、週次クォータは15%でありながらセッションクォータは71%でした——古いルーターは週次数値しか監視していなかったため、「Claude利用可能、モードNORMAL」と報告し、コーディング作業を壁に直進させました。CLIは「セッションリミットに達しました」というメッセージで3時間毎の呼び出しを拒否し続けましたが、ダッシュボードは一切問題ないと表示し続けました。実際に束縛されるリミットを読み取らないルーターはルーターではなく、単なる推測です。
其次、quality is not one number. 良いコードを書くモデルが長コンテキスト検索やUI生成にも長けているとは限りません。単一の「quality」スコアで全モデルを評価するのは無意味です——それはコーダーをリードすべきモデルと研究者をリードすべきモデルを区別できません。各エージェントはそのown軸で評価される必要があります。
第三に、the reviewer must not inherit the writer's blind spots. 私は意図的にライターとレビューアーをペアリングしています——ライターはコードを書き、レビューアーは診断を行います——そして、彼らは異なるdifferentモデルファミリーで動作しなければなりません。そうでなければ、レビューアーは同じ間違いを繰り返すだけです。ルーターの最初のバージョンは、レイテンシーでタイを破ったため、両方のヘッドを同じモデルに着地させ続けました。これは設計全体を無効にしました。
静的なテーブルは廃止しなければならなくなった。代わりに導入されたのは、ライブ状態を読み取り、タスクごとに最適なモデルチェーンを算出する意思決定エンジンだ。
分類器:タスクの読み取り
最初のコンポーネントは、タスクを読み取り、どの種類の作業かを判断する分類器である。入力は文 — 「デプロイ以降、本番環境でのペイメントエンドポイントが500を返している」 — で、出力は判定:種類、階層、優先度となる。
最初のバージョンは純粋な正規表現だった。それは機能したが、正規表現が常に持つ脆弱さの通りに脆かった。"Log parser" は ops に誤ルーティングされた(これはオペレーションタスクではなくコードコンポーネントである)。"Checkout is charging customers twice" にはエラー語彙が全くなかったため、unknown と分類され、本番インシデントにおいてメインエージェントにフォールスルーした。"Throwing 500s" は、末尾の 's' が単語境界を壊したため、ステータスコードパターンにマッチしなかった。これらはすべて実際の誤ルーティングであり、私は一つずつ修正し、各修正は新しい正規表現ルールとなった。これが間違ったツールと戦っている証拠だ。
現在、分類器はまず安価なモデルを試す — `deepseek-v4-flash:cloud` がタスクを読み取り、JSON の verdict を返す。モデルが利用不可の場合は、正規表現分類器にフォールバックする。モデルが主要な経路で、正規表現は安全網である。これは NeMoCo と同じ教訓だ:すべてのケースに手動ラベルを付けるのではなく、構造を学習し、それを転送させる。
分類器は呼び出し元からライブクォータも受け取るため、ルーターからずれることはない。呼び出し元はクォータ状態を読み取り、渡す;分類器はクォータファイルを直接読まない。重要なルール:production work は予算が厳しくても弱いモデルにダウングレードされることはない。 Claude が枯渇していても、本番インシデントは `prod` と分類される — 軽量エージェントに静かにルーティング変更され、「完了」と報告されることはない。代わりにブロックされ、ハンドオフプロトコルが起動される。品質リスクはクォータリスクより深刻であり、設計はそれを決して見失わない。
ルーター:意思決定エンジン
ルーターこそが実際の思考が行われる場所である。分類器の判定とライブプロバイダー状態を取り込み、タスクの階層ごとにモデルチェーンを算出する。
コアは軸ベースのスコアリングです。各エージェントは、それぞれのスキル軸でスコアリングされます — コーダーはコード生成、診断エージェントはデバッグ推論、リサーチャーは事実取得、クリエイティブはUI生成、オペレーションはツール呼び出し、メインはオーケストレーション。モデルの実効品質は、その合成ベンチマークスコア倍実際のセッションでの観測信頼性となります。ベンチマークでは良いが本番でエラーを起こすモデルは降格されます。これが「実際のパフォーマンスから学ぶ」レイヤーです:ベンチマークは合成能力を示し、信頼性データは実際に持続したものです。
スコアリングの式はBanderの重み行列です:`score = quality·Wq − cost·Wc − latency·Wl + claudeBonus`。コストは相対的な0..1のティアであり、実際のドルではありません — ollama cloudにはコールごとの価格がなく、Claudeはサブスクリプションであるため、正直にそれらを相互にミンマックススケールすることはできません。さらに、品質のハードフロアがあります:その軸でフロア未満のスコアを出した候補はランキング前に除外されますので、安価だが性能の低いモデルは価格だけで勝つことは決してありません。
ルーターはまたデコレレーション問題にも対応し、コーダーと診断エージェントのヘッドを異なるモデルファミリーに配置することで、レビューアーがライターの盲点を継承しないようにします。さらにサブエージェントの経済性も扱います:サブエージェントは親の仕事の一部を実行し、1つの委任で最大20倍に拡散するため、サブエージェントチェーンではコストがどの標準ティアよりもはるかに重み付けされます。これがハードな除外なくClaudeをサブエージェントチェーンから外す理由です:コストウェイトが0.45では単純に勝つことはできません。
ダッシュボード:ロボティックブレイン
ダッシュボードはテキストで捉えるのが最も難しい部分です。全体のシステムを生きている脳としてレンダリングします。
3Dブレインビューがあります — それぞれのエージェントが領域となるWebGLレンダリングされたニューラル構造で、領域を軌道移動、ズーム、クリックしてモデルチェーン、統計、オーバーライドセレクターを詳しく見ることができます。さらにグリッドビューには「電子ブレイン中心部」があります:エージェントがワークフローノードとなり、アニメーションされた信号トレースで結ばれたSVG回路基板で、全体がライブアクティビティに応じて速くまたは遅くパルスします。
脳は単なる装飾ではありません。可視化されたテレメトリです。ダッシュボードはポーリング間のセッションファイルの増加からエージェントごとのアクティビティを導出します — これはエージェントが実際に動作している最も強いシグナル — そしてそれを回路トレースに沿って伝わる信号パルスとしてレンダリングします。システムがアイドル状態のとき、脳は這うように遅くなります。忙しいとき、トレースは駆け巡ります。あなたは見ることができます:脳が考えている様子を。
さらにティアセレクターがあります(Tier 1–4のボタン6つ、「Local」シールド、「Baseline」リセット)で、これにより全艦隊を特定の品質ティアに強制できます。そしてエージェントごとのモデルオーバーライドはファイルに保存され、ライブルーターの選択が望ましくないときに特定のモデルを特定のエージェントに固定できます。ダッシュボードは脳のコントロールサーフェスです。
それを形作った失敗
ここでの設計決定はすべて、実際の失敗による傷跡であり、それらは今週の実際のコンテンツであるため、リストに値する:
- セッションリミットの盲点。 ルーターは週次のクォータだけでゲートし、実際にバインドされているセッションクォータを無視していた。 修正: 両方を読み取り、厳しい方を優先させる。
- ベンチマークエンベロープバグ。 rev1ベンチマークはプレーンな配列ではなく `{value:[...]}` エンベロープでファイルを書き込んだため、各行に `.model` フィールドがなく、ルーターは静かに空のマップを取得した。 ベンチマークデータはルーターに届かず、何も文句を言わなかった。 修正: レガシーシェイプをアンラップして、古いファイルもまだロードできるようにする。
- 軸ルーブリックの逆転。 軸ルーブリックはデバッグ推論において opus に 0.50 を付与した — これは決して本番コードをレビューすべきでないモデルより下だった。これを許して prod ティアを並べ替えると、レビュー者が作者になるところだった。 修正: prod ティアは not ルーブリックによって再ランク付けされない。 キーワードルーブリックは、述べられた設計決定を覆すほど強い証拠ではない。
- コンテキストウィンドウのデススパイラル。 オーケストレーションティアの先頭に 131kコンテキストモデルを置くと、ウィンドウがオーバーフローし、コンパクションのデススパイラルを引き起こした。 修正: オーケストレーションの候補はすべて、コンテキスト予算プラスリザーブを快適に上回るウィンドウを持たなければならない。
- 信頼性のノーオプ。 セッションログはベアなモデル名を保存し、候補はプロバイダー接頭辞を持つため、信頼性レイヤーは静かに何もマッチしなかった。 修正: マッチング前に接頭辞を削除する。
私が得た教訓
NeMoCoの投稿は次のように締めくくられました:ラベルはショートカットであり、構造が重要であり、生の経験から構造を学ぶことができます。 今週はそのエンジニアリング版でした。私は毎タスクごとにルールを手書きするのではなく、タスクを読み取る分類器とライブ状態を読み取るルーターを構築し、作業の構造がツールを決定させました。正規表現分類器は「ラベル」アプローチであり、ラベルがいつも壊れる場所、つまり予期しなかったケースや端緒で正確に壊れました。モデル支援分類器は「構造」アプローチです:パターンを学び、それを転用し、優雅にフォールバックします。
脳ダッシュボードは、それが実際に動いていることを実感させる部分です。エージェントが実際に作業しているとき、信号パルスが回路トレースを駆け抜ける様子を見ることができ、アイドル状態で全体がゆっくりと動きを止めるのを見ると、もう設定ファイルを見ているわけではありません。脈打つシステムを見ているのです。
ルーターは精神的にはオープンソースです — — 私のワークスペースにあるスクリプトのセット、`classify-job.mjs`、`model-router-core.ps1`、`quota-dashboard.mjs` — — で、Claude、クラウドのollamaモデル、そして何も消費しないローカルモデルの組み合わせで動作します。これはロックダウンされた企業システムではありません。自分で構築できる意思決定エンジンであり、それを形作った失敗こそが有用な部分です。
これが教訓です。ロスターはリストです。ルーターは意思決定です。そして脳とは、予算が使い果たされる中でリアルタイムに意思決定が行われ、自分の間違いから学ぶシステムによって得られるものです。