← ブログに戻る

Tree-sitter × MCPでコードをナレッジグラフ化、レビュー自動化の設計図

この記事を含む総合ガイド Claude Code 実戦運用ガイド

「レビューAIが読んでるのは diff だけで、その関数がどこから呼ばれてるかは見えてないんだよ」

先月、同僚がPRレビューのAIコメントを見て言った一言です。私は返す言葉がありませんでした。実際そのとおりで、多くの AI コードレビューは変更行の前後 50行を読んで、それらしいことを言っているだけ。呼び出し元が知りたければ grep で探す。それは AI がやっているのではなく、私たちがやっている作業を AI に代弁させているだけです。

構造で見せたいなら、コードを グラフ にするしかない。ここ半年、Tree-sitter で AST を取って、MCP サーバー経由でグラフDBに流し込む方向が急速に整理されてきました。この記事はその設計図です。

AST → MCP → グラフDB → レビューAI の4段パイプ。従来の diff-only レビューとの対比

何が変わったのか、一行で

「変更ファイルの周辺 50個を投げる」から「変更ファイルの blast radius だけを投げる」に変わりました。 私が最初に MCP でコードKGをつないだとき、auth.py の影響範囲を教えて と聞いたら 2秒で 7ファイルのリストが返ってきて、それまで自分が 30分かけて grep で追っていた結果とほぼ同じでした。あの 30分は何だったんでしょうね。

トークン量で言えば、Codebase-Memory の2026年の論文 で 10倍のトークン削減と 2.1倍のツール呼び出し削減が報告されていて、私の実測もその範囲に収まります。

4段のパイプライン

やっていることは意外と単純です。

コード → Tree-sitter (AST) → MCP サーバー → グラフDB → レビューAI

上から順に説明します。

1. Tree-sitter で AST を取る

Tree-sitter は 60以上の言語をインクリメンタルにパースできる。パースしてくれるのは AST (抽象構文木) で、これは「関数がどこで定義され、どこから呼ばれ、どのクラスに属し、どのファイルにあるか」という構造情報の生データです。

grep との違いは、grep は文字列で当てるだけで意味を見ていないのに対して、AST は「これは関数の呼び出しである」という意味付きのノードで返してくれること。authenticate が関数名なのか変数名なのかコメント内の単語なのか、AST は区別できます。

2. MCP サーバーで外に出す

AST を持っているだけではダメで、それを AI アシスタントから叩ける形にする必要があります。ここが MCP (Model Context Protocol) の出番です。

MCP は Anthropic が 2024年末に公開した、AI とツールをつなぐ標準プロトコル。Claude Code / Cursor / Windsurf / VS Code の各種 IDE 拡張が対応済みで、Repo-GraphRAG MCP のような実装がすでに動いており、mcpservers.org には他にも同種の実装がいくつか並んでいます (後継含む)。

MCP サーバーが提供する典型的なツールはこんな顔ぶれです。

ツール用途
build_graphコードベース全体からグラフを構築
blast_radius変更の影響範囲をホップ数付きで返す
flow_trace関数の呼び出しフローを追跡
semantic_searchグラフ構造を考慮したコード検索
risk_score変更リスクを 0-10 でスコアリング

3. グラフDBに流し込む

Neo4j でも Kùzu でも SQLite の再帰CTE でも構いません。ノードは関数・クラス・ファイル・モジュールエッジは呼び出し・継承・import。この2種類さえあれば、blast radius は「変更ノードから N ホップで届くノードの集合」という一行のクエリになります。

私は最初 Neo4j で組んでみて、次に「そこまで大がかりじゃなくていい」と気づいて Kùzu に移しました。パースが数秒、クエリがミリ秒。ローカルで完結するので CI にも組み込めます。

4. レビューAIから叩く

Claude Code なり Cursor なりの MCP 設定に、上で作ったサーバーを登録するだけ。あとは自然言語で聞くと、裏でグラフクエリが飛びます。

私: 「auth.py を変更した場合の影響範囲を教えて」

Claude (裏でツール呼び出し):
→ blast_radius("auth.py")

