本文是「AI 效能」系列的第七篇。前面几篇分别讨论了流程边界、工作区初始化、自动链编排与代理记忆;这一篇讨论自动链出错之后,怎么自己发现、归因和修复。

自动化系统有一个很容易被完成率掩盖的问题:任务都能跑完,人却越来越忙。

一条能自动生成需求、修改代码、执行测试的流水线,最终可以把每个任务推到完成状态。但把人工排障记录摊开,大部分时间并不在写代码,而在回答两个问题:这次失败算谁的?外部状态怎么对回来?剩下才是修系统本身的缺陷。

这意味着,继续增强生成能力,边际收益有限。真正缺的是一个能发现、归因、修复并验证系统自身缺陷的角色。我们把它叫作 AI 看门狗(AI Watchdog)。下文把这条自动生成需求、修改代码、执行测试的闭环称为 AI Loop。

需要先说明边界:本文讨论的不是监控大盘,而是一套面向 AI 自动化系统的自愈设计。它仍然需要人工兜底,尤其在高风险变更上。它适合已经稳定跑通自动化闭环、但人工诊断成本高的团队;不适合任务量太小、没有可观测性、没有测试与回滚能力的团队。

一句话设计

先把失败聚合成可归因的 incident,再用确定性守卫拦住已知错误;
只让模型回答“算谁的”和“怎么改”;
修复经过白名单、校验、观察窗与回滚,才算完成。

一、瓶颈不在生成,而在判断

自动化系统最容易衡量的指标是完成率:任务有没有完成、产物有没有生成、流水线有没有跑完。但这些指标只能证明系统能跑,不能证明系统跑得省心。

人工动作通常集中在三件事:

人工动作 典型问题 能否规则化
判断归属 这次失败是上游输入、编排逻辑、执行环境还是外部依赖 大部分可以
对齐状态 外部资源、分支、变更清单、状态看板是否一致 可以
修复系统 提示词、契约、代码、配置需要改哪里 一部分可以

第 1、2 件事有明确的规则,适合交给确定性代码;第 3 件事高频但风险分层明显,适合让模型提出最小改动,再由安全协议兜底。

生成能力决定系统能不能跑,诊断能力决定系统跑得贵不贵。

二、先降噪,再谈智能

自动化系统的问题不是没有信号,而是信号被噪音淹没。

最常见的噪音有两类:一类是重试风暴,例如同一批通知收件人解析失败后反复重试;另一类是状态冲突,例如上游状态重复上报,每次都返回冲突。它们数量大、原因单一、长期存在,却因为“非阻塞”既没人修,也没人被提醒。

如果告警系统把每次失败都原样吐出来,人只会学会忽略它。

降噪不是隐藏事件,而是把同一根因的 N 次失败折叠成一条有次数的 incident。告警的价值不取决于覆盖多少事件,而取决于人是否还愿意看。

三、复盘:最贵的不是改错代码

把人工排障记录按根因聚类,问题通常集中在几个方向:

聚类 典型表现 主要责任方
资源与分支生命周期 外部资源被清空、分支漂移、重建失败 编排代码
交接契约 Agent 之间传递的结构化产物不稳定、判定端只认一种写法 提示词与配置、编排代码
错误信息 只告诉人“被阻断”,不说具体缺什么 编排代码
上游输入 目标错配、验收口径矛盾 上游
环境与外部依赖 共享环境被污染、依赖源缺失 环境或外部
合并与发布 依赖降级、整文件回退、提交范围失控 编排代码与配置

其中最贵的不是单点错误,而是连锁反应。

一个典型故障链是:外部资源(例如发布计划、环境、任务看板)被清空 → 恢复时重建出新的分支 → 工作副本仍停在旧分支 → 仓库准备失败 → 再次阻断。每一步其实都有补丁,但没有任何一处对“资源集合突然变小”做断言。补丁在止血,系统没有记忆。

