コンテンツにスキップ

コードグラフでコードを検索

このガイドでは、リポジトリをコードグラフに入れ、リファクタリングの前に本当に知りたい問い — これには何が依存しているのか — に答えるために使う方法を説明します。

コードグラフは、登録済みのチェックアウトを tree-sitter でパースして構築される、シンボルとエッジのデータベースです。そのツールはエージェント向けであり、エージェントに頼むことで利用できます。

グラフがインデックスするのは Dart、JavaScript、TypeScript、TSX、PHP、Python、Rust、Zig、C、C++、Go、Java、Ruby、C#、Swift、Kotlin、R、Assembly、MATLAB、Ada です。これ以外の言語のファイルはパースされないため、search_code、code_symbol、code_callers、code_callees、code_impact には現れません。

インデックスの対象を決める要素がもう2つあります:

  • git ワークツリーでは、列挙は git ls-files --cached --others --exclude-standard に委ねられるため、あらゆる .gitignore、ネストした ignore ファイル、.git/info/exclude、グローバル除外ファイルが尊重されます。これが node_modules やビルド成果物をグラフに入れない理由です。
  • 生成された Dart は無条件に除外されます。生成ファイルは通常コミットされるため、git だけでは除外されず、コード生成のたびに変化し続けます。

チェックアウトを登録すると RepoAdded が発火し、そのチェックアウトの index_code パイプラインが自動的に開始されます。ワークスペースにリポジトリを追加を参照してください。

手動で再インデックスするには:

  1. 設定 → ワークスペース → リポジトリを開きます。
  2. リポジトリの行にあるコードをインデックスボタンをクリックします。
  3. 実行中はボタンが、完了ファイル数と合計を示す表示に変わり、キャンセル操作が付きます。完了すると、シンボル数が付いたチェックに落ち着きます。

グラフはワークスペース、リポジトリ、チェックアウトで分割されます。リンクされたチェックアウトが1つのパーティションで、各スペースのワークツリーがそれぞれ独自のパーティションを持ちます(分離リポジトリの id をキーとします)。

ハングしたように見える待ち時間の説明になるので、知っておく価値のあるスロットルが2つあります:

  • ファイルウォッチャーがホスト上で同時に受け入れるインデックス実行は1つだけなので、2つ目のチェックアウトは待ちます。index_code パイプラインはさらに、ワークスペースあたり1実行に制限されているため、同じワークスペースの2つのリポジトリはキューに入り、別のワークスペースは並行してインデックスできます。インデクサー自身は同じチェックアウトの2つの実行を直列化するため、パイプラインの開始とウォッチャーのスイープが同じものを二重にパースすることはありません。
  • 休眠スペース(直近1週間にメッセージがない)に属するワークツリーは、監視もインデックスもされません。リンクされたチェックアウトは監視され続けます。スキップの判断は5分後に再確認されるため、再びアクティブになったスペースは拾い上げられます。

エージェントに検索を頼みます。ツールは search_code で、ワークスペースとリポジトリの両方が必要です:

search_code(workspace_id: "...", repo_id: "...", query: "authentication middleware")

リポジトリの id は list_repos から取得します。省略可能な mode 引数は keyword、semantic、hybrid のいずれかで、既定は hybrid です — 名前、シグネチャ、ドキュメントコメントに対する BM25 と、ベクトル類似度を融合したものです。

各結果は、シンボルの id、名前、修飾名、種別、ファイルパス、開始行と終了行、そしてシグネチャがあればそれを運びます。id は、このページのほかのあらゆるツールに渡すハンドルです。

正確な名前が分かっている場合は、代わりに直接参照します:

code_symbol(workspace_id: "...", repo_id: "...", name: "MyClass")

どちらも検索結果の symbol_id と、省略可能な limit(既定は 50)を取ります:

code_callers(workspace_id: "...", symbol_id: "...")
code_callees(workspace_id: "...", symbol_id: "...")

code_callers はこのシンボルへ向かうエッジを持つシンボルを返し、code_callees はこれが依存しているシンボルを返します。

このページ全体が存在する理由であるツールがこれです:

code_impact(workspace_id: "...", symbol_id: "...", depth: 3)

これは逆依存の半径を計算します。つまり、calls、extends、implements エッジをたどってそのシンボルに直接的または推移的に依存するすべてです(import、mixin、ジェネリック参照はグラフに保存されていますが、ここではたどられません)。depth は最大ホップ数で、1 から 6 の間、既定は 2 です。

結果は3つのフィールドです:

  • root — 問い合わせたシンボル
  • impacted — 到達可能な集合。深さ 0 のルートを含み、それぞれがルートからの depth を持ちます
  • edgeCount — 走査がまたいだエッジの数。エッジそのものではなく件数です

名前を変更したりシグネチャを変更したりする前にこれを実行し、影響を受けるリストをエージェントのスコープとして渡してください。

結果は呼び出し元自身のワーキングコピーに対して検証される

「結果は呼び出し元自身のワーキングコピーに対して検証される」というセクション

エージェントの呼び出し元では、スペース id が自動的に注入され、結果はそのスペースのワーキングコピーに対して検証されます。呼び出し元のツリーにファイルがもう存在しないシンボルは省略され、応答には staleOmitted の件数と、それらのシンボルについてインデックスが古くなっていることを伝える注記が付きます。

同じ問い合わせに対してあなたとエージェントが別の答えを得られるのはこのためであり、あるスペースのエージェントが別のスペースのエージェントと異なる答えを得られるのもこのためです。スペース内のすべての会話はその1つのワークツリーを共有します。検証はフェイルオープンです。古い答えのほうが、空の答えより好まれます。

変更の影響範囲を知りたいときは、エージェントに code_impact(または review_studio.blastRadius)を実行するよう頼んでください。レビューコンピュートを参照してください。

セマンティック検索には埋め込みモデルが必要

「セマンティック検索には埋め込みモデルが必要」というセクション

シンボルと事実は書き込み時に、しかもオンデバイスの埋め込みモデルがインストールされている場合にだけ埋め込まれます。それまでは、mode: "semantic" と hybrid のセマンティック側には照合する対象がなく、検索は事実上キーワードのみになります。

インデックスする前に、設定 → サーバー → 診断とプライバシー → セマンティック検索でモデルをインストールしてください。シンボルは、そのファイルが取り込まれたときにベクトルを得ます。

また、サーバーバイナリを再ビルドすると文法の dylib が再ステージされて mtime が変わり、そのためすべてのインデックスのチェックポイントが無効になり、次回の実行ですべてのチェックアウトを完全に再走査することになります。再ハッシュはしますが、変更されていないファイルを再抽出はしません。

シンボルの種別: function、method、class、field、enum、constructor、getter、setter、typedef、extension、mixin、variable

エッジの種別: calls、imports、extends、implements、mixes in、references

これらのツールの正規のシグネチャは MCP ツールにあります。