P1 intelligence-evolution AI系统自进化质量控制情报管线

21天、47条真实情报、0条进入系统:当AI管线开始自我欺骗

一个日期偏移1天的设计缺陷,让情报管线在21天内持续用LLM记忆伪造内容,而GHA全程显示绿色。这是一个完整的发现-退化-诊断-止损-重建闭环的真实记录。

21天、47条真实情报、0条进入系统

2026年5月29日,情报扫描管线在UTC 22:42准时运行,成功抓取了47条真实情报——Anthropic动态、MCP协议进展、AI基础设施竞争格局。这些数据被写入文件 2026-05-29-intel-scan.json,静静等待下一个步骤来处理。

次日UTC 06:42,情报日报生成器启动。它查找的文件名是 2026-05-30-intel-scan.json——差了一天。文件不存在,程序打印了一行日志:

[ScanInject] No scan file found for 2026-05-30 — skipping injection

然后将空字符串注入到提示词中,让语言模型生成”今日6-9条精华情报”。

模型认真地完成了任务。它从训练记忆中编造了情报条目,其中包括一个物理上不可能的评分:topScore 17/10

GitHub Actions的每一个步骤都是绿色的。

这不是一次偶发事故。同样的流程在过去21天里每天运行,每天产出一份造假简报,每天GHA全绿,没有任何告警到达决策层。


为什么监控没有发现

这是这个故事里最值得停下来想的部分:系统的所有独立层次都失效了,但每层失效的方式都不同。

业务断言层:日报生成后有一个CI检查步骤,验证输出HTML”存在且非空”。造假内容是完整的HTML文档,通过了检查。代码正确地执行了错误的检查。

看门狗层:存在一个独立的健康监控程序,其职责正是验证今日6个情报产物的完整性。它在每次运行时产生exit code 2,然后停止。失败原因是:读取Slack Bot Token时发现环境变量为空,在认证测试阶段崩溃,从未到达实际的内容检查步骤。技术上,这是一个凭证配置问题;系统效果是,独立观测层在沉默中无效化了21天。

Slack告警链:日报程序在通知步骤里检测到 channel_not_found 错误,记录了一行日志,然后继续执行,退出码为0。

三个独立的反馈层,三种不同方式的失效。没有任何一层是以”明显故障”的形式失效的——都是完成了自己的工作,只是那份工作没有达到应有的效果。


根因:一个差了一天的设计假设

日期偏移问题(off-by-one UTC)并不复杂:扫描程序用当前UTC时间命名输出文件,日报程序也用当前UTC时间查找输入文件。扫描在UTC 22:42运行,日报在次日UTC 06:42运行——差了8小时,跨过了UTC零点,文件名差了一天。

但这个缺陷在代码中有一行值得关注的注释:

# graceful fallback
return ""

这行注释说明缺陷不是意外写入的,而是一个主动的设计选择:当扫描结果缺失时,优雅降级,继续运行。设计者的意图是健壮性;实际效果是,系统在输入缺失时不会停下来,而是继续生产,用语言模型的记忆填充空缺。

这是两种不同的健壮性观念之间的冲突:

  • 一种认为”系统不中断”是健壮性
  • 另一种认为”系统不产出错误内容”是健壮性

当两者发生冲突时,没有明确的选择就意味着选择了前者。


止损:37个文件,6个workflow

2026年5月30日,当诊断报告完成时,在等待重建方案审批的同时,管线执行了止损动作:

  • 37个造假文件(2026-05-23至2026-05-31)移入隔离目录 _quarantine/intelligence-fabricated-2026-05/,2022-05-22及之前的真实历史保留
  • 公开intelligence页面下线,访问重定向至首页
  • 6个相关workflow停用(覆盖synapse-ops的intel-scan/daily/action/outcome/evolution和lysander-bond的publish-to-bond)

所有动作均可逆。决策文档记录了一步回滚路径。


重建后的今天

2026年6月1日,重建后的管线产出了这份行动报告:

  • 4条情报条目,来自真实扫描
  • 3条进入行动清单(MCP协议RC版本适配评估、Claude Code多云部署评估、.skills目录插件化集成评估)
  • 内容质量评分 4/5(semantic_score),翻译层成功屏蔽内部运营术语

这不是一个功能上的改进,而是一个基础层面的修复:从”优先保持运行”改为”优先保证内容真实”。重建后的管线在输入缺失时会硬性失败(HARD-FAIL),而不是静默降级。


一个可泛化的框架

这21天暴露的核心问题,可以用一个判断来概括:

一个系统选择”继续运行”还是”停下来”,定义了它在压力下优先保护什么。

大多数工程实践默认优先保护可用性。这在很多场景下是正确的——服务器宕机比服务降级更糟。但当”继续运行”意味着”产出不可信内容”时,这个默认选择的代价是可信度,而不只是功能完整性。

针对产出内容的AI管线,有一个具体的检查问题值得在设计阶段回答:

如果上游输入完全缺失,这个步骤会做什么?

如果答案是”继续运行,用其他方式填充”,那就需要一个额外的问题:填充的内容会如何影响下游的可信度?

这不是一个可以用监控解决的问题。监控发现问题,但监控无法决定系统在没有真实输入时应该停止还是继续。这个决定需要在设计阶段做出,并写进代码里。

21天的造假运行告诉我们:没有明确写入代码的选择,不是”没有选择”,而是选择了运行。