rmコマンドなしで220万ファイル消失。AIエージェントが仕掛けた「地雷」の正体

rmコマンドなしで220万ファイル消失。AIエージェントが仕掛けた「地雷」の正体 AI

AIコーディングエージェントに、自分のサーバーを触らせていますか?

便利なんですよね。
ファイルを作り、コードを書き、テストまで回してくれます。
しかし、その便利さの裏にはリスクが潜んでいます。

今回紹介するのは、ある投稿です。
AIエージェントの作業中に、サーバー上の約220万ファイルが失われました。

ただし、投稿者はオフサイトバックアップを持っていました。
そのため、実害は最小限で済んでいます。
それでも、このスレッドには学ぶべき教訓が詰まっています。

何が起きたのか

投稿者はAIエージェント(スレッドではFable 5と呼ばれるモデル)を使っていました。
そして、コードベースへのアクセスを許可して作業していたのです。

すると、あるディレクトリの中身が丸ごと消えました。
その数、約220万ファイルです。

興味深いのは、その後の展開です。
投稿者はエージェント自身に、削除ファイルの復旧を試させました。

その結果、約110万ファイルは復元に成功。
しかし、全部は戻りませんでした。

なぜなら、復旧作業の最中に別のバックアップ用cronジョブが動いたからです。
これにより、多くのファイルが上書きされてしまいました。

不幸中の幸いは、消えたデータがオフサイトにバックアップ済みだったこと。
だからこそ、投稿者は冷静に呼びかけられたわけです。
「これを教訓にしてほしい。AIにコードベースを触らせる前に、大事なデータのバックアップを取ろう」と。

削除の仕組み:直接消されたわけではない

コメント欄で最初に飛び交ったのは、「gitを使え」という定番の指摘でした。
ところが、この事例ではgitは救いになりません。

理由を整理しましょう。
消えたディレクトリは、巨大な生データ置き場でした。

そして、.gitignoreで管理対象から除外されていたのです。
gitが追跡していないファイルは、過去のコミットから復元できません。

つまり、これはバージョン管理の問題ではなかったのです。
ファイルシステム操作の問題でした。

では、何が引き金だったのか。
エージェントはテスト用に、そのディレクトリへのシンボリックリンクを作りました。

これ自体は削除コマンドではありません。
しかし、その後の git add -A がすべてを変えます。

ignore設定はシンボリックリンクに対して期待どおりに働きませんでした。
その結果、リンクがコミットに取り込まれます。
そして、除外対象だった実ディレクトリの中身が一掃されてしまったのです。

あるコメントは、これを見事に表現していました。
「エージェントが地雷を埋め、gitがそれを踏んだ」と。

rm -rf のような分かりやすい破壊コマンドは、一度も実行されていません。
危険な状況を組み立てる判断の連鎖がありました。
それが結果として、大量削除を引き起こしたのです。

投稿者自身も認めています。
「gitignoreされたディレクトリへのシンボリックリンクをチェックするなんて、まったく頭になかった」と。

また、似た体験談も寄せられていました。
worktreeが作ったシンボリックリンクと、ディレクトリ単位のignore設定の組み合わせ。

これで .venv を吹き飛ばしたそうです。
つまり、経験者でも踏み抜く落とし穴だということです。

コメント欄の反応:責任は誰にあるのか

スレッドで最も支持を集めた意見は、実は技術的な指摘ではありません。

「訂正。あなたがFable 5を使って220万ファイルを削除したんです」
この視点です。

うまくいったときは「私が作った!」と言う。
しかし、失敗したときは「AIが壊した!」と言い分ける。

そんな風潮への皮肉として、多くの共感を集めていました。
道具の行動に対する最終責任は、操作した人間にあります。
この原則は、何度でも確認しておく価値があるでしょう。

一方で、投稿者を擁護する声も目立ちました。
この手の投稿の大半は、バックアップなしで泣きつくパターンです。

ところが、今回の投稿者はきちんと備えていました。
だから「説教される筋合いはない。むしろ模範的だ」というわけです。

さらに、深い議論もありました。
まず「芝刈り機が花を刈っても、芝刈り機を責めないだろう」という道具論が出ます。

これに対して、こんな反論が付いたのです。
芝刈り機は、自分で刈る場所を決めません。

