Coding Agent のコストを最適化する方法:Prompt Cache から Context Engineering までの調査ノート

132 min

本記事は2026年5月に執筆しました。内容はすべて調査結果であり、まだプロジェクトで実際に運用したものではありません。この分野は変化が非常に速いため、お読みになる際は時効性にご注意ください。

本記事は約20,000字の長文です。読了まで30〜40分程度かかります。

TL;DR

  • Coding Agent のコストの大部分は input token(トークン総量の93〜99%)です。毎回の API 呼び出しで完全なコンテキストが再送信されるためです
  • 最も効果的なコスト削減手段は Prompt Cache(キャッシュヒットした input は10倍安い)です。キャッシュ規律の整備(プレフィックス順序の固定、不要な MCP ツールの削除)は一度の設定で持続的に効果があります
  • Context Engineering は4つの方向に分かれます:Select(正しいコードを取り込む)、Compress(既存コンテキストを圧縮)、Isolate(タスク分割・モデル切替)、Write(情報をファイルシステムに永続化)
  • モデル階層化(Haiku で探索、Sonnet で実装、Opus でアーキテクチャ設計)により、トークン総量を変えずにコストを数倍削減できます
  • ファイルに書き出す外部メモリ(SPEC.md、planning-with-files、session handoff)によりセッション間で作業を継続できますが、メンテナンスは未解決の課題です(コードが変わってもドキュメントが追従しない)
  • 私の実際のセッショントークン数(Input 1.62M、Output 128.1K、Opus 4.6)を使った概算:最適化なしの $11.30 から、全ての施策を適用した場合は約 $4〜5 へ。これは合理的な仮定(キャッシュヒット率70%など)に基づく見積もりであり、実測結果ではありません

きっかけ

私たちのチームでは開発ツールとして Github Copilot を使用しています。先日、Github Copilot が6月から usage based billing に移行すると発表しました。チームの使用量をざっくり試算したところ、費用がおよそ3倍になりそうだったため、現在市場に出ている coding agent のコスト最適化に関するオープンソースのソリューションを一通り調査しました。皆さんの参考になればと思い、ここで公開します。私個人は Claude Code を、チームでは OpenCode を使用しているため、本記事は主にこの2つを中心に取り上げます。


料金表

コストを削減するには、まず課金の仕組みを知る必要があります。以下は2026年5月時点の Anthropic、OpenAI、GitHub 各社の公式料金ページの数値です。

Claude と GPT の料金比較

モデルInput ($/MTok)Output ($/MTok)Cached InputCache Write (5min)
Claude Opus 4.6 (1M)$5.00$25.00$0.50$6.25
Claude Sonnet 4.6$3.00$15.00$0.30$3.75
Claude Haiku 4.5$1.00$5.00$0.10$1.25
GPT-5.5$5.00$30.00$0.50— (自動)
GPT-5.4$2.50$15.00$0.25—
GPT-5.4 mini$0.75$4.50$0.075—

GitHub Copilot AI Credits

新しい課金方式では AI Credits で計量され、1 AI Credit = $0.01 USD です。消費量は各リクエストの input tokens、output tokens、cached tokens、および使用モデルの単価に基づいて算出されます。

Plan月額含 AI Credits
Pro$10$10 (1,000 credits)
Pro+$39$39 (3,900 credits)
Business$19/user$19/user
Enterprise$39/user$39/user

この表から分かるように、Cached Input は通常の Input の10分の1です。Opus 4.6 の input は $5/MTok ですが、キャッシュにヒットすれば $0.50/MTok で済みます。80%のヒット率であれば input コストは実質2割になります。Output は Input の5倍の単価で、Opus 4.6 は $25 vs $5、GPT-5.5 はさらに極端で $30 vs $5 です。Reasoning/Thinking tokens も output 単価で計算されるため、モデルが「考える」ほどコストがかかります。

最適化の優先順位は明確です。まず input をキャッシュにヒットさせる(コスト差10倍)、次に不要な input を減らす、最後に output を制御する。

そこで私が最初に調査したのは、Prompt Cache とは一体何なのか、なぜ input を10倍安くできるのか、という点です。 この問題を理解するために、まず大規模言語モデルの処理フローを簡単に見ておく必要があります。


大規模言語モデルが1回のリクエストを処理する全体フロー

flowchart TD
    A["📝 入力テキスト"] --> B["① Tokenization\nテキストを token(サブワード単位)に分割"]
    B --> C["② Embedding\n各 token を高次元ベクトルにマッピング"]

    subgraph prefill["Prefill フェーズ(全 input を一括処理、最もコストが高い)"]
        C --> D["③ Transformer Layers × N 層\n各層で Self-Attention + Feed-Forward Network\n計算量 O(n²)"]
    end

    subgraph decode["Decode フェーズ(output を1トークンずつ生成、KV Cache を再利用)"]
        D --> E["④ 次のトークンの確率分布を予測"]
        E --> F["⑤ サンプリングしてトークンを1つ出力"]
        F --> G{生成終了?}
        G -->|"いいえ"| H["新トークンをシーケンスに追加\n既存の KV Cache を再利用\n新トークンの attention のみ計算"]
        H --> E
    end

    G -->|"はい"| I["🏁 完全な応答"]

    style prefill fill:#fff0f0,stroke:#cc0000
    style decode fill:#f0f7ff,stroke:#0066cc
    style D fill:#ff6b6b,color:#fff,stroke:#cc0000

Prompt Cache がスキップするのは赤色の Prefill フェーズです。今回のリクエストの input プレフィックスが前回と同じであれば、前回の計算結果をそのまま再利用し、O(n²) のコストを省略できます。

上のフローチャートは全体像です。以下、各ステップを分解して、コストがどこで発生しているかを見ていきます。

Tokenization

モデルは「文字」を認識しません。API に送るすべてのコードや文章は、まず token(サブワード単位)に分割されます。

tokens = tokenizer("帮我修一下 billing 里的 bug")
# → [帮, 我, 修一下, billing, 里的, bug]
# → [24891, 1588, 78432, 53012, 9876, 31205]

分割に使われるアルゴリズムは通常 BPE(Byte Pair Encoding)です。原理は、単一バイトから始めて、コーパス内で最も頻繁に隣接するバイトペアを統計的に見つけ、それらを新しいトークンに結合する操作を繰り返し、最終的に数万〜十数万エントリの語彙テーブルを構築するというものです。高頻度の単語(“the”)は1トークンとして扱われ、低頻度の単語は複数のサブワードに分割されます。

flowchart LR
    A["'帮我修一下 billing 里的 bug'"] --> B["Tokenizer\n(BPE アルゴリズム)"]
    B --> C["[24891, 1588, 78432, 53012, 9876, 31205]"]
    C --> D["6 トークン"]

    style B fill:#4ecdc4,color:#fff,stroke:#2ba89e

分割結果はおおよそ以下のようになります。

入力テキスト分割された tokenstoken 数
帮我修一下 billing 里的 bug帮 + 我 + 修一下 + billing + 里的 + bug6
你好世界你好 + 世界2
calculateUsagecalculate + Usage2
const x = 42;const + x + = + 42 + ;5
不可変数据结构不可 + 変 + 数据 + 结构4

料金表の “per million tokens” はこのトークンを指します。OpenAI の Tokenizer ツール や Anthropic の token カウント API で、コードが実際に何トークンかを確認できます。

ここにコストと直結する重要な点があります。モデルごとに tokenizer が異なるため、同じテキストでもモデルによって分割されるトークン数がかなり違うことがあります。Opus 4.7 では新しい tokenizer が採用され、Anthropic の公式発表では「モデルのテキスト処理方法を改善したが、その代償として同じ input がより多くのトークンにマッピングされる可能性があり、約1.0〜1.35倍になる」とのことです。Simon Willison による実測では、同一の system prompt が Opus 4.7 で 7,335 トークン、4.6 では 5,039 トークンとなり、46%増加しました。per-token の価格は変わっていませんが、同じテキストにより多くのトークンが必要になるため、実際の請求額は12〜27%上昇します。異なるモデルのコストを比較する際、この「隠れた値上げ」は見落とされがちです。

Embedding

この段階のトークンはまだ単なる番号、例えば語彙テーブルの第53,012番目のエントリです。整数には意味情報がなく、モデルはそのまま計算に使うことができません。

Embedding が行うのは、各トークンに高次元ベクトルを割り当てることです。具体的には、大きなテーブル(語彙サイズ × ベクトル次元の行列)を参照し、トークン番号を行番号として使い、対応する浮動小数点数の行を取り出します。

flowchart LR
    A["token #53012\n'billing'"] --> B["Embedding テーブル参照\n(語彙サイズ × 4096)"]
    B --> C["[0.12, -0.85, 0.33, ..., 0.07]\n4096 次元ベクトル"]

    D["token #31205\n'bug'"] --> B

    style B fill:#9b59b6,color:#fff,stroke:#7d3c98

各単語に4096次元空間内の座標を割り当てるイメージです。意味的に近い単語は座標が近くなります。“dog” と “puppy” のベクトル距離は近く、“dog” と “spreadsheet” のベクトル距離は遠くなります。この段階の計算量は大きくなく、テーブル参照1回で済むため非常に高速です。

ただし、embedding には限界があります。各単語に割り当てられるベクトルは固定で、コンテキストを考慮しません。“bank” は “river bank” でも “bank account” でも同じベクトルが返され、「川岸」と「銀行」を区別できないのです。

この問題が解決されるのは次のステップです。

Transformer と Self-Attention

Transformer は2017年に Google が論文 “Attention Is All You Need” で提案したモデルアーキテクチャです。現在のほぼすべての大規模言語モデル(GPT、Claude、Gemini、LLaMA)はこれに基づいています。

それ以前、シーケンスデータの処理は主に RNN(リカレントニューラルネットワーク)に頼っていました。RNN には2つの問題がありました。1つは、単語を1つずつ順次処理する必要があり、長いシーケンスでは非常に遅く、GPU の並列処理能力を活かせないこと。もう1つは、前方の情報が後方に伝わるにつれて徐々に減衰し、2,000語のテキストでは冒頭の内容が末尾に到達する頃にはぼやけてしまうことです。Transformer は Self-Attention メカニズムで順次処理を置き換え、各トークンがシーケンス内の他のすべてのトークンを同時に参照できるようにしました。これにより並列処理が可能になり、距離が離れても情報が失われなくなりました。

“bank” の例に戻りましょう。Embedding は “bank” に固定のベクトルを割り当てており、2つの意味を区別できません。Self-Attention のアプローチは、“bank” に同じ文中の他の単語を参照させることです。隣に “river” があれば「川岸」方向に表現が移動し、“deposit” があれば「銀行」方向に移動します。

Self-Attention 図:Self-Attention の行列計算——Query × Key で注意力スコアを算出し、Value と乗算(出典:Jay Alammar, The Illustrated Transformer)

具体的なメカニズムを簡略化した数値例で説明します。シーケンスが3つのトークン I、went、bank のみで、各トークンの embedding が2次元ベクトルだと仮定します(実際は4096次元ですが、ここでは簡略化しています)。

各トークンのベクトルは3組の重み行列 W_Q、W_K、W_V を通じて、3つの新しいベクトルを生成します。

  • Query(Q):「私はどんな情報を探しているか?」
  • Key(K):「私はどんな情報を提供できるか?」
  • Value(V):「私の実際の内容」
           Q          K          V
I     [1.2, 0.3]  [0.5, 1.1]  [0.8, 0.2]
went  [0.7, 0.9]  [1.0, 0.4]  [0.3, 0.7]
bank  [1.1, 0.6]  [0.8, 0.9]  [0.6, 0.5]

bank の場合、その Q とすべてのトークンの K で内積を計算し、注意力スコアを算出します。

bank_Q · I_K    = 1.1×0.5 + 0.6×1.1 = 1.21
bank_Q · went_K = 1.1×1.0 + 0.6×0.4 = 1.34
bank_Q · bank_K = 1.1×0.8 + 0.6×0.9 = 1.42

softmax で正規化して確率分布(合計1)にした後、これらのスコアで V の加重和を求め、bank のこの文中における新しい表現を得ます。

flowchart TD
    subgraph attn["Attention 重み例:'I went to the bank to deposit money'"]
        direction LR
        B["bank"] -->|"0.35"| D["deposit"]
        B -->|"0.28"| M["money"]
        B -->|"0.15"| W["went"]
        B -->|"0.12"| T["to"]
        B -->|"0.10"| I["I"]
    end
    style B fill:#ff6b6b,color:#fff
    style D fill:#ffd93d,color:#333
    style M fill:#ffd93d,color:#333