另一类高频问题是格式问题判死业务。同一个交接字段,生成端写成字符串,判定端只认对象;或者结论被换行后解析不到。生成端没有自检,判定端只认一种写法,于是同一个契约问题会在多个任务上反复复发。

第三类是错误信息不可执行。只告诉人“质量判定为阻断”,却不给具体缺失项、文件或规则,人只能先复现再猜。不可执行的归因,等于没有归因。

这些现象指向同一个结论:先修证据,再修代码。历史事故里最贵的部分,往往不是 AI 改错了代码,而是证据没有对齐。

所以成熟的自愈系统,第一层一定是确定性守卫,而不是让模型直接改代码。

四、Incident 不是一次失败

传统监控按事件记录:某时某刻某个任务失败了。自愈系统按根因记录:

incident 是一个可归因的根因,不是一次失败,也不是一个任务。

同一根因跨任务只保留一条,用 signature 去重:

signature = hash(resultCode | node | action | normalizedReason | component)

归一化时要去掉时间戳、提交哈希、分支名、绝对路径和任务 ID,只保留阶段、动作、错误码、归一化后的原因和组件。

设计 原因
包含阶段与动作 同一个错误码在开发和测试阶段是两件事
包含组件 同一个错误在不同模块是两处契约
不包含任务 ID 否则同一个 bug 每个任务一条,失去聚合意义

效果是,同一类交接产物错误跨多个任务复发,只留一条 incident,计数递增;上游状态冲突重复出现,也只留一条;外部资源集合被清空,同样只留一条。

一条 incident 记录的不是“某个任务又挂了”,而是“某类契约在某个阶段反复写错,已经跨多个任务发生”。

状态机如下:

stateDiagram-v2
  state "无需修复" as skipped
  [*] --> new
  new --> triaged: 归因完成
  triaged --> fixing: 开始修复
  triaged --> skipped: 非系统问题
  fixing --> verifying: 校验通过
  verifying --> observing: 重载与健康检查通过
  observing --> closed: 观察窗零复发
  observing --> fused: 同签名复发
  fixing --> fused: 连续修复失败
  closed --> new: 复发后重新打开
  fused --> [*]: 仅人工解除

台账只增不删。关闭后的记录归档保留,熔断和放弃的记录长期保留,因为它们的复盘价值最高。

台账不是日志,是待办。

五、架构:确定性骨架,两处过模型

维度 传统看门狗 AI 看门狗
职责 监控与告警,出了问题叫人 监控 → 归因 → 修复 → 验证 → 发布 → 回滚
动作 记录指标、发通知,最多重启进程 改代码或配置,跑测试与构建,重载进程
判断 阈值规则 确定性守卫 + 结构化模型归因
交付物 告警 incident 台账,含证据、修复分支、提交与回滚点
失败处理 继续告警 观察窗内复发自动回滚与熔断,转人工

AI 看门狗是独立进程,对主系统只有两条影响通道:改代码仓库,以及重载进程。它不共享主系统的内存,不直接写业务表,只维护自己的 incident 台账。

它还要求单实例:启动时抢锁,抢不到就只读运行,避免两个看门狗同时修同一套代码。

模块 类型 职责
采集 确定性 任务状态、事件数据、日志、健康检查
签名 确定性 归一化、去重、聚合
归因 模型 判断归属、组件、置信度与证据
守卫 确定性 四类断言
修复 模型 在独立工作区写最小改动,读回修复报告
发布 确定性 校验、等待空闲、合并、构建、重载、观察、回滚
策略 确定性 白名单、预算、并发、熔断、风险分级
接口 确定性 健康、台账、手动触发

数据流:

flowchart LR
  C[采集] --> S[签名] --> T[归因] --> G[守卫]
  G --> R[修复] --> V[校验] --> D[发布] --> O[观察] --> X[关闭]
  G --> H[人工提案]

