← ラボに戻る

コードグラフを使っても、コーディングエージェントは安くならなかった

benchmarkmcpcoding-agentsevals

二つの数字が、私をこのベンチマークに引き戻した。tree-sitter で作ったコードグラフを MCP で提供する codebase-memory-mcp の README は、トークンを 99% 減らせると約束している。私自身の以前の実行では、それを包む薄いラッパーとして私が書いた cbm-lean によって、コーディングエージェントは素の grep より haiku で 26%、sonnet で 18% 安くなった。一つ目の数字は一度も再現できず、二つ目は私の設定の欠陥から出たものだった。これは、その欠陥を直して公開リポジトリでやり直した実行だ。

設定

各質問は三つの条件で実行した。

各リポジトリに十二の質問を用意した。六つは構造に関するもの。ある関数を誰が呼ぶか、その関数が何を呼ぶか、HTTP エンドポイントからデータベースへの書き込みまでの呼び出しチェーン、モジュールの構成。残りの六つは正確さを問うもの。設定値、環境変数が読まれる場所、エラーメッセージ、クラスが定義されている行。各質問には正解に含まれるべき部分文字列の一覧があり、私はそのすべてをコードと手作業で照合した。

リポジトリは、小さな三つ(FastAPI のフルスタックテンプレート、ltx-2-mlx、avoid-ai-writing。グラフのノード数は 1.6k〜5k)と、ノード数 25k の Next.js モノレポである dub。Haiku 4.5 はすべてで、sonnet 5 は dub で実行した。合計 252 回、API 価格で $14.69。

コストは tokenEquiv で測る。入力トークン、プラス 1.25 × キャッシュ書き込み、プラス 0.1 × キャッシュ読み込み。プロンプトキャッシュが有効だと、課金された入力をそのまま見ると誤解を招く。たまたま温まったキャッシュで走った条件が、その条件とは関係のない理由で安く見えてしまうからだ。

結果

実行あたりの tokenEquiv の中央値。括弧内は正解数。

条件実行回数cbm-lean素のグラフgrep
小さなリポジトリ、haiku 4.510830,321 (28/36)43,846 (32/36)31,159 (33/36)
dub、haiku 4.57218,791 (22/24)20,687 (22/24)14,955 (20/24)
dub、sonnet 57217,227 (22/24)23,085 (22/24)13,348 (22/24)

三つの結果が揺るがない。

p 値は、質問ごとの中央値に対するウィルコクソンの符号付き順位検定によるものだ。

それぞれの条件がどこで間違えたか

グラフをつなぐことと、使うことは違う

最も役に立った結果は、本番の実行ではなく、パイロットから出た。Claude Code 2.1.283 はデフォルトで、MCP ツールのスキーマを ToolSearch という手順の後ろに遅延させる。モデルにはツール名が見えるが、何かを呼ぶ前にスキーマを取得しなければならない。ヘッドレスの haiku はそれをしなかった。六回のパイロット実行で、振り分けルールの有無にかかわらず、グラフは一度も呼ばれなかった。小さなリポジトリの十二問での結果は次のとおり。

設定グラフを呼んだ正解tokenEquiv の中央値
デフォルトの読み込み、ルールあり12 問中 2 問12 問中 11 問41,008
スキーマ読み込み済み、ルールなし12 問中 4 問12 問中 9 問62,008
スキーマ読み込み済み、ルールあり36 問中 22 問36 問中 28 問30,321

スキーマを読み込んだ状態(ENABLE_TOOL_SEARCH=false)では、同じ呼び出し元の質問が、三ターンのうちに二回のグラフ呼び出しを経た。ルールなしでグラフをつないだ設定は、すべての中で最も高くついた。どのセッションもスキーマの分を払うのに、モデルはほとんどそれを使わないままだ。

MCP サーバーを公開していて、デフォルト設定でテストしているなら、まずモデルがそもそもそれを呼んでいるかを確かめてほしい。

以前の数字が間違っていた理由

最初のベンチマークは、私のプロジェクトフォルダの中で動いていた。そこの CLAUDE.md は、構造に関する質問にはグラフを使うようエージェントに指示していた。Claude Code は親ディレクトリの CLAUDE.md ファイルも読み込むので、その指示は、グラフのない条件も含めてすべての条件に届いていた。対照群に処置群の指示が与えられていたわけで、つまりその比較は、ツールと同じくらいルールを測っていた。

やり直しの実行では、上に CLAUDE.md があるツリーの外にリポジトリを置き、ユーザー設定とフックを読み込まず(--setting-sources project)、ルールはグラフを持つ条件にだけ与える。ほかの対照策も、それぞれ以前のラウンドで出た間違った結論を正したものだ。Bash と Agent はすべての条件で禁止している。範囲を限った Bash の許可はパイプでつないだコマンドに一致せず、サブエージェントはトークンを消費しながらターンを隠すからだ。条件の順番は繰り返しごとに入れ替えるので、いつも温まったキャッシュで走る条件はない。自分の条件にないツールを呼んだ実行は破棄する。そして答えは採点する。間違った答えで節約したトークンは、節約ではないからだ。

グラフをエージェントにつなごうとしているチームに伝えたいこと

限界

モデルは二つ、リポジトリは四つでノード数は 25k まで、繰り返しは二回か三回、質問はそれぞれ十二。Opus はなし、長い対話セッションもなし、25k ノードを超えるものもなし。同じ質問でも繰り返しごとの実行結果が大きくばらついたので、中央値を報告している。

再現

すべて code-graph-vs-grep にある。固定したコミット付きの質問、ベンチマークのドライバ、すべての答えを含む生の実行記録、そして cbm-lean 本体だ。

bash bench/setup.sh
node bench/run.mjs --reps 3
python3 bench/stats.py results/*.json