/note/tech

AIが書いたコードを目視で追うのはやめよう──「工場の品質検査」から考えるこれからのコードレビュー

要約:

■ 1. AIコーディングが引き起こすレビューの滞留

  • 生成AIツール導入の影響:
    • Claude Code や Codex などの導入で、コードの初稿作成時間は短縮された
    • 一方でプルリクエストのレビュー待ちが滞留し、テックリードや開発責任者が疲弊する現場が増えている
  • 差分量の急増:
    • CRUD処理や定型的なAPIクライアントの実装は、半日かかった作業が数分の指示で完了する
    • 開発者1人あたりのプルリクエスト件数や差分行数が跳ね上がる現場も珍しくない
  • レビュー速度は変わらない:
    • 差分量が増えても、レビュアーがコードを読んで正当性を検証する速度は変わらない
    • 未レビューの差分が滞留すると、ブランチの競合が頻発する
    • 再検証やマージ作業に工数を費やし、開発速度が低下する
  • 停滞の背景:
    • 人間が書いたコードを前提とする従来のレビュー手法を、AI生成コードにもそのまま適用している
    • 同僚の思考プロセスを尊重し1行ずつ文脈を読み解くやり方は、AIが高速に出力した大量のコードの精査には適さない

■ 2. AI生成コードに対する目視レビューの限界

  • AI生成コードの特徴:
    • 文法的に整っており、一見すると問題なく動くように見える
    • プロジェクト固有のアーキテクチャ規約、過去の設計判断、業務ドメイン固有の制約までは考慮しない事例が多い
  • 目視レビューの弊害:
    • レビュアーの注意が命名規則や細かな構文の違和感といった表層的なノイズに奪われる
    • 1行ずつの粗探しは疲労を招きやすい
    • 結果として境界値の抜け漏れや潜在的な不具合といった設計上の欠陥を見落としやすくなる
  • 問題の原因:
    • 「AIが生成したコードの誤りを人間がすべて目視で拾い集める」という役割分担にある
    • 開発者がAIのチェッカーとして消耗する構図を断ち切るには、レビューを受入検査として再定義する必要がある

■ 3. 製造業の品質管理(QA/QC)に学ぶ工程設計

  • 工場の品質管理の考え方:
    • 現場作業者の注意力だけに頼って不良品の流出を防ぐ体制は採らない
    • 治具や規格外部材を自動排除するセンサーといった機構(ポカヨケ)を工程内に配置する
    • 不良品が次工程へ流れない構造を作る
  • ソフトウェア開発への適用:
    • 構文規則、フォーマット、型の不整合といった形式的な誤りは「工程内の不良」に該当する
    • これらはエディタ、コミットフック、CIによってその場で遮断すべき
    • 出力のばらつきが大きいAI生成コードを扱う現場ほど、機械的な事前検査が効果を発揮する
  • 動的な検証の機械化:
    • CI環境でブラウザ自動テストツールを用いたE2Eテストを実行する
    • 画面遷移や入力フォームの挙動といった動的な回帰もレビュー前に機械的に検知できる
  • 受入検査としてのレビュー:
    • 製造業の受入検査は部品の分子構造や加工手順を全量検査せず、受入基準書に基づき寸法や耐久性、仕様への合致を検査する
    • 同様に人間が行うべきはコード1行ずつの添削ではない
    • 形式的な正しさは前工程のツールによって保証されている
    • 人間が担うのは、設計仕様を満たすか、例外的な入力に安全に振る舞うかといった外部から観測される機能と契約の検証
  • 切り分けの効果:
    • 工程内での自動排除と最終工程での仕様検査を切り分けることで、レビュアーごとの基準の揺らぎを抑えられる
    • 確認作業の範囲も絞り込める

■ 4. リンターとルールで自動的に防ぐ実装例

  • 自動化された制約:
    • 人間が判断する必要のない形式的な規則は、静的解析ツールとリンターで機械的に検証する
    • 違反があるコードはコミットできない、あるいはCIを通過しないという制約を設ける
    • これによりAIが生成した粗いコードがレビューに持ち込まれる事態を防げる
  • PHPバックエンドの場合:
    • Laravel や Symfony のプロジェクトでは静的解析ツールの導入が基本
    • PHPStan や Psalm を厳格なレベル(level max または8以上)で運用する
    • 型推論の不整合、未定義プロパティへのアクセス、null安全性の違反を検出できる
    • PHP_CodeSniffer や PHP-CS-Fixer をコミットフック(Husky や Git Hooks)に組み込む
    • コーディングスタイルの不一致を自動修正させ、インデントや命名規則の指摘時間を省く
  • フロントエンドの場合:
    • Next.js では TypeScript の型チェック(tsc --noEmit)を必須とする
    • ESLint と Prettier を組み合わせてプロジェクト規約を強制する
    • Vue では vue-tsc による型検査や eslint-plugin-vue による構文検査を組み込む
  • アーキテクチャ規則の統制:
    • モジュール間の依存関係を検証するツールを利用する(PHPの Deptrac、JS/TSの eslint-plugin-boundaries など)
    • ドメイン層がインフラ層に直接依存していないかといった制約もCIで機械的に検出できる

■ 5. 人間が担う受入検査の観点

  • 機械による統制後に残る検査:
    • 人間にしか判断できないドメインレベルの検査が残る
    • レビュアーは構文の細部から解放され、システム全体に影響する観点に集中できる
  • 要求仕様およびドメインモデルとの整合性:
    • AIは指示文に沿ったコードを生成するが、業務文脈や暗黙のドメイン制約をすべて反映できるわけではない
    • 計算ロジックが業務ルールに合致しているかの確認は人間の判断に依存する
    • 例外的な状態遷移が正しく考慮されているかの確認も人間の判断に依存する
  • システム全体に対する副作用の有無:
    • 単一のファイルや関数内では問題がなくても、システム全体への波及効果を評価する必要がある
    • 対象はデータベースのクエリ発行数(N+1問題)、トランザクションの分離レベル、外部APIの呼び出し制限など
    • 下位互換性の破壊やセキュリティ要件への抵触がないかも人間が検証する
  • テストコード自体の妥当性:
    • AIが生成するテストは、アサーションの強度が足りず単に実行エラーが出ないだけのものになることがある
    • 境界値条件を網羅しているかを確認する
    • モックの振る舞いが現実の仕様と乖離していないかを確認する
    • これらの確認は実装コード自体の閲覧以上に重視すべき検査項目

■ 6. AI活用を支える開発基盤の設計

  • ガードレールへの投資:
    • 開発者のプロンプト作成スキルだけに頼っていては、コード品質とレビュー速度の両立は困難
    • AIが大量に出力する時代だからこそ、静的解析やCIパイプラインといったガードレールの構築への投資が生産性を左右する
  • ツールと人間の境界の整理:
    • ツールによる制約と人間による検査の境界を明確に整理することが重要
    • それがレビュー待ちによるブランチの競合を減らし、安全なリリース頻度を保つ基盤となる