不改模型,如何验证事故记忆改善排障
DejaVu实验固定告警、模型和代码,仅改变历史事故记忆量,对比零条、五条与二十条记录下的响应。案例围绕数据库连接池耗尽,检验智能体能否利用失败历史调整修复建议。
AI 深度解读
AI Agent 宣称自己「越用越聪明」,该拿什么证明?DejaVu 的作者做了一个直接的实验:保持告警和代码一致,只增加可读取的历史事故,把 0、5、20 条记录下的回答并排比较。建议确实从「重启连接池」变成了「优先回滚,重启已失败 4 次」。
但这里的「学习」需要拆开看:对照实验关闭了 LLM,回答来自固定模板。它展示的是历史记录如何改变排障建议,而不是模型自身能力的提升。对准备给 Agent 加记忆的程序员,这个区别比结果更有参考价值。
从建议重启,到明确劝你别重启
实验始终使用同一条告警:
Checkout 500s: DB connection pool exhausted (payments-api)
也就是 payments-api 的数据库连接池耗尽,导致结账请求出现 500。重启连接池看起来合理,却恰好是这组事故记录里反复失败的操作。
没有历史时,系统只能给通用建议:重启连接池、重启服务、增大连接池,没有需要避开的操作,也没有相似事故可供参考。
加入最早的 5 条事故后,系统匹配到 INC-0004。建议随即变成:优先回滚连接池配置,历史成功记录是 1/1;避免重启连接池,历史失败记录也是 1/1。
它还指出,3 小时前名为 Tidy db config 的变更修改了 db/pool.py,上一次事故前也出现过对相同文件的修改。这提供了一条排查线索,但不能单凭文件重合认定根因。作者也承认,一个样本只是提示,不是证明。
当历史增加到 20 条,系统匹配到 INC-0004、INC-0009、INC-0014、INC-0020:
- 回滚连接池配置成功
3/4。 - 修复连接泄漏成功
1/1。 - 重启连接池失败
4/4。
回滚没有成功的那一次,原因是连接泄漏,所以答案里多出了第二条处理路径。
记忆的价值不只是记住成功方案,还包括保留失败方案和例外。
这比一句「建议回滚」更有用。工程师能看到建议来自几次记录,也能知道主方案不成立时该继续查什么。
怎样确认建议变化来自记忆
作者把事故按发生时间排序,依次取最早的 0、5、20 条,每次都询问同一个问题。下面这段代码负责组织对照实验,保留了原文实现:
def run(steps: list[int], live: bool = False, scenario: str = "checkout_500s") -> list[dict]:
history = sorted(load_seed(), key=lambda i: i["opened_at"])
alert = detector.primary_alert(sim_events.generate(scenario))
live_mem = HindsightMemory() if live else None
rows = []
for n in steps:
window = history[:n]
if live_mem:
mem = WindowedMemory(live_mem, {i["id"] for i in window})
else:
mem = MockMemory()
mem.retain_many(window)
result = analyzer.investigate(alert, window, mem, use_memory=True, llm=None)
rows.append({"n": n, **result})
return rows
要盯住最后的 llm=None:这次实验没有让 LLM 生成回答,文本由固定模板输出。因此,建议发生变化,不能归因于模型这次换了措辞或临时发挥。
时间边界也做了控制。opened_at 决定记录顺序,history[:n] 限定当前可见历史,避免在「只有 5 条事故」时用上后来的处理结果。
默认路径使用 MockMemory,通过 retain_many(window) 写入当前窗口。加上 --live 后,召回会访问真实的 Hindsight bank;由于其中已经存有全部记录,WindowedMemory 会过滤掉当前窗口以外的事故,防止提前读到未来信息。
不过,这也限定了实验能证明什么:它展示了历史积累如何改变固定流程的输出,没有展示开启 LLM 后,模型能否稳定理解这些记录、处理冲突并做出正确选择。
实际应用中的反馈入口是 Worked 和 Failed。工程师点击后,处理结果会通过 retain 留入 Hindsight,后续相似告警再通过 recall 使用这些记录。没有人记录结果,这条积累路径就会中断。
我的判断
我认可这种验证方法。固定问题、逐步增加历史、并排展示答案,比展示一次漂亮的 Agent 演示更容易判断记忆是否产生了作用。尤其是把失败次数写出来,能让使用者审查建议依据。
但「越用越好」在这里仍有明显前提。
首先,全部 32 条事故都是为项目编写的合成数据,规律经过刻意安排。真实事故里,同样的连接池耗尽可能来自不同原因,记录也可能缺少上下文。作者承认真实曲线会爬得更慢,但没有给出真实团队的对照结果。
其次,3/4 是历史计数,不能直接当作下一次成功概率。是否属于同一种故障、操作先后有没有影响,原文没有展开。
最后,完整的并排实验只覆盖一种告警。作者还提到 credential stuffing 场景能得到「Block ASN at WAF 成功 3/4」的建议,但没有提供同样完整的曲线,不能据此推断所有事故类型都有效。
这项实验支持「记忆能改变建议」,还不足以证明「Agent 的整体排障能力持续提升」。
与微调相比,这种方式更新的是可检索记录,便于追溯具体事故;与只检索事故描述相比,它把操作成败也纳入了依据。不过,原文没有提供与微调、普通检索或人工维护排障手册的对照数据,效果优势仍需验证。
能拿来做什么
- 给排障 Agent 加记忆时,把尝试过的操作、成功或失败结果、对应事故一起保存。只存事故描述,后续很难判断某个建议是否已经被证伪。
- 在 Node 服务排障场景中,挑一个反复出现的告警,固定输入和处理流程,按时间逐步开放历史,再比较建议是否变化。先验证记忆有没有用,再增加复杂能力。
- 展示历史依据时,同时保留次数和例外,例如「回滚成功 3/4,另一次需要修复连接泄漏」,让工程师能判断下一步,而不是只接收一个结论。
- 把固定模板验证与 LLM 验证分开进行。前者检查记录和召回是否影响结果,后者再检查模型是否误读证据,避免把两类问题混在一起。