クリーン環境で露呈するAIコードの脆弱性
深夜2時、ローカル環境で完璧に動作していたコードを、本番環境を模したクリーンなDockerコンテナにデプロイした瞬間、コンソールが真っ赤なエラーログで埋め尽くされる――。我々エンジニアなら誰もが一度は経験したことのある、あの胃が痛くなるような「It works on my machine(手元では動く)」の悪夢。この古典的かつ致命的な問題が、現代のAIエージェントが生成するコードにおいても、より深刻な形で再現されていることが明らかになった。
ミズーリ大学とSRI Internationalの研究チームが発表した論文「AI-Generated Code Is Not Reproducible (Yet)」は、AIによるコード生成の不都合な真実を冷徹に突きつけている。100の標準化プロンプトから生成された300のプロジェクトを、OSパッケージのみのクリーンな環境で、モデルが宣言した依存関係(Dc)だけで動作させたところ、正常に動作したのはわずか68.3%に過ぎなかったというのだ。言語別の成功率は以下の通りである。
| 言語 | プロジェクト数 | 成功数 | 成功率 |
|---|---|---|---|
| Python | 120 | 107 | 89.2% |
| JavaScript | 105 | 65 | 61.9% |
| Java | 75 | 33 | 44.0% |
| 合計 | 300 | 205 | 68.3% |
この研究で特に注目すべきは、依存関係の「三層モデル」という概念である。設定ファイルに明記された依存(Dc)、デバッグの末に実際に必要となった依存(Dw)、そして実行時にロードされるすべての依存(Dr)。論文によれば、DcからDrへと至る過程で、依存関係のボリュームは平均13.5倍にまで膨れ上がる。この「依存のギャップ」こそが、AIコードをまっさらな環境で動かす際の巨大な障壁となっている。
私はシニアエンジニアとして、この結果に強い危機感を抱かざるを得ない。我々は日々の開発で、AIが吐き出したコードを深く検証もせず、requirements.txtやpackage.jsonをそのまま信じてデプロイしていないだろうか。AIが「これが要る」と主張する依存関係の裏には、目に見えない巨大な依存の氷山が隠れており、それが本番環境でのデッドロックや予期せぬバージョン衝突を引き起こすトリガーになっているのだ。
自律テストがもたらす一発動作のパラダイムシフト
しかし、この「AIコードは動かない」という定説は、最新のLLMとエージェントの進化によって、すでに過去のものになりつつあるのかもしれない。Qiitaの検証記事において、Claude Code 2.1.246とClaude Opus 5を用いた追試が行われた。その結果は、4つのプロジェクトすべてが一発で動作し、追加の依存インストール(Dw)も一切不要という、論文の数値を覆す驚異的なものだった。
なぜ、これほど劇的な差が生まれたのか。その最大の要因は、AIエージェントが「頼んでもいないのに、自律的にテストを書いて実行していた」という点にある。
例えば、PythonでのCSV集計タスク(P1)ではpytestを75件、doctestを4件も自律的に生成して実行し、JavaScriptのRESTクライアント(J1)にいたっては186件ものテストを実行する中で、自ら4件 of バグを発見・修正していたという。これは、従来の「コードを生成して終わり」という一方通行のプロセスから、「生成、テスト、デバッグ、修正」という自律的なフィードバックループへの進化を意味している。
論文における失敗原因の分析を見ると、実は「依存関係の不整合」による失敗は全体の10.5%に過ぎず、半分以上の52.6%は「コードそのもののバグ」であった。つまり、AIが自らテストを書き、実行環境でコードを動かしてバグを潰す能力(TDD:テスト駆動開発の自律実行)を手に入れた瞬間、クリーン環境での動作成功率は跳ね上がるのだ。
さらに、外部ライブラリに頼らず、Pythonの標準ライブラリやNode.jsの標準API(fetchやIntl.Segmenterなど)を駆使して「依存ゼロ」でコードを書き上げるという、極めてスマートな設計判断をAI自身が下している点も見逃せない。依存がなければ、依存のギャップなど原理的に発生しない。この「引き算の美学」をAIが理解し始めたことは、我々人間のアーキテクトにとっても驚異であり、大いなる刺激となる。
コンテキスト汚染とエンジニアの新たな生存戦略
だが、この輝かしい追試結果の裏には、我々が直面する新たな技術的懸念も潜んでいる。追試の過程で、JavaScriptのMD→HTML変換タスク(J2)を実行したエージェントが、作業ディレクトリに置かれていた実験用の「prompts.md」を読み込んでいたことが発覚した。これは、AIエージェントが意図しないコンテキスト(文脈)を読み込み、それに基づいて挙動を最適化してしまう「コンテキスト汚染」の典型例である。
AIが賢くなればなるほど、開発環境に転がっているメモ書きや一時ファイル、過去のログといった「ノイズ」を勝手に解釈し、カンニングのような形で最適なコードを出力してしまうリスクが高まる。これは、厳密なサンドボックス環境での検証を困難にし、本番環境での再現性を著しく損なう原因になり得る。
また、論文の失敗原因にある「処理できなかった(16.8%)」という項目や、追試で筆者が直面した「文字列の列を合計しようとしてエラーになった」というオペレーションミスは、AIの性能限界だけでなく、それを使う人間側の「指示の曖昧さ」や「検証能力の不足」を浮き彫りにしている。
我々エンジニアが明日から取るべき実践的な処方箋は、AIにコードを書かせる際、必ず「まっさらな環境(venvやDockerコンテナ)」を自動構築し、AI自身にテストコードを書かせ、そのテストがクリーン環境で100%パスすることを確認するCI/CDパイプラインを構築することだ。AIを単なる「コード生成の自動書記」として使う時代は終わった。これからは「自律的なQAエンジニア」としてAIを飼い慣らし、その出力を厳格なサンドボックスで評価する仕組み作りが求められる。
ここで、業界への痛烈な問いを投げかけたい。AIが自律的にテストを書き、標準ライブラリを駆使して依存関係を最小化し、クリーン環境で一発動作するコードを数分でデリバリーするようになったとき、我々人間のエンジニアが書くコードの価値はどこに残されるのだろうか?単に「仕様書通りにコードを書き、テストを通す」だけの作業者は、もはやAIエージェントの足元にも及ばない。我々が磨くべきは、AIに与えるコンテキストを厳密に制御する「コンテキスト・アーキテクチャ設計力」であり、AIが生成したテスト自体の妥当性を疑う「メタな批判的思考力」ではないだろうか。


コメント