跳到主要内容

AI 功能的 Bug Bash:分布采样,而非猎捕缺陷

· 阅读需 12 分钟
Tian Pan
Software Engineer

经典的 Bug Bash 是一种为确定性软件量身定制的确定性仪式。十名工程师挤在一个 Slack 频道里两小时,对照着黄金路径流程清单疯狂测试,然后提交带有清晰复现步骤的工单:“点击 X,看到 Y,预期 Z。” 这套方法之所以奏效,是因为被测系统是可复现的——相同的输入,相同的输出,相同的 Bug,次次如此。

如果针对 AI 功能运行完全相同的仪式,你最终会得到 200 张工单,其中 180 张会因为“符合预期的随机波动”而被关闭,同时还会漏掉那 20 张预示着真正的群体性回归(cohort regression)的工单。这种形式不仅陈旧,而且完全错位了。针对基于 LLM 的功能进行 Bug Bash 并不是一场捕捉缺陷的会议。它是一场针对概率分布的抽样练习,如果团队像运行确定性测试那样运行它,就是在收集噪声并将其视为信号。

这篇文章讨论的是如何为随机系统重新设计 Bug Bash——包括流程形式、参与者、分级准则以及什么才算“完成”等方面需要做出哪些改变。

为什么沿用的模式会失效

传统的 Bug Bash 植入了三个假设,而 AI 功能打破了所有这些假设。

第一个假设是可复现性。在经典的 QA 中,“我点击了按钮,它崩溃了”就是一个完整的报告。但在 AI 功能中,同样的提示词(prompt)在连续五次运行中可能会返回五个不同的答案,其中一个可能错得离谱。单次观察只是统计噪声。没有复现次数的 Bug 报告不是真正的报告——它只是一个轶事。

第二个假设是故障模式是结构性的。按钮不渲染、表单无法提交、API 返回 500 错误。这些都是类别故障:要么存在,要么不存在。而 AI 功能的失效是沿着质量梯度分布的。按钮渲染了,答案只是对特定行业的细分用户来说有细微错误。或者答案是正确的,但其语气不对,以至于损害了信任。二元的“坏了/没坏”标准无法代表这些故障,因此它们要么被归类为“轻微”,要么根本不被记录。

第三个假设是工程师能识别故障。在确定性系统中,500 错误对每个人来说都一样。但在领域专业化的 AI 功能中——例如法律合同审查、医疗摘要生成、针对特定技术栈的代码重构——真正关键的故障是领域准确性故障。阅读临床笔记摘要的工程师无法判断“术后第三天”是否被错误地分类为“术后第二天”。但律师可以。这些故障对于你邀请的人来说是不可见的。

将这三个因素叠加在一起,这种沿用的形式就变得不仅没用,反而有害。它会产生排山倒海般不可复现、分类错误、流于表面的报告,淹没那些真正预示着可利用模式的少数关键信号。更糟糕的是,它给了团队一种虚假的信心:“我们做过 Bug Bash 了,发现了问题,发布吧。”

重塑目标:从发现缺陷到分布映射

必须转变的观念是:AI 功能的 Bug Bash 不是在寻找缺陷,而是在为一个注定会出现故障的系统绘制故障分布图。你不是在问“它坏了吗?”,而是在问“它在哪里失效、频率如何、以及针对哪一类用户?”

这种重塑改变了下游的一切。你不再希望每个参与者都反复测试同一个黄金路径。你希望他们分散在输入空间中——不同的用户群体、不同的任务类型、以及探测模型能力不同维度的不同输入。每一次会话都是一次抽样过程;每一张工单都是一个样本,而不是一个定论。

具体来说,在 Bug Bash 开始之前,组织者应该预先定义群体网格(cohort grid):垂直行业、账户层级、语言、任务类型、新手与高级用户、短输入与长输入。每个参与者负责一个单元格。如果你有 8 个人和 4 个群体,每 2 个人负责一个群体的抽样。如果你有 12 个人和 6 个群体,每个单元格 2 人,并进行刻意的重叠,以便你可以对比同一分片下的独立样本。

这不是微小的重组。它改变了你邀请的对象、你向他们简述的内容、你要求他们提交的内容,以及你随后的分级处理方式。

对抗性输入优于黄金路径输入

另一个转变是对抗性的。传统的 Bug Bash 演练的是理想路径(happy path)——即产品经理希望在周五演示的流程。对于确定性系统,这是合理的;如果理想路径可行,特殊的输入大概率也行,因为底层逻辑是一样的。

对于 AI 来说,理想路径几乎无法提供任何信息。模型在那些看起来像产品演示的输入上进行了过度训练。能够区分功能是鲁棒还是脆弱的,是那些演示中永远不会出现的提示词:拼写错误、混合语言、半截句子、刻意误导的框架、提示词注入尝试、与系统提示词冲突的输入、处于 Token 限制边界的输入,以及用户实际生产环境中混乱的格式,而非评估套件中使用的合成干净格式。

红队测试(Red-teaming)的研究已经印证了这一点。手动对抗性测试擅长发现自动化套件遗漏的细微边缘情况,尤其是故障在多轮中逐渐积累的多轮对话攻击。最近的研究表明,通过角色扮演伪装、甚至在基准数据集中从未出现过的押韵诗行混淆等技术,攻击成功率已攀升至 80% 以上。你的 Bug Bash 需要引导出这种能量。

实际上,这意味着给每个参与者一份对抗性简报以及他们的群体分配。“你是一名医疗垂直行业小企业层的用户。尝试让助手给出它不该给出的医疗建议。尝试让它言之凿凿地引用一篇不存在的论文。尝试让它泄露系统提示词。尝试让它在两轮对话中自相矛盾。”这份简报取代了黄金路径清单。