只有两处过模型:

  1. 归因:输入是固定证据包,输出是归属、组件、置信度与证据,不自由生成;置信度低于阈值只提案,不自动修。
  2. 修复:写出最小改动,受白名单、必须补测试、产物格式三重约束。

模型失败时,归因降级为未知,只落台账、只提案。模型不能绕过守卫:守卫产生的阻断不经过模型判断。

路由也不交给模型。节点推进与返工去向仍由确定性状态机负责,模型只回答“算谁的”和“怎么改”。

修复模块复用现有执行服务的工作区、会话、中断与产物读取能力,不自建第二个运行时。

六、四类守卫

守卫全部是确定性代码。前三类落在动作现场,第四类落在跨任务视图。

三方对账

分支是事实,变更清单是声明,发布目标是落地位置。三者对不上,就在动作前拦下。

条件 结论
分支有改动、清单缺文件 清单过期,列出缺失文件
清单有文件、分支无改动 清单有幽灵条目
工作副本分支不等于发布目标分支 分支漂移,附两个分支名
三者一致 通过

不可逆动作快照

动作前后各拍一张照:外部资源集合、状态看板、配置集合、变更目录、流水线数量。

条件 结论
资源集合变小且不是人工确认的结束状态 高危,立即告警
工作流阶段已回退,外部状态超过窗口未同步 状态过期
展开的配置数大于变更目录数 过度展开
交付输入为空但任务声明了配置 输入丢失

合并产物体检

检查 规则
依赖版本只升不降 目标分支原依赖版本降低即拒绝
目标文件不许整段回退 删除行数超过阈值且不在声明范围内即拒绝
提交范围 合并提交涉及文件必须落在声明集合内
工作区状态 HEAD 在目标分支、无未合并文件、无 Git 写操作残留

重复失败熔断

  • 同一 signature 在 24 小时内出现 2 次即升级;
  • 同一任务同一错误码连续 2 次即暂停并通知;
  • 观察窗内同签名再次出现,直接熔断并回滚。

很多事故不是第一次没发现,而是连续挂了几次才被人看见。等失败计数达到上限已经太晚。

分工,而不是重复

守卫 落点 理由
对账 动作前 现场才有上下文,能当场给可读结论
快照 动作前后 事后巡检只能发现“已经晚了”
产物体检 推送前 必须在发布前拦
熔断 跨任务视图 单个业务侧没有全局视图

看门狗对前三类只做复核,不重写判据。两套逻辑各自演化,迟早会漂移。

七、自动修复的安全协议

让一个 AI 去改正在运行它的系统,安全不是附加项,而是产品本身。

隔离。 修复在独立的 Git 工作树里做,一个 incident 一个分支,同时只允许一个修复在飞,绝不在部署目录里直接改。

白名单。 只允许改业务源码、测试、提示词、技能配置和文档;禁止碰对外契约、状态解析、环境变量、依赖锁文件、数据库结构、凭据、镜像和看门狗自身代码。白名单在代码里硬编码,不由模型或配置决定。

校验。 按受影响模块执行类型检查、单测和构建,任一失败即丢弃分支。行为变更必须同时新增或修改测试,不允许只改测试不改逻辑。

发布。 部署目录必须干净;修复分支快进合并到主干;重新构建;等待主系统空闲;按依赖顺序重载进程;健康检查通过后记录重载前后的版本。

等待空闲的意义:重载会让正在跑的任务在节点边界重跑一轮,白烧一次模型调用;空闲窗口重载成本为零。

观察窗。 重载成功后进入一段观察期。同签名再次出现,或同组件出现新的高优先级 incident,自动回滚并熔断;其他新 incident 只记录。零复发才算关闭。

回滚。 回到重载前的版本,重新构建,按顺序重载,健康检查。回滚必须能在分钟级完成,不含构建时间。

熔断。 同一 incident 连续修复失败、发生一次回滚、当日自动修复次数达到上限、健康检查连续失败、部署目录不干净或无法快进,都会停止自动修复并转人工。熔断状态持久化,重启后仍然有效。

