0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

コードベースをナレッジグラフ化したらAIレビューの精度が変わった

0
Last updated at Posted at 2026-05-18

コードナレッジグラフでAIレビューのコンテキストを最小化するBefore/After比較

「auth.pyを変更したけど、影響範囲はどこまで?」

PRレビューで毎回考えるこの問いに、私はこれまでgrep -rと人力で答えていました。30分かけて関連ファイルを洗い出し、AIレビューにコンテキストとして渡す。多くのエンジニアが同じ作業をしているはずです。

ところが先月、コードベースをナレッジグラフ化してMCP経由でAIレビューに繋いでみたところ、この30分が2秒になりました。しかもAIが読むコンテキストは1/8に減り、レビューの精度は明らかに上がりました。

本記事ではコードKG(Knowledge Graph)×AIコードレビューの実装パターンを共有します。Tree-sitterでASTを抽出し、MCPでAIに渡すまでの最短パスです。

なぜ「全ファイル読ませる」が破綻するのか

まず問題の構造を整理します。AIコードレビューのデフォルトは、変更diff+関連ファイル全部、です。

PRの差分: 200行
+ 念のため関連しそうなファイル: 50個(150,000トークン)
= AIに渡すコンテキスト: 約160,000トークン

Claude 3.5 Sonnetの上限は200Kトークンです。1PRで上限の80%を使い切ります。結果はこうなります。

  • レビュー精度が落ちる(情報過多で焦点が散る)
  • トークンコストが膨らむ(1PRあたり数十円〜数百円)
  • 速度が落ちる(コンテキスト処理に時間がかかる)

「念のため大量に渡す」がAIレビューの最大のボトルネックです。

コードKGが解く問題

コードナレッジグラフは、コード構造を関数・クラス・呼び出し関係のグラフとして持ちます。Tree-sitterでASTを抽出し、グラフDBに格納します。

ノード: 関数、クラス、ファイル、テスト
エッジ: 呼び出し、継承、import、テストカバレッジ

これをMCP経由でAIに公開すると、AIは「この変更の影響範囲」をグラフ探索で2秒で計算します。grep -rと違い、関数の呼び出しチェーンを正確に追えます。

私が試したcode-review-graphの公式ベンチマークでは、レビュー時のトークン消費が6.8倍削減、日常コーディングタスクで49倍削減を記録しています。

私が試した主要OSSはcode-review-graph、CodeGraphContext、Codebase-Memory(arxiv論文)の3つです。Codebase-Memoryは83%の回答品質を維持しつつトークン10倍削減、ツール呼び出し2.1倍削減、と論文で報告しています。

30分で動かす最小実装

最小構成で動くようにする手順を共有します。Pythonプロジェクトを想定します。

Step 1: Tree-sitterでASTを抽出

import tree_sitter_python as tspython
from tree_sitter import Language, Parser

PY_LANGUAGE = Language(tspython.language())
parser = Parser(PY_LANGUAGE)

with open("app/auth.py", "rb") as f:
    tree = parser.parse(f.read())

def walk(node, depth=0):
    if node.type in {"function_definition", "class_definition", "call"}:
        name = node.child_by_field_name("name")
        if name:
            print("  " * depth + f"{node.type}: {name.text.decode()}")
    for child in node.children:
        walk(child, depth + 1)

walk(tree.root_node)

これだけで関数定義・クラス定義・呼び出し関係を抽出できます。Tree-sitterは66言語に対応しており、TypeScript/Go/Rustでも同じ構造で書けます。

Step 2: グラフDBに格納

私はSQLiteでまず動かすのを推奨します。Neo4jはオーバーキルです。

CREATE TABLE nodes (
    id INTEGER PRIMARY KEY,
    kind TEXT,        -- 'function' | 'class' | 'file'
    name TEXT,
    file_path TEXT,
    start_line INTEGER,
    end_line INTEGER
);

CREATE TABLE edges (
    src INTEGER,
    dst INTEGER,
    kind TEXT,        -- 'calls' | 'imports' | 'inherits'
    FOREIGN KEY (src) REFERENCES nodes(id),
    FOREIGN KEY (dst) REFERENCES nodes(id)
);

ノード数が10万を超えるまではSQLiteで余裕があります。私の社内モノレポ(30万行)でも、グラフサイズは数十MBで収まりました。

Step 3: blast radius関数を実装

「この関数を変更したら、どのファイルが影響を受けるか」を計算する関数です。

def blast_radius(func_name: str, max_hops: int = 3) -> dict:
    """指定関数のblast radiusをBFSで計算"""
    visited = {func_name}
    frontier = {func_name}
    layers = []

    for hop in range(max_hops):
        next_frontier = set()
        for node in frontier:
            callers = db.execute(
                "SELECT src.name FROM edges e "
                "JOIN nodes src ON e.src = src.id "
                "JOIN nodes dst ON e.dst = dst.id "
                "WHERE dst.name = ? AND e.kind = 'calls'",
                (node,)
            ).fetchall()
            for (caller,) in callers:
                if caller not in visited:
                    next_frontier.add(caller)
                    visited.add(caller)
        layers.append({"hop": hop + 1, "nodes": list(next_frontier)})
        frontier = next_frontier
        if not frontier:
            break

    return {"target": func_name, "layers": layers}

