AIコードの「腐れ方」には、パターンがある

「動くコードを書いてもらう」のは、もはや難しくない。問題は、そのコードが半年後も保守できる状態かどうかだ。

Qiitaに投稿されたあるエンジニアの記事が、この問いに実測値で答えている。AIに8割のコードを書かせて半年運用した結果、実際に「腐った」書き方が5つあったというレポートだ。抽象論ではなく、NG例・OK例・理由をセットで示した実践的な内容で、AI活用の現場感がある。

腐る、という表現が的確だと思う。書いた直後は問題が見えない。においがしてくるのは時間が経ってからだ。


5つのNG例:具体的に何が起きるか

記事が挙げる5つを順に見ていこう。コードの抜粋も含めて紹介する。

1. コードを言い換えるだけのコメントを盛る

AIはコメントを頼めばいくらでも書く。ただ、その多くは「$user_id = get_current_user_id(); // ユーザーIDを取得する」のような、コードをそのまま日本語にしただけのものになる。

これが半年後に何をするかというと、「嘘の地図」になる。実装を変えるたびにコメントは古くなる。コードは正しくてもコメントは古い状態が続き、読む人を混乱させる。

記事の推奨は明快だ。「なぜそうするか、だけ残す」。コードが「何をしているか」は読めばわかる。コメントが語るべきは「なぜその設計を選んだか」という意思決定の痕跡だけ。

2. 早すぎる共通化・抽象化

AIは「共通化しておきました」が好きだ。2箇所で似た処理が出ると、render_box($type, $data) のような汎用関数を作り、内部で if ($type === 'notice') ... elseif ($type === 'error') ... と分岐させる。

見た目はスマートだが、種類が増えるたびにその関数が膨らむ。剥がしたくても剥がせない。記事の言葉を借りれば「早すぎる抽象は、想定していなかったケースが来たときに合わず、かといって剥がすのも難しくなる」。

解決策は「重複を1つ許すこと」。render_notice()render_error() を別々に書いておいて、3回目の重複が出たときに初めて共通化を考える。このルールは、AIに丸投げしがちな状況に対するひとつの歯止めになる。

3. 巨大な1関数のまま置く

「入力の取り出し → バリデーション → 整形 → DB保存 → メール送信」を1つの handle_submit() に80行で詰め込む。動くから、そのまま残る。

これが怖いのは、「どこを変えると何が壊れるか読めない」状態になることだ。半年後に触れなくなる。記事では責任ごとに validate_input()save_entry()notify_admin() と割って、handle_submit() が3行になるOK例が示されている。名前が付くことで、コードを読む手がかりにもなる。

4. エラーを握り潰す try/catch

AIはとりあえず動かすために catch (Exception $e) { return null; } と書きがちだ。例外を飲み込んで、何もなかったことにする。

本番でこれが起きると「なぜか動かない、でもエラーも出ない」という最悪のデバッグ環境になる。原因が見えないバグは、いちばん時間を溶かす。記事では error_log() でログを残した上で throw $e で上位に投げ直す形を推奨している。失敗は消さない。見える形で返す。これだけだ。

5. テストなしで、AIの実装を信じる

「たぶん合ってる、で進む」。この感覚が積み重なると、半年後に「何が正しいのか自分でも分からない」状態になる。記事の著者がそう書いている。AIの出力は、動いているように見えても仕様どおりとは限らない。テストがないと、書き直すたびに挙動が少しずつずれていく。

記事が示すOK例は、test_links_over_three_are_spam() のようにテストで仕様を固定してからAIに実装させる形だ。仕様とテストは人間が握る。実装だけAIに任せる。この分担が重要だと強調されている。


ここからは見方の話:これはAI固有の問題ではない

5つを並べてみると、あることに気づく。どれも「新人エンジニアが書きがちなパターン」とほぼ重なる。

説明的すぎるコメント、早すぎる共通化、巨大関数、例外の無視、テスト不足。10年前のコードレビューでも同じ指摘が飛んでいた。AIは新人エンジニアの書き方を再現しているとも言える。

ただ、AI固有の問題がひとつある。「自信ある雰囲気で出力する」という性質だ。新人エンジニアのコードは、書いた本人も「これで合ってるか不安」という気配があるから、レビューで止まりやすい。AIのコードは整形されていて、コメントも付いていて、一見完成しているように見える。だから素通りしやすい。

腐敗が半年後まで気づかれないのは、この「自信ある雰囲気」に起因する部分が大きい。

もうひとつ言うと、AIが書きがちなパターンを「知らないまま」レビューに臨むのと、「知った上で」レビューするのでは、目の解像度がまるで違う。この記事の価値はそこにある。5つのチェックリストを頭に入れておくだけで、AIコードのレビューが構造的に変わる。


実務的な示唆:何を人間が持ち続けるべきか

記事のメッセージを実務に落とすと、こうなる。

仕様・テスト・エラーハンドリングの設計は人間が手放さない。

AIに丸投げしてうまくいくのは「実装」だ。「何をするか」「失敗したらどうするか」「正しい動作をどう確認するか」は、人間が設計して渡す側にいる必要がある。この分担を崩すと、半年後に「何が正しいのか自分でもわからない」コードベースができあがる。

レビューの観点も変わる。「動くか」より「腐らないか」を見る。具体的には、コメントが実装の言い換えになっていないか、抽象化が早すぎないか、関数の責任が一つになっているか、エラーが消えていないか、テストが仕様を固定しているか、という5点を確認するだけでよい。

コード量が増えるほど、この観点は重要になる。AIで生産量が上がれば上がるほど、レビューなしで通過するコードの絶対量も増える。一件一件のコストが下がっても、腐敗の蓄積速度が上がれば差し引きゼロどころかマイナスになる。


今後の論点:AI活用が進むほど「腐敗の速度」はどうなるか

今のところ、AIコード活用の議論は「どれだけ速く書けるか」に集中している。生産性の向上が主テーマだ。

次に問題になるのは、「どれだけ速く腐るか」だと思っている。

コードの生産量が増えれば、それだけ保守対象も増える。テストなし・エラーハンドリングなし・巨大関数のコードが大量にコードベースに流入すれば、半年後・1年後の保守コストは急激に跳ね上がる。しかもその腐敗は、書いた直後には見えない。

「書く速さ」と「腐敗の速さ」がセットで語られるようになったとき、AI活用の評価軸が変わる。このレポートはその予兆の一つだ。8割AIで半年という実測値があるからこそ、抽象論でなく具体的な議論ができる。こういう現場報告が増えてほしいと思う。


まとめ

5つのパターンを覚えるのは難しくない。コメントは「なぜ」だけ残す。共通化は3回目から。巨大関数は責任で割る。エラーは記録して上位に返す。仕様とテストは人間が握る。

ただ、これを知っているかどうかは、AIコードを使い続けた先の半年後に差がついてくる。腐るのは書いた直後ではないから。

生成AIはコードを書くのを手伝ってくれる。腐らないようにするのは、まだ人間の仕事だ。


参考元: AIに書かせたコードで実際に腐った5つ。半年運用でわかったNG例と直し方