関数名を変えるだけで、14種類のモデルが同じコードを読む際のトークン消費を最大3分の2削減できた
- 関数に付ける名前次第で、AIが修正するときに読むファイル数が19個にも459個にも変わります。Modemは1,680回の対照実験でこのコストを明らかにしました
- 根本原因はここにあります。AIはコードを探すのにプレーンテキスト検索を使います。コンパイラが描く依存関係グラフも、シンボルを解析する言語サーバーもありません。Claude Codeチームは初期にベクターデータベースを試しましたが、結局捨てました
- 名前を一発で見つかるものに変えると、14種類のモデル・ツール組み合わせ全てでトークン消費が減少。最大削減ケースでは平均7万→2.4万トークン。中央値で3割削減。しかも、自信満々に間違えるケースはゼロになりました
- 節約できた検索予算は、そのまま判断力に変わります。同じ8ラウンドの調査予算でバグ探しをさせたところ、弱いモデルは巨大ファイルでは8個中3個しか見つけられませんでしたが、コードを分割しリネームした後は8個全てを発見。失敗したレビューのほとんどは誤った回答をしたわけではなく、予算を全てファイル探索に費やし、結論にたどり着けていませんでした
AIは一体どうやってコードを探しているのか?(基本メカニズム)
コーディングAIに「この関数名を変えて」と頼むと、彼らはまずあなたのリポジトリを検索します。
この「検索」には何ら高度な仕組みはありません。リポジトリ全体のテキストを走査し、指定した文字列が含まれる行を探します。エディタでCtrl+Fを押すのとまったく同じです。この操作はコマンドラインではgrepと呼ばれ、数十年前から存在します。AIが使うのはその高速版ripgrep(コマンドはrg)です。
彼らはコンパイラに依存関係グラフを尋ねたり、言語サーバーにシンボルを解決してもらったりはしません。彼らが認識するのは文字通り表記だけです。検索し、ヒット箇所の前後を読み、足りなければ別の言葉で再検索します。
これは特定のツールが怠けているわけではありません。Claude Codeチームは初期にベクターデータベース方式を試しましたが、結局捨てました。プレーンテキスト検索の方が優れていたからです。学界発のSWE-agentも同じ結論に至っています。モデルに与えられているのは専用のキーワード検索ツールだけで、それ以上に派手なものはありません。
パスも検索語になります。「session broker(セッション仲介)はどう動くの?」と尋ねると、AIはsession-broker、sessionBroker、session_brokerの3つの綴りでファイル名を検索します。session-broker/というディレクトリは、最初の一行を読む前から、すでに一度ヒットしているのです。
AIはこのループを回っています。検索し、ヒット箇所の周辺を読み、足りなければ別の言葉で再検索し、十分になればようやく編集を始めます。
つまり、この連鎖の中に、コードを書く人間が完全にコントロールできる入力が一つあります。それは、あなたのコード内の語彙とファイル名が、優れた検索語になり得るかどうかです。
このコストを計算したのがModemです。この会社は2025年初頭に創業し、コードを全てAIで書くことを決定しました。1年間でTypeScriptアプリコード36万行、テストコード32万行を生成し、その99.9%をモデルが作成しました。以下の知見と1,680回の対照実験は、すべてこの1年間の成果です。
名前が曖昧だと、どれほどのコストになるのか?
では、「優れた検索語」とそうでない場合、具体的にどれだけ違うのでしょうか。彼らは3つの関数で比較しました。
これら3つの関数は機能が完全に同じで、どれも外部サービスを呼び出すAPIクライアントを作成します。違いは名前だけです。
export function create(apiKey: string) { ... }
export function createClient(apiKey: string) { ... }
export function createStripeClient(apiKey: string) { ... }
Modemの約2,900ファイルからなるTypeScriptリポジトリで、それぞれを検索してみます。
つまり問題は検索の速さではありません。grepが返すのはマッチした行であり、答えではありません。const client = create(config)という一行を見ても、それがAIに求められているクライアントなのか、それとも同じcreateという名前の数百あるうちの一つなのかは分かりません。
それを判断するには、ファイルを開いてヒット箇所の周辺を読み、さらに範囲を広げたり、別の箇所を開いたりする必要があります。ファイルは数十行から数千行まで様々で、1行あたり約10トークン(トークンはAIが読み書きするテキストの単位。一度の会話で扱える量や料金はこれで計算され、おおよそ英単語1つが1トークン強に相当)とすると、誤った候補を1つ排除するだけで数百〜数千トークンを消費します。それを十数個続ければ、数万トークンが消えていきます。お願いした作業はまだ一字も実行されていないのに。
あの1,585件のヒットは、数百の無関係なものに散らばっています。テスト用のダミーデータ、データベースへのレコード挿入、バックグラウンドタスクの登録などです。一方、createStripeClientの43件のヒットは、定義、呼び出し箇所、テストで、すべて同じクライアントについて語っています。
