土曜日、丸一日かけてニコ生コメントビューアの大規模改修を行いました。更新・実装は全部で8件。バックグラウンド読み上げの改善、ギフト表示の調整、ダークモードまわりの手直し……ひとつひとつ動作確認をしながら、夜には「よし、全部入った」と満足してリリースしました。
ところが日曜の朝。何気なく開いた配信画面を見て、血の気が引きました。
ダークモードボタンが、無い。
慌てて確認すると、リリースしたアプリに入っていたのは8件のうち最後の1件、「合言葉配信対応」だけ。残りの7件は、きれいさっぱり消えていました。原因は、AI(Claude Opus 4.8)が8個目の実装を行う際に、7件の修正が入った最新ファイルではなく、改修前の古いファイルを元にコードを出力したこと。つまり8個目の実装は「7件の成果を上書きで消しながら」行われていたのです。
こうして私の日曜日は、土曜にやったはずの7件を、もう一度実装し直す一日になりました。
「AIがバカだった」で終わらせるのは簡単です。でも、この事故にはLLM(大規模言語モデル)の仕組み上、起こるべくして起こる構造的な理由があります。今回は世界中の開発者コミュニティで報告されている同種の事例や解説を調べ、なぜこれが起きるのか、そしてどうすれば防げるのかを、専門的な部分も省かずに丁寧にまとめました。AIと一緒に開発しているすべての人に、他人事ではない話だと思います。
この記事のポイント
- AIが古いコードで上書きする事故は構造的に起こる
- 原因はコンテキストの劣化と「最後に見た版」問題
- 差分確認と単一ソース運用で被害はほぼ防げる
9分57秒でわかるまとめ動画
何が起きたのか ― 事故のタイムライン
まず、今回の事故を時系列で整理します。
土曜(改修day)
AIとの長い作業セッションの中で、1件目から7件目までの更新・実装を順番に進めました。それぞれの実装後に動作確認も行い、コードは着実に育っていきました。そして8件目、「合言葉配信(パスワード付き配信)への対応」を依頼したところ、AIは完全なファイルを出力。私はそれを配置してビルドし、リリースしました。
日曜の朝(発覚)
何気なく見た配信画面に、あるはずのダークモードボタンがありません。「あれ?」と思ってコードを確認すると、8件目の出力ファイルのベースが、土曜の朝の状態、つまり改修前のコードだったことが判明。7件分の変更は跡形もなく、そこに8件目だけが継ぎ足されていました。
日曜(やり直しday)
消えた7件を、記憶とログを頼りに再実装。二度目なので多少は速かったものの、丸一日が飛びました。
ここで恐ろしいのは、「最後の実装は正しく動いていた」ことです。8件目の合言葉配信はちゃんと動く。だから最後の動作確認では異常に気付けない。消えたのは「それより前の7件」なので、全機能を総ざらいで確認しない限り発覚しません。今回、朝の配信でたまたまダークモードボタンの不在に気付けたのは、不幸中の幸いでした。
なぜAIは「古いファイル」を掴むのか ― 4つの構造的原因
世界中の開発者フォーラムやAI開発ブログを調べると、この現象は決して珍しいものではなく、複数の原因が絡み合って起こることが分かりました。ひとつずつ解説します。
原因1:コンテキストウィンドウと「注意の希釈」
LLMは「コンテキストウィンドウ」と呼ばれる有限の作業記憶の中で動いています。会話のやり取り、読み込んだファイル、出力したコード、エラーメッセージ――すべてがこの窓の中に積み上がっていきます。
問題は、この窓が満杯に近づくほど、モデルの注意力が薄まることです。近年この現象は「コンテキストロット(context rot:文脈の腐敗)」と呼ばれ、セッションが長くなるにつれてAIの出力品質が徐々に劣化していく構造的な問題として知られています。バグではなく、LLMの仕組みそのものに由来する性質です。
今回のケースでは、土曜の長いセッションの中に「改修前の元ファイル」「7回分の修正のやり取り」「7回分の出力コード」がすべて混在していました。1件目から7件目までは直前の文脈が濃かったので正しく積み上がった。しかし8件目の時点で窓の中は膨大な情報で溢れ、モデルの注意が薄まった結果、一番最初に読み込んだ、一番「まとまった形で存在する」元ファイルに引っ張られてしまった、と考えられます。
原因2:「最後に見た完全版」への回帰
これは特に重要なポイントです。セッションの中に「完全なファイル」が複数バージョン存在すると、AIはどれが最新かをタイムスタンプではなく、文脈上の存在感で判断しがちです。
7件の修正が「差分のやり取り」(ここをこう直して、という部分的な会話)で進んでいた場合、AIの中では「完全な形のファイル」は最初に読んだ古い版だけ、という状態になり得ます。すると「ファイル全体を出力して」と頼まれたとき、AIは手元にある唯一の完全版――つまり古いファイル――を土台にしてしまう。7件の修正は「会話の記憶」としては存在していても、「コードの実体」として統合されていなかったわけです。
人間でも似たことがあります。会議で7回口頭修正が入った企画書を、最後に「清書して」と言われたら、うっかり修正前のWordファイルを開いて清書してしまう。あれと同じ構造です。
原因3:「変更」ではなく「置き換え」と解釈する癖
開発者コミュニティでは「AIに1箇所の変更を頼んだら、言及していない部分まで消された・書き換えられた」という報告が数多く挙がっています。AIは指示を「追加」ではなく「置き換え」と解釈したり、自分が不要と判断した部分を勝手に削ったりすることがあるのです。ある調査では、AIコーディングツール利用者の6割以上が「不要な変更をされること」を主要な不満に挙げているというデータもあります。
今回の「8件目も実装して全体を出力」という依頼は、AIにとって「古い土台+新機能=完成品」という置き換えの解釈が成立しやすい状況でした。
原因4:最終出力の検証が「最後の1件」に偏る
これはAI側ではなく、私たち人間側の構造的な弱点です。8件目を実装した直後の動作確認は、当然「合言葉配信が動くか」に集中します。そこは動く。だからOKを出してしまう。新機能の確認は熱心にやるのに、既存機能の生存確認(リグレッションテスト)は省略しがち――この非対称性が、事故を「リリース後の朝」まで隠してしまいました。
解決策・打開策 ― もう二度と7件を失わないために
原因が構造的なら、対策も構造的に打つ必要があります。調査した情報と今回の教訓から、実効性の高い順に紹介します。
最善策:作業のたびに「最新ファイルを渡し直す」
もっとも確実なのは、大きな実装を頼むたびに、その時点の最新ファイルを添付し直すことです。「さっきの続きで」ではなく「これが現時点の最新版です。これをベースに8件目を実装してください」と、物理的にファイルを渡す。AIの中の曖昧な「会話の記憶」ではなく、目の前の実体ファイルを唯一の正(Single Source of Truth)にするのです。
GitHubの開発者ディスカッションでも、「変更を頼む前に現在のコードを貼り直し、重要な要件はたとえ既に伝えていても再度明記する」ことが最有力の対策として挙げられています。手間に感じますが、7件やり直す手間に比べれば一瞬です。
打開策:セッションを区切る(コンテキストを新鮮に保つ)
長いセッションほどコンテキストは劣化します。大きな機能の区切りごとに新しいチャットを開始し、最新ファイルと必要な要件だけを持ち込むのが有効です。古いやり取りが混ざった長大なセッションは、AIにとって「古い地図と新しい地図が同じ机に散らばっている」状態。机を一度きれいにして、最新の地図だけを置き直すイメージです。
回避策:出力を配置する前に「差分確認」を挟む
AIが出力した完全ファイルを、配置前に必ず現行ファイルと差分比較(diff)します。Windowsなら fc コマンド、あるいはWinMergeのようなGUIツールが便利です。今回のケースなら、8件目の出力と手元の最新版をdiffした瞬間、「7件分の変更が消えている」ことが数百行の差分として一目で見えたはずです。AIの出力は信頼しても、検証は省かない。 これが鉄則です。
回避策:バージョン管理(Git)でいつでも戻れるようにする
Gitでコミットを刻んでいれば、たとえ上書き事故が起きても「日曜に7件やり直す」のではなく「土曜夜のコミットに戻して8件目だけやり直す」で済みます。個人開発でもGitは保険として絶対に効きます。1件実装するごとに git commit する習慣は、AI時代の命綱です。
予防策:リリース前の「機能生存チェックリスト」
新機能の確認だけでなく、既存の主要機能が生きているかを確認する短いチェックリストを作っておきます。ニコ生コメントビューアなら「コメント受信」「読み上げ」「ギフト表示」「ダークモード切替」……と主要機能を10項目程度並べ、リリース前に1分で目視確認する。今回のような「最後の1件しか入っていない」事態は、これだけで確実に検出できます。
予防策:AIへの依頼文に「守るべきもの」を明記する
「8件目を実装してください。ただし、これまでに実装した以下の7件の機能を一切変更・削除しないこと」と、守るべき既存機能を箇条書きで添える方法です。AIは「言及されていないもの」を軽く扱う傾向があるため、「消してはいけないもの」を明示的に言語化することが抑止力になります。
まとめ ― AIは優秀な相棒、ただし記憶は信用しない
今回の事故で痛感したのは、AIの能力の問題ではなく、AIの「記憶」の性質を理解せずに運用していたことが本当の原因だった、ということです。
AIのコンテキストは、長くなるほど劣化し、古い完全版に引っ張られ、言われていないことを勝手に整理する。これはOpus 4.8に限らず、あらゆるLLMに共通する構造的な性質です。だからこそ、
- 最新ファイルを毎回渡し直す
- 出力は必ずdiffで検証する
- Gitでいつでも戻れるようにする
- リリース前に既存機能の生存確認をする
この4点を回すだけで、今回のような「一晩で7件消える」事故はほぼ防げます。
日曜を丸ごと失った代償は小さくありませんでしたが、この教訓が同じようにAIと開発しているどなたかの週末を守れるなら、書いた甲斐があります。皆さんも、AIの出力を配置する前に、ぜひ一度diffを。あの朝の「ダークモードボタンが無い」という背筋の凍る瞬間を、味わう人が一人でも減りますように。

ではでは、参考までに
コメント