金色の配線パターンが広がる基板の接写
設計と運用

AIコードレビューが見逃すアーキテクチャ違反、UUID事故の構造

目次を見る

マイクロサービス構成でAI(人工知能)コードレビューツールを導入しているチームに向けて、見落としやすい落とし穴を整理します。CIが全てグリーンで、AIレビューも「問題なし」と判定したPR(プルリクエスト)が、本番環境を止める事故につながる構造を扱います。

Linter(構文チェックツール)もAIレビューボットも、1ファイル単位では正しく動きます。それでも組織をまたぐ依存関係までは把握できません。その境界線がどこにあるかを理解しておくことは、設計判断の根拠を説明する立場の人にとって役立つはずです。

何が起きるか

認証サービスのプロトコルバッファ定義で、user_idの型をstring(UUIDv4)からint64(連番整数)に変更するPRが例として挙げられます。

タイトルは「ユーザー検索のインデックス最適化」。TypeScriptの型チェックもprotobufのスタブ生成も通り、ユニットテストも全てパスします。AIレビューボットは「B-treeインデックスの断片化を最大25%削減できます」と好意的なコメントを残します。

ところがステージング環境にマージされた20分後、決済ゲートウェイが停止します。原因は、2年前に制定されたADR(Architecture Decision Record、アーキテクチャ上の意思決定を記録した文書)が、全内部APIでUUIDv4文字列を必須としていたことです。衝突攻撃の防止とマルチテナントのデータエクスポートを目的とした取り決めでした。

さらに厄介なのは、影響範囲が1ホップでは収まらない点です。認証サービスが公開する/v1/usersを決済前サービスが呼び出し、その先の課金サービスと台帳サービスがuser_idを厳格なUUID型として永続化していました。1つのスキーマ変更が3つ先のサービスまで静かに壊していたことになります。

なぜ起きるか

原因を分解すると、3つの層に分かれます。

1つ目は、CIとAIレビューの検査範囲の狭さです。 型チェックやユニットテストは「このファイルの中で矛盾がないか」しか見ません。ADRのような組織の取り決めは、コードの外側にあるドキュメントであり、CIパイプラインの監視対象には入っていません。

2つ目は、ベクトル検索ベースのRAG(Retrieval Augmented Generation、検索で得た情報をもとにLLMが回答を生成する仕組み)の限界です。 ADRや設計文書をベクトル化して類似検索にかけても、「user_idポリシーに関する文書」で検索すると、無関係なブログ記事やRFCがヒットすることがあります。アーキテクチャのガバレッジは「このADRがこのフィールドを規定しているか」「期待される型と一致するか」という二値かつ関係的な判定であり、意味的な近さを測るベクトル類似度とは相性が悪い性質を持ちます。

3つ目は、多段階の依存関係(マルチホップの波及範囲)がRAGから見えないことです。 サービスAがサービスBを呼び、BがCに依存し、Cをチームのオーナーが管理している、という4段階のチェーンを一度に辿る仕組みがなければ、「このフィールド変更が3つ先の課金パイプラインを壊す」という結論には到達できません。加えて、数十のマイクロサービスと数十件のADRを全てLLMのコンテキストウィンドウに詰め込む方式は、応答に15〜30秒かかるうえ、中間に埋もれた重要な一文をモデルが無視してしまう現象(コンテキストの中だるみ)も起こります。

自分のプロジェクトが該当するか確認する

次の観点で、自分たちのリポジトリとレビュー体制を点検してみてください。

  • ADRやRFCなどの設計決定が、コードと分離した場所(Wiki・Confluence・Markdownリポジトリ)にのみ存在していないか
  • CIにスキーマ互換性チェック(protobufのbreaking change検出ツールなど)が組み込まれているか
  • AIレビューボットの設定が、単一ファイルのdiffのみを入力としていないか(複数ファイル・複数リポジトリの横断参照ができるかを確認)
  • サービス間の呼び出し関係を機械可読な形(OpenAPI定義・サービスメッシュの構成・依存関係マニフェスト)で管理しているか
  • 過去にスキーマ変更が原因のインシデントがあった場合、再発防止策がCIのルールとして固定化されているか

該当するリポジトリでは、まず.protoやopenapi.yamlなどのスキーマ定義ファイルに対して、差分検出ツール(buf breakingやprotobufのcompatibility checkerなど)が導入されているか確認してください。導入されていなければ、型変更だけはこの段階で機械的に止められます。

対策の手順

AIレビューの限界を補うには、判定の仕組みそのものを変える必要があります。手順として整理すると次の通りです。

ステップ1: アーキテクチャ決定をグラフ構造で表現する

ADRやサービス間の依存関係を、ノード(サービス・フィールド・チーム・ADR)とエッジ(CALLS・DEPENDS_ON・OWNED_BY・DEFINED_INなど)で表現したグラフデータベースに格納します。Neo4jやFalkorDB(Redis互換プロトコルで動く高速グラフデータベース)のような製品が候補になります。グラフ上では「このADRがこのフィールドを規定しているか」という問いを、曖昧な類似度ではなくCypherなどのクエリ言語で確定的に判定できます。

ステップ2: PRの差分をAST(抽象構文木)パラメータに変換する

LLMの役割を「ルール違反の推測」ではなく、「diffを構造化データに変換する」作業に絞ります。変更されたフィールド名・型・ファイルパスを抽出し、グラフクエリの入力として渡します。

ステップ3: グラフ探索でルール適合と波及範囲を機械的に確認する

フィールドがどのADRに紐づくか、型が一致するか、何ホップ先まで依存しているサービスがあるか、をグラフ走査で求めます。この処理はミリ秒単位で完了するため、CIのブロッキングチェックとして組み込める速度です。

ステップ4: LLMには説明文の生成だけを任せる

グラフ探索で得た「違反あり・影響範囲はこのサービス群」という確定的な結果をもとに、LLMに「なぜ問題か」「どう直すべきか」を人間向けの文章にまとめさせます。判定そのものはLLMの確率的な推論に依存しません。

ステップ5: 段階的に導入する

いきなり全社のADRをグラフ化するのは負荷が大きいため、まずは過去にインシデントを起こしたスキーマ(認証系・課金系など重要度の高いドメイン)から着手し、CIのブロッキングルールとして1つずつ追加していく進め方が現実的です。

AIレビューは「構文の正しさ」は判定できても、「組織の取り決めとの整合性」や「多段階の依存関係」はグラフ構造で機械的に確認しない限り見えません。

導入前に確認しておきたいこと

AIコードレビューを本番の防波堤として過信すると、今回のようなスキーマ変更事故を防げません。

確認すべきは次の3点です。まず、ADRのような設計決定がコードから分離された文書のままになっていないか。次に、CIにスキーマ互換性チェックが組み込まれているか。最後に、サービス間の依存関係が機械可読な形で管理され、グラフ探索のような確定的な判定に使える状態かどうかです。

完璧なグラフ化を一度に目指す必要はありません。まずは重要度の高いドメインの依存関係だけでも可視化し、CIのブロッキングルールに組み込むところから始めてみてください。

参考

Why LLM Code Reviewers Fail at Architecture—And How We Fixed It with a 9ms FalkorDB Knowledge Graph

この記事について: 本記事は AI を活用して作成し、forva AI 編集部が内容を確認・監修しています。

AI 駆動開発のご相談は forva AI へ。まずはお気軽にどうぞ。