我那套 AI 自动化系统出过的 3 次事故,和每次之后改了什么
这是「一个人的 AI 营销部门」系列第 5 篇。前四篇讲了这套系统 长什么样、 一条流水线怎么跑、 看板规则怎么定、 发布权怎么交出去。
四篇都在讲它跑通的样子。这一篇讲它坏掉的样子。
因为如果你打算把一部分活真的交给 AI 去自动跑,你会遇到的麻烦不是"它写得不好", 而是"它看起来在跑,其实已经停了三天"。我三次都栽在这上面,而且三次都不是靠告警 发现的——是我自己偶然翻日志才看到。
下面是三次事故的原样记录。
事故一:一把锁,饿死了整条评论监听
我这套系统有两条定时线:
comment-watch.sh:每分钟跑一次,检查看板上有没有人写了新评论,有才唤起 AI 去处理daily-agent.sh:每半小时跑一次,扫描整个看板找活干
两条线最初共用一把锁 /tmp/daily-agent.lock。当时的理由听起来很正当:
它们都会去改同一个状态文件,加锁防止写坏。
后果是:看板扫描一旦跑起长任务,整段时间里的人工评论一条都得不到响应。
扫描跑 15 分钟,这 15 分钟里 comment-watch 被唤起 15 次,
15 次全部撞在锁上、打一行"上一次仍在进行中"然后退出。我在卡片上写的评论,
要等到扫描结束后的下一分钟才有人看。最糟的一次是扫描跑了 40 多分钟。
改法:把锁拆成两把——/tmp/comment-watch.lock 和 /tmp/daily-agent.lock。
每条线只和"上一轮的自己"互斥,两条线之间完全并行。
但拆锁的前提是职责不重叠,所以同时定了一条硬规矩:
- 评论收件箱(读未处理评论、推进已处理水位线)由
comment-watch独占, 看板扫描那条线一行都不许碰。两边都处理评论的后果是重复回复, 或者一边把另一边还没处理完的评论标记成已处理。 - 但两边确实都要写同一个状态文件。所以所有读改写强制走一个带
flock的封装 (agent_state.py的locked_state()),裸的读改写在并发下会丢更新。
最后这一条不是洁癖。丢掉的如果是"AI 自己写过哪些评论"这个 id 列表, 那么下一分钟系统就会把 AI 自己上一轮的分析当成人的新反馈,再回一遍—— 然后它又记下自己的回复、又丢、又回。每分钟自问自答一次,直到有人发现为止。
这一条通用:并发的两个东西共用一把锁,往往不是"更安全",而是把其中一个饿死。 真正该问的问题不是"要不要加锁",而是"这两件事为什么会碰同一份数据,能不能不碰"。
事故二:没有超时,一次卡死就永久占住了锁
拆完锁,问题换了个形状回来。
两条线都是这个结构:拿锁 → 唤起 claude -p 跑任务 → 放锁。
如果 claude -p 因为任何原因卡住不退出(网络挂起、等一个永远不来的响应),
那么这个进程会一直活着,锁一直被它持有。
之后的每一轮都会撞在锁上,打一行日志:
上一次仍在进行中,跳过
然后正常退出,退出码 0。
这就是它最阴险的地方:这行日志属于正常路径。它和"上一轮还没跑完,这轮跳过" 这种完全健康的情况长得一模一样。没有任何监控会对退出码 0 报警。 系统在我眼里一切正常,实际上已经死了。
改法:两条线的 claude -p 全部套上 timeout:
timeout --signal=TERM --kill-after=60 "$TIMEOUT" claude -p ...
CODE=$?
if [ $CODE -eq 124 ] || [ $CODE -eq 137 ]; then
# 超时,走企业微信告警
fi
评论线 30 分钟,扫描线 45 分钟,都能用环境变量覆盖。 超时按 124 退出(被 KILL 兜底的话是 137),这两个码单独判断,直接推一条企业微信告警给我。
这一条通用:任何"持有锁 → 调用外部服务 → 释放锁"的结构, 外部调用必须有超时。没有超时的话,一次卡死就是永久故障, 而且是那种日志干净、监控绿灯的永久故障。
顺便说一句:--kill-after 那个参数不是可选的。timeout 默认只发 TERM,
一个真卡死的进程可能连 TERM 都不处理。
事故三:一条 git clean,抹掉了整个监听脚本
2026 年 9 月 6 日,评论监听整整一天在刷 not found。
原因是定时跑的 AI 为了"清理工作区",执行了 git checkout / git clean 一类的命令。
而 comment-watch.sh 和 trello-inbox.py 的 --check 参数当时还没有提交进 git——
它们是我临时写出来验证思路的,一直处于未跟踪状态。
一条清理命令,两个文件一起没了。定时任务还在每分钟准点跑, 跑的内容变成了"找不到这个文件"。
改法两条:
- 定时 agent 绝对禁止执行
git checkout/restore/clean/stash/ 切分支。 这条直接写死在给 AI 的规则文件里,和"不许部署上线"放在同一级。 它没有任何理由需要这些命令——一个只往前写代码的角色, 不需要任何一个会让工作区倒退的动作。 - 脚本一律提交进 git,别留未跟踪状态。 这一条是给我自己的。 "临时写的,先跑跑看"是最容易出事的状态:它已经在生产里承担职责了, 但在版本管理眼里它还不存在。
这一条通用:给 AI 的权限清单里,危险的不只是"对外"的动作。 删文件、回滚工作区、切分支这些纯本地操作,破坏力一点不比"发布上线"小, 而且没有任何外部系统会拦住它。
三次事故的共同点
回头看,这三次不是三个独立的 bug,是同一个问题的三种长相:
自动化系统的失败是静默的。
- 事故一:日志在滚,锁在等,每一行都"正常"
- 事故二:退出码 0,日志写着"跳过",监控全绿
- 事故三:定时任务准点执行,只是执行的内容变成了报错
人工流程坏掉你会立刻知道,因为有人在等结果,等不到就会来问你。 自动化流程坏掉没人等,它就那么静静地停着,直到你某天偶然想起来去看一眼。
所以现在我给这套系统定的规矩里,有一条优先级很高: 每一条自动线都必须有一个"我还活着"的正向信号,而不只是出错时报警。 每天 9 点的日报就是这个信号——它按时到了,说明整条链路是通的; 它没到,比它报错更值得我警惕。
如果你也打算把一部分工作交给 AI 自动跑,我的建议是: 在你开心地看它跑通第一轮之后,立刻花半天想清楚它坏掉的时候你怎么知道。 这半天的回报率,比你再给它加三个功能都高。
想给自己的团队搭一套?
这套系统是我给自己 12 个产品用的。现在我把同一套东西搭进别人的公司:
- 一块属于你自己的看板:AI 在里面领任务、写稿、配图、发布、汇报,进度你随时能看
- 一套它不会闯祸的规则:谁能发、发之前过几道闸、出问题多久告警,全部写死在规则文件里
- 每周 30 分钟的你:审方向、点发布。剩下的活它自己干
- 按月交付内容和数据:不是「给你一个会写字的 AI」,是内容条数、搜索展现、转化数据一起交
上面这三次事故,以及从里面抠出来的锁、超时、权限边界,都是交付内容的一部分—— 你不用再自己踩一遍。
价格:启动包 ¥3,000 起(搭板 + 规则 + 跑通第一轮),月度方案 ¥5,000 起(持续产出 + 数据复盘)。 首批 3 个创始客户 8 折,我会按你的行业把规则调到能用为止。
下一步:微信聊 20 分钟,看看你那边哪些活能自动化掉。 聊完你至少能带走一张「你的内容流水线该长什么样」的一页纸,不合适也不亏。 (微信号我正在这几篇文末统一补上,这两天就位。急的话先在 不墨 AI 里给我留言也行。)
想先自己动手也完全可以。这套流水线调用的模型能力全部来自 不墨 AI——一个订阅同时用 GPT / Claude / Gemini / DeepSeek / Kimi, 写稿、起标题、做摘要这些活它都能接。