functional-area-resolver について
functional-area-resolverは、多数のスキルを持つエージェント環境のルーティング表を圧縮するパターンです。機能領域ごとに入口をまとめ、ディスパッチャー一覧で個別スキルを示し、検証手順と評価結果も説明します。
主な機能
- 01機能領域ごとにルートを集約
- 02ディスパッチャーにサブスキルを列挙
- 03ルーティング検証の手順を提供
- 04モデルベースの評価方法を収録
活用シーン
- 01大規模なAGENTS.mdのルーティング表を縮小
- 02RESOLVER.mdのスキル入口を整理
- 03圧縮後に意図からスキルへの経路を確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ garrytan/ gbrain --skill functional-area-resolverインストール後、Claude Code で/functional-area-resolverを入力して読み込まれたか確認します。
同梱ファイルrouting-eval.jsonl
詳細
機能領域リゾルバー — ルーティングテーブルを圧縮するパターン
問題
スキルが追加されるにつれて、ルーティングファイル(RESOLVER.md、AGENTS.md)が肥大化します。各スキルに専用の行(トリガー -> スキルのパス)が割り当てられます。スキルが約200以上になると、サイズは25~30KBに達し、実際の作業に使うべきコンテキスト予算を消費します。
解決策:機能領域ディスパッチャー
領域ごとにN行を設けるのではなく、機能領域ごとに1つのエントリーに置き換えます。各エントリーには、ディスパッチ可能なすべてのサブスキルを(dispatcher for: ...)句で列挙します。
変更前(270行、25KB)
- Creating/enriching a person or company page -> `enrich`
- Fix broken citations in brain pages -> `citation-fixer`
- Publish/share a brain page as link -> `brain-publish`
- Generate PDF from brain page -> `brain-pdf`
- Read a book through lens of a problem -> `strategic-reading`
- Personalized book analysis -> `book-mirror`
- Brain integrity -> `brain-librarian`
...
変更後(13行、13KB)
- **Brain & knowledge**: create/enrich/search/export brain pages, filing,
citations, publishing, book analysis, strategic reading, concept synthesis,
archive mining -> `brain-ops` (dispatcher for: enrich, query, brain-pdf,
brain-publish, brain-export, brain-librarian, citation-fixer, book-mirror,
strategic-reading, concept-synthesis, archive-crawler, ...)
効果がある理由
LLMに必要なのは、サブスキルごとに1行設けることではありません。必要なのは次の3点です。
- 領域の認識 — 「これは脳のページに関するものだ」-> Brain & Knowledge
- サブスキルの可視性 —
(dispatcher for: ...)リストに、利用可能な項目が表示されます - スキルファイル自体 — LLMが
brain-ops/SKILL.mdを読み込めば、完全なルーティング詳細を把握できます
これは2層ディスパッチです。ルーティングファイルが領域へルーティングし、領域スキルが特定のサブスキルへルーティングします。各層はそれぞれ1つの役割を適切に果たします。
A/B 評価の結果
3種類のリゾルバーアーキテクチャを、3つのAnthropicの最先端モデル (Opus 4.7、Sonnet 4.6、Haiku 4.5)で、実際の本番環境のAGENTS.mdコンテンツを使って評価しました。 人手で作成した学習用フィクスチャ20件と、評価時まで非公開のブラインドフィクスチャ5件を使用し、 各(フィクスチャ、バリアント)の組み合わせを、シードを変えてn=3回反復しました。スコアリング方法は2種類です。**厳密(STRICT)**では、予測されたスラッグが期待値と完全一致するかを測定します。**寛容(LENIENT)**では、予測値が期待値と同じディスパッチャー領域に含まれるかを測定します。どちらも重要です。
- 厳密(STRICT)の測定内容:「LLMは正確なスラッグを返すか?」
- 寛容(LENIENT)の測定内容:「
(dispatcher for: ...)から、より具体的なサブスキルを選んだ場合でも、LLMは正しい領域に到達するか?」これは本番環境での挙動により近いものです。メールの意図に対してexecutive-assistantとリゾルバーに記載されていても、エージェントがgmailに到達すれば成功です。
学習コーパス(n=20、3シード × 3バリアント × 3モデル、寛容)
| バリアント | Opus 4.7 | Sonnet 4.6 | Haiku 4.5 | サイズ |
|---|---|---|---|---|
| ベースライン(箇条書き270行) | 81.7% ± 7.2% | 86.7% ± 7.2% | 73.3% ± 7.2% | 25KB |
| 機能領域(このパターン) | 98.3% ± 7.2% | 100% ± 0% | 88.3% ± 7.2% | 13KB |
| リゾルバーのリゾルバー(ディスパッチャー句なし) | 63.3% ± 14.3% | 41.7% ± 7.2% | 65.0% ± 12.4% | 10KB |
保留されたブラインドコーパス(n=5、3シード、寛容)
| バリアント | Opus 4.7 | Sonnet 4.6 | Haiku 4.5 |
|---|---|---|---|
| ベースライン | 100% ± 0% | 100% ± 0% | 100% ± 0% |
| 機能領域 | 100% ± 0% | 100% ± 0% | 100% ± 0% |
| リゾルバーのリゾルバー | 100% ± 0% | 73.3% ± 28.7% | 100% ± 0% |
データが示すこと
-
機能領域は学習データで、3モデルすべてにおいてベースラインを上回ります(+13~+17ポイント)。サイズは48%です。保留データでは両方とも100%に達しており、誤差の範囲内です。
-
**負荷を担うシグナルは
(dispatcher for: ...)句です。**リゾルバーのリゾルバーではこの句を取り除いており、Sonnetのスコアは41.7%まで低下します。これは、元のPRが予測していた壊滅的な失敗ケースであり、今回実際に確認されました。 -
このパターンが機能するのは、LLMがディスパッチャーリストを詳しく確認できるからです。「厳密」評価での失敗の大半は、LLMがより具体的なサブスキル(
executive-assistantではなくgmail)を選んだことによるものです。これは想定どおりの動作です。厳密スコアは性能を過小評価し、寛容スコアは本番環境のエージェントの挙動を反映します。 -
**このパターンの価値はモデルのティアに応じて変化します。**圧縮による向上(学習データ、寛容評価での機能領域とベースラインの比較)は、Opusで+17ポイント、Sonnetで+13ポイント、Haikuで+15ポイントです。機能領域とリゾルバーのリゾルバーの差が最も明確なのはSonnet(100%対41.7%)です。モデルの能力によって、ディスパッチャーシグナルの重要性が変わります。
再現方法
cd evals/functional-area-resolver
node harness.mjs --model opus # ~225 LLM calls, ~$1.70 at Opus pricing
node harness.mjs --model sonnet # ~$1.00
node harness.mjs --model haiku # ~$0.30
node rescore.mjs baseline-runs/2026-05-11-opus-4-7.jsonl # zero-cost re-score
評価記録(model、prompt_template_hash、fixtures_hash、harness_sha、ts):
evals/functional-area-resolver/baseline-runs/2026-05-11-{opus-4-7,sonnet-4-6,haiku-4-5}.jsonl。
方法論上の注意点
- 本番用のプロンプトが重要です。 「スキルのスラッグを返す」という単純なプロンプト
(
(dispatcher for: ...)に関する指示なし)では、どの圧縮バリアントも Opus で 約30〜60%に低下します。ディスパッチャー対応プロンプトはevals/functional-area-resolver/harness-runner.ts:PROMPT_TEMPLATEにあります。 エージェントのハーネスにはこれをテンプレートとして使用してください。これがないと、圧縮が機能しません。 - トレーニングコーパスとバリアントは同じリリースで作成されています。 ホールドアウトコーパスはバリアントより前に作成され、調整もされていません。これにより過学習は軽減されますが、完全には排除されません。
- 信頼区間は、シードを変えた3回の反復(n=3)における t 分布で算出しています。 n=3 の下限を維持してください。信頼区間が大きい場合、基となるサンプルにはばらつきがあります。
- 単一ベンダーでの結果です。 3つのモデルはすべて Anthropic のものです。ベンダー横断での検証(Gemini、GPT)は v0.33.x でのフォローアップです。
- ホールドアウトのブラインドセットは小規模です(n=5)。 ほとんどのセルで100%に達しており、ハーネスでは「100%」と「非決定的なミスが1回あった95%」を区別できません。20以上への拡張は v0.33.x でのフォローアップです。
先行研究と引用
この手法は、2024〜2025年の研究分野である階層型エージェントルーティングを静的プロンプトで実現する手法です。
- AnyTool(arXiv:2402.04253)は、
16K 個の API を対象に、メタエージェント → カテゴリエージェント → ツールエージェントの階層構造が、
フラットな検索を +35.4pp 上回ることを示しました。
(dispatcher for: ...)句は、 1回の LLM パスに集約されたメタエージェントの視点です。 - RAG-MCP(arXiv:2505.03275)は、 埋め込みベースの事前検索により、プロンプトトークンを49.2%削減し、精度が3.2倍向上したと報告しています。 トークン削減の結果は(48%縮小)、異なる仕組み(RAG 対 静的ディスパッチャー)ながら、私たちの結果と一致しています。
- Anthropic Agent Skills (エンジニアリングブログ) は、段階的な開示を推奨しています。フロントマター(約80トークン)は常に読み込まれ、 SKILL.md の本文は一致した場合に読み込まれます。このスキルは、スキルごとの本文レベルではなく、 ルーティングテーブルのレベルで同じ原則を適用しています。
2025〜2026年の文献には、静的プロンプトによる階層型ルーティングの公開ベンチマークはありません
(公開されている階層型方式はいずれも、2回目の LLM 呼び出しを実行時に行い、階層を解決します)。
階層を1回の LLM パスで処理するディスパッチャーリストにインライン化し、ルーティング精度を維持できるという私たちの発見が、新たな貢献です。
手法の詳細は evals/functional-area-resolver/README.md を参照してください。
圧縮方法
ステップ 1:前提条件
次のいずれかの条件に該当する場合は、圧縮を拒否します。
- ソースのルーティングファイルが12KB未満(圧縮のオーバーヘッドがメリットを上回る)。
git statusにルーティングファイルの未コミットの変更が表示される(圧縮処理での編集が、ユーザーの作業中の内容と混在するため)。
いずれかの条件を上書きしたい場合は、ユーザーが --force を明示的に指定します。
ステップ 2:どのファイルを圧縮するか
GBrain ワークスペースでは、実行時に2つのルーティングファイルがマージされることがよくあります
(src/core/check-resolvable.ts v0.31.7 による):skills/RESOLVER.md と、隣接する
../AGENTS.md です。どちらを圧縮するか選択してください。
- 片方だけが大きい(12KB超)場合:そのファイルを圧縮し、小さい方はそのままにします。
- 両方とも大きい場合:個別に、順番に圧縮します。まず AGENTS.md (通常、OpenClaw 形式のデプロイではこちらの方が大きい)、次に RESOLVER.md を圧縮します。
- 小さい方だけが大きい場合(まれ):同じルールに従い、そのファイルを圧縮します。
デプロイでルーティングファイルを1つしか使わない場合、このセクションは対象外です。 そのファイルを圧縮してください。
Step 3: 機能領域を特定する
スキルをドメインごとにグループ化します。一般的な領域は次のとおりです(デプロイ環境に応じて調整してください)。
- ブレインとナレッジ — brain-ops をディスパッチャーとして使用
- コンテンツの取り込み — ingest をディスパッチャーとして使用
- カレンダーとスケジュール管理 — google-calendar をディスパッチャーとして使用
- メールとコミュニケーション — executive-assistant をディスパッチャーとして使用
- リサーチと調査 — perplexity-research をディスパッチャーとして使用
- X/Twitter とソーシャル — x-ingest をディスパッチャーとして使用
- 場所と旅行 — checkin をディスパッチャーとして使用
- 製品と開発 — acp-coding をディスパッチャーとして使用
- インフラストラクチャ — healthcheck をディスパッチャーとして使用
- タスクとロジスティクス — daily-task-manager をディスパッチャーとして使用
- 人と連絡先 — google-contacts をディスパッチャーとして使用
Step 4: 領域エントリの形式を作成する
各領域エントリは、次のテンプレートに従います。
- **{Area Name}**: {comma-separated trigger phrases} -> `{dispatcher-skill}`
(dispatcher for: {comma-separated sub-skill names})
ルール:
- トリガーフレーズは、意図を幅広く捉えられるようにします(「ブレインのページ、情報の補強、 検索、ファイリング、引用、書籍の分析」など)。
- サブスキルのリストは網羅的にします。LLM が利用可能な機能を把握するための情報です。
- ディスパッチャーのスキルファイルには、独自の内部ルーティングテーブルを用意します。
Step 5: 常時有効なエントリは分けておく
ゲートと常時有効なエントリ(acknowledge、multi-user、entity-detector など)は、 個別の行に分けておきます。これらはディスパッチされるのではなく、すべてのメッセージで確認されます。
Step 6(必須):ルーティングの精度を検証する
圧縮したファイルをコミットする前に、2つのゲートを実行します。どちらか一方でも 失敗した場合は、コミットしないでください。
ゲート 1:構造検証。 routing-eval.jsonl
のフィクスチャが、圧縮後のルーティングファイルでも適切なスキルに解決されることを確認します。
編集したルーティングファイルがあるワークスペースから実行してください。
gbrain routing-eval --json
フィクスチャの精度が 95% を下回った場合は、変更を元に戻し、領域エントリを調整してから再実行してください。
ゲート 2:編集したファイルでの LLM A/B 検証。 フロンティア LLM がディスパッチャーのリストをたどり、
指定した圧縮内容でサブスキルに到達できることを確認します。ハーネスは gbrain リポジトリ内にあるため、
gbrain リポジトリのチェックアウトが必要です。編集したルーティングファイルをハーネスの
variants ディレクトリにコピーしてから、--variants でそのファイルを指定してハーネスを実行します。
# In your agent workspace, identify the routing file you just compressed.
EDITED=/path/to/your/AGENTS.md # or skills/RESOLVER.md, whichever you edited
# In your gbrain repo checkout:
cd /path/to/gbrain/evals/functional-area-resolver
TMP=$(mktemp -d)/variants && mkdir -p "$TMP"
cp "$EDITED" "$TMP/my-edit.md"
# Without --yes the harness prints its cost estimate and exits (no model calls).
ANTHROPIC_API_KEY=... node harness.mjs --variants-dir "$TMP" --variants my-edit \
--model opus --parallel 3
# Only after the user approves that estimate:
ANTHROPIC_API_KEY=... node harness.mjs --variants-dir "$TMP" --variants my-edit \
--model opus --parallel 3 --yes
ゲート 2 では有料のモデル呼び出しが発生します。最初のコマンドで表示される見積もりをユーザーに示し、
--yes を追加する前に同意を得てください。--yes が省略するのはハーネス独自の確認だけであり、
ユーザーの承認ではありません。
ハーネスは gbrain に同梱されたフィクスチャセットを使用します。そのため、これは「gbrain に同梱された
フィクスチャが対象とするルーティングの意図で、LLM が適切なサブスキルに到達したか」を検証します。
つまり、共有スキルに対するリグレッションチェックであり、あなた自身のフィクスチャセット全体を
再評価するものではありません。評価範囲を網羅するには、このスキルの
fixtures.jsonl と fixtures-held-out.jsonl の構成を参考に、あなたのスキル固有の意図を用意してください。
バリアントの寛容スコア(同一領域)が 95% を下回った場合は、圧縮を元に戻して調整してください。 よくある原因:
(dispatcher for: ...)リストからサブスキルが漏れている。- 領域のトリガーフレーズが狭すぎる(LLM が意図を認識できない)。
- 領域を過度に統合している(領域の数が少なすぎる。「アンチパターン」を参照)。
- ASCII の
->と Unicode の→が一致していない。現在のハーネスは両方に対応していますが、 以前のバージョンでは Unicode のみが一致しました。gbrain を v0.32.3.0+ に固定してください。
ハーネスの評価でよく見られる誤検知(圧縮の不具合ではありません):
- gbrain に同梱されたフィクスチャは、
enrich、query、gmail、executive-assistantのようなスキル名を対象とします。ルーティングファイルで これらのスキルをまったく公開していない場合、それらのフィクスチャでは厳密スコアが失敗することがあります。 寛容スコアは、(dispatcher for: ...)リストに含まれるすべてのサブスキルで正確さを保ちます。
Step 7: コミット前に差分を確認する
提案した編集内容(または実際の git diff)をユーザーに見せ、ステージングする前に
明示的な承認を待ってください。skills/book-mirror/SKILL.md と同じ運用です。
コントラクト
このスキルでは、次のことが保証されます。
- ルーティングは、フロントマターに記載された正規のトリガーと一致します。
- 圧縮は、ステップ 1 の前提条件(ファイルが 12 KB 以上で、かつワーキングツリーがクリーン、または
--force)を満たす場合にのみ実行されます。 - ステップ 6 の必須検証ゲートは、サンプルのバリエーションではなく、ユーザーが編集したファイルに対して実行されます。圧縮したファイルをコミットする前に、ユーザーは
gbrain routing-eval --jsonと gbrain リポジトリのハーネス(node harness.mjs --variants-dir <tmp> --variants my-edit)を実行します。 - プライバシー契約が維持されます。フォーク固有のファイルシステムパスのリテラル(サーバー側の brain ホーム、OpenClaw フォークのホーム)が、圧縮後の出力に漏れることはありません。
動作コントラクトの全容は上記の本文セクションに記載されています。このセクションは適合性テストのために設けられています。
出力形式
圧縮されたルーティングファイルは、ステップ 4「エリアエントリー形式を構築する」に記載されたエリアエントリーテンプレートに従います。各エントリーは次の形式です。- **{Area Name}**: {trigger phrases} -> \{dispatcher-skill}` (dispatcher for: {sub-skill list})。ディスパッチャーの矢印には ASCII の ->(このテンプレートのデフォルト)と Unicode の →`(一部の本番環境で使用)のいずれも使えます。gbrain ハーネスは両方に対応しています。
失敗した場合
gbrain のエラー code、終了コード、[AGENT] ブロック、または通知ブロックについては、エージェントオペレータープロトコルに従ってください。このスキル固有の対応は次のとおりです。
- いずれかの検証ゲート(構造検証または LLM A/B)に失敗した場合は、圧縮を拒否し、失敗したゲートを報告します。ルーティング性能が低下する、サイズの小さなリゾルバーを出荷してはいけません。
- A/B ハーネスでプロバイダーキーが不足している場合、またはコスト上限に達した場合は、LLM ゲートを実行できなかったことを伝え、元のリゾルバーを維持します。
アンチパターン
-
パイプテーブルを使ったリゾルバーのリゾルバー。 テストに失敗しました(評価テーブルを参照してください)。LLM がサブスキルを調べずに、テーブルからエリア名を選んでしまいます。
-
サブスキル名の削除。
(dispatcher for: ...)リストがなければ、LLM は特定のサブスキルにルーティングできません。このリストがルーティングの手がかりです。 -
エリアが少なすぎる。 5 エリア未満にまとめると、各エリアの範囲が広くなりすぎます。最適な数は 12~15 エリアです。
-
エリアが多すぎる。 目的に反します。エリアが 50 個あるなら、個別の行をそのまま残してください。
メンテナンス
新しいスキルを追加する場合:
- そのスキルの機能エリアを特定します。
- そのエリアの
(dispatcher for: ...)リストにスキル名を追加します。 - エリアのスキルファイルにルーティングの詳細を追加します。
- ルーティング評価を実行して(ステップ 6)、確認します。
新しい機能エリアを追加する場合:
- 内部ルーティングを備えたディスパッチャースキルを作成します。
- ルーティングファイルにエリアエントリーを追加します。
- ルーティング評価を実行して(ステップ 6)、確認します。
変更履歴
v1.0.0 — 2026-05-11
- 初版。保留データを使った A/B 評価(
evals/functional-area-resolver/を参照)とともに、gbrain v0.32.3.0 でこのパターンをリリースしました。 - リリース前にスキル名を
compress-agents-mdからfunctional-area-resolverに変更しました。この貢献の本質はファイル名ではなく、パターンです。