完全な文中で、“bank” は “deposit” と “money” に対する注意力が最も高く、その表現は「銀行」方向に移動します。文を “I sat on the bank by the river” に変えると、重みの分布はまったく異なります。

コンテキストが長くなるほどコストが高くなる根本的な理由はここにあります。n トークンのコンテキストでは、各トークンが他のすべてのトークンとの関係を計算する必要があり、合計 n × n の内積演算が発生します。10万トークンのコンテキストは、各層で100億回の attention 計算を意味します。線形増加ではなく二乗増加、O(n^2) です。

flowchart TD
    subgraph layer["単一 Transformer Layer(N 回繰り返し)"]
        direction TB
        T["入力:各トークンのベクトル表現"] --> Q["Query ベクトル生成\n「何を探しているか?」"]
        T --> K["Key ベクトル生成\n「何を提供できるか?」"]
        T --> V["Value ベクトル生成\n「実際の内容」"]
        Q --> S["Query × すべての Key\n→ 注意力スコア行列\n(n × n、これが O(n²) の原因)"]
        K --> S
        S --> W["スコア × Value の加重和\n→ 各トークンの新しい表現"]
        V --> W
        W --> F["Feed-Forward Network\n非線形変換(計算量は固定)"]
        F --> O["出力:更新されたトークンベクトル"]
    end

    style S fill:#ff6b6b,color:#fff,stroke:#cc0000
    style layer fill:#f9f9f9,stroke:#ccc

赤色部分がコストの核心です。n トークン間のすべてのペアの関連を計算するため、コンテキストが長くなるほどこの行列は大きくなります。

現代の大規模言語モデルは数十から百以上のこのような Transformer layer を持ち、各層では2つの処理を行います。Self-Attention と Feed-Forward Network(attention の結果に非線形変換を適用、計算量は固定でコンテキスト長に依存しません)です。

より直感的にこのプロセスを理解したい場合は、Georgia Tech のインタラクティブ Transformer Explainer で各ステップの計算をリアルタイムに確認できます。

Prefill:全 input を一括処理

Tokenization から Embedding、Transformer の N 層 Self-Attention まで、この一連のフローは送信されたすべての input tokens に対して一括で並列処理されます。このフェーズを Prefill と呼びます。

Prefill は推論プロセス全体で最も計算量が多い部分です。60k トークンのコンテキストを送信すると、各 Transformer 層で 60k × 60k の attention 行列を計算する必要があります。料金表の input token の費用は主にここで発生します。

Prefill にはもう1つ重要な副産物があります。Self-Attention の計算過程で、各 input token の Key と Value ベクトルがすでに算出されています。これらの K/V ベクトルは GPU メモリに保存され、初期の KV Cache を形成します。後続の Decode フェーズで新しいトークンを生成する際、これらの古いトークンの K/V を再計算する必要がなく、Cache から直接取得できます。

つまり、KV Cache は Prefill フェーズで構築され、Decode フェーズで使用・拡張されます。

ここで興味深いアイデアがあります。Prefill が行うこと(Tokenization → Embedding → Transformer 各層)は、同一アーキテクチャに基づくすべてのモデルで類似のフローですから、異なるモデル間で Prefill の計算結果を共有できないかということです。例えば同じ system prompt を1回だけ Prefill し、K/V Cache を複数のモデルで使えないか。

学術界ではすでにこの方向を探索しています。2026年初頭の論文 PrefillShare では、モデル間で Prefill モジュールを共有する方式が提案されています。モデルを Prefill と Decode の2つに分離し、Prefill モジュールを凍結して Decode モジュールのみをファインチューニングすることで、複数のタスク専用モデルが同一の Prefill の KV Cache を共有できます。マルチモデル Agent ワークロードでの実測では、p95 レイテンシが4.5倍削減、スループットが3.9倍向上しました。産業界でもこの方向に進んでおり、vLLM、SGLang、NVIDIA Dynamo がいずれも Prefill-Decode 分離アーキテクチャを構築し、Prefill と Decode を独立したサービスとして分離デプロイ・スケーリングを行っています。これらは現時点ではまだ先端的なインフラ層の取り組みであり、一般の API ユーザーが直接触れるものではありませんが、Prefill の計算再利用の余地が想像以上に大きいことを示しています。

次に生成フェーズに入ります。

Decode

Prefill が完了すると、最終層から確率分布が出力されます。「次のトークンとして最も可能性が高いのは何か?」サンプリング戦略に基づいて1つのトークンを選択し、そのトークンをシーケンスに追加して、すべての層を再度通過させ、次のトークンを生成します。この繰り返しで、モデルが終了マーカーを出力するまで続きます。

このトークンを1つずつ生成するプロセスを Decode と呼びます。新しいトークンを1つ生成するたびに、理論的にはそれ以前のすべてのトークンと再度 attention を計算する必要があります。つまりすべてのトークンの Key と Value ベクトルを再計算することになります。しかし、以前のトークンの K/V は前のステップですでに計算済みで変化していないため、すべて再計算するのは無駄です。

これが前節で計算結果を GPU に保存する理由です。各トークンの計算済み Key と Value ベクトルをキャッシュしておき、次のトークン生成時にそのまま再利用し、新しいトークンに対してのみ Q/K/V を計算します。先ほどの行列の例でこのプロセスを説明します。

Prefill フェーズ、3つの input token を一括処理し、K/V 行列を構築:

K cache:              V cache:
[I_K   ]  [0.5, 1.1]    [I_V   ]  [0.8, 0.2]
[went_K]  [1.0, 0.4]    [went_V]  [0.3, 0.7]
[bank_K]  [0.8, 0.9]    [bank_V]  [0.6, 0.5]

Decode 第1ステップ、モデルが "account" を生成:
account 自身の Q/K/V のみを計算し、K/V をキャッシュに追加:

K cache:              V cache:
[I_K      ]              [I_V      ]
[went_K   ]              [went_V   ]
[bank_K   ]              [bank_V   ]
[account_K]  ← 新規追加   [account_V]  ← 新規追加

account の Q とキャッシュ内の全4つの K で内積 → 注意力スコア → V の加重和

Decode 第2ステップ、モデルが "balance" を生成:
同様に balance 自身の K/V のみを計算し、1行追加。Q と5つの K で内積。

各ステップで1行追加するだけで、古いものは再計算しません。これは同一リクエスト内部の高速化メカニズムで、推論エンジンが自動的に処理します。

KV Cache 図:KV Cache は生成されたトークンごとに逐次蓄積——Token 1 が [K1,V1] を作成、Token 2 が [K2,V2] を追加、後続のトークンは自身の K/V を計算して追加するだけ(出典:Hugging Face KV Caching Explained)

Prefill vs Decode:コストはどこに

フェーズ内容計算量対応する費用
Prefill全 input tokens を一括処理O(n^2)、n = input 長Input token 費用(Opus 4.6: $5/MTok)
Decodeoutput tokens を1つずつ生成新トークンごとに O(n)Output token 費用(Opus 4.6: $25/MTok)

Prefill が高コストなのは、プロンプト全体を一括処理するためです。60k トークンのコンテキストを送信すると、各層で 60k × 60k の attention 行列を計算する必要があります。Output の単価が高い($25 vs $5)のは、Decode フェーズでは GPU 使用率が低く、毎回1トークンしか生成しないため Prefill のような大規模並列処理ができず、プロバイダーがハードウェアの遊休コストを補うために output 単価を高く設定しているためです。

ここで疑問が生じます。今回のリクエストと前回のリクエストで input の前半部分が完全に同じ場合(system prompt、ツール定義、プロジェクトルールがすべて変わっていない場合)、その部分の Prefill 計算をスキップできないか。

できます。それが Prompt Cache です。


各種 Cache の違い

開発者は日常的にさまざまな Cache を扱いますが、LLM の文脈での “Cache” は普段使っているものとは少し異なります。私も大規模言語モデルの動作原理を理解してから、ようやくこれらを整理できました。

開発者にとって馴染みのある Cache

Cache場所キャッシュ対象
ブラウザキャッシュクライアントCSS/JS/画像;Cache-Control ヘッダーで制御
CDN キャッシュエッジノードHTTP レスポンス
Redis / Memcachedアプリケーションサーバーデータベースクエリ結果、計算結果
データベース Buffer Poolデータベース内部ホットデータページ

これらの Cache には共通点があります。キャッシュしているのは「結果」です。入力が同じなら、前回の結果をそのまま返し、計算をスキップします。

LLM の世界の Cache

LLM 推論には、私たちにとって重要な2種類の Cache があります。キャッシュしているのは最終回答ではなく、中間計算状態です。

KV Cache は同一リクエスト内部の高速化です。第101トークンを生成する際、前の100トークンの K/V はすでに計算済みなので、そのまま再利用します。ドキュメントを書いている時の「短期記憶」のようなもので、前に書いた内容を最初から読み直す必要がありません。これはユーザーが制御できるものではなく、推論エンジンが自動的に処理します。

Prompt Cache(Prefix Cache とも呼ばれます)はリクエスト間で Prefill 計算を再利用するものです。今回のリクエストの input 前半が前回と同じであれば、そのプレフィックスの Prefill をスキップし、前回計算済みの K/V をそのまま再利用します。マニュアルの最初の50ページを昨日読んだのであれば、今日は51ページから読み始めるだけで済みます。Cached Input が10倍安くなる理由はここにあります。最もコストの高い Prefill 計算をスキップするためです。

もう1つ Semantic Cache があります。これはアプリケーション層のミドルウェアで、新しい質問が以前の質問と「意味的に十分類似」していれば、API を呼び出さずに古い回答をそのまま返します。これは Redis により近く、最終結果をキャッシュしています。FAQ やカスタマーサポートには有効ですが、Coding Agent には向いていません。コードは常に変化しており、「意味的に類似した質問」でも異なるコードバージョンでは回答が完全に異なるためです。

Cacheキャッシュ対象リクエスト間?制御可能?請求への影響
KV Cache現在のリクエストで計算済みの K/V不可不可透過的(推論高速化)
Prompt Cache同一プレフィックスの Prefill K/V可能一部可能cached input 料金を直接決定
Semantic Cache意味的に類似した質問の旧回答可能完全に可能API 呼び出し全体をスキップ

Prompt Cache の核心ルール:プレフィックスが完全一致であること

最初のトークンから1つずつ比較します。ある位置で差異が生じると、そこから後ろはすべて cache miss になります。

リクエスト A: [system prompt][tools][rules][history A][user message A]
リクエスト B: [system prompt][tools][rules][history B][user message B]
              ↑ この部分が同一 → cache hit    ↑ ここから異なる → miss

プロバイダーごとにメカニズムが異なります。Anthropic では明示的に cache_control breakpoint と TTL(5分/1時間)を設定でき、最初の cache write は通常の input より1.25〜2倍高コストですが、以降の read は0.1倍です。OpenAI は同一プレフィックスを自動検出し、cached input 0.1倍、追加の cache write 費用はありません。GitHub Copilot はベースとなるモデルの cache メカニズムを利用し、ユーザーから見えるのは AI Credits 内で cached input がより安いという点です。

Cache に影響を与えるもの

プレフィックスが完全一致である必要があるため、前方の内容を変更すると Cache のヒットに影響します。コミュニティでまとめられた要因は以下の通りです。

Cache キラー理由対処法
system prompt 内のタイムスタンプ毎秒変わるタイムスタンプをメッセージ末尾に移動
MCP ツールの登録順序がランダムツールリストが毎回異なる登録順序を固定
ランダムな few-shot サンプルサンプルの配列が変化サンプルセットと順序を固定
session ID がプレフィックスに埋め込みセッションごとに異なるサフィックスに移動
頻繁な compact/summarize要約が毎回異なる → 新しいプレフィックスcompact をできるだけ遅延
未使用の MCP ツールが未整理プレフィックス空間を無駄に占有定期的に整理

分かりやすい例を挙げます。私の Claude Code 環境には40以上の MCP ツールが登録されており、ツール schema だけで約8〜10k tokens を占めます。これらの schema の順序が毎回異なると、後ろの50k tokens がどれだけ似ていても miss になります。逆に順序を固定すれば、この8〜10k tokens は安定してキャッシュにヒットするプレフィックスとなり、毎回0.1倍の価格で済みます。

この認識は私の最適化の考え方を変えました。system prompt を短くするのはもちろん良いことですが、より効果的なのはそれを安定させ、常にキャッシュにヒットさせることです。

