删症状≠修根因:collect_cron_results 连续三天假阴性的教训
本文最后更新于 2026年7月24日 凌晨
每天凌晨三点,我的 AI Agent 系统有四个 cron 任务同时启动:日记、AutoQuant、回测调度员、策略深挖。另外还有一个叫 collect_cron_results.py 的脚本,负责汇总所有 cron 的执行状态,每天报告谁成功谁失败。连续三天,它把刚启动的任务全标成了 ❌ 失败。
第一天的”修复”是删掉这些报错的 session 记录,再删掉对应的 cron 任务。第二天,同样的问题又出现了。第三天,我终于改了脚本本身。这篇记录的是这三天的弯路,以及一个教训:删症状不等于修根因。
问题是什么
collect_cron_results.py 是日记系统的数据采集脚本,从 state.db 提取当天所有 source='cron' 的 session 记录,判断每个任务是成功还是失败。
判断逻辑很简单——查最后一条消息有没有 “error”、”失败”、”exception”、”❌” 这些关键词:
1 | |
看起来没毛病。但每天 03:00 有四个 cron 同时触发,collect_cron_results 在 03:00:23 跑起来时,其他三个 session 刚启动 23 秒。它们还没跑完,最后一条消息还是 cron 的 prompt 文本。而 prompt 里恰好包含”❌”字符。
结果:三个正在运行的任务全被标成 ❌。
第一天的”修复”:删掉报错记录
06-23 的日记记下了当时的处理方式:
08:00 cron 清理空 session + 删除对应的 cron 任务。
这是最直觉的反应——报告里有错误,那就把错误的东西删掉。但删完之后,collect_cron_results 第二天又报了同样的错。
因为问题不在 session 记录,也不在 cron 任务本身。它们是正常的,只是检测逻辑判断错了。
删症状的操作做了什么: 把”被误报的 session”和”对应的 cron 任务”都删了。相当于体温计显示发烧,就把体温计摔了。
第二天:同样的报错又来了
06-24 凌晨 03:00,四个 cron 照常同时启动。collect_cron_results 照常在 03:00:23 执行,照常把三个刚启动的 session 标成 ❌。
日记里记了一句很直白的话:
这个修复是错的——删了症状没修根因,今天同样 4 个 session 再次出现。
这时候问题链路已经清楚了:
1 | |
根因不在数据,在检测逻辑。has_error() 没有区分 “任务还在跑” 和 “任务真失败了”。

原来的逻辑把所有 session 都塞进 “成功” 或 “失败” 两个框。但运行中的任务既不该算成功也不该算失败,它需要第三个状态。修复后,ended_at IS NULL 的分支直接标为运行中,不再走到关键词检测那一步。
真正的修复:三行代码
改法很直接。在检查 error 关键词之前,先看 session 是否已经结束:
1 | |
ended_at IS NULL 意味着 session 还在运行。这时候不检查 error 关键词,直接标为 None(显示 ⏳ 运行中),和 True(❌ 失败)、False(✅ 成功)三种状态分开。
输出效果:
1 | |
不再有假阴性。运行中的任务就是运行中,不是失败。
还有一个坑:假阳性
同一个脚本还有相反方向的问题。AutoQuant 这类长 session(100+ 消息、80+ 工具调用),跑完之后最后一条消息里可能提到 “❌→✅ 修复过程”。关键词检测看到 “❌”,又标成失败了。
这次的修法是加一个强成功信号覆盖:
1 | |
cron_complete 是 Hermes 的正常退出标记。如果一个 session 正常退出、做了 5 次以上工具调用、产生了 10 条以上消息,那它大概率不是失败的——即使最后一条消息恰好含了个”❌”。
教训
这三天踩下来,有三条:
第一,删症状不等于修根因。 报告里有错误,第一反应是删数据。但数据本身没问题是检测逻辑有问题。删数据只能让今天的报告好看,明天同样的问题还会出现。
第二,状态机不能只有两个值。 原来的逻辑只有”成功”和”失败”。但现实中还有第三种状态——“还在跑”。把运行中的状态硬塞进二分类,必然误判。加一个 None 值,三行代码就解决了。
第三,关键词匹配是脆弱的。 用”❌”这种 emoji 做错误标记,在 cron prompt 里、在修复过程汇报里都会出现。纯关键词匹配分不清上下文。最终方案是关键词 + 结构化信号(end_reason + 工具调用数 + 消息数)的组合判断。
如果你也在做类似的 cron 监控或 session 状态检测,检查一下你的判断逻辑:有没有区分”运行中”和”失败”?有没有被 emoji 级别的关键词匹配坑过?
参考文献
- Hermes Agent 官方文档 — cron session 生命周期与
end_reason字段定义 - 非定时任务衰减律:’记得做’等于’不会做’ — 同一时期关于 cron 任务管理教训的另一篇文章