Claude Codeで「指摘ゼロになるまで回すレビューループ」を組んだが、ゼロにならなかった

指摘ゼロを目指した

PRのレビュー待ちが積み上がっていく。チームの誰もが経験する光景でしょう。

自分のチームでも同じ課題がありました。AIによるコードレビューは既にいくつかのツールが存在しますし、自分も試してきました。ただ、1つのAIに「全部見て」と投げると、どうしても指摘が浅くなります。セキュリティ、ロジック、テスト、命名を1回のプロンプトでカバーしようとすると、どの観点も中途半端になりがちでした。

「専門性を分けて並列に走らせ、指摘がゼロになるまで自動修正を繰り返す」仕組みを組んでみました。結論から言うと、ゼロにはなりませんでした。ただ、ゼロにならない理由のほうが学びになりました。

なぜ6人に分けたのか

人間のレビューでも、セキュリティに詳しい人とドメインモデリングに詳しい人では見るポイントが違います。それと同じで、AIにも「あなたはセキュリティの専門家です」とロールを絞ったほうが、深い指摘が出てきます。

自分が作ったのは、以下の6つのレビュアーです。

レビュアー 主な観点
Code Reviewer ロジック正確性、エッジケース、エラーハンドリング
Security Reviewer SQLインジェクション、XSS、認証/認可、シークレット漏洩
Test Reviewer カバレッジギャップ、アサーション不足、テスト分離
DDD Reviewer 集約境界、ユビキタス言語、ドメインロジック漏洩
Readable Code Reviewer 命名の明確さ、ネスト深度、説明変数
Spec/Design Reviewer 仕様の矛盾、後方互換性、データモデル整合性

Code Reviewerには「門番ではなくメンターとして振る舞え」という指示を入れています。指摘も Must Fix(必須修正)/ Should Fix(推奨修正)/ Consider(検討)/ Nitpick(好みレベル)の4段階に分けさせることで、重要度が一目でわかるようにしました。

これらを Claude Code の Agent tool で run_in_background: true にして並列起動します。PR差分を取得してファイルを backend / frontend / test / config に分類し、各レビュアーに関連ファイルだけを渡します。6人が同時に動くので、直列に6回レビューするより待ち時間が短くなります。

「指摘ゼロまで回す」収束ループ

レビュー結果を受け取ったあと、ただ人間に渡すだけでは物足りません。自動で直せるものは直して、再レビューに回します。これを「指摘がゼロになるまで繰り返す」ループにしました。

フローは以下のとおりです。

収束ループのフロー
  1. 6レビュアーの結果を統合テーブルにまとめる
  2. 各指摘の妥当性を検証する(後述)
  3. critical / warning レベルの指摘を自動修正する
  4. 修正後に再レビュー
  5. 指摘ゼロになるか、5ラウンドに達したら終了

ここで重要なのは「過剰修正ループに陥らないための安全弁」です。実際に動かすと、AIが修正した箇所に対して別のAIが新しい指摘を出し、それを直すとまた別の指摘が出る……という無限ループが起きえます。

対策としていくつかのルールを入れました。

  • 関係ないリファクタはしない。指摘された箇所だけを最小限に修正する
  • 設計判断が必要な指摘は修正しない。人間に判断を委ねて報告だけする
  • テスト失敗は最大3回リトライ。3回連続で失敗したら中断して報告する
  • 20ファイルを超えるスコープは中断。影響範囲が大きすぎる修正は人間に委ねる
  • 5ラウンドで強制終了。収束しない場合は残りの指摘をリストにして報告する

この「自動でやるライン」と「人間に返すライン」の境界設計が、仕組み全体で最も悩んだポイントでした。

AIの指摘にAIがツッコむ

検証エージェントの構造

6レビュアーが出す指摘には、当然ノイズも混じります。的外れな指摘や、プロジェクトの文脈を知らないがゆえの見当違いなコメントもあります。

そこで、レビュー結果をさらに別のClaude Codeエージェントに渡して妥当性を検証するステップを入れました。検証用エージェントがコードベースの文脈を踏まえて「この指摘は妥当か」を判断し、妥当性が低いと判定された指摘は削除するか、info レベルに降格させます。

「AIの指摘にAIがツッコむ」という構造です。たとえばSecurity Reviewerが「この入力値はサニタイズすべき」と指摘しても、検証用エージェントが「このパスはバリデーション済みのデータしか来ない」と却下する、といったことが起きます。

