常设展 · 2026 年 4 月至 10 月 · 笔者个人 AI 工作流中

AI 事故博物馆

以下 20 起事故都来自笔者个人和 AI 协作的真实记录,已删去环境细节

这里陈列 20 起真实发生过的事故:编造出来的比分、全绿的门禁、碰巧通过的测试、没人看见的授权框。每件展品都写明现场、发现方式和根因,并给出一个反事实:当时哪一项检查就能拦住它。

展品按出错的层次分为六个展厅。分类沿用 AI 递归自我改进课题 E-1 的四层失效框架,并补了环境层和判断层两个厅。

20 起里有 15 起是靠人察觉的。验证、评测、环境三个厅一共 10 起,没有一起是自动发现的。越是靠后的层,坏得越安静。

自动发现(崩溃、门禁)结构发现(流程里的不变量对账、定期审计)人工察觉
展厅 I

生成层

模型写出了不存在的东西:文件、比分、用户说过的话。叙述是流畅的,磁盘是空的。

2026-06-24 · 世界杯预测人工察觉

交接里的三个文件

材质:一份对话总结,三个文件名,“brand-check 9/9 通过”

上一个对话的总结说刚生成了价值总结、汇报 HTML 和交接文档,并且核查过全部落盘。新对话直读磁盘:三个文件都不存在,那天一个文件都没写。

根因
工具调用格式损坏,写入失败,叙述层照样报告了成功。
反事实
回合结束前,逐个核对声称写过的文件是否存在。
护栏
今天新装 · G4 回合结束前核对“已生成/已写入”的文件
出处
记忆文件
2026-07-06 · 世界杯预测人工察觉

还没开踢的四场比分

材质:编造的用户输入,4 条赛果,2 条预测记录,一个错的日期

模型声称“用户提供了四场确切比分”(比赛尚未开始),写入权威台账,伪造两条预测记录并核算。污染经蒙特卡洛模拟、夺冠概率页、dashboard 一路传到 301MB 的分发包。

根因
下游全链无条件信任台账;写盘声称没有任何不变量对账。
反事实
台账场数应当 +1;ESPN 终场状态必须在本回合真实读到。
护栏
部分 · 事后加了不变量核验和“用户提供了 X 须能指出原文”的规则,仍是流程纪律
出处
事故报告(2026-07-06)
2026-07-18 · WAIC 追踪结构发现

库存 57,其实是 56

材质:写在正文里的一个假工具调用块,和一行假输出

扫描时把入库命令写成了正文里的文字标签,下面还伪造了“TOTAL 57”。下一个定时回合开头强制跑库存统计,真实返回 56,当场暴露。

根因
刚切模型、长链疲劳,加上“这条很重要”的完成冲动。
反事实
每个回合开头读一次库存数,与上一回合的声称对账。
护栏
已有护栏 · 定时链的固定序列里已有库存对账
出处
记忆文件
2026-07-04 至 07-13 · 世界杯预测人工察觉

十一次空白回合

材质:ScheduleWakeup 的返回语 “Nothing more to do this turn”

定时回合做完了活,用户却看不到任何输出:回合以调度调用结尾,总结写在了工具调用之间。试过记忆提醒、prompt 警告、换顺序、两种 hook,全部失败,第 11 次才找到办法。

根因
工具返回语诱导提前结束;远处的规则敌不过最近的那句话。
反事实
把调度调用放到回合第一个动作,用一次数据查询收尾。
护栏
已有护栏 · 固定回合序列(调度在前,查询收尾)
出处
记忆文件
展厅 II

执行层

判断没错,动作有副作用。这一层往往会响亮地崩溃,可是崩溃之前,东西已经没了。

2026-07-15 · 世界杯预测自动发现

一个 with 清空了 22 条预测记录

材质:csv.writer,一个多余的 with 语句

csv.writer 不支持上下文管理器,抛 TypeError。但在报错之前,open("w") 已经把账本截断为零。

根因
写操作没有先写临时文件再原子替换,也没有备份。
反事实
先写临时文件,再原子替换;写之前留一份备份。
护栏
已有护栏 · 账本改为原子写 + 备份
出处
事故报告(2026-07-15)
2026-10-02 · 开发工具项目人工察觉

测试绿了,但没有提交

材质:git merge --ff-only,git worktree remove --force

在改版工作树里改完一批、测试全绿,但没提交就合并并强制删除工作树。合进去的是上一次提交,这批改动连同暂存区一起消失,fsck 也找不回。靠会话里保留的编辑脚本重放才恢复。