しかし、エージェントは違います。
誰も指示していないのに、シンボリックリンクを作るという判断を自ら下しました。

売るときは「エージェント」と呼ぶ。
なのに、事故が起きた途端に「ただのツール」と呼び変える。
それはおかしくないか、と。

責任は人間にあります。
それでも、自律的に判断する道具のリスクは従来の道具とは質が違います。
この両方を、同時に受け止める必要がありそうです。

スレッドから拾える実践的な防御策

コメント欄には、具体的なノウハウが数多く投稿されていました。
特に有用だったものを整理します。

  • エージェントにmainブランチへ直接コミットさせない。必ずプルリクエストを経由させて、すべての変更を自分の目で確認する
  • サンドボックスで動かす。Dockerコンテナなどの隔離環境で権限を絞り、rmのような危険コマンドは明示的に拒否する
  • 唯一のコピーの上で作業させない。読み取りアクセスしか与えていなくても、ファイルは壊れうる前提で、フォークやコピー上で作業する

このあたりが基本線です。
加えて、運用の工夫も紹介されていました。

例えば、多段構成のブランチ運用です。
セッションごとにブランチを切ります。

次に、devブランチへプッシュ。
そこからmainへPRを出す、という流れです。

「やりすぎでは」という自問もありました。
しかし、「それが普通のソフトウェアエンジニアリングだ」という返信が付いていたのが印象的です。

また、設定ファイルにルールを書き込む方法もあります。
gitや外部サービスに関わる操作は、すべて明示的な承認を必須にする。
しかも、その承認は次の操作に持ち越さない。

さらに徹底している人もいました。
エージェントの言い回しで誤って許可を与えないよう、用語の定義まで指定しているそうです。

バックアップ戦略についての知見も豊富でした。

  • 削除機能を持たないバックアップツールを毎時走らせる
  • ZFSを使い、エージェント起動のたびにスナップショットを取る
  • 複数の場所に分離して保管する

そして、重要な注意がひとつ。
バックアップは定期的に動作確認してください。
いつの間にか止まっていた、という失敗談が実際に語られていました。

復旧作業に関する指摘も見逃せません。
今回は復旧中にcronのバックアップジョブが動きました。
そして、ファイルを上書きしてしまったのです。

だからこそ、復旧を始める前に自動ジョブを止める。
あるいは、ボリュームのスナップショットを先に取っておく。
そんな助言が寄せられていました。

辛口の指摘もあります。
そもそも、バックアップのはずのジョブがファイルを上書きする設計自体が危険信号だ、と。

プロンプトの問題ではない

「安全確認をプロンプトに書いておけば防げた」という意見も出ました。
しかし、これには説得力のある反論が付いています。

エージェントは、非決定的に動きます。
十分な回数スクリプトの実行を承認すれば、いつかは必ずミスが混ざるのです。

人間がタイポをするのと同じですね。
実際、エージェントのやらかしパターンは山ほど報告されていました。

シンボリックリンクの誤解、gitignoreの誤解、相対パスの間違い。
さらには、worktreeの取り違えや、git resetやstashの事故もあります。

つまり、完璧なプロンプトで事故を防ぐ発想には限界があるのです。
事故は起きる前提で考えましょう。

そして、起きても致命傷にならない構造を作る。
これが、スレッド全体を貫く結論でした。

まとめ

今回の事例のポイントを振り返ります。

エージェントは、削除コマンドを直接実行していません。
シンボリックリンク、git add -A、.gitignoreという三つの要素が絡み合いました。

その結果、追跡外の220万ファイルが消えたのです。
この事例は二つのことを教えてくれます。

gitで守れない領域があること。
そして、一見無害な操作の組み合わせが破壊的な結果を生むことです。

守りの基本はシンプルです。
エージェントの変更には、必ずレビューを挟む。
作業環境を隔離する。

そして何より、大事なデータのバックアップを複数持つこと。
動作確認まで行えば、なお安心です。

あるコメントが言うとおり、「AIに触らせる前にバックアップ」ではありません。
最初からバックアップしておくべきなんですよね。

AIエージェントは強力です。
だからこそ、失敗しても笑って復旧できる仕組みを先に用意しましょう。
そのうえで、思い切り働いてもらえばいいのです。

タイトルとURLをコピーしました