この記事は、NFLaboratories Advent Calendar 2025 1日目の記事です。
はじめに
みなさんこんにちは、研究開発部 研究開発担当のonaotoです。 突然ですが皆さんDevinは使っていますか?
Devin*1はAI開発エンジニアの一つです。私たちは開発フローに組み込んで、チャット経由で作業を依頼しています。
軽微なバグの修正やちょっとした機能追加などはあっという間にやってくれるのでとても重宝しています。
しかし、そんなとても便利なDevinですが私の曖昧な指示のせいで事故が起きてしまったので今日はその話を書こうと思います。
怒涛のRevert
まずはこちらの画像をご覧ください。

これは退勤前に修正依頼を出したPRを朝確認した時の画面です。Commit数が1万件もあります。コミットログにはRevert "Revert "Revert "Revert"という文字が延々と並んでいます。なかなかの迫力です。
なぜこのようなことが起きたのでしょうか?
怒涛のRevertを引き起こした指示
怒涛のRevertを引き起こしたのは何てことない指示でした。
abc1234 この段階までブランチを戻して
このときDevinから見るとリモートブランチは進んでいる状態で普通にpushすると弾かれる状態だったようです。 そこでDevinは私に尋ねました。
指示いただいたコミットabc1234までローカルは戻しましたが、リモートが進んでいるため通常の push が拒否されました(non-fast-forward)。このPRブランチをそのコミットに戻すには --force-with-lease での push が必要です。実行してよろしいでしょうか?
ここで私はこう答えました。
一つ一つ打ち消しコミットを作って戻していってください。
これが"悲劇の種"でした。 Devinはこの指示を受け入れて忠実に作業を開始してくれました。 そう、怒涛のRevert祭の開幕です。
Devin、気が付く
コミットが1万件を超えたとき、流石にDevinも自分の作業が何かおかしいということに気がついたようです。 以下のような確認が入りました。
「git revert で abc1234 まで戻し、git rev-list abc1234..HEAD --count を 0 にする」という要件について確認です。 git revert は新しいコミットを積むため、`git rev-list abc1234..HEAD --count` は 0 になりません。 達成基準は以下のどちらでしょうか? A) ブランチのツリー内容を abc1234 と完全一致にする(`git diff abc1234..HEAD` が空)+ローカル/CIグリーン。コミット数は増加します。 B) abc1234 をブランチヘッドにする(`reset/push --force` 相当)ことで git rev-list ... --count を 0 にする。 現状は A の方針で進めており、count は増加しています。このまま A で完了でよろしいでしょうか? それとも B を許可(force push 可)いただけますか? 指示確定まで、自動バッチは停止しています。
こうして怒涛のRevert祭はDevinの自我により終焉を迎えました。
もたらされた影響
pushのたびにCIが実行されたために余計なCIコストが発生していました。また、Devin側の実行リソース(ACU)も無駄に消費されました。
幸いどちらも大きな額にはなっていませんでしたが、もし気が付くのが遅れていたらと思うとヒヤッとします。
学び
今後同様の事故を起こさないようにするために以下のような対策が必要かなと思います
- 作業内容ではなくどうなったら完了かの達成条件を指示する
- 例)最終状態が
git diff <target>..HEADで空ならOKとする
- 例)最終状態が
- 異常な数のコミットが発生しないようにあらかじめセーフガードの指示をしておく
- 例)単独の指示でコミット数が10件を超えたら停止して確認する
人間だと10回もRevertが続けばおかしいことに気がつきそうですが、AIはまだそこまで空気を読むことはできないということを実感しました。
おわりに
Devinそのものはとても便利で、毎日助けてもらっています。 ただ、使う側も十分なリテラシーを備えないと思わぬ事故が発生する、そんな当たり前なことに改めて気がつきました。
みなさんもAI開発ツールを使う際は達成条件の明確な指示を意識してみてください。 未来の自分の睡眠とCIコストを守ることができます。