レビューの問題

AI生成コードに対する標準的なアドバイスは「注意深くレビューせよ」だ。

このアドバイスは正しいが、スケールにおいては無意味だ。

AI出力をレビューする開発者は、注意力があり、ドメインに精通し、時間的プレッシャーがないときに問題を発見する。それ以外のすべての条件 — つまり大半の条件 — では、見落としが発生する。

AI生成の問題をAIレビュアーが検出するのはさらに信頼性が低い。確率的システムに別の確率的システムの出力を検証させているのだ。失敗モードは相関する。

スケールする唯一のパターンは決定的enforcementだ。すべてのコミットでチェックされ、疲労や楽観によってオーバーライドされず、違反時にビルドを失敗させるルールだ。

決定的とは何を意味するか

決定的とは、誰がいつ実行しても毎回同じ結果を生み出すチェックを意味する。

  • リンタールールは決定的だ。
  • 型チェックは決定的だ。
  • 境界インポート制限は決定的だ。
  • contract testは決定的だ。
  • 人間のレビュアーの注意力は決定的ではない。
  • LLMの評価は決定的ではない。

この区別はAI生成codebaseにおいてより重要だ。なぜなら、生成されるコードの量がどのチームも手動でレビューできる範囲を超えるからだ。レビューを生成速度に比例してスケールさせることはできない。決定的チェックは簡単にスケールできる。

ガードレールスタック

AI生成codebaseに対するガードレールスタックは4層で構成される:

レイヤー1:型システム

型システムは最初のガードレールだ。厳密な型は、どのレビュープロセス — 人間でもAIでも — も一貫して検出できない種類のエラーを捕捉する:

  • null違反
  • interfaceの不一致
  • 網羅されていないケース
  • 引数の型の誤り

プロジェクトがTypeScriptを使用する場合、strict: trueは交渉の余地がない。強い型システムのない言語を使用する場合は、ツールで追加するか、別の言語を選択せよ。

レイヤー2:アーキテクチャルール

アーキテクチャルールは境界の規律をenforceする:

  • 他の画面の内部からの画面インポートは不可。
  • ドメインロジックがインフラストラクチャを直接インポートすることは不可。
  • composition rootをバイパスして依存関係にアクセスするmoduleは不可。
  • ベンダーSDKはアダプターmodule外に現れてはならない。

Semgrep、ArchUnit、dependency-cruiser、またはカスタムESLintルールなどのツールでこれらを静的にenforceできる。重要なのは、CIで実行されビルドを失敗させることだ。開発者が無視できる警告はガードレールではない。

レイヤー3:Contract Tests

Contract testsは、完全なシステムを実行せずにmoduleがinterfaceを満たすことを検証する:

  • 認証アダプターが認証interfaceを満たす。
  • 分析アダプターが分析interfaceを満たす。
  • ストレージアダプターがストレージinterfaceを満たす。

これらは高速に実行され、結合境界をテストし、AI生成コードが型シグネチャは満たすが振る舞いのcontractに違反するという特有の失敗モードを捕捉する。

レイヤー4:決定的な結合チェック

結合レベルでは、チェックはシステム全体の特性を検証する:

  • composition rootがランタイムエラーなしにすべての依存関係を解決する。
  • 依存関係グラフに循環が含まれない。
  • 必要なすべての環境変数が宣言されている。
  • 設定がランタイムではなくビルド時に有効である。

AI生成コードのためのSemgrep

Semgrepはアーキテクチャルールをコードとして表現することに優れているため、特に言及に値する:

  • 文字列マッチングではなくAST構造に対するパターンマッチング。
  • 汎用リンティングだけでなく、プロジェクトごとのカスタムルール。
  • すべてのコミットで実行できるほど高速。
  • 境界違反をエンコードできるほど表現力豊か。

AI生成を多用するチームは、アーキテクチャ境界をエンコードしたSemgrepルールセットを維持すべきだ。AIが境界に違反するコードを生成した場合、マージ前にビルドが失敗する。人間の注意は不要だ。

これはAI出力のバグを捕捉することではない。どのように生成されたかに関わらず、構造的違反のマージを不可能にすることだ。

AIコードレビューが実際に検出するもの

AIコードレビューツールが役立つ用途:

  • スタイルの一貫性
  • ドキュメントの欠落
  • 明白なロジックエラー
  • 代替アプローチの提案

AIコードレビューツールが信頼できない用途:

  • アーキテクチャ境界違反
  • module間で導入される微妙な結合
  • 振る舞いのcontract違反
  • システム全体の推論を必要とするセキュリティ特性

失敗モードは、AIレビューが時折見落とすということではない。失敗モードは、予測不能に見落とし、何かを見落としたかどうかを知ることができないということだ。これが、決定的enforcementを置き換えられず、補完のみできる理由だ。

経済性

決定的ガードレールは実行コストが安く、初期構築コストが高い。

アーキテクチャルールの記述には数日かかる。Semgrep設定の維持には継続的な注意が必要だ。contract testsの設定にはまずinterfaceの定義が必要だ。

しかし一度存在すれば、ほぼゼロの限界費用ですべてのコミットで実行される。疲れない。金曜の午後にチェックを省略しない。年功序列や社会的圧力に屈しない。

コード量が多く生成速度が速いAI生成codebaseにとって、この経済プロファイルは決定的だ。代替案 — AI生成速度に合わせて人間のレビューをスケールさせること — は実現不可能だ。

AI-Nativeアーキテクチャとの関連

この広範なパターンについてはStanford CS146S Is Right About AI Coding — The Missing Subject Is Architectureで書いた。決定的ガードレールは、置換可能なアーキテクチャを現実のものにするenforcementメカニズムだ。

ガードレールなしでは、アーキテクチャ境界は願望にすぎない。ガードレールがあれば、境界は構造的なものになる。「moduleの分離を保つよう心がけている」と「module分離が違反されればビルドが失敗する」の違いは、AI速度の反復に耐えるアーキテクチャとその下で崩壊するアーキテクチャの違いだ。

現代のソフトウェア開発者はAIツールの習熟だけでなく、AI生成コードを速度を落とさず構造的に安全に出荷するためのガードレールスタックを必要としている。

FAQ

AI生成コードにアーキテクチャルールをenforceするための最良のツールは?

Semgrepはカスタムアーキテクチャルールにとって最も柔軟な選択肢だ。AST構造に対するパターンマッチングをサポートし、CIで高速に実行でき、プロジェクト固有の境界をエンコードできる。JavaScript/TypeScriptプロジェクトには、dependency-cruiserやカスタムESLintルールも効果的だ。

AIコードレビューは人間のコードレビューを置き換えられるか?

いいえ。AIコードレビューはスタイルとドキュメントについて人間のレビューを補完するが、アーキテクチャ境界のenforcementとセキュリティ特性については信頼できない。決定的チェック(型システム、リンター、アーキテクチャルール、contract tests)が、注意力に依存するレビューの唯一のスケーラブルな代替だ。

チームを遅くせずにガードレールをどう設定するか?

型システムから始めよ(strictモード、例外なし)。最もリスクの高い3つの境界にアーキテクチャルールを追加せよ。外部連携にcontract testsを追加せよ。各層の設定には1日かかり、実行には数秒だ。遅延を生むのはチェック自体ではなく、違反だ。

ガードレールとリンターの違いは?

リンターは改善を提案する。ガードレールはビルドを失敗させる。区別はenforcementだ。AI生成codebaseでは、量が多すぎて一貫した手動の注意が不可能なため、提案はスケールにおいて無視される。ビルドの失敗だけが準拠を保証する。