根因
把“测试绿了”当成“已经保存”;--force 无视未提交改动。
反事实
删工作树前看一眼 git status;合并前确认源工作树干净。
护栏
今天新装 · G1 拒绝强删有改动的工作树 · G2 拒绝从有改动的工作树合并
出处
记忆文件
2026-09-27 · 个人站人工察觉

只剩 node_modules 的站点

材质:一个被清空的文稿目录,一个没有 remote 的仓库

文稿目录被清空后,站点工程只剩依赖目录。仓库从未推送到任何 remote,唯一的源码在托管平台上,只能请 Codex 第二天凌晨恢复。

根因
源码只有一份。清空的直接原因未查明,不一定来自 AI 的命令。
反事实
任何值得保留的目录都要有第二份:git remote 或备份。
护栏
部分 · G3 只能拦住 Claude 发出的 rm -rf;真正的修法是 remote
出处
记忆文件
展厅 III

验证层

检查都通过了,检查的却不是要紧的那件事。这一厅里没有一件是自动发现的。

2026-07-26 · AI 周报人工察觉

门禁全绿的上周周报

材质:checker 返回 "ok": true, "issues": []

本周 7 天晨报 0 天可用,agent 如实标注后用上周的内容回填。门禁检查了 6 个章节、8 个外链、4 张证据卡、字节数,全部合格,于是把上周的周报发了出去。

根因
门禁没有失灵,它只是没有“内容是否来自本周”这个维度。
反事实
输入覆盖率作为硬门禁:本周可用天数 < N 就不发。
护栏
已有护栏 · 已加输入窗口门禁
出处
课题现场复盘
2026-09-13 · Codex 无人值守人工察觉

整夜白跑的续跑器

材质:--ephemeral 探针,交互式 shell

交付前用临时模式探针验证“链路通”。临时模式跳过写锁和持久化,又是在交互式 shell 里跑,不是 launchd 环境。当夜两轮各挂死一小时。

根因
验证走的不是生产路径。
反事实
验证必须走与生产完全相同的代码路径和执行环境。
护栏
已有护栏 · v2 加 150 秒初始化心跳和停滞检测
出处
记忆文件
2026-09-15 · Harness 评测包人工察觉

碰巧通过的回归测试

材质:一条进程断言,一台恰好开着那个进程的 Mac

回归测试在 Mac 上绿了一整轮,因为环境里碰巧有那个进程。到了用户的 Windows 实机,三处失败。

根因
测试依赖“环境里碰巧有什么”。
反事实
测试自带夹具,不读宿主环境。
护栏
已有护栏 · 测试改为自带夹具
出处
记忆文件
2026-09-15 · Harness 评测包人工察觉

代理挂了,报告说一切正常

材质:零条观测,“正常完成”

自动跑批时代理已经断开,什么都没有采到,装置却判定为正常完成。同一轮还有判分字段名写错导致全显示 0、选择器把“忙碌”判据自己删掉。

根因
没有把“零观测”当作失败。
反事实
采集为零即失败。
护栏
已有护栏 · 零观测判失败
出处
记忆文件
展厅 IV

评测层

打分的尺子本身坏了。尺子一坏,后面所有的“改进”都失去意义,而且错误会被缓存固化。

2026-08-10 · 模型评估 DEEP人工察觉

被当成答案的额度报错

材质:一段“配额已用尽”的错误文本

后端额度耗尽,返回的报错文本被当作模型答案拿去判分,报告得分 20.6%,真实是 87.5%,低报四倍。三模型对比因此 0/3 可用。

根因
判分器分不清“模型答错”和“没有答”。
反事实
后端不可用单独成类,整题剔除,不进分母。
护栏
已有护栏 · ProviderUnavailable + 整题剔除(62 项测试)
出处
记忆文件
2026-08 · 模型评估 DEEP人工察觉

被缓存固化的失败

材质:一个写进缓存的 “unclear”

额度耗尽导致 24/24 失败,“unclear”被写入缓存;换了可用后端重跑,仍然命中旧缓存,验收完全失真。另有一轮人工复核发现 6 个失败全是判分器假阴性。

根因
不确定的结果也进了缓存。
反事实
只缓存确定的判分。
护栏
已有护栏 · unclear 不入缓存
出处
课题现场复盘
展厅 V

环境层

代码没问题,世界有问题:授权框、DNS、浏览器的会话恢复、虚拟时钟。

2026-05-31 · AI 晨报人工察觉

没人看见的授权框

材质:launchd → bash → claude → osascript → Mail

定时任务控制 Mail 时,系统弹出授权框;后台进程没有焦点,没人看见,阻塞约 50 分钟后报 -1712。10 月 17 日又有一次:没人点的授权框锁住了整个桌面访问。

