ツールコンテキストとプロンプトキャッシュ
内蔵ハーネスが発行するすべてのリクエストには、2 つのことが当てはまります。ツール定義がそこでの最大の固定コストであること、そしてそれらのほとんどが使われることがないという点です。このページでは、Control Center がそれに対して何を行っているのか、そしてその答えが単に「ツールを減らして送る」ではない理由を説明します。
問題はバイト数ではなく注意力
「問題はバイト数ではなく注意力」というセクションControl Center は約 126 個のツールを登録します。すべてを送信すると、その定義はリクエストごとに約 23,000 トークンを消費します — これは圧縮では決して触れられないコストです。ツール定義は、会話とは別のリクエスト領域に含まれるからです。
トークンの請求額は誰もが口にする不満ですが、プロンプトキャッシュがあれば、それはより小さな問題でもあります。本当のコストは選択精度です。公表されているツール呼び出しの評価は、モデルがコンテキスト内のツール数が 30〜50 個程度までは正しいツールを確実に選び、それを超えると次第に悪化するという点で一致しています。原因として挙げられているのはトークン数ではなく意味的な重なりです。カタログに似た説明のツールが複数含まれるようになると、モデルはケイパビリティを思い出すのではなく、似たもの同士の間で選ぶことになるからです。
126 個のツールがあると、エージェントは毎ターン、その範囲をはるかに超えています — ファイルを読むだけでよかった数多くのターンも含めて。
二層のサーフェス
「二層のサーフェス」というセクションそのため、1 回の実行には 2 つのものが提示されます:
- 常駐セット — およそ 24 個のツールで、リクエストごとに完全なスキーマとともに送信されます;
- それ以外すべての名前インデックス。 “Tickets and projects” や “Memory and knowledge” のような見出しでグループ化され、カタログ全体で数百トークンしかかかりません。
現在のカタログで計測すると、ツールブロックは約 23.1k トークンから約 5.0k トークンへ、およそ 78% 小さくなり、常に表示される集合が、選択が確実になる範囲内に収まります。
常駐セットは、実行がほとんどの実行で使うツールです。ファイルとシェルの語彙(read、write、edit、search、bash、…)、ディスカバリーツール、タスクチェックリスト、メモリ検索、そして現在のモードがその出力を届けるために呼び出さなければならない動詞です。モード自身の出力動詞は常に常駐します — 実行が、成果物を生み出すその 1 つの呼び出しを探しに行かなければならないことは決してありません。
遅延は利用できないことを意味しません
「遅延は利用できないことを意味しません」というセクションここが、この設計を単に安上がりではなく安全にしている部分です。遅延ツールは最初のターンから呼び出せます。 送信されないのは、そのスキーマだけです。
エージェントはプロンプトの中でその名前を見ます。その名前を直接呼び出せば、ハーネスはスキーマを読み込み、同じステップでツールを実行します — エラーも往復もありません。モデルは、そのツールがかつて「アンロードされていた」ことを知る必要はありません。
エージェントがタスクはわかっているが名前を知らない場合、search_tools は平易な言葉の説明(「チケットを誰かに割り当てる」)を受け取り、実行のサーフェス全体を順位付けし、一致するものをスキーマをすでに読み込んだ状態で返すので、次のターンでそのまま呼び出せます。検索が何も見つけられなかった場合、それは率直にそう伝え、別の言い回しやより広い検索を提案します — これは意図的なものです。空の検索結果を「このケイパビリティは存在しない」と読んだエージェントは、もう一度探す代わりに代替品をでっち上げるからです。
search_tools は内蔵ハーネスにのみ存在します。外部の MCP クライアントには代わりに search_tool_bm25 があり、同じインデックスを順位付けしますが、一致を説明するだけです — それらのクライアントはすでに tools/list ですべてのスキーマを受け取っているので、読み込むものは何もありません。
遅延が決してしないこと
「遅延が決してしないこと」というセクション遅延はモードのツールフィルターの後に適用され、それに取って代わることは決してありません。遅延が隠すのはスキーマであり、モードが拒否したツールを明らかにすることはできません。有効化されたツールも、常駐ツールとまったく同じように承認プロンプトとアクションガードレールを通ります。そして、そもそも実行のサーフェスになかった名前をツールが読み込むことはできません。
外部クライアントが見る MCP サーフェスは影響を受けません。tools/list は今でも完全なカタログを返します。以前、それを削減しようとした試みはエージェントを完全に壊しました。MCP クライアントはツール名を自身のキャッシュ済みリストと照合して検証し、サーバーに問い合わせることなくリストにないものを拒否するため、「隠されているが呼び出し可能」なツールは単に到達不能でした。遅延はハーネスの中にあり、実行の途中でツールを読み込むことはハーネスが実際にできることです。
無効にする
「無効にする」というセクション--tool-deferral=off(または CC_SERVER_TOOL_DEFERRAL=off)を使うと、許可されたすべてのツールが再び常駐となり、遅延が存在する前にサーバーが発行していたリクエストとまったく同じものを生成します。詳しくは cc_server CLI リファレンスを参照してください。
プロンプトキャッシュ
「プロンプトキャッシュ」というセクションエージェントのワークロードは釣り合いが取れていません。巨大なプロンプトを送って小さな応答を受け取ることをターンごとに繰り返し、そのたびに同じプレフィックスを使います。プロバイダーはそのプレフィックスをキャッシュし、キャッシュの読み取りは新規のものの約 10 分の 1 のコストで済みます。したがってキャッシュヒット率は、最適化ではなくハーネスの第一級の特性です — そして Anthropic ではスループットももたらします。キャッシュされたトークンは 1 分あたりの入力上限にカウントされないからです。
キャッシュはプレフィックスの完全一致で機能するため、そこから 1 つの支配的なルールが導かれます。
すでに送信したものを書き換えない
「すでに送信したものを書き換えない」というセクション変更されたバイトは、その位置以降のキャッシュを無効にします。そのためハーネスは追記しか行いません。新しいメッセージは末尾に、新しく有効化されたツールスキーマはキャッシュ済みのツールブロックに統合するのではなく、その後ろに置きます。この順序のおかげで有効化は安上がりになります — キャッシュされたプレフィックスは同一のままで、実行はたった今読み込んだスキーマの分だけを支払うからです。
ループはまた、コンテキストを取り戻すために、古いターンの古びたツール出力を削減します。書き換えるだけの価値がある量を取り戻せるようになるまで待つため、削減は継続的なキャッシュミスではなく、まれに起きる深い書き換えになります。
ブレークポイントを置く場所
「ブレークポイントを置く場所」というセクションプロバイダーが許可するキャッシュマーカーの数には限りがあり、Control Center はそれを意図的に使います:
| マーカー | 対象 | 有効期間 |
|---|---|---|
| 最後の常駐ツール | ツールブロック | 1 時間 |
| 最後のシステムブロック | ツール + システムプロンプト | 1 時間 |
| 前のターンの末尾 | 最後のリクエストまでの履歴 | 5 分 |
| 現在のターンの末尾 | 履歴全体 | 5 分 |
最後の 2 つは連動するペアであり、その理由は微妙です。キャッシュの検索は、以前のリクエストが保存したものを求めて、限られた数のブロックをさかのぼって探します。多数のツールを並行して実行する 1 つのターンは、そのウィンドウより多くのブロックを出力することがあり、その場合、片方の末尾マーカーが静かにミスし、レスポンスには何も示されないまま、リクエストは満額を支払います。前のリクエストが停止した正確な位置にマークを付けることで、ヒットは競合ではなく構造的なものになります。
ツールとシステムのプレフィックスが長い有効期間を取るのは、それが実行全体を通じて一定であり、同じ形をしたすべての実行とサブエージェントで共有され、そして時計がリクエストの開始時に始まるからです — 数分間ストリーミングするターンは、次のリクエストが形成される前に、短いウィンドウのほとんどをすでに使い切っています。
サブエージェントは 1 つのプレフィックスを共有する
「サブエージェントは 1 つのプレフィックスを共有する」というセクション同じ種類のサブエージェントはバイト単位で同一のプロンプトプレフィックスを生成するため、それぞれが独自のものを書き込むのではなく、1 つのキャッシュエントリを読むべきです。しかしエントリは、それを書き込んだリクエストが応答を開始して初めて読めるようになるため、一斉に起動されたファンアウトでは、すべての子が、自分たちが共有するプレフィックスの割増コストを支払うことになります。
ハーネスは、ある形の最初の子を開始させ、それがストリーミングを始めるとすぐに兄弟を解放します。待ち時間には上限があります。遅い最初の子が犠牲にするのはキャッシュヒットであり、ファンアウトそのものではありません。同じ理由で、すべてのサブエージェントはプロファイルに関係なく同じ常駐ツールセットを受け取ります — プロファイルごとに変えると、得るものがないまま共有プレフィックスが断片化します。プロファイルはすでに、子が何を呼び出せるかを決めているからです。
動作を観察する
「動作を観察する」というセクション両方の半分は、想定ではなく観察可能です:
- 会話のコンテキストエクスプローラーは、常駐ツール、遅延インデックス、そして送信されていない各スキーマがどれほどコストになるかを報告します。これは実際の実行が使うのと同じコードパスから構築されています。
- 各実行は、どの遅延ツールを読み込んだか、そしてそのきっかけが何だったかを記録するため、何も見つからない検索は、エージェントが静かに別のことをする中に消えるのではなく、検索ミスとして可視化されます。
- オブザーバビリティはキャッシュ率を、処理されたすべてのプロンプトトークン(キャッシュ書き込みを含む)に対するキャッシュ読み取りとして報告します — プレフィックスを再構築し続ける実行は、キャッシュを必要としなかった実行のようにスコアを上げるのではなく、低いスコアになります。