コミュニティには cache アライメントの問題を専門に解決するツールがあります。claude-code-cache-fix(約1,800 stars, MIT)は、Claude Code の --resume session が cache regression を引き起こすことを発見しました(micro-compression 時に埋め込まれるタイムスタンプが毎回異なり、プレフィックスバイトが変化する)。ローカルプロキシで sentinel を固定フォーマットに正規化することで、cache hit rate を82.3%から95.5%に向上させました。

Claude Code でサードパーティのローカルモデルを接続している場合、さらに直接的な cache キラーがあります。Claude Code は各リクエストの先頭に attribution header を追加しますが、このヘッダーは毎回変わります。Anthropic 自体の API にとっては問題ありませんが、ローカル推論サーバーにとってはプレフィックスが変わるため KV Cache がすべて無効になり、毎回最初から Prefill する必要があります。実測データによると、Qwen2.5-Coder 14B がコンシューマーGPUで6k トークンコンテキストの場合、最初のトークンのレイテンシが1.8秒から24秒に跳ね上がり、cache ヒット率がゼロになり、スループットが約90%低下しました。修正方法は ~/.claude/settings.json の env に "CLAUDE_CODE_ATTRIBUTION_HEADER": "0" を追加することです(シェルの export では効かず、settings ファイルに書く必要があります)。


Cache から Context Engineering へ

ここまでの内容から感じ取れるように、Prompt Cache の層で私たちができることは比較的限られています。プレフィックスの順序を固定する、不要な MCP を整理する、attribution header をオフにする。これらを済ませればキャッシュヒット率はすでに十分高くなります。コミュニティのオープンソースツールの大部分も cache 層で工夫しているわけではなく、別の層に集中しています。それは、コンテキストに入る内容の総量をいかに減らすか、そしてモデルに少ない発話で十分なコードを出力させるにはどうすればよいか、という点です。

2025年半ば、Context Engineering という言葉が頻繁に登場し始めました。Anthropic はエンジニアリングブログ “Effective context engineering for AI agents” で体系的に解説し、核心的な主張はコンテキストウィンドウを希少資源として管理し、必要に応じて読み込み、事前読み込みしないことです。LangChain の Lance Martin は具体的な操作を4つのカテゴリに分類しました。Select(関連情報を取り込む)、Compress(トークンを削減する)、Isolate(独立したウィンドウに分離する)、Write(ウィンドウの外に保存する)。以降はこのフレームワークに沿って展開します。


Select:正しい情報を取り込む

これは Context Engineering の中で最も重要かつ複雑なステップです。コードベースは数十万行に及ぶ可能性がありますが、Agent がこの1ラウンドで見る必要があるのは500行かもしれません。その500行をどう見つけるか。

市場には2種類のソリューションがあります。1つ目は Cursor に代表される Indexing、2つ目は Claude Code に代表される Grep です。

Codebase Indexing

Indexing のアプローチは、コードベースにあらかじめクエリ可能なインデックスを構築し、Agent が一発で目的のコードにたどり着けるようにすることです。現在市場に出ているソリューションを原理別に分類しました。

Embedding ベクトルインデックス

コードをチャンクに分割し、セマンティックベクトルを生成してベクトルデータベースに格納し、クエリ時にセマンティック類似度で関連コード断片を検索します。

ツールStarsLicense特徴
Claude Context (Zilliz)11.3kMITAST chunking + Milvus ベクトル DB + hybrid BM25+ベクトル検索;OpenAI/VoyageAI/Ollama embedding 対応
CocoIndex Code1.7kApache-2.0軽量;AST-aware chunks + ローカル SentenceTransformers;インクリメンタルインデックス
SeaGOAT1.3kMIT完全ローカル;ChromaDB + ripgrep ハイブリッド検索;クラウド API 不要
claude-context-local229GPL-3.0Claude Context の純ローカル版;EmbeddingGemma + FAISS;API コストゼロ

データセキュリティに敏感なプロジェクトでコードをクラウドに送信したくない場合は、SeaGOAT または claude-context-local がより安全な選択です。マルチリポジトリ・マルチ言語サポートが必要なら Claude Context が最も機能豊富です。

Cursor や Augment の Index 機能も同じ原理です。ただし、Embedding でインデックスを構築するため、Embedding の問題はそのまま当てはまります。例えば、

  • 同義語/社内用語の問題:“billing” で検索しても、コード内で “subscription”、“metering”、“invoice” と呼ばれている可能性があります。Embedding モデルは汎用コーパスで訓練されており、社内の用語テーブルを必ずしも理解しません。“login” で検索しても SessionCreation という関数が見つからないかもしれません。
  • 確率的な結果:セマンティック検索が返すのは「最も類似した」結果であり、「最も正しい」結果ではありません。高い confidence の誤った回答は、見つからないよりも危険です。Agent がその結果に基づいてそのまま進めてしまうためです。

AST / ナレッジグラフ

このカテゴリのツールは Tree-sitter でコードの AST(抽象構文木)を解析し、関数、クラス、呼び出し関係、継承関係を抽出してグラフを構築します。

ツールStarsLicense特徴
Graphify48.6kMITTree-sitter (20言語) + LLM セマンティック抽出 → マルチモーダルナレッジグラフ;NetworkX + Leiden クラスタリング
GitNexus37.9kMITTree-sitter → KuzuDB グラフデータベース;完全 WebAssembly クライアント実行;Graph RAG Agent
code-review-graph15.6kMITインクリメンタル変更検出 → blast radius 分析;6.8x fewer tokens on reviews, 49x on daily coding と主張
CodeGraph2.2kMITTree-sitter → SQLite + FTS5;Claude Code MCP;ファイルシステム watch によるインクリメンタル同期
Aider Repo Map41.6kApache-2.0Tree-sitter シンボル抽出 → 有向グラフ → PageRank ランキング;トークン予算内で二分探索で最重要な定義を選出

すでに Claude Code を使用している場合、CodeGraph は MCP 経由で直接接続でき、最も手軽に始められます。多言語の大規模コード理解が必要な場合は Graphify のカバー範囲が最も広いです。Aider のソリューションは、完全ローカルで外部サービスに依存したくないシナリオに適しています。

Aider のアプローチは詳しく見る価値があります。ベクトルデータベースも embedding も使わず、PageRank でコードシンボルの重要度をランク付けします。現在のチャットで言及されたファイルの重みは50倍、アクティブな識別子の重みは10倍です。そしてトークン予算内(デフォルト1024 tokens)で二分探索により最上位の定義を選出し、簡潔なツリー構造としてモデルに提示します。完全ローカル、各メッセージで再計算、結果は決定的です。

Grep:Claude Code がなぜ Index を使わないのか

Index と AST グラフを見た後、自然な疑問は「Claude Code はなぜ codebase indexing をしないのか?」です。

答えは、試したが断念した、というものです。Claude Code の初期バージョンでは RAG + ローカルベクトルデータベースを使用していましたが、チームは agentic search(grep + glob + read)の方が RAG よりも一貫して優れていることを発見しました。Boris Cherny(Claude Code の創設エンジニア)が複数の場で理由を説明しています。2026年の Amazon Science の論文も裏付けを提供しており、キーワード検索は agentic tool use を通じて RAG の90%以上の効果を達成でき、ベクトルデータベースは不要とされています。

grep の優位性はいくつかの点にあります。

  • ゼロ設定:インデックス不要、embedding モデル不要、ベクトル DB 不要。clone してすぐに検索できます。
  • 究極の鮮度:Agent が書いたばかりのコードを、次の瞬間には grep で検索できます。Index には5〜10分の遅延があり、古い index は Agent を誤った方向に導きます。
  • 全フォーマット対応:YAML、Dockerfile、.env、Markdown、設定ファイル、grep ならすべて検索できます。Index や LSP は通常、コードファイルのみカバーします。
  • 障害モードが穏やか:grep の最悪ケースは結果が多すぎること(ノイズ)で、Agent はフィルタリングできます。Index や LSP の設定が誤っている場合や依存関係が不足している場合、空の結果を返す可能性があり(Agent は関連コードがないと判断)、この false negative は false positive よりもはるかに危険です。

grep の代償も明確です。

  • トークン消費が多い:“billing” で検索すると200行返され、大部分はノイズですが、すべてコンテキストに入ります。数ラウンド後にはコンテキストが無関係なコードで溢れます。
  • 同義語に対応不可:“billing” で検索しても “subscription” というコードは見つかりません。この点は embedding と同様に問題がありますが、失敗の仕方が異なります。
  • 大規模リポジトリで遅い:Cursor のエンジニアリングチームが報告しているように、ripgrep の呼び出しが大きな monorepo で15秒を超えることがあります。

ここまでで明確な階層が見えてきます。Embedding Index は「おそらく関連するコードを見つける」もの、AST グラフは「コード間の構造的関係を理解する」もの、grep は「キーワードでその場で検索する」ものです。三者にはそれぞれ長所と短所がありますが、共通の精度の問題があります。grep は200のテキストマッチを返しますが、そのうち本当に関数呼び出し箇所なのは3つだけで、残りはコメント、文字列、テスト内の偶然の同名です。Embedding は「意味的に最も類似した」結果を返しますが、間違っている可能性があります。AST グラフは構造を理解しますが、動的言語のリフレクションやランタイム動作はカバーできません。

コンパイラの理解を直接使って「この関数はどこで呼び出されているか」に答える方法はないか。あります。それが LSP です。

LSP:Agent にコンパイラの目を与える

LSP(Language Server Protocol)は Microsoft が2016年に VS Code 向けに設計したプロトコルです。それ以前は、各 IDE がすべての言語のインテリジェント機能(補完、ジャンプ、リファクタリング)を自前で実装する必要があり、膨大な作業量でした。LSP のアイデアは「言語インテリジェンス」を独立したバックエンドサービス(Language Server)として抽出し、IDE が標準化プロトコルで通信するというものです。TypeScript には tsserver、Rust には rust-analyzer、Python には pyright、Go には gopls があります。LSP プロトコルをサポートする任意のエディタでこれらの機能を利用できます。

AI Agent にとって、LSP はコンパイラレベルの正確なナビゲーションを提供します。grep “calculateUsage” は純粋なテキストマッチングで、文字列が関数名、変数名、コメント、文字列リテラルのいずれかを知りません。LSP の find-references は型システムと構文解析を通じて、セマンティック層の真の呼び出し箇所のみを返します。go-to-definition は一発で関数定義にジャンプし、200件の grep 結果から探す必要がありません。hover は型シグネチャを直接提示し、ファイル全体を読む必要がありません。

コミュニティで再現可能なベンチマークが実施され、5つのコードベース、13タスク、3言語でテストした結果、LSP は grep に比べて5〜34倍のトークンを節約しました。節約幅はコードベースのサイズに正比例します。15k行のプロジェクトで5倍、319k行のプロジェクトで34倍です。理由は直感的で、grep の結果量はコードベースに比例して線形増加しますが、LSP が返す参照数は実際の呼び出し箇所にのみ関連し、コードベースのサイズには無関係です。

方法プロセストークン消費
grepgrep calculateUsage → 200以上の結果 → 1つずつ read → 5ラウンド後に発見~12,000
LSP find-references1ステップで3つの正確な呼び出し箇所を返す~500

各 AI coding ツールの LSP サポートには大きな差があります。OpenCode は LSP をコアアーキテクチャとして位置づけ、30以上の事前設定済み言語サーバーを内蔵し、対応するファイルタイプを開くと自動的にダウンロード・インストールされ、Agent は diagnostics、hover、go-to-definition、find-references、call hierarchy を直接利用できます。Claude Code にも内蔵 LSP サポートがあり(11言語、ENABLE_LSP_TOOL=1 の設定が必要)、ただし実際のトリガー率は低く、コミュニティからのフィードバックでは “I haven’t come across a case where it has used the LSP yet” との声があります。Claude Code で LSP を強制的に使用したい場合は、cclsp(637 stars, MIT)を MCP bridge としてインストールし、enforcement-kit(294 stars, MIT)で hooks を使って grep 呼び出しをインターセプトできます。