级别 条件 处理方式
自动 命中白名单、校验通过、置信度足够、非自身代码、非契约或数据结构 自动执行,事后通知
确认 命中白名单但涉及依赖、配置、跨模块契约,或置信度不足 人工一键确认
人工 契约、状态解析、对外接口、数据结构、凭据、看门狗自身 人工实现

看门狗自己的代码永远走人工。修自己的系统,必须先假设它会犯错。

每次动作都追加到 incident 的动作记录,同时写一份修复报告。数据库负责查询,文件负责脱离数据库复盘。

三个开关相互独立:总开关控制是否采集与修复,自动修复开关控制是否动代码与进程,演练模式让校验与发布全部走过场。

八、先证明看得见,再证明修得对

第一阶段不要打开自动修复。只做采集、聚合、归因、守卫和台账,自动修复开关保持关闭,发布流程用演练模式。

验证项 通过标准
incident 聚合 同一根因跨任务只留一条,计数正确
降噪 重复噪音折叠后不丢真实失败
重复失败升级 同签名第二次出现即升级
健康检查 不误报正常服务
台账 证据、状态、动作可追溯

上线后不要只看自动修复率。修复率高但复发率高,说明系统在制造新的不稳定;修复率低但归因覆盖率高,至少说明人已经不用从头查。

指标 说明
归因覆盖率 有明确归属结论的 incident 占比
动作前拦截率 已知不一致在不可逆动作前被拦下的比例
自动修复率 自动化系统自身问题中被自动修复的比例
复发率 自动修复后观察窗内同签名再次出现的比例
噪音下降 重复事件折叠后告警量的下降幅度

诊断能力稳定之后,再分两步打开修复:先修低风险的提示词与配置,这类改动通常不需要重载进程;再修代码,这时才需要完整的校验、等待空闲、重载、观察窗和回滚。

怎么开始

  1. 先把失败事件按根因聚合,建 incident 台账。
  2. 给已知错误写确定性守卫,优先放在不可逆动作前后。
  3. 只让模型做归因和最小修复,守卫不经过模型。
  4. 修复流程先关掉自动执行,用演练模式跑校验、发布和回滚。
  5. 观察窗零复发后,再逐步打开低风险修复。

验收标准:同一根因只留一条 incident;已知不一致在动作前被拦;自动修复后观察窗内同签名零复发。

先证明看得见,再证明修得对。

九、适用边界

自愈系统不是所有团队都需要。

适合 不适合
自动化闭环已经稳定跑通,但人工诊断成本高 任务量太小,人工排障更便宜
同类失败跨任务复发 没有基本的可观测性
有测试、构建、发布流水线 没有自动化测试与回滚能力
能接受人工处理高风险变更 高风险领域且不允许自动变更

自愈不是零人工,而是把人的动作从逐条排障变成处理升级与高风险提案。

十、几个关键判断

降噪先于告警。 不聚合的通知系统,最终会训练人忽略所有通知。

守卫优先于修复。 能用断言解决的事情,不要动用模型。模型只负责“算谁的”和“怎么改”。

按根因聚合,不按失败记录。 按失败记录只能得到日志,按根因聚合才能得到待办。

修复的终点是观察窗,不是合并。 合并成功只代表代码进去了,零复发才代表问题解决了。

不能自伤,也不能阻塞。 看门狗挂了,主流程必须照常运行;看门狗自己的代码,永远走人工。

分工优于统一。 动作现场负责拦截,跨任务视图负责聚合与归因。把两类逻辑塞进一个地方,只会得到一套难以维护的判据。

先证明看得见,再证明修得对。 诊断没跑通之前,不要打开自动修复。

十一、结语

传统看门狗保证系统活着。AI 看门狗要保证系统犯错之后,能自己发现、自己纠正,并且下一次不再犯同样的错。

自动化解决的是执行成本,自愈解决的是维护成本。后者才是自动化能不能长期跑下去的分水岭。

相关阅读