☰
模型输出不确定?AI应用测试实战:从评估集到回归体系
2026/9/28 14:27:33 网站建设 项目流程

模型输出不确定,AI 应用到底怎么测试?一份 QA 实践笔记

如果你接手过 AI 应用的测试工作,大概率经历过这样的场景:同一个问题,上午跑通了一条链路,下午再跑一次,模型的回答换了措辞,甚至核心结论都变了。你拿着传统软件测试的思维去提 bug,开发一脸无奈地说“这是模型行为,不是 bug”。你追问那到底怎么才算对,开发给你一句“语义上对就行”。那一刻,你大概会感觉到,过去积累的用例设计、断言方法、回归策略,在一夜之间全都不太够用了。

这篇笔记不是教科书,是我在一家中小型自研公司做 AI 应用 QA 大半年踩坑攒下来的实践总结。内容聚焦一个核心问题:当模型输出不确定,AI 应用到底应该怎么测。会讲到测试思路的转变、评估集怎么建、评测维度怎么定、工具链怎么选,以及一套从零搭起来的可落地方案。适合正在做 AI 应用测试的 QA、刚转岗做 AI 评测的研发,以及所有被“模型输出飘忽不定”折磨过的技术人。

1. 先想明白:AI 应用的测试,为什么不能照搬传统 QA

1.1 传统测试的确定性假设,在模型输出面前全盘失效

传统软件测试有一套很成熟的体系:需求分析、用例设计、断言验证、回归执行。这套体系的底层逻辑建立在三个确定性假设之上:

  • 输入可枚举:我可以把合法输入、非法输入、边界输入都列举出来。
  • 输出可预期:给定输入,我知道正确输出应该是什么,哪怕是一个范围。
  • 行为可重复:同一条用例,无论跑多少遍,只要代码没变,结果就不变。

这三个假设在传统功能测试里天经地义,但到了 AI 应用里全部失效。模型输出的不是固定值,而是一个概率分布上的采样结果。你问“帮我总结这段合同的风险”,第一次它列出三点,第二次变成四点,第三次可能把第二条换了个说法。你没法拿一个固定的“期望结果”去做字符串比对,也没法断言“必须包含某句话”,因为模型换个表达方式,语义可能完全一致,但字面上能差出十万八千里。

这不是说 AI 应用没法测,而是说测试的对象变了。我们不再测试“这个函数返回什么”,而是测试“这个模型+提示词+参数配置组成的系统,在多大比例下能产出可接受的结果”。测试的中心从“验证实现是否正确”变成了“评测质量是否达标”,从一次性的通过/不通过,变成了概率意义上的质量评估。

1.2 从“是否符合预期”到“是否在质量边界内”的思路转换

我在团队里推行这套思路的时候,反复给大家打的一个比方是:传统测试像是在用游标卡尺量螺丝,要求每个尺寸精确到小数点后两位,超差就是不合格品;AI 测试更像是在做食品质检,你没法保证每包薯片里的盐粒分布一模一样,但你可以定标准——盐度必须在某个区间内,不合格率不能超过某个比例,消费者吃到的整体体验要稳定。

所以,AI 应用测试的第一件事,不是写用例,而是定义质量边界。什么叫可接受?什么叫不可接受?边界划在哪里?

拿我们做的智能客服知识库问答系统举例。用户问“我们的年假政策是什么”,系统回答时遗漏了“入职满一年才享有年假”这个前提条件,这算不算 bug?如果按功能测试思路,这当然算,但你怎么断言一个模型的输出有没有覆盖某个前提?这提示了第一条认知变化:AI 测试里的“正确”不是一个点,而是一个集合,一个由语义等价、信息完整、立场安全、格式合规等多个维度共同框定的区域。QA 的工作,从“写断言”变成“定义边界+建立衡量边界的方法”。

这个思路转换不只是在测试人员脑子里发生,还得让开发、产品、业务方共同认账。我在项目启动时最常做的一件事,就是拉着业务负责人一起对“质量红线”达成书面共识——哪些错误是绝对不能容忍的,哪些偏差是可以接受的,哪些场景必须 100% 覆盖。这群人是你后续所有测试判断的立法机构,没有他们点头,你的评测标准就是空中楼阁。

