🛡️

AIレビューの「で、これ合ってんの?」を減らす

に公開

reviewersスキルの実行結果

AIにコードレビューをさせて、返ってきた指摘を眺めながらこう思ったことはないでしょうか。

「で、これ合ってんの?」

指摘の数は出る。でもその中に、的外れなもの、文脈を無視したもの、スタイルレベルのものが混ざっている。結局、全部の指摘を自分で検証する羽目になって、レビューの時短どころか確認作業が増えている。

レビューにはディフェンスが必要

人間のPRレビューを思い出してください。

レビュアーが「ここ問題では?」と指摘する。実装者が「いや、ここはこういう意図でこうしてます」と返す。レビュアーが「なるほど、それなら問題ないですね」あるいは「いや、それでもこのケースは危ないです」と返す。

このやり取りの中で、的外れな指摘は自然に落ちていき、本当に対処すべき問題だけが残る。

このディフェンスのプロセスこそが、レビューをレビューとして機能させているものだと思っています。指摘を出すだけなら、誰でもできる。AIならなおさら、大量に出せる。でもディフェンスがなければ、指摘の数だけ増えて質が伴わない。それはレビューではなく、ただのノイズでしかない。

今のAIコードレビューツールには、このディフェンスのプロセスがありません。だから作りました。

設計 — 広く拾って、厳しく絞る

僕がAIレビューに求めていたことはシンプルです。

  • 重要な指摘だけを見たい — ノイズに時間を取られたくない
  • 拾い漏れを防ぎたい — 一つの視点では観点が偏る
  • 指摘の確度がわかってほしい — 優先順位をつけて効率よく確認したい

これを実現するために、3ステップのマルチエージェントアーキテクチャを設計しました。

アーキテクチャ

この設計には裏付けになる研究があります。

AI業界の速度感で言えば古い論文かもしれません。ただ、ここで重要なのは「複数の独立したレビューを集約すると品質が上がる」「異種アンサンブルは同種より強い」という原理そのもので、これはモデルの世代が変わっても変わらないはずです。

単一のAIに「全部見て」と投げるのではなく、同一のdiffをペルソナの異なる複数のレビュアーに独立して読ませ、結果を統合する。このアプローチを採用した理由です。

Step 1: Focus Analysis — diffから専門家を決める

Step 1: Focus Analysis

最初にHaikuエージェントがdiffを分析し、変更内容に応じたレビュアーペルソナを2〜4個、動的に生成します。

なぜペルソナを動的に生成するのか

「Security」「Performance」「Readability」のように固定ペルソナを用意する方法もあります。でも、インフラ変更のPRにフロントエンドの専門家は要らないし、DB migrationのPRにUI reviewerは要らない。PRの内容によって見るべき観点は全く違います。

だからファイル拡張子ではなく変更のセマンティクスからペルソナを決定するようにしています。認証周りとDB migrationを含むPRなら「Security Auditor」と「Database Migration Specialist」が自動で立ち上がる、という具合です。

なぜHaikuなのか

このステップのタスクは「diffを読んでペルソナ定義を構造化出力する」ことだけです。コードの深い理解は不要で、速度とコストを優先してHaikuを選んでいます。

レビュアー数の上下限

固定3名ではなく、Focus Analyzerが分析したドメイン数に応じて2〜4名の範囲で決定します。

  • 2名以下にしない: 単独レビューではアンサンブル効果が得られない
  • 4名以上にしない: Multi-Review論文の限界収益曲線から、3→5名の追加は67%のコスト増に対してRecall向上が15-25%程度。費用対効果が低下する

Step 2: Parallel Review — 専門家が並列で読む

Step 2: Parallel Review

生成されたペルソナの数だけSonnetエージェントが並列に起動し、それぞれの専門分野に集中してレビューします。

各レビュアーには明確なルールを課しています。

  • 自分のフォーカスエリア外は指摘しない — 専門外の浅い指摘を防ぐ
  • 指摘は1人あたり最大5つ — レビュアーは2〜4名いるので、全体では最大10〜20個の指摘がconsolidatorに渡る。1人あたりの上限がないと低品質な指摘が増えてconsolidatorの判断を圧迫するため、個々のレビュアーには重大度で厳選させ、網羅性はレビュアーの人数で担保している
  • 実際のソースファイルを読んで検証する — diffだけでなく周辺コンテキストを確認する

重大度は3段階です。

重大度 基準
CRITICAL セキュリティ脆弱性、データ損失リスク、本番クラッシュ
WARNING バグ、不正な動作、重要な保守性の懸念
SUGGESTION 改善の機会、非ブロッキング
なぜSonnetなのか

レビュアーはコードを読んで判断する能力が求められます。Haikuでは力不足で、かといってN並列で全員Opusにするとコストが跳ね上がる。判断力とコストのバランスでSonnetを選んでいます。

なぜファイル分担ではなく全員が同じdiffを読むのか