LSP の問題も明確です。

  • リソース消費が大きい:Language Server は常駐メモリです。TypeScript プロジェクトの tsserver は2〜4GB のメモリを消費し、大規模プロジェクトの rust-analyzer は初期化に30〜60秒かかります。OpenCode で数十の言語サーバーをすべて起動すると、マシンが明らかに重くなります。OpenCode が通常特に重い理由の1つです。
  • 動的言語の精度が低い:Python の getattr、Ruby の method_missing、JavaScript の動的 import は LSP からは見えません。LSP は静的解析に依存しており、ランタイムの動作は把握できません。
  • 非コードファイルはカバーできない:YAML、Dockerfile、Markdown、設定ファイルでは LSP は役に立ちません。grep の方がこれらのシナリオでは有用です。
  • エディタ向けに設計されており、Agent 向けではない:LSP のインタラクションモデルはカーソル位置に基づく1回1操作で、Agent が必要とするのはバッチ的なクロスファイルクエリです。このミスマッチには現時点で良い解決策がありません。
  • Agent が自発的に使わない:強制しなければ、Agent は LSP をスキップして直接 grep を使います。grep の呼び出しの方がシンプルだからです。enforcement-kit のような hook はこの問題を解決するためのものです。

私の暫定的な判断としては、静的型付け言語(TypeScript、Rust、Go、Java)では LSP を有効にすべきで、投資対効果が明確です。特に OpenCode のようなすぐ使える環境ではなおさらです。動的言語のプロジェクトや小規模プロジェクトでは、良い CLAUDE.md と grep の組み合わせの方がより現実的かもしれません。

ビジネスコードマップ:最も信頼性の高いコンテキスト

どんな Index よりも信頼性が高い方法は、人間の知識を直接 Agent が読める文書として書くことです。

CLAUDE.md / AGENTS.md / .cursorrules はすべて同じことをしています。Agent に「このプロジェクトのエントリポイントはどこか、ビジネス概念は何と呼ばれているか、よくあるハマりどころはどこか、詳細はどこで調べるか」を伝えるのです。Anthropic はブログでこれを “always-loaded context” と呼んでいます。

良い CLAUDE.md は道標であり、百科事典ではありません。「Agent がタスクを受けた後、最初に知る必要があるのは何か」に答えるべきであり、すべてのモジュールのドキュメントを詰め込むべきではありません。

## Architecture
- エントリ:src/api/routes.ts
- ビジネスロジック:src/services/
- 課金関連:src/billing/(src/payments/ ではない)

## Domain Glossary
- plan = ユーザー側プラン、subscription = 経理側サブスクリプション
- metering = 使用量収集(≠ billing)
- usage_event ≠ usage_summary(生イベント vs 集約)

## Common Pitfalls
- src/generated/ 配下のファイルは変更しないこと
- billing の単体テストには mock clock が必要
- npm run test:unit を使うこと、npm test は使わないこと(後者は全量 e2e を実行)

なぜこれが Index より安定するのか。確定的だからです。Agent が “billing は src/billing/ にある” と読めば、リポジトリ全体を grep する必要がなくなります。節約されるのはわずかなトークンではなく、3〜5ラウンドの無効な探索です。しかも stale にならず(メンテナンスする人がいる限り)、embedding も外部サービスも不要です。

コミュニティではこの方向でいくつかのコンセンサスが形成されています。最も影響力があるのは Karpathy の CLAUDE.md 規範(142k+ stars)です。Karpathy は、AI Agent がコードを書く際に繰り返し発生する4つの問題を観察しました。間違った仮定を黙って立てて検証しない、単純な問題を過度に抽象化する、変更すべきでないコードを変更する、検証基準を定義せずに書き始める、という4つです。これらの4つのルールにより Agent のエラー率は41%から11%に低下しました。

コミュニティはその後、これをベースに複数回の改良を行いました。Mnilax が30のコードベースで6週間テストした後、agent fights、hook cascades、skill loading conflicts、multi-step workflow drift など、原版で扱われていなかった問題をカバーする8つのルールを追加し、エラー率をさらに3%まで低下させました。彼の重要な見解の1つは、prompt の指示は提案であり、hooks こそが強制実行であるということです。コードで強制できるルールは prompt に頼るべきではなく、80%の prompt 遵守 + 20%の hooks によるフォールバックが、より現実的な作業方法です。

CLAUDE.md の書き方については、重要なコスト制約があります。Anthropic は200行以内に抑えることを推奨しています。200行は約1,500〜2,000 tokens で、各リクエストのプレフィックスに注入されます。500行に膨張すると、毎ラウンド5,000 tokens の税金になります。多くのチームが、Agent がもともと知っていること(“TypeScript でコードを書いてください” など)を書いてしまい、トークンを消費しながら何も変わっていないということがあります。Agent がコードから推論できない情報のみを書くべきです。アーキテクチャの決定、ビジネス用語、チームの取り決め、既知のハマりどころなどです。

ゼロから書きたくない場合、自動生成のソリューションもあります。Caliber はプロジェクト構造、依存関係、コードパターンをスキャンして CLAUDE.md を自動生成します(.cursorrules と MCP server 設定も同時に生成)。Claude Code には /init コマンドも内蔵されており、コードベースから初期の CLAUDE.md を生成できます。ただし、自動生成の結果は通常、手動でトリミングする必要があります。ジェネレーターは発見できるものをすべて書き込む傾向があり、200行の予算を超えやすいためです。

Skill/MCP Triage

前述の Index、Grep、LSP は「正しいコードをどう見つけるか」を解決するものです。しかし Coding Agent のコンテキストにはコードだけでなく、大量の MCP ツール定義と Skill 指示も含まれています。私の Claude Code 環境を計算してみたところ、40個の MCP ツールが登録されており、schema だけで約8〜10k tokens を占め、毎回のリクエストでその分の費用を支払っています。

ここで解決すべき問題は2つあります。1つは Skill のように MCP でプログレッシブディスクロージャーを行う方法(あるいはそもそも MCP を廃止して CLI に置き換え、schema がコンテキストを消費する問題をなくすこと)。もう1つは、Skill 自体が増えていった場合に、Skill にもプログレッシブディスクロージャーを適用する方法です。

MCP ツールの Triage

Claude Code には ToolSearch メカニズムが内蔵されており、自動的に有効化され、手動設定は不要です。Claude Code はすべての defer 可能なツール定義の総トークン数を計算し、コンテキストウィンドウの10%を超えると自動的に deferred loading を開始します。無効の場合、147個のツール定義が約 90k tokens 各リクエストに注入されます。有効にすると、約25個のコア内蔵ツールと1つの ToolSearch ツールのみが保持され、約15k tokens に削減、95%の削減です。Agent が defer されたツールを必要とする場合、まず ToolSearch(BM25 または regex でツール名と説明を検索)を呼び出し、3〜5個の候補を取得して完全な定義に展開してから呼び出します。

ToolSearch の代償は1回追加の呼び出し(検索してから使用)で、検索品質はツールの名前と説明の書き方に依存します。コミュニティからのフィードバックでは、内蔵ツールが誤って defer され機能が劣化するケースが報告されています。

OpenCode も MCP 層で同様のことを行おうとしています。PR #12520 で mcp_search によるオンデマンド発見が実装され、7以上の MCP server の67k tokens の起動コストを約350 tokens に削減することを目標としています。執筆時点ではまだマージされていません。

コミュニティでは MCP triage に関するさまざまなソリューションが開発されており、原理別に分類できます。Schema 圧縮はツール記述自体を短縮するもの、遅延読み込みは2〜3個の meta-tools ですべてのツールを置き換え必要に応じて完全な schema を取得するもの、Code Mode はさらに過激で、1〜2個の実行ツールのみを公開し Agent がバックエンドを呼び出すコードを書くものです。

ツールStarsLicense原理特徴
IBM ContextForge3,747Apache-2.0Gateway + 圧縮MCP/A2A/REST 統一ゲートウェイ;TOON フォーマットでツール出力を圧縮
Headroom1,924Apache-2.0出力圧縮ツール返値を圧縮(60-95%)、schema 自体は非圧縮;可逆
1MCP440Apache-2.0遅延読み込みinstructions → inspect → run 3ステップのプログレッシブディスカバリー
One MCP392MITプロキシ集約複数 MCP server を単一エンドポイントに統合;Service Groups を Skills としてエクスポート
mcp-server-code-execution-mode333GPL-3.0Code Moderun_python のみ公開(約200 tokens);Agent が Python でバックエンドツールを呼び出す
MCPProxy227MIT遅延読み込みretrieve_tools セマンティック検索;約99% トークン削減;組み込みセキュリティ隔離
mcp-funnel153MITフィルタ + 遅延読み込みhideTools ホワイトリスト/ブラックリスト(glob);オプションの discover_* meta-tools
Forgemax149CustomCode ModeN server × M ツールを2つのツール(search + execute、約1,100 tokens 固定)に圧縮;V8 サンドボックス実行

Skill の Triage

Skill(.md 形式の指示ファイル)にもトークン膨張の問題があります。Anthropic 公式の Agent Skills 仕様では3段階のプログレッシブディスクロージャーが定義されています。Level 1 は system prompt に名前と説明のみ配置(約50〜100 tokens/skill)、Level 2 は Skill tool を通じてオンデマンドで全文を読み込み、Level 3 はオンデマンドで resources を読み込みます。各主要 coding agent はすでにこのメカニズムを内蔵しており、skill の全文はプリロードされません。ここまでで問題は解決したように見えます。

実際に多くインストールすると、そうではないことが分かります。

問題は metadata 自体にあります。skill 全文はプリロードされませんが、各 skill の名前と説明は依然として system prompt に注入されます。コミュニティではこの「発見の天井」を掘り下げた人がいます。Claude Code は available_skills にトークン予算の上限を割り当てており(リバースエンジニアリング分析によるとコンテキストの約1%、最低8,000文字)、各 skill の説明は最大250文字で切り捨てられます。8,000 ÷ 250 = 最大約32個の skill が効果的にマッチングされます。これを超えると説明が短すぎ、Agent がマッチングできず無視します。63個の skill をインストールした人が確認したところ、セッションに表示されたのは42個のみで、残りは予算で切り捨てられました。Google Workspace CLI は95個の skill をインストールし、毎ラウンドの metadata だけで2,007 tokens を消費します。

skill を多くインストールするとトークンの無駄だけでなく、Agent のパフォーマンスも低下します。Vercel の評価では、Agent が56%の確率で関連するインストール済み skill を無視し、skill をインストールした方がベースラインよりも悪化する結果となりました(テスト通過率58% vs 63%)。使用されない skill がコンテキスト内でノイズを発生させるためです。Perplexity も skill 設計ガイドで同様の判断を示しています。「Skill を1つ追加するたびに、他のすべての Skill のパフォーマンスが低下する可能性がある」。実験データは示していませんが、メカニズムを説明しています。各新規 skill の説明がルーティング時に既存の skill とモデルの注意力を競い合い、誤ったアクティベーションを引き起こす可能性があるのです。また、単一の skill 内部の構成方法も重要だと指摘しています。米国税法の全1,945セクションを1つのフォルダ(1つの skill)に入れると、モデルのパフォーマンスはその skill をインストールしない場合よりも悪化し、論理的に階層化して整理する(多段ディレクトリ + クイックリファレンスガイド + カスタム検索ツール)必要があるとしています。

現在コミュニティではこの天井に対して3つの対処方針があります。

数量の制御。skill は約30個以内に抑え、それを超えると発見率が低下します。大量の skill をインストールしてどれが使われているか不明な場合、Token Optimizer(1,051 stars, PolyForm NC)で実際の使用状況を監査し、一度も発動していない skill や hook を整理できます。監査 + 整理で44%のオーバーヘッド削減を達成した例もあります。

ネイティブインデックスを回避し、外部検索で代替。発見の天井に関するブログの著者は PreBrief というローカルデーモンを開発しました。小型モデルですべての skill をベクトルに embed し、ユーザー入力時にセマンティック検索で該当する skill のみを prompt に注入し、同時に元の skill を disabled ディレクトリに移動してネイティブインデックスを回避します。OpenCode 側では、opencode-triage(MIT)が hooks ですべての skill を非表示にし、triage({ query }) でキーワードマッチングルーティング(IDF 重み付けとスペル修正付き)を行い、19個の skill を1,226 tokens から59 tokens に削減(95%)しています。

プリインストールせず、必要時に発見。Google Cloud のエンジニアが Dynamic Skills Agent を開発しました。skill をまったくプリインストールせず、Agent が特定の能力を必要とした時に searchAgentSkills で信頼できる GitHub リポジトリからオンデマンドで検索・インストールします。metadata のオーバーヘッドはゼロで、代償は初回使用時に検索とインストールの1ラウンド分の遅延が発生することです。

3つの方向はいずれもまだ実験段階です。現時点で最も現実的なアプローチは、skill 数の制御 + 定期的な監査・整理です。

CLI による MCP の代替:進行中のトレンド

さらに過激なアプローチもあります。MCP を使わず、CLI コマンドで代替するというものです。これなら schema 税の問題は根本的に存在しません。

