第 38 章:Deferred Tool Loading と Tool Search

「ツールが増えたら遅延ロードすればいい」——ところがツール数は計量単位として間違いで、遅延先を 1 つ誤ると全セッションの初回応答が 6 秒遅くなる。


5 分で要点掴む

  1. 予算はトークンで持つ。ツール数ではない——小さい Schema 30 個は大きい 5 個より安いことがある
  2. トリガーは 2 つ:予算超過またはコールド集合に always-defer カテゴリが含まれる
  3. 遅延してはいけないツールがある——セッションを開くツールでは、検索の往復がまるごと待ち時間になる
  4. Warm Set はセッション単位で毎回コールド起動。キーは名前ではなく Schema フィンガープリント
  5. 遅延は Schema を隠すだけ。権限の拒否ではない——別のシステム

10 分パス:38.1-38.3 → 38.5 → Kocoro OSS Lab


公開ソースのスナップショット:実装例は 2026-07-27 に確認した Kocoro 公開 origin/main のコミット 4ec6772 に基づきます。学ぶべき対象は不変条件であり、定数は最新ソースで再確認してください。

38.1 6 割が目次だった Prompt の話

MCP Server を 4 つ繋ぎます。GitHub、Postgres、Slack、ブラウザ自動化。合わせてツールは 74 個。

そのうえで、毎リクエスト何を送っているか見てください。

system prompt        1,800 tokens
tool schemas        23,400 tokens    74 ツールの完全な JSON Schema
conversation         4,100 tokens
─────────────────────────────────
                    29,300 tokens

2 万 3 千トークンのツール定義を、全 Turn の全反復で再送しています。ツール 2 つしか触らない質問に答えるためにです。モデルは 74 項目のカタログを読んで 1 行選んでいて、あなたはそのカタログ代を毎回払っています。

素直な解は、モデルが要らない Schema を送るのをやめ、必要なら取りに来させることです。それが Deferred Loading で、仕組み自体は難しくありません。面白いのは、素朴な実装のほとんどが事態を悪化させること——しかも本番でしか表に出ないことです。

38.2 ツール数は計量単位として間違い

最初に思いつくのは件数の閾値です。30 個を超えたら遅延モードへ。

でも Schema の大きさは同じではありません。文字列引数 2 つの read_file なら数百トークン。オプション引数 15 個、入れ子のセレクタオブジェクト、列挙された待機条件を持つブラウザ自動化ツールなら、それ 1 つで数千に届きます。前者 30 個は後者 5 個より安い。

だから、本当に気にしている量に予算を張ります。公開 Runtime は Schema のトークンを直接見積もり、予算と比べます。

schemaTokenBudget = 8000      // コンパクトな Schema JSON で約 28K 文字
charsPerTokenSchema = 3.5     // 保守的な比率、コンテキスト推定器と同じ

8000 トークン。「コンパクトな Schema JSON で約 28K 文字を、意図的に保守的な文字/トークン比で換算した値」です。この保守性は意図的なもので、Schema コストを低く見積もることは、守ろうとしていた予算をそのまま突き破ることを意味します。だから比率は「Schema は高い」側へ倒してあります。

数えられるものではなく、実際に払っているものに予算を張ること。 件数の閾値は、誰かが饒舌な Server を 1 つ繋いだ日に壊れます。

38.3 トリガーが 2 つある理由

ここが「予算を見るだけ」より面白いところです。実際の条件は論理和です。

deferredMode := len(coldDeferred) > 0 &&
    (shouldDefer(a.tools, a.tools.SortedNames(), schemaTokenBudget) ||
        hasCategoricalDeferred(coldDeferred))

予算超過、またはコールド集合に always-defer カテゴリのツールが含まれること。

2 つ目の節はなぜ要るのか。高価で、かつ特定の文脈ではまず使われないツールがあるからです。macOS の GUI 自動化、スケジューリング、ヘッドレスのプロセス制御——ワンショットの CLI タスクはどれにも触れませんが、Schema は毎リクエストに相乗りします。always-defer 集合が狙うのはそこです。

Keeping them in the deferred set means cold-start tools[] ships ~5K fewer tokens; sessions that DO need them pay one extra tool_search round-trip per session.

