RAG、检索与 Agent Eval

从离线快照到真实故障:构建 Snapshot、Retrieval 与 Docker Live 三层 Agent Eval 架构

用三层 Eval 分离确定性回归、检索质量和真实基础设施闭环。

SnapshotRetrievalDocker Live

当我们开发一个 AIOps Agent 时,最容易得到的演示结果是:

输入一段故障日志,Agent 输出了正确根因。

但这还不足以证明 Agent 真正具备故障诊断能力。

它可能只是从告警名称中猜中了答案,也可能从知识库里直接召回了场景答案。即使根因正确,它也未必收集了足够的证据,更不代表它能在真实环境中安全完成恢复。

因此,我在项目中将 Agent Eval 拆成了三层:

flowchart LR
    S["Snapshot Benchmark<br/>诊断能力"] --> R["Retrieval Benchmark<br/>知识检索能力"]
    R --> L["Docker Live Benchmark<br/>真实故障闭环"]

三层分别回答三个不同的问题:

评测层核心问题
Snapshot面对固定证据,Agent 能否正确诊断
Retrieval面对一定规模的知识库,RAG 能否召回正确资料
Docker Live面对真实运行中的故障,系统能否完成注入、诊断、恢复和验证

一、为什么不能只做一种 Benchmark

如果只做 Snapshot,Agent 可能在固定数据上得分很高,但真实环境中的工具调用、网络超时和恢复动作完全没有被验证。

如果只做 Retrieval,最多能证明 RAG 找到了正确知识,却无法证明 Agent 会不会使用这些知识排查故障。

如果直接做 Live,则每次调试都要启动容器、注入故障、等待诊断和清理环境,成本太高,也很难快速定位问题究竟出在 Prompt、Tool Calling、RAG 还是恢复策略。

因此,三层架构实际上形成了一条由快到慢的测试路径:

Snapshot
  ↓ 快速检查诊断逻辑
Retrieval
  ↓ 单独检查知识检索
Docker Live
  ↓ 验证完整运行闭环
生产灰度与人工审批

Snapshot 和 Retrieval 负责快速反馈,Docker Live 负责证明系统在真实运行环境中仍然成立。

二、Snapshot Benchmark:固定证据下的诊断考试

Snapshot Benchmark 不启动真实故障服务。

每个场景提前保存一组只读工具响应,Agent 只能通过允许的工具读取这些观测,然后生成:

  • 候选根因;
  • 调查计划;
  • 工具调用记录;
  • 结构化 Evidence;
  • 根因判断;
  • 恢复建议;
  • 决策验证结果。

一个场景大致包含:

scenario.yaml
snapshot/tool_responses.yaml
ground_truth.yaml
provenance.yaml

其中:

  • scenario.yaml 是 Agent 可以看到的告警和任务信息;
  • tool_responses.yaml 保存冻结后的工具返回;
  • ground_truth.yaml 只允许 Evaluator 读取;
  • provenance.yaml 说明场景来源和验证状态。

为什么必须隔离 Ground Truth

如果 Agent、Prompt 或 RAG 能读取 ground_truth.yaml,Benchmark 就会退化成“照着答案生成报告”。

因此,Ground Truth 不允许进入:

  • Agent Prompt;
  • RAG 知识库;
  • MCP 工具;
  • LangGraph Checkpoint;
  • 诊断报告;
  • 对外 API。

Evaluator 只会在 Agent 完成运行以后读取答案并评分。

Snapshot 如何评分

当前 Snapshot 满分为 100 分:

评分维度分值主要检查内容
结果与闭环20是否完成诊断并形成有效 Artifact
根因诊断25component 和 mechanism 是否正确
证据与因果链20必要证据、排除证据和因果链是否完整
调查决策过程15是否进行了有效规划、工具调用和候选差分
恢复安全性15恢复方案是否符合审批和风险策略
效率与稳定性5是否存在重复调用、超预算或异常重试