2. 测试策略怎么搭:评估集、评测维度与回归基线

2.1 评估集:没有评估集,谈 AI 测试就是耍流氓

如果说传统测试的根基是“测试用例库”,那 AI 测试的根基就是“评估集”。所谓评估集,就是一组“输入+期望行为描述”的集合,用来反复检验模型输出质量的基准数据。评估集不是一次性用的,它是 AI 应用测试的锚点,每次迭代都要拿同一批问题去跑,对比前后质量变化。

我在项目里把评估集分成三层来建设,每层服务的测试目的不同:

  • 第一层:核心冒烟集(50~100 条)。覆盖产品最核心的用户路径,比如客服问答的“热门问题 Top 30”、文档助手的“高频检索场景”。这一层要保证把主链路跑通,每次改动提示词、调整模型参数后先跑它,就像传统测试里的冒烟测试。我有一个习惯:冒烟集里的问题必须包含一部分“简单直给”的问题,它们是为了快速暴露结构性故障用的。

  • 第二层:回归集(300~500 条)。按业务场景、问题类型、输入形态分层设计,目的是监测模型迭代、提示词调整后有没有引入“回归”。比如客服问答里既有“政策咨询类”,也有“投诉处理类”,还有“闲聊兜底类”,每一类都要有足够的样本。

  • 第三层:全量评估集(1000 条以上)。用于发布前的全面质量评估,通常还会配上比较完整的期望行为打分标准。全量评估集的建设成本和标注成本都高,但它是做模型选型、提示词版本对比时最有力的底牌。

这里要特别提醒一个新手容易犯的错:评估集不等于网上随便找一些问答对。合格的评估集必须和你的业务深度绑定,每条 case 都得能追溯到真实用户场景。我建评估集的第一批数据,就是直接从客服聊天记录里捞出来的脱敏真实问题,而不是产品经理拍脑袋编的。

2.2 评测维度怎么定:正确性之外,还要看这六件事

有了评估集,接下来要定义“怎么算好”。AI 应用的质量维度比传统功能测试复杂得多,单看“答案对不对”远远不够。我在实践中沉淀出一套六维评估框架,每个维度都会在实际评测脚本中单独打分:

维度说明典型问题示例
答案正确性核心事实、结论是否正确完整政策条款引用错误、关键前提缺失
指令遵循度是否按提示词要求的形式、长度、语气输出要求 JSON 却输出 Markdown
格式合法性结构化输出是否严格符合既定 schemaJSON 字段缺失、枚举值非法
安全合规是否包含不当言论、幻觉捏造、越权建议医疗建议编造、侮辱性表达
信息完整性用户问题的所有子问题是否都被覆盖多条件问题只回答了其中一个
语气与可读性表达是否自然、友好、符合产品调性回答生硬、口语化过度

这六个维度的权重不是平均分配的,应该由业务风险等级决定。比如医疗问诊类应用,安全合规和答案正确性必须拉到最高权重;闲聊陪伴类应用,可读性和安全合规更重要,正确性反而相对宽松。

实操上,我给每个维度设计了 1~5 分的打分卡。拿“信息完整性”来说,5 分代表问题中所有约束条件、隐含的子问题全部覆盖,3 分代表主要问题回答了但遗漏次要点,1 分代表只抓了表面关键词、漏掉了核心意图。打分卡越具体,后面的量化评估越可靠——这一点千万别偷懒,模糊的打分标准会直接导致不同的评估员给出完全不同的分数,最终数据没法用。

2.3 回归策略:AI 应用也有“bug 回归”,只是方式不同

传统软件里,开发改了一行代码可能影响十个功能,所以需要回归测试。AI 应用里存在同样的风险,而且更容易被忽视。你调了一下提示词想让回答更简洁,结果发现所有已购商品类的回答都把赠品信息省略了,这就是一种经典的提示词回归。