取引条件がはっきり書かれています。コールドスタートごとに 5K トークン節約、その代わり GUI ツールを実際に使うセッションは 1 回だけ余分な検索往復を払う。大半のセッションがデスクトップに触れない CLI ワークロードなら、明らかに得です。そしてこれはあなたのワークロードについての判断であって、普遍的な真理ではありません。デスクトップ自動化製品なら、正しい always-defer リストはほぼ逆になります。

38.4 決して遅延してはいけないツール

ここが最も間違えやすい部分で、この章の冒頭にある数字の出どころです。

Gateway ツールは既定で遅延対象です。しかし 2 つだけ明示的に除外されており、その理由は全文読む価値があります。

web_search/web_fetch are the most common opener of a NEW session (e.g. "what's the news on X") — deferring them forces the model into an extra tool_search round-trip before it can call the tool at all, adding ~6s of observed latency to the very first reply of a session, every session, since the WorkingSet warm cache is session-scoped and starts cold each time.

丁寧に読んでください。ここには別々の事実が 2 つあります。

1 つ目。Warm キャッシュはセッション単位で、毎回コールドから始まります。 前のセッションでモデルが掴んだツール事情は消えています。新しいセッションはすべて、最初の遅延ルックアップに定価を払います。

2 つ目。そのコストは初回応答に落ちます。 ユーザーが既に注意を投じた深い反復ではなく、質問した直後に最初に見るものの上に落ちます。6 秒間なにも出ない。しかもそれは、この システムが速いかどうかの印象を決めるやり取りの上でです。

だから規則は「高い Schema を遅延せよ」ではありません。検索コストが「ユーザーが待っていない場所」に落ちる Schema を遅延せよ、です。セッションを開くツールは、Schema がどれだけ大きくても、最も遅延してはいけない対象です。

memory_recall の除外は関連しつつ別の理由です。暗黙のメモリ注入が何も拾えなかったときのフォールバック経路だからです。遅延させたときに観測された失敗は、モデルが最初の試行で古いバージョンの Schema を幻覚し、1 ターン無駄にすることでした。修正コストは約 1.5K の追加 Schema バイト——そしてここが肝心ですが、それはキャッシュ可能な system プレフィックスに相乗りします。ターンごとではなく、セッションごとに 1 回の支払いです。

この最後の点は持ち帰る価値があります。キャッシュされたプレフィックスに住む Schema のコストはセッション全体で償却されるので、「高いが常駐」は「安いが遅延」に勝ちうるのです。

38.5 Warm Set と、フィンガープリントをキーにする理由

モデルが一度検索して Schema を受け取ったあとは、もう一度送っても注意コストはゼロ、トークンも安い。だから残しておきます。それが Warm Set——モデルが既に取り寄せた Schema を持つ、セッション単位のワーキングセットです。

見えにくい失敗があります。MCP Server が更新され、ツールの引数の形が変わる。あなたの Warm Set は古い Schema を持ったまま、モデルは古い形で呼び出し、ツールは拒否する——もっと悪ければ、黙って受け取って別のことをします。

だから Warm Set はSchema フィンガープリントで無効化されます。名前ではありません。実効ツールセットが変われば、古い定義から派生した warm エントリは有効でなくなります。名前をキーにするのがバグで、内容をキーにするのが修正です。

38.6 遅延は認可ではない

ここははっきり書く価値があります。セキュリティに見えて、そうではないからです。

Schema をモデルから隠しても、そのツールが呼ばれないわけではありません。モデルは名前で呼び出しを出せます。検索カタログで名前を見たかもしれないし、Skill の説明で見たかもしれないし、単に当てただけかもしれません。Deferred Loading は能力記述に対する検索の最適化です。モデルが何を見るかを整えるだけで、何をしてよいかは整えません。

権限は別のシステムで、実行時に強制されます。危険なツールに対する唯一の防御が「Schema が Prompt に入っていない」ことなら、防御は存在しません。 実際の認可層は第 25 章と第 33 章が扱います。この章はトークン経済の話だけです。

ついでに言えば、同じ分離は Skill 制限にも現れます。allowed-tools は Schema のフィルタではなく実行時の拒否として実装されています。tools 配列をバイト安定に保ち、Prompt Cache に効かせるためです。2 つのシステム、2 つの機構、意図的に統合しない。これは第 39 章が土台にしている規律そのものです。

