跳到主要内容

Agent 分支覆盖率:你的评测仅命中了 Happy Path,而非 Planner 的 If-Else 逻辑

· 阅读需 9 分钟
Tian Pan
Software Engineer

我上季度合作的一个团队针对其支持智能体(support agent)运行了一套包含 240 个案例的评估集。连续六个月,测试结果全线飘绿。接着,他们更换了规划器提示词(planner prompt)中的一个句子——仅仅是一次语气调整——结果第二天生产环境的人工接管请求激增了 3 倍。而评估分数却纹丝不动。人工接管分支仅仅是开始在以往能在线解决的临界案例上触发,而评估集中没有一个案例属于这种临界类型。该分支存在于提示词中,存在于生产环境中,唯独不存在于评估集中。

这就是我想命名的失败模式:智能体分支覆盖率 (agent branch coverage)。代码覆盖率工具在过去的 40 年里一直是调试的基础,但智能体系统具有运行时控制流——规划器分支会选择工具、限定回复条件、升级到人工、拒绝执行、或尝试不同的策略重试——而评估集仅触及团队想到的那些案例。规划器 80% 的决策分支从未在测试下执行,于是,一份“全绿”的评估报告就成了一场披着回归测试外衣的冒烟测试。

提示词中隐藏的控制流

现代智能体提示词本质上是一个程序。它虽然是用英语编写的,但拥有分支。阅读任何生产环境的系统提示词,你都会发现它们:“如果用户询问账单,则进行人工接管。”“如果请求模糊,在采取行动前先询问一个澄清问题。”“如果工具返回超过 50 行,请在继续之前进行总结。”“如果你无法核实用户身份,请礼貌拒绝并结束对话。”

其中的每一条都是一个 if-else。模型就是解释器。评估集理应是你的测试套件。然而,在我见过的几乎所有团队中,评估集都是由某人写下脑海中浮现的示例而组建的——而不是通过梳理提示词的分支图并询问“这些决策中哪一个经过了测试?”

DeepEval 团队一直通过他们所谓的 DAG 指标(DAG metrics)来使这一过程正式化——这是一种基于决策树的评分方式,每个评估步骤都基于先前的判定进行分支,镜像了规划器本身的结构。Braintrust 将智能体评估分为轨迹检查(trajectory checks,智能体是否走对了路径?)和单步检查(每个单独的决策是否正确?)。Anthropic 的《解密评估》(Demystifying Evals)一文指出,智能体故障更多表现为跨轮次的复合错误静默工具失败,而不是错误的最终答案。这三者都指向同一个核心点:评估的单位是决策,而不是响应。如果你没有测量做出了哪些决策,你就无法知道自己遗漏了哪些。

MC/DC 在 40 年前做对了什么

安全关键型软件(Safety-critical software)自 20 世纪 70 年代以来一直面临这个问题。航空标准 DO-178C 和汽车标准 ISO 26262 不仅仅要求语句覆盖率——它们还要求修正条件/判定覆盖 (MC/DC)。它要求判定中的每个条件都必须在测试中被分别执行,并证明其能独立地影响结果。一个包含 16 个条件的判定在 MC/DC 下需要 17 个精心挑选的测试。而朴素的“测试每个组合”方法则需要 65,536 个。之所以发明 MC/DC 规范,是因为人类的直觉在挑选关键输入时表现极差;你需要的是结构化论据,而不是凭感觉。

智能体系统至少应该具备这一水平的入门版。虽然不是完全的 MC/DC——这种数学方法无法干净地应用于概率型解释器——但其底层理念是通用的:枚举分支,并要求提供每条分支在测试下被触发的证据。 当在提示词修订中添加新分支时,请将其视为新的代码路径:在合并之前必须通过测试。

高标准不是“你的模型是否正确”。概率系统不接受二元答案。低标准则有用得多:“评估集中是否有案例触发过该分支执行?”分支的零覆盖率是置信度的硬性下限。你可能不知道它是错的,但你清楚自己从未审视过它。

对规划器进行插桩,而不仅仅是输出

机械化的步骤其实很小,但几乎总是被遗漏。让规划器在输出动作的同时,发射一个识别其刚刚应用的规则的分支 ID(branch ID)。例如:“BR-ESCALATE-BILLING”、“BR-CLARIFY-AMBIGUOUS”、“BR-REFUSE-IDENTITY”。通过结构化输出要求将这些 ID 固化在提示词中——大多数现代模型 API 都会很乐意在用户可见的回复旁边返回一个名为 decision_path 的 JSON 字段。

现在,你的追踪日志(trace logs)就带有了针对每个决策的归因。评估运行器可以在运行后计算每个案例触及的分支 ID 集合。在整个套件中进行汇总,你就得到了一个覆盖率矩阵——哪些分支被评估集覆盖了,哪些没有。

这正是工作变得有趣的地方。我指导过的一个团队在第一次生成这种矩阵时发现:

  • 提示词中的三个分支在 240 个评估案例中从未被触发。
  • 一个分支在 192 个案例中被触发——这迹象表明了一个过度活跃的备选路径,它掩盖了上游真实的失败。
  • 两个团队认为冗余的分支,实际上是满足特定用户模式的唯一路径。
加载中…
References:Let's stay in touch and Follow me for more thoughts and updates