Scalekit がベンチマークを実施し、同じ GitHub 操作で gh CLI は1,365 tokens、GitHub MCP server は44,026 tokens でした。32倍です。理由は GitHub MCP server が43個のツールを公開し、毎回のリクエストでこの43個のツールの完全な schema がコンテキストに含まれるためで、実際に使用するのは1つだけでも同じです。CLI には schema 税がなく、Agent はトレーニングデータから gh コマンドの使い方を知っているため、1回で完了します。月10,000回で計算すると、CLI は約 $3.20、MCP は約 $55.20 です。

Google の対応がこのトレンドを最もよく示しています。2026年3月に Google Workspace CLI(gws)を発表し、Drive、Gmail、Calendar、Sheets、Docs のすべての Workspace API をカバーしました。同時期に1,151行の MCP server コードを書き上げましたが、2日後にすべて削除し、CLI として発表しました。

MCP の価値はガバナンス能力にあります。per-user OAuth、ツールレベルの権限境界、構造化された監査ログです。しかし日常の開発では、コマンドラインの権限は開発者本人の権限に由来するものであり、うっかり rm -rf しない限り、より細かい権限制御はオーバーエンジニアリングです。

私も CLI で済むなら MCP は使わない方針です。Github、Jira、Azure DevOps、Supabase、AWS、Google Workspace にはすべて公式またはサードパーティの CLI ツールがあります。本当に CLI がない場合は、公式 API doc をローカルに取得し、Claude/Agents.md にこのツールを使いたい場合は直接 Curl コマンドを送信するよう明記する方法があります。最後の手段として MCP を検討します。


Compress:既存コンテキストのトークン数を削減する

コンテキストがすでに膨張した場合はどうするか。圧縮です。しかしここには核心的な矛盾があります。圧縮とキャッシュは対立関係にあるのです。圧縮は履歴を変更して短縮する必要があり、キャッシュは履歴が変わらないことを要求します。加えて、個人的な感覚とチームメンバーのフィードバックによると、コンテキスト使用率が80%に達した時点で、Agent はすでに的外れなことを言い始めます。そのため最善の方法は、コンテキストが完全に埋まってから圧縮することではありません。戦略として、予防は圧縮よりもはるかに重要です。

予防型ツール(Cache を破壊しない)

この種のツールは、コンテンツがコンテキストに入る前に圧縮し、既存の履歴には手を加えません。

ツールStarsLicense圧縮対象原理圧縮率
RTK49.2kApache-2.0CLI コマンド出力Rust バイナリが Bash をインターセプトし、出力をセマンティックに書き換え80%(session 合計)
Context Mode~15kELv2ツール実行結果サンドボックス実行、生データはコンテキストに入らず、SQLite + FTS5 で保存98%(自称)
lean-ctx1.7kApache-2.0CLI 出力 + ファイル読み取り + MCPShell hook + MCP server + Tree-sitter AST60-95%(cached re-read 約13 tokens)
Headroom1.8kApache-2.0コンテキストに入るすべてのコンテンツlibrary/proxy/MCP、CacheAligner でプレフィックスを整合、可逆圧縮87%(10,144→1,260 tokens)

カバー範囲が異なり、これが選択の鍵です。RTK は Bash 出力のみで、Read/Grep/Glob や MCP の戻り値には触れません。Context Mode はツール実行結果を管理しますが MCP の JSON-RPC レスポンスはインターセプトできません。lean-ctx は最もカバー範囲が広く(Shell + Read + MCP の3チャネル)、Headroom は cache アライメントを積極的に考慮する唯一のツールです。

RTK:CLI 出力圧縮

RTK (Rust Token Killer)(GitHub, 49.2k stars, Apache-2.0)は、この分野で現在最も使われているツールです。Rust で書かれた CLI プロキシで、シェルコマンドの出力をインターセプトし、コンテキストに入る前にセマンティックな書き換えを行います。gzip のような汎用圧縮ではなく、コマンドの意味を理解した上で精緻化します。50個の同一 ESLint エラーが1行の “ESLint: 50 errors in src/components/ (no-unused-vars)” に変わり、テスト出力は失敗項目とサマリーのみ保持します。

インストールは簡単です。rtk init -g の1コマンドで、インストール後すべての Bash 呼び出しが透過的に RTK を通過します。

RTK の README にある30分間セッションのベンチマークを、コマンドタイプ別に見ると以下の通りです。

コマンドタイプ圧縮率
ディレクトリ一覧 (ls/find)80%
ファイル読み取り (cat/head)70%
検索 (grep/rg)80%
Git (status/log/diff)92%
テスト (npm test/pytest)90%
Session 合計80% (~118k → ~24k tokens)

Git とテストの圧縮率が最も高いのは、出力が最も重複しているためです。100行の diff のうち、本当に気にする変更はわずか5行かもしれず、200行のテスト出力で重要な情報は最後の3行 “3 failed, 47 passed” だけかもしれません。

ただし RTK にも明確な制限があります。圧縮するのは現在のラウンドのコマンド出力のみで、既存の履歴には触れません。50ラウンド / 150k token のセッションでは実際に節約されるのは約1.6%です。Claude Code 内蔵の Read/Grep/Glob の出力も圧縮できません(Bash hook を通らないため)。

Context Mode:サンドボックス実行

Context Mode(GitHub, 約15k stars, ELv2)はまったく異なるアプローチを取っています。核心的な考え方は、生データがコンテキストウィンドウに入ることは一切ないということです。

6つの MCP sandbox tools を提供し、Agent が本来直接使用するツールを置き換えます(ctx_execute、ctx_batch_execute、ctx_execute_file、ctx_index、ctx_search、ctx_fetch_and_index)。データフローは以下の通りです。

  • ツールが隔離された子プロセスで実行される
  • 生の出力がすべてローカルの SQLite に書き込まれる(FTS5 全文索引付き)
  • LLM に返されるのは1〜2行のサマリーのみ(コマンドステータス、出力行数、重要情報)
  • 詳細が必要な場合、Agent が ctx_search を呼び出して BM25 でオンデマンド検索

具体的な効果:Playwright ページスナップショット 56KB → 5.4KB、700KB ファイル読み取り → 3.6KB。

PreCompact Hook も搭載されています。/compact がトリガーされる前に、重要な状態(アクティブファイル、実行結果、作業進捗)を自動的に SQLite にリカバリースナップショットとして保存し、新しいセッション起動時に自動注入され、Agent はブレークポイントから続行できます。

制限事項:

  • ELv2 license(社内利用は可能、ホスティングサービスとしての提供は禁止、OSI のオープンソース定義に準拠しない)
  • MCP tool レスポンスのインターセプト不可(JSON-RPC がモデルに直達し、Context Mode には中間層がない)
  • 3ヶ月で136バージョン、コミュニティでは安定性を疑問視する声あり
  • HN フロントページで570ポイント、注目度は高いが実運用のフィードバックはまだ少ない

lean-ctx:全チャネル圧縮

lean-ctx(GitHub, 1.7k stars, Apache-2.0)と RTK の最も重要な違いはカバー範囲です。RTK は Bash 出力のみを管理しますが、lean-ctx は3つのチャネルを同時にカバーします。

  • Shell hook でコマンド出力を圧縮(RTK と類似)
  • MCP server でファイル読み取りとコード分析を圧縮(RTK では不可)
  • Tree-sitter AST(21言語)でコード構造を理解した上でセマンティックレベルの圧縮

ファイル読み取りに関しては、lean-ctx は10種類の read mode を提供します。

  • full:完全な内容
  • map:ファイル構造の概要のみ返す
  • signatures:関数/クラスのシグネチャのみ抽出
  • diff:変更部分のみ表示
  • 他

初回読み取りで60〜95%の圧縮。cached re-reads は興味深い設計で、同じファイルを Agent がセッション内で再度読み取ると、lean-ctx がファイルに変更がないことを検出し、約13 tokens の短いメッセージ(「以前読み取り済みで変更なし」)を返して、数千 tokens の重複投入を回避します。

全体で59個のツール、95以上の圧縮モードを提供。Property Graph 機能もあり、AST の上にコードグラフを構築(imports/calls/exports/type_ref を追跡)し、クエリ時にハイブリッド検索(BM25 + embeddings + graph proximity)を行います。

Headroom:cache-aware 圧縮

Headroom(GitHub, 1.8k stars, Apache-2.0)は、圧縮と Prompt Cache の間の協調に特に注意を払っています。

コア機能:

  • CacheAligner:圧縮完了後、結果の構造と配置を積極的に調整し、圧縮後のコンテンツが前回のリクエストのプレフィックスとできるだけ整合するようにして、cache ヒット率を向上させます
  • CCR(可逆圧縮):圧縮されたコンテンツについて、モデルが後から元データを見たい場合、headroom_retrieve で復元できます。圧縮は取り消し可能です
  • Kompress-base:Hugging Face の圧縮モデルでテキスト圧縮を行い、ベンチマークでは 10,144 tokens → 1,260 tokens(87%)で、回答品質に測定可能な低下はありません

インストール複雑度の比較

これら4つのツールの導入コストはかなり異なります。

ツールインストール方法複雑度
RTKrtk init -g 1コマンドで自動的に hook を登録最もシンプル
Context ModeClaude Code marketplace からワンクリックインストール、または npm install -g context-modeシンプルだが、6つの sandbox tools の使い方を理解する必要あり
lean-ctxbrew install lean-ctx または cargo install lean-ctx、その後 lean-ctx setup で AI ツールを自動検出・設定中程度、setup は自動設定するが初回は read modes の理解が必要
Headroompip install headroom-ai[all]、その後デプロイ方式に応じて設定(library モードが最もシンプル、proxy/MCP は追加設定が必要)最も複雑、Python 環境 + 設定項目が多い。手間をかけられるチーム向け

RTK と Context Mode は「インストールしたら放置」タイプです。lean-ctx は read modes を理解するために少し時間が必要で、それによって最大の効果を発揮します。Headroom の CacheAligner と可逆圧縮は強力ですが、設定とデバッグのコストも最も高く、運用能力のあるチームや独自パイプラインに統合したいシナリオに適しています。

選択の指針:チームが主に CLI でコマンドを実行している場合(build、test、lint)、RTK は即効性があります。Agent が大量のファイル読み取りと MCP 呼び出しを行う場合、lean-ctx のカバー範囲がより広いです。Headroom は cache ヒット率を極限まで追求する場合、または圧縮を独自パイプラインに統合する必要がある場合に適しています。

圧縮型ツール(Cache を破壊する)

予防をどれだけ徹底しても、セッションが長くなればコンテキストは膨張します。私自身の体感では、コンテキストが70〜80%に達した時点でモデルの集中力が散漫になり始め、/compact が自動トリガーされる95%までは待てません。コミュニティの現在の主な方向性は Dynamic Compression(動的圧縮)で、一律に要約してやり直すのではなく、セッション進行中に選択的に既存コンテンツを削減します。

ツールStarsLicense圧縮粒度原理
DCP2.8kAGPL-3.0完了済みツール呼び出しの選択的剪定自動重複排除 + LLM セマンティック圧縮、API payload を変更、元の session はそのまま
Cozempic300MIT階層的段階的クリーニング(3段階)session JSONL ファイルを直接変更、冗長データを削除
Magic Context636MITバックグラウンド非同期圧縮historian モデルがバックグラウンドで圧縮、Compartments + Facts で永続化

これら4つのツールの核心的な違いは「圧縮がどこで発生するか」と「粒度の細かさ」です。DCP は API payload をインターセプトし、リクエスト送信前に古いツール呼び出しを置換します。元の session ファイルは無傷で遡及可能です。/compact は最も粗暴な方法で、コンテキスト全体を要約にまとめて最初からやり直し、cache は完全にゼロになります。Cozempic は session ファイル自体を直接変更し、蓄積されたゴミデータを物理的に削除します。Magic Context はバックグラウンドで非同期に実行され、メインの Agent を中断せず、cache の節約が cold start コストを上回るかどうかも計算します。セッション中に細かく制御したい場合は DCP。セッションがすでに手に負えないほど膨張している場合は /compact または Cozempic で一度クリーニングしてやり直し。手間をかけたくない場合は Magic Context がバックグラウンドで自動処理します。

DCP:選択的剪定

