可回放的告警归因引擎如何约束大模型
开源项目 Antibody 汇总日志、指标、链路和服务事件,将关联告警合并为事件,并按证据与置信度排列可能根因。检测和归因采用确定性逻辑,大模型仅负责解释,模型不可用时由模板接替。
完整中文译文
微服务告警最吵的地方,未必是最先出问题的地方。Antibody 想解决的就是这个错位:把日志、指标、链路和服务事件归并成故障,再用证据排列可能的根因。
这个项目最有价值的选择,是让代码负责判断,让语言模型负责解释,并允许系统回答「证据不足」。不过,它的成绩全部来自模拟环境;复杂模式下,整体表现也没有超过「选异常最强的服务」这个简单基线。它值得读,恰好因为作者把边界也摆了出来。
根因分析为什么不直接交给模型
Antibody 是五人团队 Ace Azael 在 2026 年 9 月为 Microsoft Codathon Problem 3 开发的项目,获得校内第 1 名、9,900 分,已交付并以 MIT 协议开源。
它处理的是常见的级联故障:底层服务坏了,调用它的服务接连报错,值班工程师收到成千上万条告警。受害服务可能比根因服务更吵,单看告警数量容易追错方向。
团队从第一天就定下约束:检测、关联、排序、建议都必须确定且可重放。给定相同输入,应该能够复现判断过程。语言模型只把已经算好的证据改写成英文说明,并标注为 AI 生成;模型不可用时,由模板根据同一份证据生成解释。
诊断结果不依赖语言模型是否在线。
这段原始流水线把职责划分得很清楚:
ingest learn the dependency graph from trace spans (caller -> callee)
detect per-service EWMA baselines, z-scores, error-log and error-span ratios
debounce: 2 bad ticks in a row before anything counts
correlate a new abnormal service joins an open incident if it calls into the failure
rank 8 signals -> an RCA score from 0 to 1 (not a probability)
verdict HIGH / MEDIUM / LOW from fixed rules. LOW means "insufficient evidence"
suggest fault signature -> restart, roll back or scale out
human acknowledge -> apply fix -> verify recovery -> resolve -> remember
要留意 rank 这一行:0 到 1 的 RCA 分数是排序分数,不是「根因概率」。给分数加上小数点,并不会自动获得统计意义。
检测阶段结合每个服务的指数加权移动平均(EWMA)基线、z-score、错误日志和错误 span 比例,连续两个采样周期异常才计入。关联阶段则利用 trace span 学到的调用关系,把相关异常收进同一故障。
排序共使用 8 个信号。原文列举了异常图上的个性化 PageRank、异常出现先后、调用方错误日志的指向、本地故障特征、近期部署,以及与历史已解决故障的匹配,但没有完整展开全部八项。
「不知道」怎样变成可执行规则
Antibody 的 HIGH、MEDIUM、LOW 来自固定规则,考察第一候选领先第二候选多少、有多少种独立证据一致,以及是否存在反证。规则不满足时,系统拒绝给出确定结论;LOW 明确表示证据不足。
这里区分了两件事:系统总能排出第一名,但第一名未必值得相信。

修复建议也受规则约束。已识别的故障特征可以映射到 restart、roll back 或 scale out;遇到新类型故障,只返回 investigate,不会硬凑一个修复动作。
后面还有人的处理闭环:确认故障、应用修复、验证恢复、解决并记录。原文没有证明这些建议可以安全地自动执行。
跑分能证明什么,又暴露了什么
基准包含 84 个场景:7 个服务、6 类故障,每种组合使用 2 个随机种子。每个场景都有已知根因,真实答案只用于评分,不提供给引擎。运行 python bench.py,约 7 秒可以复现。
困难模式下,作者报告:
- HIGH 占判断的 78.6%,其中正确率为 98.5%。
- LOW 占 8.3%;这些场景如果强行猜测,正确率只有 42.9%。
- 排除拒答后,系统实际作答的正确率为 95.8%。
这些数字支持的是「拒答能筛掉一部分不可靠判断」,不能把 95.8% 当成所有场景的总体准确率。
更关键的是对照结果。干净流量下,两个更简单的基线同样达到 100%,作者承认模拟器太容易,无法拉开差距。困难模式下,完整模型整体只与「异常最强者」打平。
它的优势集中在静默崩溃引发的级联故障:根因服务不再发声,调用方却大量报错。它的弱点是故障发生在调用图上层、下层又存在误导性异常。6 次失误中,5 次被标成 LOW 或 MEDIUM,说明置信标签能提示多数失误,但没有全部兜住。
另外,两起无关故障同时发生时,6 对测试全部被拆成独立故障;检测时间中位数为 2 秒。数据库崩溃场景中,约 2,000 个事件被归并为一个故障,涉及 5 个告警服务,db 排在根因首位。
我的判断
我认同「代码决策、模型解释」的职责划分。对于已有结构化证据、需要复盘的运维流程,它让结论来源更容易检查,也避免模型故障拖垮诊断链路。
但确定性只保证过程可复现,不保证规则正确。这个项目也没有证明复杂排序在总体准确率上优于简单基线。它更有说服力的部分,是静默崩溃场景的表现,以及拒答机制暴露不确定性的能力。
工程边界同样明确:7 个服务全是模拟的,ingest API 虽然接受真实数据,却尚未接入真实系统;历史修复记忆只存在于进程中,重启即丢失;API 没有认证,定位是本地演示。接入生产后的数据质量、规模和效果,原文没有给出验证。
作者称这些数字来自 bench.py 和 README,并披露写作使用了 AI 辅助。因此,它提供了一组可复现的项目自测结果,还不足以证明生产效果。
能拿来做什么
- 给 Node 微服务做告警归并时,可以先利用 trace 调用关系识别同一条故障链,再评估是否需要加入复杂排序。
- 开发 AI 运维助手时,可以先让代码输出结构化证据、候选根因和置信标签,再让模型生成说明,并保留模板降级路径。
- 评估根因分析工具时,应同时记录总体表现、作答覆盖率和拒答场景的表现,并加入「异常最强者」等简单基线。
- 设计修复建议时,可以把未知故障明确落到人工调查,并在关闭故障前验证恢复,避免把一条流畅解释直接当成执行依据。