一次 AI Agent 归档操作引发的"删库"事故
日期:2026-07-04
影响:50 个后端核心文件被删除,共 2916 行代码
根因:568acd1— Comet archive 阶段 AI agent 误删生产代码
修复:fd146ac— 从历史 commit 精确恢复所有文件
发生了什么
事情发生在一个看似平常的周五下午。
我用 Comet 工作流完成了博客分类系统的全部开发,从 open 到 design,从 build 到 verify,一路绿灯。最后一步 comet-archive,屏幕上也亮起了令人安心的 "7/7 步骤成功"。
然后我启动了后端。
Could not import module "app.main"
我盯着终端愣了 3 秒。app/main.py —— 整个后端的入口文件,不存在了。
很快我发现,不只是入口文件。50 个核心文件全部蒸发,像是有人在后端目录里执行了一次精准的外科手术:
| 被波及的模块 | 文件 |
|---|---|
| 应用入口 | app/main.py |
| 核心配置 | app/core/config.py、app/core/security.py |
| 依赖注入 | app/api/deps.py |
| 路由层 | app/api/routes/login.py、users.py、items.py、api_keys.py、private.py、utils.py |
| 工具库 | app/slugify.py、app/utils.py |
| 数据库迁移 | 3 个历史 alembic 迁移 + env.py |
| 测试代码 | 全部 10+ 个测试文件 |
| 其他 | 邮件模板、初始化脚本等 |
一个刚被标记为"成功"的 commit,把项目砍成了空壳。
追踪根因
事故发生在哪一步?
Comet 工作流的五个阶段:
comet-open → comet-design → comet-build → comet-verify → comet-archive
↑
💣 事故在此触发
前四个阶段都正常完成。问题出在最后一步 comet-archive(归档阶段)。
归档本应该做的事情很简单:
- 把 delta spec 合并到主 spec(加了 17 行,3 个 capability)
- 把设计文档和计划文档移到
docs/superpowers/目录 - 把 change 目录移到
openspec/changes/archive/归档
但 AI agent 在执行归档清理时,把 backend/app/ 下的 50 个生产文件也一并删除了。它很可能把"需要清理的临时文件"和"项目源代码"搞混了。
为什么没能及时发现?
三个环节都错过了拦截机会:
- Archive 阶段没有验证。它是 Comet 流程的最后一个阶段,流程本身设计了归档,但没有设计"归档完跑一下应用试试"这个步骤。
- 提交时没有审核 diff。AI agent 提交前,我没有看一眼
git diff --stat。如果你用 AI 干活,这个习惯必须养成。 - 合并后没有 smoke test。
dev → main合并后直接 force push 了,没有跑uv run uvicorn app.main:app验证一下。
和合并方式有关吗?
无关。这是一个常见的疑问,这里澄清一下:
文件是在 568acd1 这个 commit 中被删的。后续的 git merge dev,只是把这个 commit 带到 main 分支,不改变任何文件内容。不管你用 fast-forward(指针移动)还是 --no-ff(创建合并提交),结果都一样——文件该没还是没。两种方式的区别只在历史图形是否分叉,对文件增删无任何影响。
怎么恢复的
得益于 Git 的不可变性,被删的文件并没有真正消失,只是当前版本不再引用它们。
恢复思路很直接:找到删除前的最后一个正常 commit(c363a14),精确列出被删文件,然后一一恢复。
# 列出 568acd1 删除了哪些文件
git diff --diff-filter=D --name-only c363a14..568acd1 -- backend/app/
# 从 c363a14 逐个恢复这些文件
git diff --diff-filter=D --name-only c363a14..568acd1 -- backend/app/ |
ForEach-Object { git checkout c363a14 -- $_ }
顺便修了一个配套问题:pyproject.toml 里缺少 hatchling 的构建目标配置,导致重启时包识别失败:
[tool.hatch.build.targets.wheel]
packages = ["app"]
最终用 fd146ac 完成了恢复,后端恢复正常。
教训
这次事故没有造成不可逆的损失,但它暴露了几个在使用 AI 辅助开发时需要特别注意的点:
-
不要让 AI agent 替你"信任"变更。Agent 报告 "7/7 成功" 不等于真的没问题。批量提交前,花 5 秒看
git diff --stat能避免 50 分钟的事故恢复。 -
关键操作后立即验证。Archive 完就跑一下应用,不要等几个步骤之后才发现。把
smoke test当作每个流程阶段的结束仪式。 -
Git 是你的安全网。这次能在 10 分钟内恢复,完全依赖 Git 的 commit 历史。
git checkout <commit> -- <paths>是一个值得记住的命令。 -
流程设计也要考虑失败场景。Comet 流程的 archive 阶段缺少内置的验证步骤,这是一个可以被改进的点。
总结
这次事故本质上是 一个信任问题:人类对 AI agent 输出的"成功"标记产生了过度信任,跳过了本不该跳过的检查步骤。
AI agent 很强,但它不会对自己的错误感到不安。那个 "7/7 步骤成功" 不会告诉你它刚刚删掉了半个项目。
看一眼 diff,跑一下应用,这两件事永远值得做。