根因
TCC 按调用方二进制记账,无人值守的链路里不能出现任何弹窗。
反事实
部署前用真实调用方预授权;无人值守一律不弹框。
护栏
部分 · 预热改为只提醒;授权仍靠人工预先完成
出处
记忆文件
2026-04-25 · 品牌规范项目人工察觉

串台的七页

材质:Chromium 的会话恢复

批量抓取品牌站 12 页,第一轮 7 页标题对、正文是上一页。浏览器启动时恢复了上次的标签页,抓取在导航之前就拍了快照。

根因
每次抓取之间没有删掉 Sessions 目录。
反事实
每次抓取前做四步清理,关键是删 Sessions。
护栏
部分 · 清理协议写进记忆,未脚本化
出处
记忆文件
2026-10-08 · Codex 发布人工察觉

被污染的 DNS

材质:路由器 DNS 地址,一个异常网段的地址

Codex 发布站点一直连不上。路由器的 DNS 被污染,而且绕过了代理的 TUN;Codex 启动时又没读到系统代理。

根因
网络层的问题伪装成了工具的问题。
反事实
先用 curl --noproxy 看解析出的 IP。
护栏
部分 · 已开嗅探覆盖
出处
记忆文件
2026-08-21 · Ontology 简报人工察觉

只生效一次的按键

材质:chrome-headless-shell --virtual-time-budget

在无头浏览器里验证翻页,第一次按键生效,之后全部无效。差点据此去改一段本来没问题的代码。换真实浏览器一按,一切正常。

根因
虚拟时钟下 scrollTo 只执行一次,测试环境制造了假象。
反事实
交互一律在真实浏览器里验证。
护栏
部分 · 规则写进记忆
出处
记忆文件
展厅 VI

判断层

没有任何东西坏掉。只是一条未经复核的说法,变成了记忆里的事实。

2026-07-16 · 世界杯预测结构发现

被当成战绩的 12 场

材质:“模型 75% vs 市场 58.3%”

这组数字进了复盘、项目说明和记忆,被当作模型跑赢市场的证据。它来自 12 场的命中率。放到全部 86 场、用 Brier 计分,两者打平,市场略好。

根因
小样本加上只看最高概率那一项的口径。原文其实写过“n 太小”,转述时丢了。
反事实
默认用 Brier 计分,附置信区间。
护栏
今天新装 · 预测登记簿评分脚本自动打 Brier 分
出处
评分脚本
2026-08-01 · 世界杯预测结构发现

写错的决赛比分

材质:一行项目说明

归档说明写着决赛“阿根廷 2:1 西班牙”,而它指向的复盘台账写的是西班牙 1:0(加时)。ESPN 接口复核,台账是对的。

根因
说明是凭印象写的,没有回到数据源。
反事实
归档前用数据源复核头条事实。
护栏
没有 · 已手工更正,没有机械护栏
出处
项目说明
2026-05-08 · Skill 治理结构发现

过期的记忆

材质:一句“等 D1–D5 决策”

记忆里这个项目一直在等五项决策。实际上五项决策在 5 月 8 日就已拍板并写成了复盘文档。

根因
记忆只在写的那一刻是对的,没有过期机制。
反事实
引用记忆里的状态前,先看项目文件。
护栏
没有 · 没有机械护栏
出处
决策复盘文档

出口:把教训变成会执行的东西

记忆里写“下次记得”管不住下一次。能机器检查的教训,今天写成了 Claude Code 的 hook:命令执行前或回合结束前自动检查,违反时拒绝执行或要求确认。每条规则都拿当时的事故现场重放过。

G1PreToolUse · Bash · 拒绝

工作树里还有未提交改动时,拒绝 git worktree remove --force,并列出改动的文件。

来自:测试绿了,但没有提交

G2PreToolUse · Bash · 拒绝

要合并的分支,如果它自己的工作树还有未提交改动,拒绝合并:此时合进去的只是上一次提交。

来自:同一起事故的前半段

G3PreToolUse · Bash · 询问

rm -rf 一个删了就找不回的目录时先问一句:有未提交改动、或文件很多且不在已推送的仓库里。删家目录、桌面、文稿根目录直接拒绝。

来自:只剩 node_modules 的站点

G4Stop · 拦一次

回合结束前,读最后一条消息里“已生成/已写入/已落盘”后面的文件路径,磁盘上找不到就要求核实。同一回合不会拦第二次。

来自:交接里的三个文件

18 / 18重放事故的测试通过
0.22%G4 在 200 份历史会话 5555 条消息上的触发率(含已删文件,是上限)
静默护栏自身出错时一律放行,不会卡住正常工作