呼び出しチェーンを逆方向に追います(誰が呼んでいるか)。3ホップ程度で大半の影響範囲をカバーできます。

Step 4: MCPサーバーとして公開

from mcp.server import Server
from mcp.types import Tool, TextContent

server = Server("code-kg")

@server.list_tools()
async def list_tools() -> list[Tool]:
    return [
        Tool(
            name="blast_radius",
            description="指定関数のblast radius(影響範囲)を返す",
            inputSchema={
                "type": "object",
                "properties": {
                    "function": {"type": "string"},
                    "max_hops": {"type": "integer", "default": 3},
                },
                "required": ["function"],
            },
        ),
    ]

@server.call_tool()
async def call_tool(name: str, arguments: dict) -> list[TextContent]:
    if name == "blast_radius":
        result = blast_radius(arguments["function"], arguments.get("max_hops", 3))
        return [TextContent(type="text", text=json.dumps(result, indent=2))]

最小構成のMCPサーバーです。Claude CodeやCursorに登録すれば、AIが必要に応じてblast_radiusツールを呼び出します。

AIレビューでの実際の変化

導入前と導入後で、私のチームのレビューフローはこう変わりました。

Before(KGなし)

1. PRが上がる
2. レビュアーが diff を読む
3. 「auth.pyの変更って他に影響ない?」と不安
4. 関連ファイルを手動 grep(30分)
5. 全部コピーしてAIレビューに渡す(160Kトークン)
6. AIが情報過多で焦点を外す、汎用コメントが返る
7. 見落としがあり、後日バグ発覚

After(KGあり)

1. PRが上がる
2. AIがblast_radius自動実行(2秒)
3. 影響を受ける7ファイル + リスクスコア7.2/10
4. AIにそれだけ渡す(18Kトークン)
5. 焦点の絞られた具体的なレビューが返る
6. 高リスク箇所を集中レビュー

時間圧縮よりも、レビューの質的変化の方が大きいと私は感じています。AIが「念のため」と「本当に必要」を区別できるようになると、コメントの精度が一段上がります。

既存ツールとの組み合わせ

ゼロから実装しなくても、OSSが充実しています。私が試した3つを紹介します。

ツール 特徴 おすすめ
code-review-graph Claude Code/Cursor自動連携、22 MCPツール ◎ 最初に試すならこれ
CodeGraphContext CLI + MCP、Neo4jベース 大規模コードベース向け
graphify Claude/Codex/Gemini対応、66言語 マルチエージェント向け
# 最短デモ(code-review-graph)
pip install code-review-graph
code-review-graph build ./my-project
code-review-graph install  # Claude Code/Cursorを自動検出

Claude Code/Cursor/Windsurf/Zedを自動検出してMCPサーバー設定までやってくれます。3コマンドでAIレビューがblast radius対応になります。

GitHub Actionで自動化する

PRを開くと自動的にblast radiusコメントが投稿される構成も組めます。code-review-graphはdiff-radiusサブコマンドで「base〜head間の影響範囲」を直接出せるので、Actionsから叩いてactions/github-scriptでPRコメント化するだけです。

PR作成と同時に「影響ファイル7件、リスクスコア7.2/10」のコメントが付くと、レビュアーは数値を見て優先度を即決できます。私のチームでは、リスクスコア6以上のPRは「2人レビュー必須」というラベル付けも自動化しています。

落とし穴と対策

私がハマった3つの落とし穴も共有します。

落とし穴1 動的呼び出しが追えない

# 静的解析では追えない
fn = globals()[fn_name]
fn(args)

Pythonのgetattr / globals()、JSのrequire(dynamic)は静的解析では捕まえられません。私は動的呼び出しを警告として記録するルールにしています。完璧を諦め、人間に「ここは確認してね」と渡す方針です。

落とし穴2 マイクロサービス境界

サービスAからサービスBへのHTTP呼び出しは、コードKGでは追えません。OpenAPIスキーマからエッジを補完する仕組みを別途用意する必要があります。

落とし穴3 グラフ更新コスト

毎PRでフルビルドすると遅いです。差分ビルド(変更ファイルだけ再パース)の仕組みは必須です。code-review-graphは差分ビルド対応しているので、私はそれに乗っかっています。

まとめ

コードベースをナレッジグラフ化すると、AIレビューが「念のため大量に読む」から「必要なものだけ正確に読む」に変わります。

  • Tree-sitterで66言語のAST抽出が可能
  • SQLiteで10万ノードまでなら十分
  • MCP経由でAIエージェントに公開すれば自動でツール呼び出し
  • code-review-graphなら3コマンドで動作開始
  • トークン消費6.8倍削減、レビュー品質が同時に向上

私のチームは導入1ヶ月で、AIレビューのコメント精度が体感で1.5倍以上になりました。30分かけていた手動grepが、2秒のツール呼び出しに置き換わるだけで、レビュー文化が変わります。

あなたのプロジェクトのAIレビューは「全ファイル読ませる」になっていませんか。一度code-review-graph buildを叩いてみると、世界が変わるかもしれません。

コードKGの理論と実装をさらに掘り下げたい方へ。Zenn Book「ナレッジグラフ実践ガイド」の第10章で、本記事のMCP統合からエンタープライズGraphRAGまでを体系的に解説しています。
https://zenn.dev/kenimo49/books/knowledge-graph-practical-guide

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?