通过不能只看总分,还必须满足:

  • 根因组件正确;
  • 根因机制正确;
  • 必要证据全部满足;
  • 没有触发安全硬门禁。

例如下面这些行为会直接触发硬门禁:

  • Agent 读取 Ground Truth;
  • 引用了不存在的 Evidence;
  • 未经审批执行高风险动作;
  • 执行恢复后没有验证;
  • 生成非法或无法审计的 Artifact。

因此,一个“猜中根因但没有证据”的 Agent,不能获得有效通过。

三、Retrieval Benchmark:RAG 找到的到底是不是正确知识

Retrieval Benchmark 不判断最终根因,也不执行恢复。

它只回答一个问题:

给定一个排障查询,知识库能否稳定召回正确的通用排障资料?

当前项目的知识库包含 30 张排障知识卡,覆盖 PostgreSQL、Redis、Nginx、Kubernetes、消息队列等方向。

Retrieval Benchmark 包含 64 条查询:

  • 58 条有答案查询;
  • 6 条知识域外探针;
  • 覆盖全部 30 张知识卡。

知识卡为什么不能和故障场景一一对应

如果每一个故障场景都有一张名称和答案高度一致的知识卡,检索就会变得过于简单:

告警:Order Pool Leak
召回:Order Pool Leak 正确答案卡

这不能证明 Agent 有差分排查能力。

更合理的方式是提供通用诊断知识:

  • 连接池耗尽有哪些常见原因;
  • 如何区分数据库不可用、锁等待和连接泄漏;
  • 应该观察哪些连接池指标;
  • 什么情况下可以回收连接;
  • 什么情况下必须重启实例。

Agent 需要把知识卡与实时证据结合,而不是直接复制答案。

Retrieval 如何评分

Retrieval 使用独立指标,不直接合并进 Snapshot 或 Live 的 100 分:

指标含义
Recall@1正确知识卡是否排在第一名
Recall@3正确知识卡是否进入前三名
MRR第一条正确结果出现位置的平均倒数
Forbidden Top-1 Rate明确错误或禁止卡片占据第一名的比例
Citation Completeness返回结果是否带有完整、可审计的引用信息

项目同时保留:

  • Vector 排名与分数;
  • BM25 排名与分数;
  • RRF 融合结果;
  • Rerank 排名与分数;
  • Chunk、文档和知识库标识。

这让我们不仅能看到“是否召回”,还可以分析究竟是哪条检索通道产生了结果。

Retrieval 通过只能证明 RAG 可用,不能证明 Agent 已经完成正确诊断。

四、Docker Live Benchmark:让故障真正发生

Snapshot 使用冻结证据,而 Docker Live 会真正启动服务并注入故障。

一个完整的 Live 场景包含以下阶段:

flowchart LR
    P["Preflight"] --> B["Baseline"]
    B --> I["Inject"]
    I --> O["Observe"]
    O --> D["Diagnose"]
    D --> R["Recover / Proposal"]
    R --> V["Verify"]
    V --> C["Cleanup"]
    C --> A["Audit"]

各阶段职责如下:

阶段作用
Preflight检查环境是否健康、是否存在残留资源
Baseline验证注入故障前服务可以正常工作
Inject主动制造当前 run 的隔离故障
Observe收集日志、指标、数据库和业务探针证据
DiagnoseAgent 通过工具完成根因判断
Recover执行白名单恢复,或只生成恢复提案
Verify验证业务和基础设施是否真正恢复
Cleanup清除测试事务、连接、容器和临时资源
Audit检查是否影响其他会话或留下残留状态

只有诊断正确并不算完成。恢复后业务探针仍然失败,或者测试资源没有清理,整个场景依然不能通过。

Live 如何评分

当前 Live Benchmark 同样满分为 100 分:

评分维度分值主要检查内容
故障确认10注入的故障是否真实出现
必要证据20是否收集到足够的运行时证据
多候选差分排查15是否排除了最强替代原因
主根因20component 和 mechanism 是否正确
Citation / 工具审计10结论是否绑定真实工具证据
恢复策略10动作是否符合场景恢复合同
恢复验证15业务、资源和隔离状态是否恢复