38.7 スナップショットの根拠

観測4ec6772 のソース位置
Schema トークン予算 8,000 とその導出toolbudget.go L15
保守的な 3.5 文字/トークン比率toolbudget.go L18
Deferred Mode は予算またはカテゴリで発動loop.go L2158
always-defer カテゴリ、コールド起動で約 5K 節約toolbudget.go L39
browser_* はプレフィックスで遅延toolbudget.go L56
never-defer の除外と 6 秒の根拠toolbudget.go L63
Warm Set はツールセットのフィンガープリントをキーにするwarmset.go L11
tool_search の構築deferred.go L22

これらは特定時点の実装例であり、普遍的な契約ではありません。

38.8 よくある落とし穴

ツール数で予算を張る。 前述のとおり。饒舌な Server が 1 つ繋がれた日に壊れます。

セッションを開くツールを遅延する。 6 秒の税を、初回応答で、毎セッション徴収されます。遅延対象を選ぶ前に、実際に何がセッションを開いているかログで見てください。

warm エントリを名前でキーにする。 Server が Schema を更新するまでは動きます。その後は不正な呼び出しを産み、しかもモデルのエラーに見えます。

Warm Set がコールドから始まることを忘れる。 定常状態だけで考え、新しいセッションが毎回ゼロから始まることを忘れる。これが 6 秒問題がテストで見逃される理由です。長い手動セッションでは決して現れません。

遅延をセキュリティ境界とみなす。 違います。拒否は実行時に起きます。

遅延させすぎてモデルが何も発見できない。 フォールバックのカタログが名前しか並べず、その名前が難解なら、モデルは良いクエリを組み立てられません。カタログの名前は耐荷重部材です——説明的に付けてください。

Kocoro OSS Lab(10 分)

  1. neverDeferTools のコメントを読み、論証の構造に注目します。観測されたレイテンシの数値が、具体的なユーザー可視の瞬間に結びつき、さらに具体的なキャッシュ特性に結びついています。
  2. alwaysDeferTools を見て、デスクトップ自動化製品なら誤りになるのはどれか考えます。このリストはワークロードの仮定を符号化しています。
  3. 自分の Schema トークン支出を見積もります。ツール定義をコンパクトな JSON にして文字数を 3.5 で割り、コンテキストウィンドウと比べてください。数パーセントを超えるなら、あなたにもこの問題があります。

ここだけは押さえる

  1. 予算はトークンで、ツール数ではない。 Schema のサイズは 1 桁違います。
  2. トリガーは 2 つ。 予算超過、またはコールドな always-defer カテゴリの存在。後者は「高価だが使われず、予算も超えない」ツールを捕まえます。
  3. セッションを開くツールは遅延しない。 検索コストは初回応答に落ち、キャッシュは毎セッション コールドから始まります。
  4. キャッシュされたプレフィックスの Schema は見た目より安い。 コストはセッション全体で償却され、「高いが常駐」が「安いが遅延」に勝ちえます。
  5. 遅延は検索であって認可ではない。 拒否は実行時に属し、両者を混ぜればどちらも得られません。

次章:第 39 章は、そのキャッシュされたプレフィックスを守る価値のあるものにしている規律そのものを扱います。

この記事を引用する / Cite
Zhang, Wayland (2026). 第 38 章:Deferred Tool Loading と Tool Search. In AI Agent アーキテクチャ:単体からエンタープライズ級マルチエージェントへ. https://waylandz.com/ai-agent-book-ja/%E7%AC%AC38%E7%AB%A0-Deferred-Tool-Loading%E3%81%A8Tool-Search/
@incollection{zhang2026aiagent_ja_38_-Deferred-Tool-Loading_Tool-Search,
  author = {Zhang, Wayland},
  title = {第 38 章:Deferred Tool Loading と Tool Search},
  booktitle = {AI Agent アーキテクチャ:単体からエンタープライズ級マルチエージェントへ},
  year = {2026},
  url = {https://waylandz.com/ai-agent-book-ja/%E7%AC%AC38%E7%AB%A0-Deferred-Tool-Loading%E3%81%A8Tool-Search/}
}