DCP(GitHub, 2.8k stars, AGPL-3.0)は OpenCode プラグインで、セッション進行中に完了済みのツール呼び出しを選択的に削減します。全量要約ではありません。claude-dcp(MIT)はその Claude Code 移植版です。

  • 2つのことを行います。自動重複排除(LLM コストゼロ)とセマンティック圧縮(LLM 駆動)
  • 自動重複排除:Agent が1セッション内で同じファイルを3回読み取った場合、DCP は最後の1回の出力のみ保持し、前の2回を placeholder に置換。重複する git status や URL fetch も同様
  • セマンティック圧縮:DCP は compress ツールを公開し、Agent 自身がある会話セグメントが完了したと判断した場合(例:バグが修正され、トラブルシューティング過程の20ラウンドのツール呼び出しが不要になった場合)、compress を呼び出してその部分を技術的要約に置換
  • 元の session ファイルは変更せず、API に送信される payload 内でのみ置換。ログは完全に保持され遡及可能
  • 設定:maxContextLimit デフォルト 100k tokens(超過で圧縮リマインダーをトリガー)、minContextLimit デフォルト 50k tokens、パーセンテージ “80%” に変更可能。個人的にはこの設定は適切だと思います。大部分の200kコンテキストのモデルにとって、100kはちょうど半分使用したスイートスポットです
  • shadow copy メカニズムにより cache hit rate は約85%を維持(DCP 不使用時は90%)
  • 制限:AGPL-3.0 license のため商用利用にはコンプライアンスへの注意が必要。セマンティック圧縮には追加の LLM 呼び出しが必要で、Prefill し直すよりは安価だがゼロコストではない。圧縮品質は Agent の「この会話セグメントが完了したかどうか」の判断に依存し、誤って圧縮すると情報が失われる

Cozempic:session ファイルの物理的クリーニング

Cozempic(GitHub, 300 stars, MIT)は Claude Code の session JSONL ファイルを直接操作し、蓄積されたゴミデータを削除します。

  • DCP との違い:DCP は API payload を変更(ランタイムインターセプト)、Cozempic はファイル自体を変更(永続的クリーニング)
  • 典型的なシナリオ:1つのファイルを50回変更し、毎回 tool result が完全な diff を記録して2MBに達するが、Agent は古い diff を必要としない(ファイルを再度読めばよい)。Cozempic は最新のいくつかの diff のみ保持し、古いものは1行の要約に圧縮するか直接削除
  • 18種類のクリーニング戦略を3段階に分類:
    • Gentle:/compact で要約済みだが原文が残っているメッセージの削除、ファイル読み取りの重複排除、metadata の剥離
    • Standard:長すぎるツール出力の truncate、期限切れの古い結果のクリーニング、system reminder の重複排除
    • Aggressive:古い base64 画像の削除(直近20%のみ保持)、繰り返しの error-retry ループの折りたたみ、32KB超の大きなブロックの truncate
  • 約23〜45%の節約
  • デフォルトは dry-run モード(報告のみで変更しない)、--execute を付けて初めて実際に変更。変更前に自動バックアップ

Magic Context:バックグラウンド非同期圧縮

Magic Context(GitHub, 636 stars, MIT)は OpenCode プラグインで、Claude Code プラグインはありません。バックグラウンドで非同期に圧縮し、メインの Agent はまったく待つ必要がありません。

  • バックグラウンドで独立した historian モデルを実行し、古い会話を非同期で処理。メイン Agent は圧縮完了を待つ必要も中断されることもない
  • 圧縮結果は Compartments(タイムライン順に整理された要約ブロック)として保存され、新しいラウンドのリクエスト時にコンテキストに注入
  • 会話から Facts(決定事項、制約、選好)を抽出して個別に永続化。Facts は圧縮時に失われず、/compact の誤った固定化問題を部分的に解決
  • cache-aware スケジューリング:cache の節約額と cold start コストを計算し、圧縮の効果がプラスの場合のみトリガー
  • Facts はセッション間で保持され、新しいセッション起動時に自動注入

インストール複雑度の比較

ツールインストールコマンド備考
DCPnpm i @tarquinen/opencode-dcpOpenCode プラグイン、インストールすれば即使用可能
claude-dcpgit clone + 3つの hooks を設定Claude Code 移植版、PreCompact、PreToolUse、UserPromptSubmit を手動設定が必要
Cozempicpip install cozempic && cozempic initPython 環境が必要、デフォルト dry-run セーフモード
Magic Contextopencode.json に "plugin": ["@cortexkit/opencode-magic-context"] を追加OpenCode 専用;内蔵 compaction を無効化し、historian モデルの追加設定が必要

補足:API レベルの context editing

API で独自の Agent を開発している場合、Anthropic の context editing がサーバーサイドのコンテキスト管理機能を提供しています。clear_tool_uses 戦略で古い tool result を時間順に自動クリーニングでき、トリガー閾値、直近 N 回の呼び出しの保持、特定ツールの除外を設定できます。OpenAI にも同様の compact endpoint があります。これらは Claude Code / ChatGPT ユーザーには透過的ですが、独自の Agent を構築する場合は API レベルでより精緻な制御が可能です。


Isolate:タスク分割とモデル切り替え

前述の Select と Compress はツールを導入する話で、設定を変更するだけで節約できます。Isolate とこの後の Write は異なり、使い方の習慣を変えるものです。

Isolate の核心的な考え方は、大きなタスクをサブタスクに分割し、独立したコンテキストウィンドウで実行して、完了後に結論のみをメインの Agent に返すことです。コスト削減のレバーは2つあります。1つはモデルの段階分け(安価なモデルで簡単な作業をする)、もう1つはコンテキストの隔離(sub-agent は不要な履歴を持たない)。トークン総量は変わらないか増えることもありますが、コストは下がります。

モデルの段階分けとコンテキスト隔離

料金表を振り返りましょう。Haiku $1/$5、Sonnet $3/$15、Opus $15/$75(per MTok input/output)。同じ作業を Haiku にやらせるのと Opus にやらせるのでは、価格差は15倍です。問題はどの作業を Haiku に任せられるかです。

Claude Code のアプローチは、内蔵の Explore agent がデフォルトで Haiku 上で動作し、読み取り専用でコードベースの探索に特化していることです。また Explore と Plan agent は CLAUDE.md と親セッションの git status をスキップし、コンテキストのオーバーヘッドをさらに削減します。Claude Code ユーザーコミュニティの統計によると、API 呼び出しの36.5%が Haiku 上で実行されていますが、この部分は総コストのわずか2.3%($8/$354)です。安価なモデルが3分の1以上の呼び出し量を消化しながら、かかるコストはほぼ無視できます。