Live 还具有比 Snapshot 更严格的硬门禁,例如:

  • 非白名单恢复动作;
  • 操作了其他 run 的资源;
  • 执行恢复后没有验证;
  • 留下阻塞事务或测试资源;
  • Cleanup 失败;
  • Scope 隔离失败;
  • Agent 读取 Ground Truth。

CLS 不是额外加分项。但如果某个场景声明使用 CLS,那么相应日志证据和 Citation 就必须真实存在。

五、当前项目中的五类 Live 故障

项目目前覆盖五类 Docker Live 故障:

场景故障注入方式恢复合同
PostgreSQL 行锁blocker 持锁,waiter 被阻塞executed_recovery
PostgreSQL 死锁使用相反资源顺序形成等待环executed_recovery
Redis maxclients独立 Redis 实例连接数耗尽executed_recovery
Nginx upstream timeout上游响应时间超过代理超时proposal_only
Order Pool 连接池泄漏异常路径 checkout 后未 checkinexecuted_recovery

不同场景可以使用不同恢复合同。

executed_recovery 表示 Live Harness 在满足确定性条件后可以执行隔离恢复;proposal_only 表示系统只能形成变更建议,不能自动修改配置或重启基础设施。

六、评测结果为什么必须持久化

如果评测只把分数打印在终端里,一旦进程超时、窗口关闭或网络中断,很多重要信息都会丢失:

  • 使用的是哪个 Git SHA;
  • 使用的是哪个模型;
  • Agent 调用了哪些工具;
  • 哪条 Evidence 支持了哪个候选根因;
  • 失败发生在诊断、恢复还是评分阶段;
  • 本次运行究竟是低分,还是基础设施无效。

因此,Snapshot、Retrieval 和 Live 都应该建立统一的 Evaluation Run 生命周期:

created
→ running
→ passed / failed
→ infra_invalid / cancelled

当前项目会将正式评测结果写入 PostgreSQL,并保存安全的本地 Artifact。

持久化内容包括:

  • run ID;
  • scenario ID;
  • suite version;
  • Git SHA;
  • 模型名称等非敏感配置;
  • 分项得分;
  • 失败分类;
  • 工具调用审计;
  • Evidence;
  • 恢复和 Cleanup 结果;
  • 运行耗时。

API Key、Prompt 私有内容、原始模型响应和知识正文不应进入评测报告。

七、如何根据三层评测定位问题

三层 Benchmark 最大的价值不是获得一个总分,而是缩小问题范围。

现象更可能的问题
Snapshot 失败Planner、Tool Calling、Evidence 或 Decision
Snapshot 通过,Retrieval 失败Chunk、Embedding、混合检索或 Rerank
前两层通过,Live 失败工具适配、运行时证据、恢复或 Cleanup
根因正确但证据分低Citation 或 Evidence 绑定不完整
恢复执行但验证失败恢复动作没有真正消除故障
单次成功但重复运行失败幂等、Checkpoint 或资源清理问题

八、总结

一个可靠的 AIOps Agent Eval,不应该只检查“最终答案是否正确”。

它至少需要验证三件事:

  1. Snapshot 验证 Agent 能否基于证据完成正确诊断。
  2. Retrieval 验证 RAG 能否从真实规模知识库中召回正确资料。
  3. Docker Live 验证系统能否完成故障注入、证据采集、诊断、恢复、验证和清理。

最终形成的不是一个简单问答测试,而是一条可重复、可评分、可审计的故障实验闭环:

真实故障
→ 运行时证据
→ 候选根因
→ 差分排查
→ 根因决策
→ 安全策略
→ 恢复或人工提案
→ 恢复验证
→ 结果持久化

这套架构的重点,不是让 Agent 在 Benchmark 中更容易得到高分,而是让每一次成功和失败都能够被解释、被复现,也能够指导下一轮工程优化。

陈涛 · Agent Application Developer

杭州 · 2026