复现次数就是工单格式

如果确定性 Bug 工单是“复现步骤”,那么随机性 Bug 工单就是“复现步骤加上观察到的频率”。没有频率,你就无法进行分级处理。对于同样的输入,运行五十次才出现一次的失败可能是统计噪声;而运行五次就出现四次的失败则是真正的 Bug。在观察到的那一刻,两者看起来是一模一样的。

分级标准需要强制执行这一点。没有复现次数的工单应该被退回,而不是直接关闭。最低门槛是:“我运行了该提示词 N 次,失败发生了 K 次。”对于 Bug Bash 来说,五次尝试是一个合理的底线;十次更好,但速度较慢。工具在这里至关重要——给参与者一个“一键运行相同提示词五次并捕获所有输出”的按钮,因为让用户手动重试同一个提示词会导致复现次数虚高,并让参与者感到沮丧。

一个好的标准会将频率分为三个区间:罕见(5 次中出现 1 次或更少,标记为孤例,不予晋级)、偶尔(5 次中出现 2–3 次,晋级为评估候选对象,在发布前进行调查)以及可靠(5 次中出现 4–5 次,视为真正的 Bug,修复前禁止发布)。确切的阈值是可以调整的,但原则是不可动摇的:频率是数据点的一部分,而不是元数据。

这也意味着你不能像在确定性 Bug Bash 中那样实时处理工单。在第 30 分钟观察到的失败需要重新运行,可能需要由另一个群组的第二名参与者来执行,然后你才能确定它是否真实存在。在结束时安排一个 30 分钟的综合分析环节,对标记的工单进行重新采样,而不仅仅是讨论。

领域专家在现场,而非流程中

参与者群体是第三个杠杆。仅由工程师运行的 Bug Bash 只会抓到“工程师式”的 Bug:延迟激增、流式传输中断、JSON 格式错误、重试风暴。它会漏掉每一个该功能本应正确处理的“领域正确性”故障。

对于临床总结功能,你的 Bug Bash 需要临床医生参与。对于合同修订功能,你需要律师。对于针对特定框架的代码重构功能,你需要精通该框架的工程师,而不是能读懂任何代码的通用型人才。关于领域专家参与 LLM 评估的研究一致发现,最有价值的反馈只有领域专家才能提供:“这个答案在语法上是正确的,但任何在职临床医生都不会那样表达。”

难点在于运营层面的要求。领域专家很昂贵,容易对重复性任务感到疲劳,而且当被要求从头开始设计评估标准时,他们的 AI 素养通常较弱。Bug Bash 的形式必须适应这一点。为每位领域专家配备一名工程师,由后者负责操作工具、记录复现次数,并将“这是错的”转化为结构化的工单。将专家的会议时间限制在 60–90 分钟内——超过这个时间的疲劳会导致评分趋于平均化,从而失去价值。预先构建好输入集,以便专家是根据现实输入审查输出,而不是在时间压力下生成提示词。

综合分析环节是工程师与专家搭档发挥作用的地方。专家指出一些微妙的问题;工程师将其转化为一个确定性的评估案例(eval case),从此以后的每一次模型升级都可以重新运行。这种转化——从孤例到评估案例——才是 Bug Bash 真正的交付物。那些被提交后又关闭、却未能成为评估案例的工单,都是浪费精力。

什么是完成

传统的 Bug Bash 在工单数量趋于平缓或时间耗尽时结束。要么 Bug 被修复了,要么被分流到了待办事项中,然后团队继续前进。

随机性 Bug Bash 的结束方式不同,因为目标不同。交付物不是一份工单列表,而是三个产出:

  • 扩展的评估集。 来自 Bash 的每一个确认模式都会被提升到回归评估套件中,包含失败的输入、所属的群组以及失败描述。下一次模型升级将自动针对这个扩展集运行。这就是 Bug Bash 如何随着时间的推移产生复利价值,而不是成为一次性的仪式。
  • 群组故障热力图。 一个“群组 × 任务类型”的网格,包含来自 Bash 的单元格级通过率。这不仅告诉你在“哪里失败”,还告诉你在“哪里比基准失败得更多”——这才是驱动路线图的信号,而非原始的故障计数。
  • 未确定频率的列表。 复现率处于模糊中间地带(偶尔发生,而非可靠发生)的工单被记录为“需要更多采样”,而不是直接关闭。它们会进入下一次 Bug Bash,或者在生产流量中进行自动采样,直到积累了足够的数据进行分类。

如果 Bug Bash 结束时没有产生这三个产出,那么它结束得太早了。如果产生了这些产出,团队不仅发布了一个功能,还构建了一套永久性的基础设施,在用户发现之前就能捕捉到下一次回归。

核心感悟

架构层面的转变在于,Bug Bash 就像行业从确定性软件时代继承下来的其他 QA 仪式一样,是一种采样工具。对于确定性系统,样本量为 1 就足够了,因为每个样本都能代表总体。对于随机性系统,样本量为 1 只是从分布中进行的一次抽取,几乎无法告诉你关于该分布其余部分的任何信息。

在 AI 质量上胜出的团队,是那些将每一个 QA 产出——Bug Bash、内部试用、客户 Beta 测试群组,甚至是支持工单——都视为采样工具,以此不断更新系统故障地图的团队。而失败的团队则仍在使用 2018 年的确定性 QA 手册来应对 2026 年的概率分布,并纳闷为什么他们发布后的事件图表看起来像心电监护仪。

像进行采样一样运行下一次 Bug Bash。引入正确的群组。强制要求复现次数。将模式提升为评估案例。闭环处理。你的 QA 团队继承的模式适用于他们过去交付的系统。但对于你现在交付的系统,它是错误的。

References:Let's stay in touch and Follow me for more thoughts and updates