AI 应用回归策略要分级,不能所有变更都跑全量。我采用的三级回归方案是:

  1. 改提示词:跑核心冒烟集,必要时加跑受影响场景的回归子集。提示词改动是最高频的变更,必须用最短的路径快速验证。
  2. 改模型参数(温度、top_p、max_tokens 等):跑完整回归集,因为参数对输出的影响是全局性的,可能悄悄改变所有场景的回复风格。
  3. 换模型或升级模型版本:跑全量评估集,并且要做对比。同一波评估集,旧模型全局跑一遍,新模型全局跑一遍,计算每个维度的分数差异,再决定是否切换。

这套分级回归执行了一段时间,帮我抓到一个特别隐蔽的回归:有一次我们只是调整了系统提示词里的“请使用礼貌用语”,结果连带所有中文回复都多了一句“如需进一步帮助,请随时联系”,用户体感很差。如果只跑一条最简单的冒烟用例,这个问题根本不会暴露;但回归集里包含“如何修改收货地址”这类流程指引型问题,很快就把“多话啰嗦”的漂移暴露出来了。

3. 工具链怎么选:自动化测试框架与 AI 评测的配合

3.1 传统自动化测试框架还能不能用

先说结论:能用,而且要大胆用。我们在 AI 应用测试里最常用的自动化工具仍然是 pytest,搭配 requests/OpenAI SDK 直接调用模型接口,本质上和测试一个 HTTP API 没有区别。

你完全可以用 pytest 搭一套 AI 评估的骨架:一个测试函数对应一批评估 case,通过参数化把评估集里的每一道题喂给模型接口,拿到模型返回结果后,再把它传给评估函数打分,最后生成报表。这个流程里真正需要重新设计的不是测试框架,而是“断言”这一步——传统断言是 assert result == expected,AI 测试的断言变成了“对模型输出做质量评估然后与阈值比对”。

实际工程里我建议这样组织代码结构:评估集数据独立存放(JSON/CSV),测试代码只负责调度和打分,评测标准单独抽成一个函数模块。这样数据、逻辑、标准三层分离,后续任何一层变更都不用动另外两层,是我踩过代码硬耦合的坑之后总结出来的经验。

3.2 让大模型当裁判:LLM-as-a-judge 的实战用法

评估模型输出最常见的两种路子:一种是算文本相似度(BLEU、ROUGE、语义向量余弦相似度),另一种是让一个更强的大模型来当裁判,也就是 LLM-as-a-judge。

文本相似度对“意思对了但说法不同”这类情况非常不友好。我曾经用 ROUGE 评估两个都算正确的回答,一个简洁一个详尽,得分差异巨大,但人工评定其实都是合格。所以我的建议是:不要把文本相似度作为主要评判手段,它更适合做粗筛,不适合做最终质量裁决。

LLM-as-a-judge 是目前更可靠也更好用的方案。做法是写一个评分提示词,把用户问题、模型回答、评分标准(就是我们前面定的打分卡)一起发给裁判模型,让它按 1~5 分打分,并输出简要理由。核心实践经验有三条:

  • 裁判模型要比被测模型强,否则裁判根本看不出细微错误。我们被测模型用 7B 级别开源模型,裁判模型选用更强的商用模型,效果差距非常明显。
  • 评分标准必须显式写进提示词,不能只写“请评价质量”五个字。我的评分提示词里会把每个维度的行为锚点明明白白列出来,比如“当回答遗漏了问题里明确包含的时间条件,完整性评分不得超过 3 分”。
  • 对裁判结果保持怀疑,辅以规则校验。裁判模型本身也是模型,也可能出错。我通常在裁判打分之外,再加一套硬规则兜底:比如“回答中出现安全词表则直接判定失败”“JSON 解析失败直接判定格式维度 0 分”。这样模型的主观判断和规则的客观校验结合,结果才可信。

3.3 确定性校验:不该变的地方必须锁死

AI 应用很玄学,但不是处处玄学。应用里其实有很多确定性部分,这些地方必须用传统测试的严格断言来锁死,不能惯着。

