grepはLSPに勝るのか?コーディングエージェントがより高度なツールを無視する理由
Grep beats LSP? Why coding agents ignore your fancier tools (agentconnect.md)
要約
この記事では、コーディングエージェントがコード検索や編集タスクにおいて、grepのようなシンプルなツールを、LSP(Language Server Protocol)ベースのより高度なセマンティックナビゲーションよりも好む傾向があることを調査しています。その理由は、ツールのLLM(大規模言語モデル)フレンドリーさ、つまりモデルが直接利用しやすい出力形式やコンテキストを提供できるかどうかにあり、単に結果の精度が高いだけでは不十分であることが示唆されています。ツールのインターフェース設計や、モデルが学習した行動パターンとの親和性が、エージェントのツール選択に大きく影響することが明らかになりました。
全文翻訳
GrepはLSPに勝る?コーディングエージェントがより高度なツールを無視する理由
なぜコーディングエージェントは、より正確な結果を返す検索インターフェースを無視するのでしょうか?
これは、単純なテキスト検索であるgrepと、LSP(Language Server Protocol)ベースのセマンティックナビゲーションを比較した小規模な調査で直面した問題です。私はセマンティックナビゲーションがノイズを減らし、トークンを節約すると予想していました。しかし、エージェントはほとんどの場合grepを使い続け、セマンティックパスを強制すると、タスクの成功率が低下することさえありました。
精度は、ツールがLLMフレンドリーであるための要素の一部に過ぎませんでした。ツールは、次のステップのために十分なコンテキストを、モデルが直接操作できる形状で返す必要もあります。慣れ親しんでいるかどうかも重要かもしれません。モデルはトレーニング中に類似したアクションパスを学習している可能性があります。インターフェースの効果は、以下の結果に直接現れています。トレーニングが結果を説明していると証明することはできませんが、データには合致しています。
いずれにせよ、モデルはツールを単独で使用するわけではありません。利用可能なアクション、その入力、そして返ってくるコンテキストを定義するハーネスを通じて使用します。
[画像: エージェントの能力はモデル×ネイティブハーネス]
モデルとその慣れ親しんだツールのループは、一つの能力表面として機能します。
2つのコード検索インターフェースの比較
grepはテキスト検索を実行します。一致するテキストを見つけ、ファイルパス、行番号、一致したコンテンツを返します。LSPベースのツールは、参照、定義、ドキュメントシンボルの3つの機能を通じてセマンティックナビゲーションを実行します。これらは、コメント内の同じ単語と実際の関数呼び出しを区別できます。
LSPは診断、リネーム、コードアクションも提供します。これらはテストしていないため、結果は上記の3つのナビゲーション機能のみに適用されます。
このパイロット調査では、3つのClaudeモデル、複数のPythonおよびTypeScriptリポジトリ、そしてコードの特定、参照の網羅性、複数ファイルのリネームという3種類のタスクを対象としました。各セルは2〜3回実行されたため、数値を最終的な判定ではなく、傾向として捉えてください。
タスクが完了した場合のみトークン使用量を比較しました。失敗した実行は、早期に停止しただけで効率的に見えることがあります。
エージェントはタスクによってルーティングする
単純なコード特定タスクでは、3つのモデルすべてが、両方のツールが利用可能な場合でも、セマンティックツールを0%から6%の時間しか選択しませんでした。セマンティックファーストパスを強制すると、成功率は100%から89%に低下しました。
参照の網羅性タスク、つまりエージェントがすべての呼び出し元を見つける必要があるタスクでは、状況は異なりました。モデルは45%から57%の時間でセマンティックナビゲーションを選択しました。
[画像: タスク別のセマンティックツール使用率:特定とリネームではほぼゼロ、参照の網羅性では45%〜57%]
両方のツールが利用可能でエージェントが自由に選択した場合のセマンティックツール呼び出しの割合。
| タスク | Opus 4.8 | Sonnet 4.6 | Haiku 4.5 |
|---|---|---|---|
| 特定 | 0% | 4% | 6% |
| 参照の網羅性 | 45% | 50% | 57% |
| 複数ファイルリネーム | 3% | — | — |
参照タスクでLSPパスが得たものは精度でした。grepの0.76に対して1.00であり、返されたすべてのサイトが実際の呼び出しであり、同じ名前のテキストからの誤った一致がなくなったことを意味します。
エージェントが最終的に見つけた真の呼び出しサイトの割合であるリコールは、両方のパスで約0.66にとどまりました。よりクリーンな結果は、より多くの呼び出しを見つけることにはつながりませんでした。エージェントはまだすべてを処理する前に停止しており、異なるバックエンドがそれを修正するわけではありません。より強力なモデルでは、精度の向上はトークンを節約するどころか、より多くのコストがかかりました。
ノイズの多いコードベースではLSPが有効
クリーンなTypeScriptリポジトリであるremedaでは、grepはすでにすべての参照を正しく解決していました。LSPに切り替えてもF1スコアに変化はなく、トークン使用量は16%増加しました。F1は精度とリコールを組み合わせたもので、変化がないということは検索品質が向上しなかったことを意味します。
hono、別のTypeScriptリポジトリでは、grepの精度は0.51にすぎませんでした。これは、同じ識別子が多くの場所に現れるためです。ここでLSPはF1スコアを0.246向上させ、トークン使用量を12%削減しました。
Pythonリポジトリのrequestsは中間でした。F1スコア+0.072、トークン使用量+19%。
[画像: LSPによるF1スコアの変化:クリーンなTypeScriptリポジトリremedaでは+0.000、ノイズの多いTypeScriptリポジトリhonoでは+0.246、ノイズの多いPythonリポジトリrequestsでは+0.072]
参照の網羅性におけるセマンティック検索によるF1スコアの向上(ΔF1 = LSP − grep)。
| リポジトリ | 言語 | grep精度 | ΔF1 (LSP − grep) | トークンコスト |
|---|---|---|---|---|
| remeda | TypeScript | 1.00 | +0.000 | +16% |
| hono | TypeScript | 0.51 | +0.246 | −12% |
| requests | Python | 0.76 | +0.072 | +19% |
同じ言語の2つのリポジトリで反対の評価が得られたため、「静的型付け言語はLSPに適している」というのは誤った予測因子です。重要なのは、そのコードベースでgrepがどれだけの誤った一致を生成するかです。grepがすでにクリーンな場所では、セマンティックナビゲーションは純粋なオーバーヘッドですが、同じ名前がどこにでもある場所では、精度がそれに見合う価値をもたらします。
出力形状がエージェントの動作を変える
LSPベースのツールは当初、ファイルパス、行番号、列番号のみの場所を返しました。エージェントは参照の場所を知っていましたが、何かを決定する前にコードを見るためにファイルを開く必要がありました。
grepは行自体を返します。
src/auth.ts:42: return validateToken(token)
場所とコンテンツが一緒に届くため、モデルは再読することなく関連性を判断できます。
そこで、セマンティックナビゲーションの応答を変更し、各参照の両側に2行のソースコードを添付するようにしました。バックエンドと参照のセットは同じままで、モデルが見るものだけが変わりました。
複数ファイルのリネームタスクでは、LSPパスのpass@1は0.67から0.83に上昇し、後続のファイル読み取りはエピソードあたり15.2から3.2に減少しました。これはgrep自身の4.3よりも少ない値です。
[画像: grep、LSP(場所のみ)、LSP(インラインコンテキスト付き)のPass at 1と後続のファイル読み取り数]
複数ファイルのリネーム、Opus 4.8、pyright、事前ウォームアップされたインデックスを使用。両方のLSPパスは単一のバックエンドを共有し、出力形状のみが異なります。
| パス | pass@1 | サイトリコール | トークン | 後続の読み取り |
|---|---|---|---|---|
| grep | 1.00 | 1.000 | 2,451 | 4.3 |
| LSP — 場所のみ | 0.67 | 0.930 | 4,131 | 15.2 |
| LSP + インラインコンテキスト | 0.83 | 0.958 | 3,336 | 3.2 |
場所のみの場合、モデルは読み取りを計画し、ツールを呼び出し、結果を消化してから行動する必要があります。ソースコードがインラインで表示される場合、これらのステップは不要になります。
Anthropicはエージェント向けの効果的なツールの作成で同様の点を指摘しています。ツールは非決定的なエージェントのためのインターフェースであるため、それらが返すコンテキストは設計の一部です。セマンティックに正しいツールであっても、各結果の解釈に複数の追加アクションが必要な場合、ワークフローは貧弱になります。
慣れ親しみが改善を駆動したかどうかは未解決です。モデルはトレーニング中に多くのgrepのような軌跡を目にした可能性があり、インライン形式はそれらが知っているものに似ているかもしれません。あるいは、各応答が単により多くの有用な情報を含んでいただけかもしれません。どちらの説明も結果に合致しており、この調査ではトレーニングデータを操作していないため、それらを分離することはできません。
一部のタスクは構造的にレキシカル検索を優先する
インターフェースの変更では除去できない違いもあります。LSPとgrepは異なるセットを取得します。セマンティック参照はコード内の実際のシンボル関係です。リネームは、コメント、ドキュメンテーション文字列、設定、文字列リテラルにも触れる必要がある場合があります。これらはfind_referencesでは設計上返されませんが、grepは返します。
セマンティック参照 ⊂ テキスト上の出現
テキスト全体にわたる編集の場合、grepは、LSPベースのナビゲーションで完璧なトレーニングを受けたモデルであっても、より優れた検索ツールになる可能性があります。
この調査でgrepが有利だった説明は、次の2つに絞られます。
- 構造。 一部のタスクはテキスト的な網羅性を必要としますが、テストされたセマンティックツールはそれを提供しません。この調査はこれを直接裏付けています。
- 分布。 モデルは、慣れ親しんだツールや結果の形状でより多くの練習を積んでいる可能性があります。これはルーティングと出力形式の結果と一致しますが、この調査では証明できません。
[画像: grepの結果の背後にある構造的および分布的な原因]
ハーネスはシステムの一部である
コーディングエージェントはモデル以上のものです。モデルの周りにはハーネスがあります。コンテキスト内の指示、利用可能なツール、それらの入力スキーマ、結果とエラーの形状、そして次にモデルに何を見せるかを決定するループです。
エージェントの能力 = モデル × ハーネス
この調査では、LSPバックエンドは変更されず、モデルも変更されませんでした。数行のソースコードを返すだけで、成功率とファイル読み取り数を動かすことができました。
Anthropicの長期間実行されるエージェントのための効果的なハーネスに関する作業は、より長い時間スケールで同様の点を指摘しています。環境設定、進捗アーティファクト、検証ルーチンが、セッション全体でエージェントが達成できることを決定します。単一のツールループ内では、結果形式、エラーメッセージ、フォールバックパスが同じ役割を果たします。
トレーニング後のエージェントの軌跡には、ハーネスもそれらの例におけるプロンプト、ツール呼び出し、結果、および回復パスを定義します。read、grep、edit、bashの繰り返し使用を通じてトレーニングされたモデルは、それらのインターフェースに依存するポリシーを学習する可能性があります。それを異なるツールレイヤーに移動すると、その効果的な能力が変わる可能性があります。
これが、モデルのベンチマーク結果が異なるランタイムにそのまま適用されない理由です。
ツールを追加する前の6つのチェック
LSPはノイズの多いコードでの検索品質を向上させ、小規模な応答形式の変更でほとんどの後続読み取りを削除したため、LSP、MCP、または新しいエージェントスキルに反対しているわけではありません。新しいツールを信頼する前に、完全なエージェントループ内でテストすることを主張しています。ネイティブツールサーフェスから始め、次に以下を確認してください。
- 同等の精度で実際のタスクをテストする。 成功率も低下した場合、トークン使用量の削減は勝利ではありません。
- エージェントがそれを呼び出すかどうかを測定する。 ツールが利用可能であっても、モデルがいつ使用するかを知っているとは限りません。
- 次の決定のために十分なコンテキストを返す。
path:line:contentは、通常、ベアロケーションオブジェクトよりも優れています。 - ネイティブのフォールバックを維持する。 セマンティック検索とレキシカル検索は異なる問題を解決します。
- タスクとコードベースでルーティングする。 ノイズの多いリポジトリはセマンティックナビゲーションの恩恵を受ける可能性があります。テキスト全体のリネームには、依然として
grepが必要です。 - 重要な場合は新しい軌跡を強化する。 プロンプトはツールを導入できますが、それを使用するための信頼できるポリシーを作成するとは限りません。
効果的なエージェントの構築は、シンプルで composable なパターンを推奨しています。ツールも同様です。ツールの数が増えても、より能力の高いエージェントになるわけではありません。
結論
セマンティックナビゲーションは誤った一致を減らしましたが、それはgrepがノイズの多い場合にのみ効果がありました。ベアロケーションとして返された場合、より正確な結果はより多くの読み取りを引き起こしました。ソースコードが数行添付されている場合、同じ結果は使いやすくなりました。新しいツールの評価には、エージェントがそれを選択するかどうか、タスクが成功するかどうか、コストはいくらか、そして出力が次のステップをサポートするかどうかを監視することが含まれます。
完全な実験設定、タスク定義、および結果については、Does a Language Server Save Tokens for Coding Agents?を参照してください。
これは、エージェントを接続するためのオープンプロトコルを使用し、各モデルをネイティブランタイムとツールループと共に維持するという、AgentConnectの製品原則です。
これは、小規模なタスクセット、少数のリポジトリ、3つのClaudeモデル、およびセルあたり2〜3回のロールアウトによる予備的なパイロットです。参照、定義、ドキュメントシンボルを介したLSPベースのナビゲーションをテストしました。textDocument/rename、診断、またはコードアクションはテストしていません。リネーム機能を備えたLSPは、grepが最も得意としたリファクタリングタスクで異なるパフォーマンスを示す可能性があります。編集タスクはローカルであり、標準的なSWE-benchスコアではありません。これらの発見は、すべてのモデル、ツール、コードベースにわたる最終的な判定ではなく、有用なシグナルです。