← ブログに戻る

AIコードレビュー、Diffで依存を見逃す実測

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

半年前、私は自社リポジトリのAIレビュー結果を眺めながら、優秀なレビュアーを雇っているつもりでいました。実際に頼んでいたのは、両目を紙で覆ったまま「この差分は問題ありません」と即答する新人でした。差分の外で何が壊れているかは、当人には見えていませんでした。

この記事は「AIレビューの入力範囲」の話です。同じシリーズで書いた Tree-sitter+MCPでレビュートークンを8〜49倍削った はトークン圧縮の話、ナレッジグラフで対象を9割削った は絞り込みの話でした。本記事はその逆方向、「Diffだけを渡すと、依存グラフの先にあるバグが構造的に見えない」という盲点の話です。

Diffだけでは届かない場所がある

CodeRabbit や Copilot PR Review の初期設定は素直です。変更ファイルの差分をLLMに投げます。差分の中にバグがあれば、これで見つかります。問題は、差分の中には問題がないのに、差分の外にバグを埋め込むタイプの変更です。

典型例を挙げます。

関数 A を編集しました。返り値の型を User から User | null に変えました。差分にはそのシグネチャ変更しか出ません。しかし A を呼ぶ B は差分に含まれません。B を呼ぶ C はもっと遠くにあります。C のコードでは user.name を平然と参照しています。A の変更以降ここが null.name で落ちます。

Diffだけを渡された AI レビュアーは、A の変更が「型を拡張しただけ」に見えます。呼び出し側のコードは入力に入っていないので、影響評価が構造的に不可能でした。人間のレビュアーですら気付きにくい変更が、AIには最初から見える形で届いていません。拙著 AIコードレビューを仕組み化する技術 の第2層(AIレビュー)を書いていて一番強く感じたのはこの点でした。AIレビューの限界は「モデルの賢さ」の問題ではありません。

「入力範囲の設計」の問題です。

同じモデルでも、Diffだけを渡すか、call graph を1ホップ添えるかで、検出できるバグの種類がまるで変わります。

call graphを1ホップ添えるだけで何が変わるか

「依存グラフ全部を添える」はやりすぎです。コンテキストが膨れて逆にレビューが甘くなります。

私が落ち着いた線は 1ホップ

差分に含まれた関数の直接の呼び出し元と呼び出し先だけを添える設計です。

  • 変更関数 A の呼び出し元 (B のシグネチャと使用箇所)
  • 変更関数 A の呼び出し先 (A が呼ぶ関数の型)

これだけで先ほどの null 伝播は「差分」に見えます。B の使用箇所が入力に含まれるので、A の返り値変更と B 側の user.name 参照を同じコンテキストで読める。AIは「ここで null チェックが要る」と指摘できるようになります。

実装は tree-sitter で AST を取り、call graph をローカルに構築するだけです。GitHub Actions で PR に対して走らせ、差分ファイルの AST 差分から 1-hop neighbors を取り出して CodeRabbit の path_instructions に流します。ハーネス側で前処理します。CodeRabbit の設定は素直なまま保てます。2ホップ以上に広げると、コンテキストが 5〜10 倍になります。AI レビューの指摘が「一般論として良い設計です」に丸まっていきます。1ホップは、依存バグの多くを掬いつつ、レビューのシャープさを保てる境界線です。数字で言うと私の環境では、差分だけの構成で見逃していた依存性起因の指摘の大半が1ホップ拡張で再現できました。2ホップにしても、追加で拾える指摘は少ないのに入力量だけ増えます。

Diff-only と call graph 1-hop の比較

AGENTS.md にレビュー範囲を宣言する

もう一つの効き手は、AGENTS.md に「AIレビュアーが読むべき範囲」を明示的に書くことです。ハーネス側で call graph を用意しても、モデル側にその文脈を使ってほしい旨を書かないと、モデルは差分の中だけで結論を出そうとします。

# AGENTS.md

## Review Scope

コードレビュー時、AIレビュアーは以下を範囲とすること。

- 差分ファイル (Primary)
- 差分関数の呼び出し元 1 ホップ (call graph より提供)
- 差分関数の呼び出し先 1 ホップ (同上)

差分の変更が呼び出し元の期待型と整合しない場合、
`issue:` ラベルで報告する。整合するが呼び出し側の実装で
`null` / `undefined` を扱っていない場合、`suggestion:` で提案する。

これを書くと、Conventional Commentsのラベル (issue: / suggestion:) がそのまま「差分外バグの深刻度分類」になります。Book では第3層(人間レビュー)を「設計と方向性の判断」に絞る話をしていますが、AGENTS.md をこう書くと、第2層のAIレビューが「依存範囲の型整合性チェック」まで担うようになります。

見えていないものは、防げない

Diff-only AI レビューが機能する場面は確かにあります。単一ファイル内で完結する変更、テストコードの追加、ドキュメント修正。これらは Diff だけで十分です。

一方で、モジュールをまたぐシグネチャ変更、null 許容の拡張、共通関数のリファクタリングは、Diff だけを渡した AI レビューにとって構造的な盲点です。call graph の 1 ホップを添えるだけで、この盲点の多くが視野に入ります。AGENTS.md に「範囲を1ホップ拡張する」と一行書きます。pipeline 側で用意します。実装コストで言えば 200 行未満の GitHub Actions で足ります。

「AIレビューが最近甘くなった」と感じているチームは、モデルを替える前に、モデルに渡している入力の設計を見直したほうが早いはずです。

両目を紙で覆ったまま賢いレビュアーを探しても、賢いレビュアーはやはり紙の外を見てくれません。

3層モデル(自動 / AI / 人間)で AI レビュー層をどう設計するかは、拙著の第2層(AIレビューの導入設計)に詳しく書きました。本記事の call graph 1 ホップ拡張は、その章の実装例のひとつです。

参考

AIコードレビューを仕組み化する技術 関連書籍 AIコードレビューを仕組み化する技術 AIコードレビュー 自動化 | hooks 設計・CodeRabbit 導入・Conventional Comments・GitHub Actions パイプライン 書籍ページを見る →