「レビュアーAはフロントエンド、Bはバックエンド」のようにファイルを分担させる方法もあります。でもこの方法には大きな弱点があって、クロスファイルの問題を見落とす。フロントエンドの変更がバックエンドのAPIの暗黙の前提を壊していた、というケースは分担レビューでは拾えません。

だから全員が同じdiff全体を読み、それぞれの専門的な視点でフィルターする設計にしています。

Step 3: Defense & Consolidation — ディフェンスで絞る

Opusエージェントがconsolidatorとして、すべてのレビュアーの指摘を受け取り、一つひとつ検証します。

  1. 指摘された箇所のソースファイルを実際に開いて、周辺のコードも含めて読む — diffだけではわからない前後の文脈(既にサニタイズされている、別の場所でバリデーション済み、など)を確認する
  2. 指摘が本当に問題か、周囲のコンテキストで緩和されていないかを判断する
  3. 採用・却下の判定と、その理由を明示する

人間のレビューで実装者が「いや、ここはこういう理由でこうしてます」と返すやり取り。それをエージェントが自動でやってくれるイメージです。

指摘の一覧と信頼度スコア
Step 3: Consolidated Review — Summary

各指摘をソースコードと突き合わせて採否を判定した結果
Step 3: Consolidated Review — Defense

今回はあえて穴のあるコードを対象にしたため全件採用されていますが、通常のPRでは的外れな指摘が却下されます。

なぜOpusなのか

全レビュアーの指摘を横断的に読み、ソースコードと突き合わせて採否を判断する。このスキルの中で最も難しいタスクです。ここにはモデルの最高の判断力を投入すべきだと考え、Opusを選んでいます。

なぜConsolidatorを並列にしないのか

指摘の妥当性検証も複数エージェントで並列に行う方法はあります。ただ、運用してみてOpusを複数並列で走らせるほどの費用対効果を感じませんでした。Opus 1人で十分な判断精度が出ており、ここにコストをかけるならレビュアーの数を増やす方がRecall向上に効きます。

信頼度スコア

複数のレビュアーが同じ問題を指摘した場合は統合(dedup)され、信頼度スコアが付与されます。

信頼度 基準
HIGH レビュアーの66%以上が指摘、または検証済みの重大バグ
MEDIUM 40%以上が指摘、または単一レビュアー+ソース検証で確認
LOW 単一レビュアー、未検証、またはスタイル関連のみ

信頼度の計算は固定の3名ではなく、実際のレビュアー総数Nに対する比率で行います。レビュアーが2名でも4名でも、スコアの基準が崩れないようにするためです。

最終出力では信頼度HIGHの指摘から順に並ぶので、上から見ていけば重要なものから確認できます

ディフェンスの透明性

Consolidatorは採用した指摘だけでなく、却下した指摘の理由も明示します。

この記録があることで、「なぜこの指摘は採用されたのか」「なぜこれは無視されたのか」がわかるようになります。判断の過程が全て見えるからこそ、残った指摘を信頼して見ることができます。

なぜ判断理由を明示するのか

最初は単純にマージ・重複排除するだけのconsolidatorを作っていました。でも、そのレビュー結果をそのまま別のエージェントに「これ対応して」と渡したら、「いや、これは不要な作業なので対応しません」と却下されてしまった。根拠のない指摘リストだけ渡されても、受け取った側は自分で判断するしかない。だから「やらなくていい」と判断されてしまう。

この経験から、consolidatorには採用・却下それぞれの判断理由を明示させるようにしました。ソースを読んだ上で「ここは実際に問題がある」と根拠付きで残してくれていれば、下流のエージェントも人間も、その指摘を信頼して動けます。

モデル選択のまとめ

ステップ モデル 理由
Focus Analyzer Haiku 構造化出力のみ。速度・コスト優先
Reviewers Sonnet コード判断力が必要。N並列のコストバランス
Consolidator Opus 最も難しい採否判断。最高の判断力を投入

タスクの難易度に応じてモデルを使い分けることで、品質を落とさずにコストを抑えられます。

ただ、この構成は固定ではなく、モデルの進化に合わせて運用しながら上げていくつもりです。例えばSonnetの次世代が出てコストが下がれば、ReviewersをそちらにしたりConsolidatorをさらに強いモデルに上げたりといった調整は当然あり得ます。

おわりに

実際にこのスキルを使い始めてから、レビューとの向き合い方が変わりました。以前は指摘を一つずつ「これは本当か?」と検証する作業だったのが、今は信頼度HIGHの指摘から順に確認するだけで済む。自分の目で見る時間を、本当に重要な問題に集中できるようになりました。

指摘を出すだけがレビューではなくて、ディフェンスがあって初めてレビューとして機能する。この記事で伝えたかったのはそれだけです。

参考文献

  • arXiv:2509.01494 — "Enhancing LLM-based Code Review with Multi-Review Aggregation" (2025)
  • arXiv:2406.04692 — "Mixture-of-Agents Enhances Large Language Model Capabilities" (2024)

Discussion