以我们的客服问答系统为例,整条链路分三段:检索召回、上下文组装、模型生成。第三段是概率性的,但前两段完全可以做成确定性校验——召回是否命中正确的知识库文档、组装后的上下文是否包含用户问题的必要限定条件,这些都是可以硬断言的。

另外一个确定性大阵地是结构化输出。现在很多 AI 应用要求模型输出 JSON,让下游系统解析。JSON 的合法性、字段完整性、枚举值范围这些完全可以用 JSON Schema 做严格校验,不需要模糊打分。

我始终强调一句话:AI 应用测试的最高境界,是明确知道哪些地方要“放过模型一马”,哪些地方要“跟模型死磕到底”。把确定性命门锁死,把概率性空间管住,测试的稳定性和可信度都上来了。

4. 从零搭一套 AI 应用 QA 体系的实操记录

4.1 先定需求与红线:把“质量”翻译成可执行指标

这里用我实际做的项目当例子:一个企业内部知识库问答助手,员工可以问休假政策、报销流程、组织架构等,模型基于向量检索到的文档片段生成回答。

项目启动第一周,我没急着写测试代码,而是拉着业务方和研发把质量要求聊透,最后落到一张纸上:

  • 红线场景(任一触发即判测试失败):涉及“医疗建议”“法律结论”“贬损他人”“绝对化承诺”的回答;引用不存在的文档或政策条款;输出内容偏离问题主题知识库范围。
  • 质量指标(核心场景通过率):核心冒烟集 50 条测试,要求回答完整率不低于 90%,格式合法率 100%,安全合规 100% 无违例。
  • 可接受的表现波动:同一问题多次回答,核心信息点覆盖率允许 20% 以内的浮动,但关键限定条件(如时间、资格、金额)缺失率不得超过 5%。

这些数字不是拍脑袋定的,而是先跑了 200 条真实问题的人工评测后,以人工合格率为参考倒推出来的。没有基线数据就定指标,后面一定会被不现实的指标反复折磨。

4.2 评估集建设:从真实日志里捞,分三批落地

第一批评分量最大的还是真实数据。我从客服聊天记录里筛了 300 条脱敏问题,覆盖高频问题、长尾问题、误导性提问、多条件复合问题四类。为保证场景均衡,我按“高频问题 40%+边缘情况 30%+困难问题 30%”的比例人工调平。

第二批评分针对已知短板补齐边界。比如我发现系统对“报销时限是多久”这类直接问政策的问题表现不错,但对“我上个月底提交的报销为什么还没到账”这种混合了流程状态的问题经常答非所问。所以专门补充了一批“复合意图”问题进回归集。

第三批是通过线上日志持续回流。系统上线后,生产环境里的真实提问会成为评估集的新鲜血液。我每个双周从日志里抽 20 条未覆盖类型的问题人工 demo 确认后补入回归集,让评估集保持对真实环境的敏感度。

4.3 评测脚本与 CI 接入:让回归每天自动跑

工具链我选了 pytest + 一套自研的评估 runner。核心代码如下所示,逻辑不复杂:读评估集、调模型、并发评分开写、汇总出报告。

import pytest import json from concurrent.futures import ThreadPoolExecutor # 评估集文件结构: [{ "id": "case001", "question": "...", "expect": "...", "tags": ["policy"] }] TEST_SET = json.load(open("eval_sets/core_smoke.json")) PASS_RATE_THRESHOLD = 0.9 # 核心场景通过率红线 def call_model(question): # 调用被测应用的统一接口,拼接 prompt、请求模型、返回文本 return client.chat(question) def judge(question, answer): # 分两条线:硬规则校验 + LLM 裁判打分 rule_result = run_hard_rules(answer) llm_score = run_llm_judge(question, answer) return rule_result and llm_score >= 4 @pytest.mark.parametrize("case", TEST_SET, ids=lambda c: c["id"]) def test_core_case(case): answer = call_model(case["question"]) assert judge(case["question"], answer), f"case {case['id']} failed"

