AIにAIのコードを叩かせたら6割が修正された——「コンテキスト分離」が変えるレビューの常識
「AIにコードを書かせて、そのままセルフチェックまでやらせる」——これは今や多くの開発現場で試みられている手法だ。ところが実測データを見ると、この運用には根本的な欠陥がある。
エンジニアのmasuda masuo氏がZennに投稿した記事は、自律型開発プラグイン「kusabi」の運用ログ(454セッション、40,443ターン、約64.4億トークン分のSQLiteデータ)をもとに、「コンテキストを分離した敵対的レビュー」の効果を実測している。結果は明快だった。一発で合格したコードはわずか20%。約60%は敵対的レビューによって修正が必要と判定されていた。
AIに自分のコードを見せると、何が起きるか
まずセルフチェックがなぜ機能しないのかを整理しておく。
LLMがコードを書く際、そのコンテキストウィンドウ(会話履歴)には実装過程の情報が蓄積されている。「さっきこのエラーが出たからこう直した」という試行錯誤の記憶、「自分が書いたコードだから期待通り動いているはずだ」という自己正当化のバイアス、膨大なツール実行ログ——これらを背負ったままレビューをさせると、モデルは実際のコード差分よりも「思考の履歴」を優先して参照する。
これは人間の認知バイアスと同じ構造だ。自分が書いたコードのバグは見えにくい。いくら「厳しくチェックしてほしい」とプロンプトで指示しても、実装時の文脈を引きずったままでは客観的な視線は生まれない。
問題の本質は「AIの賢さが足りない」ではなく、「コンテキストを引き継いでいる」ことにある。この認識が出発点として重要だ。
数字が示すこと:一発合格はたった20%
kusabi-reviewが実施した301ラウンドのコードレビューの判定結果を見ると、現実はかなりきびしい。
| 判定 | 件数 | 割合 |
|---|---|---|
| needs-attention(修正要求) | 180回 | 59.8% |
| approve(一発合格) | 62回 | 20.6% |
| discard(破棄) | 28回 | 9.3% |
| partial / approve-partial | 19回 | 6.3% |
| unparseable(フォーマット不正) | 6回 | 2.0% |
「AIに指示すれば完璧なコードが一発で返ってくる」という感覚は、実測ベースでは5回に1回しか起きていない。残り80%は何らかの修正・破棄・部分承認が必要になっている。
レビューで検出されたバグ・問題は合計269件。深刻度別に見ると、Critical(致命的、システム全体の障害やデータ破壊につながるもの)が7件、High(主要機能の不全やセキュリティバイパス)が38件、Medium(エッジケースの考慮不足など)が111件、Low(軽微なスタイル違反等)が112件だった。
Criticalが7件というのは、頻度としては少ない。ただし問題は「1件でも本番に入れば致命的」という性質のものが複数あった、という点だ。
実際に見つかったバグ4選
元記事が開示しているCritical・Highの具体例が、この問題の実態をよく表している。
① デバッグコードの消し忘れ(Critical)
実装エージェントが開発途中の動作確認用に raise AssertionError('sabotage-check') を2箇所に挿入。本実装を完了した後、削除を忘れたまま「実装完了」として出力した。実装側AIは達成感を持ったまま(=その文脈のまま)セルフチェックを走らせたため見落とした。レビュー側AIはGit Diffだけを冷徹に検証し、即座にCritical判定を出した。
② リファクタリングによる関数本体の空洞化(Critical)
検索処理のリファクタリング中、実装エージェントが関数のロジック本体を誤って消してしまい、MCPの検索ツールが常に None を返すだけの「空の関数」になっていた。構文エラーにならないためパースは通る。レビューAIは「すべての検索呼び出しがNoneを返し、パイプラインが停止する」とロジックの破壊を検出した。
③ セキュリティスキャン・ゲートの無効化(High)
コンテナ内のシークレットリーク検証機能を実装した際、.gitleaksignore や gitleaks:allow コメントが存在するとスキャン自体がサイレントにバイパスされる穴が残った。レビューAIは「コンテナ内部のコード変更によって外側のセキュリティゲートを無効化できる構造的欠陥がある」と指摘した。
④ 安全フラグ(–read-only)の無視(High)
--read-only を指定しても特定バックエンドの起動ロジックのバグによりフラグが無効化され、書き込みツール権限が付与されたままになっていた。表面上は正常に見える。「安全オプションが内部で握りつぶされている」という仕様上の不整合を検出した。
これら4件に共通するのは、どれも「動く」ということだ。エラーが出ない。テストが通る場合もある。だからセルフチェックをすり抜ける。
なぜ「賢いモデル」より「コンテキスト分離」が効くのか
ここからが、この記事の一番おもしろい部分だ。
マルチエージェント開発の文脈でよく聞く問いに「実装モデルとレビューモデルに性能差が必要か?」がある。直感的には「賢いレビュアーが必要」と思いがちだが、データは違うことを示している。
同一モデル同士——DeepSeek v4 Flash(実装)→ DeepSeek v4 Flash(レビュー)——の組み合わせで実施した111ラウンドで、needs-attention判定は54回(48.6%)発生した。検出内訳はCritical 2件、High 21件、Medium 47件、Low 55件。同じモデルが自分自身のバグを、コンテキストを遮断するだけで約半分の確率で見つけている。
さらに逆の組み合わせも成立している。上位モデル(claude-opus-5やdeepseek-v4-proで実装)→ 軽量モデル(deepseek-v4-flashやgemini-3.7-flash-highでレビュー)という構成でも、軽量レビューモデルが上位実装モデルの見落としを的確に指摘していた。deepseek-v4-pro(実装)→ deepseek-v4-flash(レビュー)の5ラウンドでは、4ラウンド(80%)で修正指摘が発生している。
ここで得られる実務的な示唆は明確だ。レビューの精度を上げるために高額な上位モデルを使う必要はない。コンテキストを遮断するだけで、同じモデルが強力なレビュアーになる。
仕組みとしては単純だ。レビューエージェントに渡す情報を「リポジトリのベース状態 + 変更差分(Diff)+ テスト結果」のみに限定する。実装時の試行錯誤の記憶も、自己正当化のバイアスも、ツール実行の冗長ログも——何も渡さない。すると、モデルは純粋なコードレビュアーとして機能する。
実務への示唆:何を変えるべきか
「しっかりレビューしてほしい」というプロンプトの工夫でこの問題は解決しない。それはこのデータが示している。
ここで考えるべきは、アーキテクチャの話だ。kusabiが実装している「コンテキスト・ファイアウォール」の原則は3つある。
- 会話履歴の完全遮断:実装エージェントの試行錯誤の痕跡を、レビューエージェントに見せない
- 構造化レポートの強制:フリーテキストではなく、severity・title・fileを持つJSON Schemaで指摘を出力させる(曖昧な評価を防ぐ)
- サーキットブレーカーの設置:最大ラウンド数を設け、回復不能な場合は破棄または人間へのイシュー化に安全に退避する
これを自前の開発パイプラインに取り込もうとすると、実装コストはゼロではない。ただし「セルフチェックで安全と判断されたコードが本番に入る」状況と比較すれば、投資対効果は明確だ。
次に問題になるのは、コストと責任の所在だろう。AIが出した指摘をAIが承認するアーキテクチャにおいて、最終的に誰が責任を持つのか。サーキットブレーカーが作動したとき、それを人間が適切に判断できる仕組みになっているか。データには「unparseable(フォーマット不正)」が6件あった——レビューレポート自体が壊れるケースも存在する。
自律開発のループに人間がどの粒度で介在するかは、まだ設計の余地が大きく残っている論点だ。「AIが見たAIのバグ」を信頼するかどうかは、ツールの精度だけでなく、その出力フォーマットの構造的な堅牢さにもかかっている。
「プロンプト」から「構造」へのシフト
この記事が示しているのは技術的な話だけではない。AI活用の発想の転換を示している。
「より賢くなるよう促す」から「認知限界を構造でカバーする」へ。プロンプトエンジニアリングが花盛りの今、むしろシステムのアーキテクチャ側で問題を解く方向に目が向き始めている。
実測値として「一発合格20%」という数字を持っておくと、AI駆動開発の期待値調整に使える。「AIにコードを書かせれば完成する」ではなく、「AIにコードを書かせ、別のAIに監視させる仕組みが必要」という認識が出発点になる。
マルチエージェントの設計で次に問われるのは、おそらく「どのレイヤーで人間の判断を挟むか」だ。全自動化はできても全自動化すべきかは別の問いで、それぞれのチームが自分たちのリスク許容度をもとに答えを出すしかない。
参考元: AIにAIのコードを敵対的レビューさせたら6割叩き直された話 — 64億トークンのログが明かす『コンテキスト分離』の威力