一方で危うさもあります。検証用エージェントが誤って妥当な指摘を却下するリスクは常にありますし、AI同士の判断が一致したからといって正しいとは限りません。これは「フィルタとしてある程度機能する」くらいの期待値で使っています。

6つのレビュアーが並列でコードをレビュー

実際に動かしてみた感触

数十のPRに対して実際に走らせてみました。体感としては、指摘の内訳はおおよそこんな比率でした。

  • 有用な指摘が4割くらい。とくにエッジケースの見落としやテストのカバレッジギャップは人間が見逃しがちなので助かる
  • ノイズが3割くらい。プロジェクト固有の規約を知らないための的外れな指摘。検証エージェントで半分くらいは除去できる
  • 的外れが2割くらい。コンテキストの理解不足に起因するもの。繰り返し出るパターンはプロンプトに除外条件として追記していった
  • 意外な発見が1割くらい。人間では気づきにくい設計上の矛盾や、過去のrevert履歴との不整合など。一番価値を感じた部分である

DDD Reviewerの指摘は好みが分かれるでしょう。自チームではDDDを実践しているので入れました。ただ、集約境界やBounded Contextへの言及は、チームでモデリングの合意が取れていないと「それはそういう設計方針なんだけど……」となりがちです。逆に、ドメインロジックがコントローラに漏れているという指摘は的確なことが多いです。

発展: CI向けのシェルスクリプト版

Claude Codeのスキルとは別に、CI組み込み用のシェルスクリプト版も作りました。claude -p でヘッドレスモードのエージェントを3つ(Code / Security / Test)並列起動し、結果をJSONで集約します。PRが作成されたタイミングで自動実行される形です。6レビュアー版と比べると観点は絞られますが、CIのパイプラインで運用するにはこのくらいの粒度がちょうどいいと感じています。

人間のレビューは楽になったか

実感としては、「楽になった部分」と「変わらない部分」がはっきり分かれました。

人間のチェック負荷を下げるために、AIレビューの結果だけでなく、E2Eテストの実行結果やスクリーンショットなどのエビデンスをPRコメントに添付する仕組みも入れました。レビュアーが「動作確認はしたの」と聞く手間がなくなり、PRを開いた時点で判断材料が揃っている状態を目指しています。

楽になったのは以下の部分です。

  • 機械的なチェック(命名、ネスト、テスト不足)は人間の指摘が不要になった
  • 「これ大丈夫か」レベルの確認作業が減った
  • レビュー前にAIの指摘を読むことで、差分の理解が早くなった

一方、変わらなかったのは以下の部分です。

  • 設計の妥当性判断は人間にしかできない
  • ビジネス要件との整合性チェックはAIには難しい
  • 「このPRの意図」を理解した上でのフィードバックは人間の仕事のまま

つまり、AIレビューが代替したのは「チェックリスト的なレビュー」であって、「対話的なレビュー」ではありません。人間のレビュー負荷は減りましたが、なくなりはしません。機械的なチェックから解放された結果、設計やアーキテクチャの議論へ集中できるようになりました。これが一番大きな変化でした。

定量的な成果としては、レビューのボトルネックが解消されたことでマージ速度が上がりました。前年1年間のマージ数を、この仕組みを導入してから2ヶ月半でクリアしています。

マージ数の比較

レビュー待ち時間の短縮が、チーム全体のスループットに直結した形です。

まとめ

  • AIレビュアーは「専門性を分割して並列に走らせる」ほうが、単体で全部見せるより深い指摘が出る
  • 自動修正ループは強力だが、安全弁の設計が肝心。やりすぎると過剰修正の無限ループに陥る
  • AIの指摘をさらにAIで検証する構造は、フィルタとしてそこそこ機能する。過信は禁物
  • 人間のレビュー負荷は「チェックリスト的な部分」で明確に減る。設計判断は人間の仕事のまま

個人的には、6レビュアーの並列実行よりも、「収束ループの安全弁設計」と「どの指摘を人間に返すかの判断基準」に一番時間を使いました。ツールの作り込みよりも、運用のさじ加減のほうが難しい。当たり前の話ですが、実感としてそう感じました。

コメント

タイトルとURLをコピーしました