CI 接入做的是一套双阶段流水线:每次代码合并前,跑核心冒烟集 50 条,速度控制在 5 分钟内;每天凌晨全量跑回归集 400 条,自动生成质量报告并推送群里。这里有个教训:一开始我把全量回归挂在了每次合并前,结果一次模型接口抖动导致所有提交都红灯,大家怨声载道。后来改成“核心集卡合并,回归集跑定时”,节奏才理顺。

4.4 线上监控补位:LLM 输出不能被放养

测试环境做得再充分,也无法完全模拟生产环境的输入分布。所以我额外加了一层线上监控,核心就两件事:

一是抽检。按 5% 比例采样生产环境的问答记录,先用规则过滤明显异常(超时、拒答、空回复、格式乱码),再抽取一部分送去做人工抽检打分。抽检结果每两周汇总一次,进入质量周报。

二是用户反馈闭环。产品里加了“回答是否满意”的点赞点踩按钮,点踩的数据自动进入待评审队列。我每周处理一次,点踩较高的回答当作新的评估集候选,防止线上持续产生同类问题而我们毫不知情。

这套体系跑下来,真实效果很直接:上线首月,人工抽检的核心场景通过率稳定在 95% 左右;提示词调整引发的回归被 CI 抓到 3 次;线下的严重事实性错误从每周 4~5 个下降到 1 个以内。

5. 常见问题与排查技巧实录

5.1 高频问题速查表

问题现象可能原因排查方法解决建议
同一用例跑两次,一次过一次挂模型温度过高 / 上下文随机扰动 / 裁判打分波动固定随机种子或降低温度;同一 case 跑 3 次取多数结果关键判断场景温度下调到 0.2 以下
核心集全过,线上却出同类问题评估集与真实分布脱节对比线上日志提问风格与评估集差异定期从真实日志回流新 case 进评估集
改了个小提示词,大批用例变差提示词改动影响了全局指令遵循对比改动前后的回归集逐 case 分维度差异用分级回归,先跑受影响场景子集
LLM 裁判给分忽高忽低评分标准模糊 / 裁判模型太弱看裁判输出理由,检查打分锚点是否含糊细化打分卡,换更强的裁判模型
JSON 输出时而合法时不合法模型对复杂 schema 遵循能力不足检查失败 case 的错误字段分布加解析失败自动重试,配合 few-shot 示例
全量回归一次要跑两小时评估集太大且串行执行分析耗时分布,看模型调用占多少并行化改造,按场景分配执行

5.2 独家避坑经验:三个容易犯的严重错误

最后一个大坑,我从自己团队和同行交流里提炼了三点,希望能帮大家少交点学费。

第一,不要用模型自带的 logprobs 来充当置信度。我一开始以为拿到模型每个 token 的概率,就能断言“这回答是不是瞎编的”,实际测下来效果很一般。模型给出低概率 token 并不等于错误,很多创造性表达本来就在概率尾端;反过来高概率输出也可能是训练数据里的陈词滥调。置信度判断只适合做信息熵统计,不适合当正确性判断。

第二,不要迷信 BLEU 和 ROUGE 这类文本重合指标。它们适合做机器翻译、摘要这类对原文强依赖的任务,但开放问答里同样的语义可以有无数种表达,重合度低不代表错。我见过一个团队用 ROUGE 做门禁,导致开发为了刷分不停把模型输出改得和参考答案越来越像,最后可读性差到用户投诉。

第三,评估集不是只增不改的“死库”。数据分布漂移是常态:某个政策半年后更新了、某个热门话题不再热了,评估集里的“正确答案”过时了,如果不主动清理和更新,评估集本身就会变成测试质量的污染源。我每个月固定做一次评估集体检,标记过时 case、修正期望行为、淘汰无效题目,让评估集和业务一起“活着”。

我个人做完这套体系最深的体会是:AI 应用测试本质上不是在“测一个产品”,而是在“测一个不断变化的系统”——模型在变、提示词在变、数据分布在变,所以测试方法和评估数据也得跟着变。与其追求一套一劳永逸的完美方案,不如把一个能持续演进的 QA 闭环搭起来,然后让它和产品一起迭代。这也是这份实践笔记最想传递的东西。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询