AIエージェントのファイル編集におけるデータ損失(破壊的置換)とDLPガード設計
1. 概要
AIエージェントによる自動コード編集において、「指示されたコードの書き換え」が引き起こす予期せぬソースコードの破壊や消失(データ損失)は、極めて普遍的かつ深刻な課題である。 OpenCode(anomalyco/opencode#31248)等のインシデント事例は、単純なテキスト置換やファイルの無断上書きが、プロジェクトの健全性を一瞬で崩壊させるリスクを示している。 本稿では、AIの編集ツールにおけるデータ損失の発生メカニズムを分析し、コンテナサンドボックス(sunaba)が実装している「DLP(Data-Loss Prevention)ガード設計」の有効性について考察する。
2. インシデントの分析:opencode#31248
2.1. 曖昧な置換対象(oldString)による広域破壊
AIエージェントがファイル内の特定箇所を書き換える(置換する)際、対象として提示する oldString(置換前文字列)が短すぎるか、あるいはファイル内でユニーク(一意的)でない場合、単純な replaceAll 処理は以下の破壊を引き起こす。
- エージェントが意図していない無関係な場所(別の関数や変数名等)まで同時に書き換えられる。
- コンパイルエラーや型チェックエラーが発生するまで、この「サイレントなコード破壊」に開発者が気づかない。
2.2. ファイルの「無断サイレント上書き」
ファイルへの新規書き込みツール(write)において、既存のファイルが存在する場合の警告(警告ダイアログや例外)がない場合、エージェントは既存ファイルのパスに対して新規作成コマンドを送り、ファイル全体の数千行のロジックを一瞬で消し去ってしまう。
3. sunaba にみる三層のDLP(データ損失防止)ガード設計
これらの「AIによる無断コード破壊」に対し、sunaba(コンテナファイル編集ツール)は、インフラおよびAST(抽象構文木)のレベルで、以下の「三層の盾」を実装してデータ損失を完全に防止している。
3.1. 第一の盾:置換ターゲットの一意性チェック(Unique Match Assertion)
sunaba のファイル部分置換ツール(replace_file_content)は、AIが指定した TargetContent(置換前文字列)について以下の制約を強制する。
- ファイル全体をスキャンし、
TargetContentが 「ファイル内で唯一(1箇所のみ)」 マッチすることを確認する。 - 複数箇所でマッチした場合、または全く見つからない場合は、サイレント置換を実行せず、即座にエラー(
multiple occurrences foundまたはnot found)を返して処理を中断する。 - エージェントに対し「置換のスコープ(行範囲)を広げて、一意に特定できる形で再試行せよ」と突き返すことで、無関係な箇所のサイレント巻き込み破壊を防ぐ。
3.2. 第二の盾:編集取り消し機能(undo_file_edit)
AIがコード編集を行う際、sunaba はファイル変更前のスナップショット(バックアップ)をコンテナ内部に自動保存する。
- 万が一、AIの変更によって深刻な不具合や不要な上書きが発生した場合でも、ユーザーまたはエージェント自身が
undo_file_edit(編集取り消し) ツールを実行することで、ミリ秒単位で過去の健全な状態にファイルをロールバックできる。
3.3. 第三の盾:ASTレベルのシンボル置換(edit_symbol)
テキストの単純置換には、インデントや微細な構文の揺れによって置換に失敗する、あるいはロジックを壊す限界がある。
sunabaでは、Python等の抽象構文木(AST)をパースし、特定の「クラス定義」や「関数定義」のノードそのものをピンポイントで書き換えるedit_symbolツールを提供する。これにより、テキストレベルでの誤認を排除し、セマンティックな安全性を担保した編集を実行する。
4. 結論
AIエージェントのファイル編集を、単なる「テキスト検索・置換(replaceAll)」や「ファイルの無断上書き(write)」のまま放置することは、データ損失の爆弾を抱えることと同義である。 sunaba のように、
- 実行前に一意性をアサーションする(第一の盾)
- いつでもロールバックできるタイムマシン(Undo)を備える(第二の盾)
- ASTを用いてセマンティックに置換する(第三の盾) という多層のDLPガードを設計することが、自律型開発エージェントを本気で実務に投入し、コードの安全性を確保するための必須要件であるといえる。