AIコードレビューのためのコンテキスト検索手法の比較
Compare The Market社は、AIコードレビューのために2つのコンテキスト検索手法(GKGとRAG)を比較しました。厳格な評価の結果、知識グラフベースのGKGがRAGよりもコードレビューの品質指標で優れており、コード構造と関係をより正確に理解し、誤検出を減らすことがわかりました。
Compare The Market社では、マージリクエスト(MR)を自動的にレビューする内部AIツールを開発しています。目標は、開発者がコードに関するフィードバックを受け取る時間を短縮し、組織全体のMRスループットを向上させることです。このツールはMRオープン後数分でインテリジェントな初回レビューを提供します。当初のレビューアは保守的で、コード変更を単独でレビューするため誤検出が多発していました。そこで、変更がシステム全体の中でどのように位置づけられるかをレビューアに理解させる必要がありました。例えば、削除された関数はデッドコードのように見えますが、別のサービスから動的に呼び出されている場合はそうではありません。
このため、エージェントがコードベースのコンテキストをどのように取得するかという基本的なアーキテクチャ上の決定に直面しました。次の2つの主要なオプションがありました。
- GitLab知識グラフ(GKG):Tree-sitter AST解析を使用してコードエンティティと関係の構造化知識グラフを構築するコード分析エンジン。Kuzuグラフデータベースに格納され、「この関数のすべての呼び出し元を検索」や「クラス階層を表示」などの正確なクエリが可能です。
- 検索拡張生成(RAG):コードをチャンク化し、埋め込みを作成し、セマンティックに類似したコードスニペットを検索するベクトル類似度検索アプローチ。
私たちは直感に基づいてGKGを選択しました。コードレビューにはコード関係の構造的理解が必要であり、単なるセマンティック類似性ではないという仮説です。関数の変更をレビューする場合、それを呼び出すもの、それが呼び出すもの、そして広範なアーキテクチャにどのように適合するかを知る必要があります。RAGは「類似」コードの検索に優れていますが、類似性はコードレビューの関連性と同じではありません。
この記事ではその直感を検証します。Databricks上のMLflowを使用した厳格な評価により、4つのアプローチを比較し、コードレビューの品質にとって最も重要な指標でGKGがRAGを上回ることがわかりました。データはアーキテクチャ上の決定が正しかったことを裏付けています。
4つのアプローチ
4つの異なる構成を評価しました:ベースライン、GKG、RAG、GKG+RAG。
GKG統合
昨年、GitLabはGitLab知識グラフ(GKG)というMCP(モデルコンテキストプロトコル)サーバーのベータ版を導入しました。APIはリポジトリをインデックス化し、コードベースの構造化されたクエリ可能な表現を構築します。依存関係をグラフのノードにマップし、関数定義とその使用法を理解し、継承階層を追跡し、モジュール間の相互参照をキャプチャします。結果はコードのセマンティックマップであり、ファイルのリストだけでなく、関係のウェブです。MCPサーバーによって提供されるツールを通じて、AIエージェントはこのグラフをリアルタイムでクエリできます。
GKGはまだベータ版で、ネイティブのGitLab CI/CD機能として利用できなかったため、公式のGKGバイナリをラップする軽量Dockerコンテナーである別のサイドカーサービスを構築し、CIパイプラインでレビューアと一緒に実行しました。ワークフローは次のとおりです。MRパイプラインが起動すると、サイドカーコンテナーがプロジェクトソースをマウントし、コードベース全体をインデックス化して知識グラフをゼロから構築します。インデックス化後、ローカルポートでGKG MCPサーバーを起動し、一連のツール呼び出しを公開します。AIレビューアはMCPサーバーに接続し、レビューワークフローの一部としてこれらのツールを使用します。
GKGはシンボルグラフ(コードベースの構造化表現)を構築します。ノードはコードエンティティ(クラス、関数、変数)を表し、エッジは関係(呼び出し、継承、インポート)を表します。リポジトリをインデックス化すると、コードベース構造全体を示すインタラクティブなグラフ可視化が作成されます。各ノードタイプは異なるコードエンティティを表します。オレンジ(ディレクトリ)、緑(ファイル)、紫(定義:コードで定義されたクラス、関数、メソッド)、青(インポートされたシンボル:外部依存関係とインポート)。エッジは関係を示します。どのファイルにどの定義が含まれているか、どの関数が他の関数を呼び出すか、どのモジュールがどのシンボルをインポートするか。
例えば、単純なUserServiceクラスを考えます。GKGはそれをグラフとしてマッピングし、クラス、そのメソッド、およびそれらのメソッドを呼び出すすべてのファイルを示します。AIレビューアが変更の影響を理解する必要がある場合、GKGにクエリを実行します。たとえば、誰かがvalidate_input()を変更した場合、エージェントは「この関数を誰が呼び出すか?」と尋ねます。この正確な情報により、レビューアはvalidate_input()への変更がこれらの呼び出し元のいずれかを壊す可能性があるかどうかを評価できます。これは差分だけでは不可能です。
RAG統合
RAG実装では、LlamaIndexを使用したインテリジェントなコードチャンク化と、OpenAI埋め込みを使用したベクトル類似度検索を使用しました。インデックス化パイプラインは、リポジトリ内のコードファイルをスキャンし、LlamaIndexのCodeSplitter(AST認識チャンク化)を使用してコードをセマンティックユニット(関数、クラス)に分割し、OpenAI text-embedding-3-smallで埋め込みを作成し、FAISSベクトルストアに保存します。検索パイプラインは、クエリ埋め込みに基づいて最も類似したコードブロックを取得します。
CodeSplitterはグラフファーストアプローチを採用しています。まずコードのASTグラフを構築し、この構造的理解を使用してセマンティックに意味のあるチャンクを作成します。ナイーブなテキストチャンク化とは異なり、セマンティック境界を識別します。関数境界(各関数がチャンクになる)、クラス境界(クラス定義とそのメソッド)、論理グループ化(関連コードをまとめる)。
ただし、RAGはコードレビューで根本的な制限に直面する可能性があります。ベクトル空間でのセマンティック類似性に依存しており、自然言語には適していますが、コードには固有の限界があります。
- シンボル解決ができない:同じ名前の関数定義と関数呼び出しを区別できない。
- 参照追跡ができない:関数の変更をレビューするとき、その関数のすべての呼び出し元を確実に見つけられない。
- チャンク境界の問題:AST認識チャンク化でも、重要なコンテキストが異なるチャンクに分割される可能性がある。
- 精度と再現率のトレードオフ:セマンティック類似性の最適化により、関連するが実際には無関係なコードが返され、LLMにノイズが混入する可能性がある。
評価設定
生成AIレビューアの評価は、分類器や検索エンジンの評価とは根本的に異なります。コードレビューには正規の正解がありません。2人の専門エンジニアが同じMRをレビューしても、異なるが同様に有効なフィードバックを書きます。したがって、標準的な精度指標は適用できません。品質は多次元です。レビューは正しいリスクを特定しても重大度を誇張するかもしれません。完璧に調整されていても重要な問題を見逃すかもしれません。正しい懸念を表面化しても間違ったコード行を指すかもしれません。
信頼できる評価のために、固定された参照点が必要です。社内リポジトリからの79の実際のMRからなるゴールデンデータセットを構築しました。各エントリは、複数の次元にわたって専門家が注釈を付けたグラウンドトゥルースを持っています。期待されるサマリーポイント、期待される問題、期待されるインラインコメント(特定のファイルとコード行にバインド)、期待されるスコア範囲。これらのMRは実際の生産の複雑さを表し、さまざまなコードベース、変更サイズ、タイプをカバーしています。
4つのアプローチすべてが同じ79のエントリで評価され、各生成レビューは5つのコア品質次元で評価されました。
- カバレッジ:出力にいくつの期待されるサマリーポイント、問題、インラインコメントが含まれているか?
- 精度:レビューアが表面化したもののうち、実際に正当なものはいくつか?過剰生成をペナルティします。
- インラインコメント位置の正確さ:コードレビューは本質的に空間的です。問題を散文で特定するだけでは不十分で、正しいファイルと関連するコード変更にアタッチする必要があります。
- スコアの調整:レビューアが割り当てた重大度スコア(0-10)は、人間が妥当と考える範囲内か?
- 構造的妥当性:必須フィールドが存在し、整形式であることを確認するスキーマチェック。すべてのアプローチがこの次元で一貫して合格しました。
微妙な基準(たとえば、要約が「同じポイントをカバーしているか」)では、テキストマッチングは機能しません。LLMを自動審判として使用し、参照期待値と生成出力を比較して、期待されるポイントのヒット数をカウントしました。
評価はMLflowとDatabricksで実行され、データ準備、比較、反復最適化が含まれていました。
結果と結論
GKGはカバレッジと精度の両方でRAGを大幅に上回りました。GKG統合により、レビューアは知識グラフをクエリして初期の懸念を検証し、より正確で一貫性のあるフィードバックを生成し、誤検出を劇的に減らすことができました。RAGはセマンティック類似性タスクでは良好に機能しましたが、コードレビューに必要な構造化されたニーズには不十分でした。GKGとRAGの組み合わせはGKG単独よりも有意に優れておらず、GKGがレビューに必要なコアコンテキストを提供することを示しています。
このアーキテクチャ上の決定により、AIコードレビューツールは表面的なセマンティクスに依存するから、コードベースの真の構造を理解するへと進化し、開発者により信頼性が高く、信頼できるレビューフィードバックを提供できるようになりました。