結果:
  Hop 1: middleware.py, api/login.py, api/register.py
  Hop 2: tests/test_auth.py, tests/test_login.py
  Hop 3: conftest.py

  リスクスコア: 7.2 / 10

このリストがあると、次に私は「じゃあ Hop 1 の 3ファイルだけを読んで、レビューして」と言える。AI に投げるコンテキストが最小化される、というのはこういうことです。

PRレビューでどう変わるか

Before / After がわかりやすいので、二列で並べます。

Before(KGなし)

  1. PRが作成される
  2. レビュアーが diff を読む
  3. 「この変更、他のどこに影響するんだっけ」と不安になる
  4. 手で関連ファイルを探す。時間がかかる
  5. 見落として、翌週バグが出る

After(KGあり)

  1. PRが作成される
  2. AI が blast radius を先に返す
  3. 影響ファイル・関数・リスクスコアが提示される
  4. 高リスク箇所に集中してレビューできる
  5. 見落としが減る(ゼロにはならない)

もっと踏み込むと、Code-Graph-RAG のように呼び出しグラフをCIから叩ける実装もあり、私はこれを社内の週次リポジトリに組み込んで、レビュアーの視線を最初の 3分で最重要箇所に振る使い方をしています。

LinkedIn の 28.6% 短縮事例と接続する

「本当に効果あるのか」という話は、LinkedIn が社内カスタマーサポートに GraphRAG を入れて issue の中央値解決時間を 28.6% 短縮した (論文、MRR は 0.522 → 0.927) ケースが有名で、これはコードではなく issue tracker が対象ですが、ドキュメントをグラフ化して検索する という設計思想はまったく同じ。コードでも似た比率が出るのは想像に難くないです。

私が測った範囲で言うと、レビュー1本あたりのトークン量が 150,000 → 18,000 に落ちて、Claude API の月額請求が3分の1になりました。品質が落ちたかというと、逆に見逃しが減っている感触があります。理由はシンプルで、無関係な 40ファイルを AI に読ませても AI は疲弊するだけで、7ファイルに絞ったほうがちゃんと読んでくれるからです。

つまずきポイント

導入して 3ヶ月、私が実際にハマった 3つ。

1. 言語横断のプロジェクト

TypeScript と Python が混在するモノレポでは、Tree-sitter の grammar を両方入れて、なおかつ「TS の import が Python の CLI を呼んでいる」ような境界は AST では見えない。ここは別途 shell スクリプトや CI設定ファイルもパースする層を足す必要がありました。

2. グラフの鮮度

コミットのたびに再構築すると重い。私は「変更ファイルとその direct dependencies だけ差分更新」で妥協しました。1週間に一度、フルリビルドを CI で回す。これで p99 でも 30秒以内で追いつきます。

3. リスクスコアの誤検知

初期の実装では「Hop 数が多いファイルはリスク高」という単純ルールで、テストファイルまで巻き添えで高リスク判定されました。テスト・ドキュメント・自動生成コードを除外するフィルタを追加してから、実用に耐える精度になりました。

まとめ

Tree-sitter で AST を取り、MCP でグラフDBに流し込み、レビューAIから叩く。この 4段のパイプができると、コードレビューは「diff を眺める」から「blast radius を先に確認して、影響が集中する箇所を優先的に読む」に変わります。トークン消費は 8倍から10倍単位で減り、見逃しも減る。

まだ「AST パーサー書けばいいのね」で終わるほど枯れてはいませんが、既存の MCP サーバー実装を組み合わせれば、週末で試せる範囲に来ています。私はこの半年でコードレビューの体感が明確に変わりました。試す価値はあります。

実装レベルの詳細は、私が書いた『ナレッジグラフ活用大全』にまとめています。GraphRAG の理論、コードKG の設計、MCP との統合を、この記事で触れきれなかった箇所も含めて扱っています。

ナレッジグラフ活用大全 — GraphRAG・コードKG・MCPの実装ガイド。

ナレッジグラフ活用大全 関連書籍 ナレッジグラフ活用大全 ナレッジグラフ 活用大全 | GraphRAG・Neo4j・RDF・Property Graph・Emotion AI の実践書 書籍ページを見る →