AIコーディングエージェントはPRを数分で生成できる。しかしそのPRがコードベースに入るべきかどうかを判断するのは、依然としてチームの仕事だ。
ボトルネックはなくなっていない。実装からレビューへ移動しただけだ。
この問題に「AIレビュアーを追加する」という解決策は、構造的な問題にツールを当てようとしている。なぜそれでは足りないのか、そして実際に何が変わるのかを説明する。
AIはコードの生産量を増やした。レビュー能力は変わっていない。
Microsoftが2026年初頭にClaude CodeとGitHub Copilot CLIを導入したケースを分析したプレプリントによると、ツールを採用したエンジニアは採用しなかったグループに比べて、約24%多くのPRをマージしたと推定されている。
著者たちはこの数字の解釈に慎重だ。マージされたPR数は価値の量と同じではなく、因果的な推定には不確実性が伴う。しかし実際の運用への影響は明確だ。AIコーディングエージェントを使うチームは、メインブランチに入れる前に判断が必要なコード変更を、より多く生成している。
シニアエンジニアのレビュー時間が24%増えるわけではない。コード生成の速度は伸ばせるが、「この変更はコードベースに入れてよいか」を判断する能力はそうではない。AIエージェントが実装を加速すると、制約点はレビューへ移動する。
AIレビューには限界がある
自然な対応は、レビューにもAIを追加することだ。コードを書けるなら、レビューもできるはずだという発想だ。
AIレビューは実際に問題を見つける。しかし、人間のレビュアーが指摘する問題に対する検出率は、ツール紹介の印象より低い。
SWE-PRBench(実際のPRレビューフィードバックを基準にAIレビューの品質を測定するベンチマーク)は、フロンティアモデル8種を評価した。差分だけを見た場合、人間がフラグを立てた問題の15〜31%しか検出できなかった。コード生成で優秀なモデルが、コードレビューでも一貫して優秀というわけではなかった。
より意外な結果はコンテキストに関するものだ。実行データ、テスト結果、広範なリポジトリ情報を追加すると——役立つはずの情報を与えると——8種のモデル全てで一貫して性能が低下した。構造化された2,000トークンのdiff+サマリーのプロンプトが、2,500トークンのコンテキスト豊富なプロンプトより良い結果を出した。入力が長くなるほど、特定の問題の検出率が下がる。アテンション分散が原因とみられる。
別のベンチマークc-CRABでは、PR-agent、Devin、Claude Code、Codexの4エージェントを評価し、合計で約40%のタスクに対応できたと報告している。著者はさらに指摘している——エージェントは人間のレビュアーとは異なる観点を重視する傾向があるため、人間が指摘したであろう問題との重複は40%より小さい。
AIレビューが全ての問題に無効というわけではない。明らかな問題を検出し、単純なパターンへの対応時間を短縮する。問題は特定のカテゴリだ。本来なら推論を必要としないはずの制約に対して、AIレビューは特に非効率になる。
レビューが必要な問題と、そうでない問題がある
コードレビューには本質的に異なる2種類の問題が届く。この2つを同じ扱いにすると、スケールしないリソースを浪費する。
1つ目は判断が必要な問題だ。抽象化がドメインを正しく表現しているか。設計の決定が要件変更に耐えるか。実装がプロダクトの意図に沿っているか。こうした問題はレビューで扱うべきものだ。
2つ目は答えが決まっている問題だ。ハンドラーがデータベースクライアントを直接インポートしているか。UIコンポーネントがサービス層を迂回しているか。認証が必要なルートにミドルウェアがついているか。禁止パッケージが本番コードの依存関係に含まれているか。
後者もレビューに届く。しかしレビュアーは判断をしているのではなく、PRが開かれる前に自動チェックが検出できたはずのものを探している。
AIレビュアーへ後者を送っても、やはりコストがかかる。決定論的に答えが出る問題に対して、AIが確率的な推論を行う。静的チェックであれば、パターンを探して結果を返すだけだ。
指示ファイルは意図を伝えるが、強制しない
AIコーディングエージェントを使うチームは、CLAUDE.md、AGENTS.md、Cursorのルールファイルにアーキテクチャルールを書くことが多い。エージェントがルールを読んで守るという期待のもとに。
エージェントはルールを読む。しかし遵守は保証されない。
指示ファイルはエージェントの挙動を確率的に変える。リポジトリの構造や慣習についての文脈をモデルに与える。それが出力に影響するが、出力を制約するわけではない。目の前のタスクが、アーキテクチャの境界を越える簡単な解法へ引き寄せるとき、指示はモデルの実質的な推論から後退する。
このメカニズムの詳細はなぜAIコーディングエージェントがアーキテクチャの乖離を引き起こすのかで説明している。短くまとめると、指示は入力であり、強制ではない。制約とは、出力がマージ前に満たす必要があるものだ。指示とは、生成中にモデルが考慮するものだ。
同じ限界はAIレビューにも当てはまる。生成された出力を確率的にチェックしても、違反が通り抜ける余地は残る。
決定論的なチェックをレビューより前に置く
構造的な解決策は、判断が必要なものとそうでないものを分け、決定論的なチェックをパイプラインの早い段階に移すことだ。
AIエージェントがコードを書く
↓
決定論的なアーキテクチャチェック
(レイヤー境界、禁止インポート、必須パターン)
↓
テストとセキュリティスキャン
↓
AIによるレビュー
(曖昧な問題、設計上の疑問、非自明なパターン)
↓
人間の判断
(トレードオフ、意図、リスク許容)
2番目のステップのチェックは、洗練されている必要はない。正確で速いことが必要だ。UIコンポーネントがデータベースクライアントをインポートしていたらPRを拒否するチェックは二値的だ。インポートがあるかないか。推論は不要だ。
このチェックを構築する際に実際の問題に当たる。リポジトリ固有のアーキテクチャルールを、静的ツールが実行できる形式で表現することだ。一般的なリンターは構文とスタイルを扱う。「このリポジトリのハンドラーはリポジトリ関数を直接呼び出してはならない」や「この特定のパッケージは本番コードで禁止されている」は表現できない。
Unbxのルールエンジンを構築する過程で、ユーザーが自然言語でアーキテクチャの制約を記述し、そこから実行可能なTree-sitterクエリを生成するようにした。生成はほとんどの場合うまく機能した。しかし、構文的に正しいクエリが必ずしも正しいとは限らないことがわかった。
あるケースで、禁止したいインポートパスを検出するクエリを生成した。クエリはコンパイルでき、エラーなく実行できた。実際のコードベースに適用すると、そのパスと同じ文字列を含むログメッセージや定数にもフラグを立てた。クエリがinterpreted_string_literalノードを、import宣言の内部に限定せずに取得していたからだ。ルールは、読んでも誤りがわからない形で間違っていた。
このことから、ルール生成の後に必ずcanary検証のステップを設けるようになった。各ルールに対して、対象の違反を含む最小限のコードサンプルを生成し、ルールを適用して検出を確認する。違反なしで類似のパターンを使うサンプルも実行し、誤検知がないことを確認する。どちらかが失敗したら、ルールを再生成する。
この経験が示すことは広い意味を持つ。LLMを使ってアーキテクチャチェックを生成すると、チェック自体が確率的な成果物になる。コンパイルできたからといって、生成されたルールが正しいわけではない。チェックの検証は、そのチェックが検出しようとするコードの検証と同様に必要だ。
人間が判断すべきものは何か
ここで言っているのは、レビューを自動化せよということではない。人間の判断を必要としない意思決定を、人間のレビューパスから取り除くことが目標だ。
人間の判断の段階に残すべきもの:
- 設計の決定がプロダクトの変化に耐えるか
- 実装が仕様だけでなく意図を反映しているか
- トレードオフがチームの現状において許容できるか
- 次にコードを変更する人が理解できるか
- アーキテクチャの例外がこのケースで正当化されるか
これらの問いは、レビュアーの経験と文脈から価値が生まれる。静的チェックやAIモデルが確実に代替できるものではない。こうした問いのためにレビュー能力を守ることが、解消できる問いを早い段階へ移す理由だ。
AIエージェントが実装を加速したとき、ボトルネックはレビューへ移動した。決定論的なチェックを早い段階に移すことで、その負荷の一部をレビューから外に出せる。人間の判断をなくすのではなく、判断が本当に必要な場所を再調整する。
目標は、すべてのレビューコメントを自動化することではない。リポジトリがすでに知っているルールに人間の判断を使うのをやめることだ。