AI 智能测试怎么测试:从用例设计到结果判定

模型与算力

讲 AI 应用测试的全流程:怎么定评测目标和判定标准、用例集怎么攒和防污染、结果怎么读、回归怎么跑。

模型答得挺溜,上线后客户却说你功能不对——这类问题十有八九出在测试环节:没定清楚什么叫「对」,用例是随手凑的,判定全靠眼睛看,上线之后改动一次就悄悄退化了。这篇不讲选型也不讲部署,只把 AI 应用的测试流程拆成几步:先定评测目标和判定口径(规则判定、模型判定、人工抽检各管什么),再讲用例集怎么攒、怎么防污染,最后是结果怎么读、回归怎么做。

模型答得挺溜,上线后客户却说你功能不对——这类问题十有八九不是模型选错了,而是测试环节没做扎实:没定清楚什么叫「对」,用例是随手凑的,判定全靠眼睛看,上线之后改动一次就悄悄退化了。这篇不讲选型也不讲部署,只把 AI 应用的测试流程拆成几步:先定评测目标和判定口径,再讲用例集怎么攒、怎么防污染,最后是结果怎么读、回归怎么做。

和传统软件测试最大的差别在于:AI 应用的「正确」经常不是一个布尔值。同一句回答,有人觉得够用了,有人觉得漏了关键点。所以第一步不是写用例,而是先把判定标准写成别人能复核的条件,否则后面攒多少用例都是在自说自话。

第一步:定评测目标与判定标准

先写清「这次测什么」,这句话不写清,用例就没法定。是测事实准确、格式合规、检索召回,还是端到端任务能不能走完?目标不同,用例形态几乎完全不同:测格式的用例只关心输出结构,测召回的用例则要先看命中的文档对不对,再看最终回答。

规则判定
用关键词、正则、JSON 结构、字段校验来判断,最便宜也最稳,适合有确定答案的场景
模型判定
用另一个模型当裁判,适合开放回答,但要固定裁判模型与提示词版本,并定期人工抽检校准
人工抽检
只抽边界样本,用来验证前两者准不准,不要全量靠人,人手一多口径就散了

判定标准要落成可勾选的条件,比如「必须引用了指定文档」「输出必须是合法 JSON 且字段完整」「不得出现未在上下文中出现的实体」。避免「回答得不错」这类无法复现的描述——同一份输出,两个人打分会不一致,那这条标准就是无效的。

用例集怎么攒:来源、分层与防污染

用例来源按可信度排:真实用户问题日志 > 业务方提供的边界场景 > 手工构造的合成用例。合成用例可以凑量,也能快速覆盖冷门场景,但由它得出的结论只能当参考,不能当成上线依据,因为它往往带着写用例人的想象。

  • 常见主路径:用户最常问的那几十种问法,必须全部覆盖,且要保留原始口语表达而不是改写成标准问句
  • 边界输入:空值、超长文本、混语言、全角符号、只有表情没有文字这类
  • 对抗输入:诱导越权、要求编造事实、让它忽略既有约束,看它守不守规矩
  • 格式压力:要求结构化输出时,检查它会不会多包一层解释文字或者漏字段

防污染有三条:一是别把正式用例贴进提示词或微调数据里;二是建立固定评测集与滚动评测集两套,固定集只用来对比版本、平时锁住不公开;三是上线后如果把某条坏例修进了系统提示词,就要把它从评测集里撤出并归档,否则下次测试等于自己泄题,通过率虚高。

污染方式典型表现处理动作
用例进提示词固定集通过率突然变高把该条撤出固定集,另建一条同义改写的新用例
用例进微调数据同类问题表现明显优于其他问题改从真实日志里补样本,并重新标基线
评测集版本混用两次对比数字对不上给评测集打版本号,改过就重标基线

结果怎么读:别只看一个总分

一个总分最没有信息量,因为它掩盖了失败集中在哪里。分开看四类数字:整体通过率、分层通过率、失败类型分布、以及判定方式之间的分歧率。分歧率高说明规则或裁判提示词写得不好,先修评测再谈模型——换模型解决不了评测本身的问题。

  1. 按层看通过率主路径、边界、对抗、格式各看一份,别混成一个总分;某一层特别低就是明确的改进方向
  2. 给失败样本归因逐条标成模型能力不够、提示词没写清、检索没召回、工具调用失败;混着看会得出「换个模型就好了」这种错误结论
  3. 多跑几轮看稳定性同一输入多次结果差异大的任务,说明该场景不适合直接上线,得加约束或加人工复核
  4. 把成本一起记对比版本时记平均耗时和调用次数,质量涨了但耗时翻倍划不划算要看业务场景,具体口径可以到 /tools/model-cost-calculator 按当时的单价算

回归怎么做:改动一次就跑一遍

回归的核心不是「测得多全」,而是「每次改动都跑一遍同一批」。固定评测集在换模型、改提示词、调检索参数、升级依赖时都要跑,这几类改动最容易造成静默退化——功能没报错,但质量悄悄掉了,不跑回归根本发现不了。

改动类型最容易掉哪一层回归时重点看
换模型或调温度格式层、边界层结构是否仍合法、边界输入是否更飘
改提示词主路径、对抗层新增约束有没有把正常回答也约束死
调检索参数召回相关层引用是否准确、是否漏掉关键文档
升级依赖全层先跑固定集,再看哪一层出现新失败类型

给回归设门槛而不是设分数:先跑一遍现在的基线,把各项指标记下来,之后要求不低于基线的某个容忍区间,超出就拦截上线。门槛定多紧跟业务容忍度有关,面向内部工具可以松一点,面向用户直接触达的问答就要紧一些。

  • 保留版本快照:模型名、提示词版本、检索配置、评测集版本一起记,否则出了问题无法复现
  • 评测集本身也要打版本号,改过就要重新标基线,不能让新旧基线混着比
  • 回退预案要提前写好:哪几项指标跌到什么程度就回滚,谁来决定
  • 别只测不拦:很多团队不是没测,是测出问题了没人拍板回滚

跑整体回归的成本可以先量出来:用 /tools/speed-test 先测出接口延迟基线,再按用例条数估总耗时,决定是把回归挂到每次提交还是每晚跑一次。延迟数字会随网络和负载变化,具体以当时实测为准。

下一步评测标准和用例集不是一次写完就完了,第一版跑通固定集、标好基线,后面才有对比的依据;跑之前先去核对一下各家中转站和模型接口的当前状态,避免把接口波动错判成模型退化。

常见问题

没有标注团队,用例集从零开始怎么攒最快?

先把线上真实问题导出来,按问题类型聚类,每类挑十几条代表性样本,再补上业务方最怕出错的几个边界场景。第一批有个几十条就能用,关键是先跑起来、能看到版本之间的差异,再逐周往里补,不要等集齐几百条才动手。

模型判定和人工判定结果对不上怎么办?

先看是系统性偏差还是零散分歧。系统性偏差通常是裁判提示词没写清判定维度,把标准拆细重写;零散分歧就抽出来人工复核,把结论回灌到裁判的示例里。长期看要定期用人工抽检给模型判定校准,分歧率稳定在一个可接受区间才算能用。

评测集要不要随着业务变化更新?

要,但方式要分开。固定评测集只做少量替换,保证能跨版本对比;业务新场景单独开一份滚动评测集,允许频繁增删。如果全都随时改,历史分数就失去可比性,等于每次都在重开一局。

本文依据各平台公开文档与官方公告整理,只做中文归纳;具体做法、参数与限制以官方文档为准。