モデルの段階分けに加えて、sub-agent はコンテキスト隔離によっても総支出を削減します。Anthropic 公式ドキュメントに例が示されています。Explore agent は自身のコンテキストで6,100 tokens のファイルを読み取り(session.ts 2,200 + timeouts.ts 800 + config/*.ts 3,100)、メインの Agent に返す時は420 tokens の結論のみです。中間過程の93%が破棄され、メインの Agent のコンテキストはスリムに保たれます。さらに、特定のタスクについては sub agent の agents.md を修正して関連するコンテキストのみを注入できます。例えば SQL やデータベースチューニングの場合、関連するビジネス制約と技術知識を入力するだけで済み、バックエンドコード全体の書き方を知る必要はないかもしれません。この場合、専用の最適化 agent にこの作業を任せることができます。

コミュニティではこの方向でより体系的なソリューションが開発されています。現在比較的活発なのは3つです。oh-my-claudecode(Claude Code プラグイン)、oh-my-openagent(旧名 oh-my-opencode、OpenCode プラグイン)、oh-my-opencode-slim(oh-my-openagent の簡略版、OpenCode プラグイン)。三者は異なる作者によるもので、互いに独立しています。

oh-my-claudecodeoh-my-openagentoh-my-opencode-slim
Stars(調査時データ)~34.6k~59k~4.6k
LicenseMITSustainable Use License v1.0(非 OSI、商用再配布禁止)MIT
対象プラットフォームClaude CodeOpenCode(+ Codex/Pi 適応中)OpenCode
Agent 数19個 + 階層バリアント7個のコア agent + チーム専門家7-8個
モデルルーティング方式Haiku→簡単、Opus→複雑;クロス CLI ルーティング対応(Codex、Gemini)タスクカテゴリで自動ルーティング(quick/deep/visual/ultrabrain)各 agent が JSON 設定で明示的にモデル + variant を指定

License の違いは注目に値します。oh-my-claudecode と slim はいずれも MIT で自由に使えます。oh-my-openagent はカスタムの Sustainable Use License v1.0 を使用しており、個人および社内利用は許可されていますが、それを基に商用製品や SaaS を再配布することは禁止されています。個人またはチーム内部での使用には影響しませんが、二次開発で商用製品を作りたい場合は slim の MIT ライセンスの方が安全です。

三者の設定方式は異なりますが、段階分けのロジックは高度に一致しています。3つのツールの実際の設定から、3層のモデル段階分けと各層に対応するタスクタイプを帰納できます。

第1層:安価/高速モデルで雑務を処理

典型的なモデル:Haiku($1/$5)、GPT-5.4-mini($0.75/$4.50)、Gemini Flash、DeepSeek Flash。

この層のタスクには共通の特徴があります。結果が決定的であるか、エラーのコストが低いことです。具体的には以下を含みます。

  • ファイル検索とコードナビゲーション。コードベース内で特定の関数定義を見つける、変数名を grep する、ディレクトリのファイル構造を一覧表示する。Claude Code 内蔵の Explore agent はデフォルトで Haiku を使ってこの作業を行います。oh-my-opencode-slim では Explorer(デフォルト GPT-5.4-mini)、oh-my-openagent では Librarian(デフォルト Gemini Flash)と呼ばれています。この種のタスクは本質的にパターンマッチングで、推論能力は不要、モデルが grep/glob/read ツールを正しく呼び出せれば十分です。
  • 単一ファイルの小修正。フォーマット、import の並べ替え、変数名の一括置換、欠落した return 文の追加。変更範囲が小さくコンテキストも少ないため、安価なモデルがエラーしても修正コストは微小です。oh-my-opencode-slim はこの用途に専用の Fixer agent(デフォルト GPT-5.4-mini)を設けています。
  • ドキュメント検索。外部ドキュメントの閲覧、API 使い方の確認、Stack Overflow の検索。oh-my-opencode-slim の Librarian(GPT-5.4-mini)と oh-my-openagent の Librarian がこれを担当します。

この層のモデル費用はほぼ無視できます。前述のデータの通り、API 呼び出しの36.5%が Haiku 上で実行されながら、総コストのわずか2.3%です。

第2層:中間モデルで実装を担当

典型的なモデル:Sonnet($3/$15)、GPT-5.4($2.50/$15)、Kimi K2.6。

この層のタスクはコードのセマンティクスを理解する必要がありますが、モジュール間のアーキテクチャ決定は含みません。

  • テストの記述。関数に単体テストを書く。関数シグネチャ、入出力、境界条件を理解する必要がありますが、システム全体の設計を理解する必要はありません。
  • 簡単なバグ修正。エラーメッセージが明確で、箇所が特定されているバグ。null pointer、off-by-one、error handling の欠落など。修正は通常1〜2ファイルに限定されます。
  • 標準的な実装。既存のパターンに沿って新しい CRUD エンドポイントを書く、新しいフォームフィールドを追加する、インターフェースが明確に定義された機能を実装する。設計判断は不要で、既存コードのスタイルに合わせて書くだけです。

oh-my-claudecode ではこの層を Tier 2 と呼び、oh-my-openagent の quick カテゴリがここにルーティングされます。Augment Code も実装層には Sonnet を推奨しています(SWE-bench Verified 79.6%の成績を引用)。

第3層:強力なモデルで意思決定を担当

典型的なモデル:Opus($15/$75)、GPT-5.5($5/$30)、Claude Opus 4.7 max variant。

この層のタスクは、間違えた場合の代償が非常に大きいものです。

  • アーキテクチャ設計。新しいサービスの技術スタックを決定する、モジュール間のデータフローを設計する、サービス間通信に message queue か REST かを選択する。この種の決定は今後数ヶ月の開発に影響し、間違えた場合の手戻りコストはモデル費用をはるかに上回ります。
  • モジュール間のリファクタリング。billing モジュールの課金ロジックを変更する場合、上流の metering がどう収集するか、下流の invoice がどう生成されるか、中間の subscription ステートマシンがどう遷移するかを理解する必要があります。コンテキストが複数のサービスにまたがり、推論チェーンが途切れてはいけません。
  • セキュリティレビュー。認証フローに脆弱性がないか、権限制御が正しいか、SQL インジェクションや XSS がないかを検査する。この種のタスクは正確性への要求が極めて高く、false negative(発見できなかった脆弱性)は false positive(誤検出)よりもはるかに危険です。

Augment Code の Model Routing Guide は別の角度から同じ段階分けのロジックを裏付けています。調整には Opus、実装には Sonnet(SWE-bench Verified 79.6%)、ファイルナビゲーションには Haiku、コードレビューには GPT-5.2。彼らのデータでは model routing により40〜60%のコスト削減が可能です。120人のチームで月間モデル支出が $52,000 の場合、4〜6週間以内に通常20〜35%の低下が見られ、開発者の行動を変える必要はありません。Augment はその後 Prism を発表してこのプロセスを自動化しました。

分割すべきでない場合

Agent の分割はコストフリーではありません。誤って分割すると、コスト削減にならないだけでなく、品質も低下します。

前述のように、sub-agent とメイン agent の間のコンテキストは隔離されています。この隔離はコスト削減の前提ですが、同時に代償も伴います。複数の sub-agent 間でビジネスコンテキストを共有する必要がある場合、現時点では良い方法がありません。Google はすでに A2A(Agent-to-Agent)プロトコルを発表していますが、実際の coding agent のシナリオでは、1つの agent が別の agent に「そちらのビジネスコンテキストは何ですか」と直接聞いて正確な回答を得られるような agent チームはまだ見たことがありません。

現在の実装はかなり粗雑です。各 sub-agent がビジネスコンテキストを理解する必要がある場合、それぞれがコードベースを一から探索し直します。agent A が billing モジュールの3,000行のコードを読んで課金ロジックを理解しても、agent B が同じ情報を必要とする場合、agent A に聞くのではなく同じ3,000行をもう一度読みます。3つの agent なら3倍の探索コストです。UIUC の論文は7つのデータセットと6つのモデルで実測し、multi-agent システムは single-agent に比べて4〜220倍のトークンを消費し、最適化後でも2〜12倍必要としました。

分割すべきかどうかを判断する私個人の基準はおおよそ以下の通りです。

分割に適する分割に不適切
独立したディレクトリ内でコードを探索(結論は数百 token で要約可能)サービス間の因果推論(分割すると推論チェーンが途切れる)
テスト、lint、フォーマットの実行(結果は pass/fail)繰り返し協議が必要な設計判断(調整オーバーヘッド > 節約)
互いに独立したファイルの並列処理コンテキストが密結合したリファクタリング(各 agent が全体像を再理解する必要)

経験則として、sub-agent に一文で指示を出せ、その結果も一段落で要約できるなら、分割に適しています。sub-agent に長い背景説明を書いている自分に気づいたら、そのタスクは隔離に向いていません。


Write:情報をコンテキストの外に移す

前の4つの方向(Select、Compress、Isolate)はすべてコンテキストウィンドウ内部での工夫です。Write は発想を変えます。常に存在する必要のない情報をファイルシステムに移し、Agent が必要な時に読み戻すのです。

Andrej Karpathy は Y Combinator AI School の講演で1つのアナロジーを述べています。model weights は CPU(固定の計算基盤)、context window は RAM(短期的、揮発性、容量が限られた作業記憶)。MemGPT 論文(2023年10月、Charles Packer 他)はこのアナロジーを3層アーキテクチャとして正式化しました。

階層アナロジー機能
Core MemoryRAMcontext window 内、agent が直接読み書き
Recall MemoryDisk cache検索可能な会話履歴、context 外に保存
Archival MemoryCold storage長期保存、agent が tool call で照会

OS の仮想メモリページングの概念を直接借用しています。データが主記憶容量を超えた場合、主記憶とディスクの間でページングを行います。後に Letta プラットフォームとして商業化されました。

現在の Agent メモリの実装方法

実装面では、現在のほとんどの agent はかなりシンプルで、基本的に markdown ファイルをベースとしています。coding agent に限らず(Claude Code の MEMORY.md、OpenCode の AGENTS.md、Codex の AGENTS.md)、汎用 agent のアプローチも似ています。例えば Hermes や Openclaw も markdown ファイルでメモリを記録しています。一段階上には SQLite + 全文検索ベースのソリューション(agentmemory、Engram など)があります。さらに上にはベクトルデータベース(pgvector が現在のトレンドで、すでに Postgres があれば独立したベクトル DB を導入する必要がない)、そして専用のメモリプラットフォーム(Mem0 が3段階 Extraction→Consolidation→Retrieval を実装)があります。最近ではすべてを Postgres に戻すトレンドもあります。

しかし日常的に coding agent を使うシナリオでは、これらの重量級ソリューションはほとんどの場合オーバーエンジニアリングです。coding agent のメモリ需要は汎用 agent とは異なります。百万ユーザーのパーソナライゼーション状態を管理する必要も、「3ヶ月前にユーザーが言ったこと」を時系列推論する必要もなく、必要なのはセッション間でプロジェクトコンテキストと作業進捗を保持することです。markdown ファイル + 合理的なディレクトリ構造 + /clear の規律で基本的に十分です。

以下、coding agent のシナリオでの Write の具体的な方法を見ていきます。

内蔵の lazy loading メカニズム

Claude Code にはすでに多くの「外に保存して必要時に読み込む」メカニズムが内蔵されています。Auto Memory の MEMORY.md はコンテキストに最初の200行のみ読み込み、topic ファイルはオンデマンドで読み取ります(公式ドキュメント)。AutoDream はアイドル時間にバックグラウンドでメモリを統合し、重複排除、古いエントリの除去、矛盾項目の統合を行います。Path-scoped rules(.claude/rules/)は対応するファイルを操作する時のみ読み込まれます。/btw の質問と回答は会話履歴に入りません。Skill と MCP schema は前述の Select セクションで述べたプログレッシブローディングです。これらはすべて lazy loading で、情報は必要な時にのみコンテキストに入ります。

コミュニティの Write パターン

内蔵メカニズムの他に、コミュニティでは明示的な Write パターンがいくつか発展しています。用途別に分類します。

外出し Spec

実は、現在基本的に皆が使っている Spec Driven Development も一種の外部化されたメモリだと考えています。トークンコストの観点から見ると、50ラウンドの議論で蓄積した80k token の会話履歴を2k token の spec ファイルに圧縮することで、coding agent がコンテキストを探すために必要なトークンを効果的に削減できます。

作業状態の永続化と Session Handoff

タスクが一回限りでない場合(例えば複数のイテレーションにまたがるフィーチャー開発)、spec だけでなく、セッション間で継続的に更新可能な作業状態が必要です。

コミュニティではこの方向で最も活発な以下のソリューションがあります。

Planning-with-files(Manus モード)。3つのファイルを作成します。task_plan.md(フェーズ分割、進捗追跡)、findings.md(調査ノート)、progress.md(session ログ、エラー履歴)。Hooks で強制実行されます。PreToolUse は Write/Edit/Bash の前に自動的に plan を読み取って目標を更新し、PostToolUse は進捗更新をリマインドします。Manus AI 自身の言葉では「Markdown is my ‘working memory’ on disk.」

Alive。5つのファイル + 12の hooks:key.md(プロジェクト基盤)、now.md(現在の状態)、log.md(不可変の決定履歴)、tasks.md(ワークキュー)、insights.md(静的知識)。hooks は log エントリの削除を阻止し、session 境界での読み書きを強制します。Alive と planning-with-files の違いは、プロジェクトレベルの永続的知識に重点を置いている点で、単一タスクの実行追跡だけではありません。

Agent Kernel。より簡潔で、3つのファイル:AGENTS.md(汎用指示)、IDENTITY.md(agent のアイデンティティ)、KNOWLEDGE.md(知識ディレクトリインデックス)。Claude Code、Codex、Cursor、OpenCode 間で使用可能です。

これらのソリューションには共通点があります。hooks が鍵です。markdown ファイルだけでは不十分で、コンテキストの増大に伴い agent はファイルをスキップしたり誤読したりします。コミュニティの経験では、session 境界(SessionStart、PreCompact、Stop)で hooks により強制的に読み書きすることで、agent が実際にこれらのファイルを利用するようになります。TodoWrite(現在は Tasks API)との違いは、TodoWrite は in-context で各ラウンドコンテキストに含まれ session 終了で消えますが、planning-with-files のものは実際のファイルであり、/clear やセッション間で生き残ります。

session を終了する必要がある場合(context limit に近づいた、またはタスクが次のフェーズに移行)、handoff が関わってきます。現在の状態を次の session にどう渡すか。

直感的な方法は、コンテキストをファイルにダンプして次の session に読ませることです。しかしこれは対症療法でしかありません。現在の session の200k token のコンテキストをダンプすると、次の session でも200k token となり、やはりオーバーフローします。良い引き継ぎ方は「コンテキストを次に渡す」ではなく、「まず5〜10%に圧縮してから渡す」です。

HumanLayer の ACE-FCA は現在最も具体的に記述されたスキームです。作業を Research → Plan → Implement の3フェーズに分割し、各フェーズ間で完全なコンテキストリセットを行い、約200行(約1,500 token)の構造化文書のみを引き継ぎます。

フェーズ成果物目標サイズ内容
research_doc.md約200行問題要約、関連ファイルとその用途、情報フロー、重要な発見、推奨案
implementation_plan.md約200行番号付きステップ、変更するファイル、テスト方法、依存関係
progress.md約100行目標、完了ステップ(チェック済み)、現在のステップ、残作業

重要なルール:元のファイル内容や検索結果を引き継ぎ文書に含めることは許可されません。sub-agent が3,000行のコードを検索しても、返すのは50行の圧縮要約のみです。トークン予算の目標は、作業中のコンテキストを40〜60%に維持することです。彼らはこの方法で300k行の Rust コードベースを処理したと報告しています。

Matt Pocock(grill-me の作者)は /handoff skill を作りました。考え方は類似しています。現在の session を構造化 markdown に圧縮し、コンテンツをコピーするのではなくファイルを参照し、一時ディレクトリに保存して新しい session がこのファイルから起動します。/compact との違いは、/compact は同じ session 内で継続するのに対し、/handoff はまったく新しい session に切り替えることです。これは私も現在試しているもので、他のソリューションに比べてより軽量で管理しやすいです。

コミュニティには context-save/context-restore skill もあります。/context-save で現在の作業状態を .claude/context.md にスナップショット(何をしていたか、重要な決定、未解決の問題 + git 状態)し、新しい session で /context-restore で復元します。/rewind との違いは、/rewind はコード状態を復元し、context-save は「何をしていたか、なぜそうしたか」という理解を復元します。

自動化された永続メモリ

手動のファイル管理が面倒な場合、コミュニティには自動化ソリューションがあります。claude-mem(約74.8k stars)は5つのライフサイクル hooks で自動的に session データをキャプチャし、session 終了時に AI がセマンティック要約に圧縮(5,000 tokens → 約500 tokens)、次の session で自動注入します。agentmemory(約9.4k stars)は Ebbinghaus の忘却曲線に基づいて自動圧縮と減衰を行い、約1,900 tokens で240の観察を保存(CLAUDE.md にすべて詰め込むと22,000+ tokens が必要なのに対し、92%削減)。これらのベンチマークはツール側自身のテストであり、独立した検証は不足しています。

Write でないもの

よくある2つの誤解があります。

  • 長すぎる CLAUDE.md。CLAUDE.md は always-loaded context であり、毎回の API 呼び出しで必ず付加されます。数千行のドキュメントを詰め込むのは「コンテキストの外に保存する」ではなく、「毎回強制的に読み込む」です。5,000 token の CLAUDE.md は毎メッセージで5,000 token の税金を意味します。Anthropic は200行以内を推奨しています(約1,500〜2,000 tokens)。良い CLAUDE.md は道標(Agent に詳細をどこで探すか伝える)であり、百科事典ではありません。

  • 「すべてをファイルに保存する」。Oracle 開発者ブログは次のように警告しています。「saving everything including full conversation logs, every data point, and all outputs causes memory artifacts that grow unbounded.」原則は、Agent が使う情報のみを保存し、Agent がコードや git 履歴から推論できる情報は保存しないことです。

書いた後のメンテナンス:Context Drift

Write 戦略には避けられない問題があります。書いた後にコードが変わったのに文書が追従せず、agent が誤った前提で作業してしまうことです。harness engineering の分野ではこれを context drift と呼びます。Birgitta Böckeler の martinfowler.com の記事(2026年4月)は、「how do we keep a harness coherent as it grows?」を open question として明確に挙げており、solved problem ではありません。

Context drift は2種類あります。

  • 構造的 drift:ファイルパスが変わり、CLAUDE.md に「billing は src/billing/ にある」と書いてあるが、誰かが src/services/billing/ に移動した。
  • 意味的 drift:コードロジックが変わったが古いパスはそのまま。CLAUDE.md に「billing は月額課金」と書いてあるが、すでに従量課金に変更されており、src/billing/ ディレクトリは元の場所にある。

構造的 drift にはすでにツールがあります。ctxlint は CLAUDE.md/AGENTS.md 内のすべてのファイルパスを解析し、それらがまだ存在するか確認し、git history の rename を調べ、build/test コマンドが package.json と一致しているかクロスチェックします。CI に npx @yawlabs/ctxlint --strict を1行追加するだけです。Caliber の caliber refresh は git diff を分析して CLAUDE.md を自動更新し、pre-commit hook として実行できます。

意味的 drift には基本的に成熟した解決策がありません。現時点で最も近い設計思想は2つあります。1つは Addy Osmani が提案した記述ではなくポインタを書く方法。「billing のロジックは src/billing/README.md を参照」とすれば、パスが切れた場合 ctxlint が検出できます。一方「billing は月額課金」という記述テキストの腐敗はサイレントです。もう1つはコードからリアルタイムに導出する方法(Aider の repo map は各メッセージで AST から再生成、CodeGraph はファイルシステム watcher でインクリメンタル同期)で、コンテキストが常にコードの現状から来るようにし、人間が書いた文書に依存しないようにします。 社内でも以前この問題を議論しました(@Xu kunyu)。私が個人的に推奨するソリューションは、GitHub Agentic Workflow で定期的に文書とコードをスキャンして alignment を行い、drift を検出したら自動的に PR を提出して修正するというものです。このアイデアはまだ実装していませんが、context drift の検出と修復を CI/CD パイプラインの一部にするという考え方で、人間が更新を忘れないことに頼るのではありません。


出力の管理

ここまではすべて input 側の最適化でした。直感的には output の単価は input の5倍(Opus $25 vs $5)なので、output を最適化した方が割に合うように思えます。しかし実際のトークン分布を見ると、そう単純ではありません。

今日の私の実データを例に挙げます。Input 1.62M tokens、Output 128.1K tokens(Opus 4.6)。

トークン数で見ると、input が92.7%、output が7.3%で、これはコミュニティの実測データと一致しています。Branch8 の Claude Code session は94.5〜98.6%、Cursor の1週間実測は97.9%、Stanford/Microsoft の2,000以上の SWE-bench トラジェクトリに関する論文はさらに極端で153

。理由は、毎回の API 呼び出しでコンテキスト全体(system prompt + CLAUDE.md + 会話履歴 + 読み取ったファイル)が再送信され、input はラウンド数に比例して線形増加するのに対し、output は各ラウンドで比較的安定しているためです。

しかし金額で計算すると話が変わります。同じく今日のデータで、すべて Opus 4.6 の標準価格(cache を考慮しない)で計算すると:

  • Input:1.62M × $5/MTok = $8.10(71.7%)
  • Output:0.128M × $25/MTok = $3.20(28.3%)

Output はトークン数では7%しか占めていませんが、単価が5倍のため、実際には約3割の費用を占めています。

さらに cache ヒットを考慮すると(input の70%が cache にヒットし、cached input が $0.50/MTok と仮定)、さらに興味深い結果になります。

  • Cached input:1.134M × $0.50 = $0.57
  • Non-cached input:0.486M × $5.00 = $2.43
  • Output:0.128M × $25 = $3.20
  • 合計:$6.20、output が51.6%を占める

cache ヒット率が高くなるほど input の実質コストは押し下げられ、output の比率がより大きくなります。前述のキャッシュとコンテキスト最適化を十分に行った後では、output がコストの大部分を占めるようになるのです。したがって output の最適化は価値がないわけではなく、input の最適化が十分に行われた後に初めて顕在化します。ただし現在コミュニティで議論されている主なソリューションは1つだけ、Caveman です。

Caveman

Caveman(61k stars、MIT License)は Claude Code で最も注目度の高い output 最適化 skill です。prompt 指示によりモデルに極度に圧縮された言葉で応答させ、冠詞、フィラーワード、礼儀的表現を除去し、技術的な実質のみを残します。

ただし議論もあります。単に "be brief" と書くだけでほぼ同等の効果が得られるというテスト結果もあります(419 vs 401-449 tokens、品質 0.985 vs 0.970-0.976)。また Caveman は output tokens にのみ影響し、input が支配的な session では実際のコスト節約は約7〜13%で、宣伝される65%ではありません。

個人的には個人利用に向いていると思います。自分で理解できれば十分です。チームでデフォルトで Caveman をオンにするのは適切ではないでしょう。モデルが200 token 少なく書いても、人間が圧縮された応答を理解するのに5分余計にかかるなら、必ずしも割に合いません。

その他の方向

独自の agent を開発している場合、もう1つのソリューションは Batch API の使用です。Anthropic と OpenAI の両方が Batch API を提供しており、非リアルタイムの一括リクエストで50%の価格割引が受けられます。即座の応答が不要なシナリオに適しています。例えば大量の文書翻訳、バッチコードレビュー(1日分の PR をまとめて実行)、バッチテスト生成(モジュール内のすべての関数に一括でテストを書く)、バッチドキュメント生成。重要なのは、これらのタスクはまとめてから実行でき、毎回同期的に結果を待つ必要がないことです。


観測と実践

まずコストの内訳を把握する

コストがどこに発生しているか分からなければ、最適化は手探りです。

私個人は CC Switch を使っています。もともとクロスプラットフォームの API プロバイダー管理ツール(API key の切り替え、endpoint、failover)ですが、トークン消費とコスト推移を見られる usage dashboard が付属しています。Claude Code、Codex、Gemini CLI、OpenCode、OpenClaw に対応しています。

公式提供のツール以外に、コスト監視に特化したツールとして、コミュニティで比較的活発なものは以下です。

ツールStars(調査時データ)対応プラットフォームトークンタイプの区別特徴
ccusage~14.5kClaude Code、OpenCode 等15の agentinput/output/cache read/cache writebunx ccusage でゼロインストール、ローカル JSONL を読み取り、日/週/月/session で表示
tokscale~3.1kClaude Code、OpenCode、Cursor 等22以上の agentinput/output/cache read/cache write/reasoningRust TUI、Cursor 対応(API sync 必要)、contribution graph あり
agentsview~1.1kClaude Code、OpenCode 等14以上の agentinput/output/cache read/cache writeローカル web dashboard、SQLite インデックス、ccusage より100倍高速

Claude Code と OpenCode はいずれもローカルに JSONL ログを書き込むため、ccusage と tokscale はこれらのファイルを直接読むだけで済みます。Cursor はローカルログを書き込まないため、tokscale は API sync(tokscale cursor login)でデータを取得します。OpenCode 自体の TUI にもセッションレベルのトークンとコスト表示が内蔵されており(リアルタイム更新)、追加ツールなしでも確認できます。

自作 Agent で API を使用している場合、LiteLLM(約48k stars)を統一ゲートウェイとして使用でき、100以上のプロバイダーに対応し、per-project/per-user のコスト追跡が組み込まれています。ただしすべての agent トラフィックをルーティングする必要があり、上記のツールよりもはるかに重量級です。

エンドツーエンドの概算

今日の実データ(Input 1.62M, Output 128.1K, Opus 4.6)を使って、前述の各次元を通して1つの計算にまとめてみます。

何もしない場合、すべて標準価格で:Input 1.62M × $5 + Output 0.128M × $25 = $11.30。

Step 1:キャッシュ規律。system prompt と MCP schema の順序を固定し、attribution header をオフにし、不要な MCP ツールを整理。input の70%が cache にヒットすると仮定(cached input $0.50/MTok):Input コストが $8.10 から $3.00 に低下(cached 1.134M × $0.50 + non-cached 0.486M × $5.00)。output $3.20 を加えて合計 $6.20。45%の節約。このステップは1回の設定変更だけです。

Step 2:無効な探索の削減。CLAUDE.md の道標を整備(agent にコードの場所とビジネス用語を伝える)、静的型付けプロジェクトで LSP をオン(1回の find-references で5ラウンドの grep を代替)。session の総トークンが30%削減され、1.62M から 1.13M に。同じく70%の cache ヒットで:Input コスト約 $2.10、output $3.20 を加えて合計 $5.30。

Step 3:膨張の予防。RTK で CLI 出力を圧縮(80%圧縮率)、または lean-ctx でファイル読み取りと MCP 返値をカバー。session がさらに15%スリム化すると仮定し、合計約 $4.70。

Step 4:隔離。重い探索タスクは Haiku sub-agent($1/$5 vs Opus の $15/$75)、異なるタスク間で /clear。探索部分のコストは15倍安く。このステップの節約は、安価なモデルに任せられるタスクの量に依存します。

Step 5:出力制御。簡単なタスクで /effort を下げ、自動化パイプラインに structured output + Batch API(50%割引)を使用。前のステップで input コストを押し下げた後、output の比率はすでに半分を超えており、このステップの価値が明確になります。

$11.30 から約 $4-5 へ、半分以上の節約です。最大の貢献は cache ヒット(Step 1)と無効トークンの削減(Step 2)からで、この2つで大部分を節約でき、しかも投資が最小です。

強調しておきますが、これらの数字は概算です。実際の効果はセッション構造、キャッシュヒット率の変動、タスクタイプに依存します。しかしオーダーの方向性は正しいはずです。

私が個人的に推奨する実施順序

以下は投資対効果比で並べた実施順序です。ただし断っておきますが、これは私個人の推奨であり、私たちのチームもこの一連のフローを完全には実践できていません。いくつかのステップ(例えば context drift の自動化検出)はまだ議論段階です。この記事は調査ノートであり、実戦報告ではありません。

Step 0: 観測
  ccusage または tokscale をインストールし、コストの内訳を把握する。
  データを見ずに最適化するのは手探りと同じ。

Step 1: キャッシュ規律(1回の設定変更で長期的に効果)
  system prompt と MCP schema の順序を固定する。
  不要な MCP ツールを整理する。
  ローカルモデルでは attribution header をオフにする。
  claude-code-cache-fix で resume session の cache regression を修正する。

Step 2: 無効な探索の削減(半日の作業で長期的に効果)
  CLAUDE.md を整備する——道標であって百科事典ではなく、200行以内に抑える。
  静的型付けプロジェクトで LSP をオンにする(TypeScript、Rust、Go、Java)。
  大規模プロジェクトでは CodeGraph などの AST インデックスを導入する。

Step 3: コンテキスト膨張の予防(ツールの導入)
  RTK で CLI 出力を圧縮する。
  agent が大量のファイル読み取りと MCP 呼び出しを行う場合は lean-ctx を検討する。
  不要な Skill を定期的に整理する。

Step 4: 隔離(使い方の変更)
  重い探索タスクを sub-agent に分割し、安価なモデルを使う。
  異なるタスクの間で /clear する。
  並列 agent は worktree を使ってファイル衝突を回避する。
  順序推論タスクに対して無理に multi-agent にしない。

Step 5: Write(ワークフローの変更)
  複雑なタスクはまず SPEC.md を生成し、/clear 後に新しい session で実行する。
  長期タスクには planning-with-files などのスキームで作業状態を永続化する。
  調査と実装を分けて行い、調査結論をファイルに保存し、コーディング時にオンデマンドで読み取る。
  定期的に ctxlint または Caliber で context drift を検査する。

Step 6: 出力制御(仕上げの最適化)
  簡単なタスクで /effort を下げる。
  自動化パイプラインに structured output を使う。
  まとめて処理できるタスク(翻訳、一括レビュー)は Batch API で50%割引を活用する。

指標はトークンだけを見ないでください。少なくとも3つのカテゴリを同時に見ます。

カテゴリ重要指標
コスト総コスト、cached input の割合、output コストの割合
効率tool call 回数、初回成功率、総所要時間
品質context の漏れがないか、誤った修正がないか、人間による修正が必要か

Agent が context を漏らし始めたり、誤った方向に進んだり、成果物の品質が低下したりした場合、削減しすぎています。良い最適化とは、コストが下がっても品質が落ちないことです。


References

Context Engineering フレームワーク

Harness Engineering

料金と課金

LLM の原理

トークン消費研究

Multi-Agent 研究

Agent メモリ

Select ツール

Compress ツール

Isolate ツールとドキュメント

Write ツールとパターン

Context Drift とメンテナンス

  • ctxlint — CLAUDE.md/AGENTS.md のパス検証と自動修復
  • Caliber — git diff から CLAUDE.md を自動更新
  • claude-code-cache-fix — resume session の cache regression を修復

出力制御とコスト監視