>_ AI 应用训练营
lang ~ ai-course/12-testing-and-iteration 7 min read

12 · 测试与迭代

十题测试法、三层打分、Recall@k 与 MRR 量化指标

"对于AI产品来说,上线是刚刚开始"——这句话是这一章的核心精神。前面几章跑通了流程,这一章开始才是真正决定项目质量的部分。

12.1 十道标准测试题

导购类(4题):
1. 有什么鱼推荐吗
2. 鲈鱼多少钱一条
3. 有没有新鲜的虾
4. 想买点水果,有什么推荐

知识类(4题):
5. 鲈鱼怎么做好吃
6. 榴莲怎么看好坏
7. 草莓怎么保存
8. 鸡蛋怎么判断新不新鲜

模糊类(2题):
9. 家里有条鲈鱼,怎么做,你们还有卖吗
10. 想吃榴莲但怕挑到不好的,有推荐的吗

12.2 三层打分标准

硬错误:回答了错误信息(比如推荐了不存在的商品,说错价格)—— 最严重,优先修
软错误:方向对但不精准(比如脑补了用户没提过的情境,检索范围过宽带出无关内容)
体验问题:内容准确但表达生硬(比如机械的复述式开头)—— 优先级较低但影响体验

12.3 第一轮测试结果(真实记录)

题号 问题 评分 主要问题
1 有什么鱼推荐吗 5/5
2 鲈鱼多少钱一条 5/5
3 有没有新鲜的虾 4/5 检索范围偏大,多推荐了不相关商品
4 想买点水果,有什么推荐 3/5 脑补了用户没说的情境("怕胖"),只推单一商品
5 鲈鱼怎么做好吃 4/5 "你是想问...吧"复述式开头,显得生硬
6 榴莲怎么看好坏 4/5 同上,且回答语气像在回应"我的有酒精味"这个具体场景
7 草莓怎么保存 4/5 同样的复述式开头问题
8 鸡蛋怎么判断新不新鲜 4/5 同样的复述式开头问题
9 家里有条鲈鱼,怎么做,你们还有卖吗(模糊) 5/5 无(首次测试即通过)
10 想吃榴莲但怕挑到不好的,有推荐的吗(模糊) 5/5 无(首次测试即通过)

发现的系统性问题: 5-8题全部出现同样的"你是想问...吧"复述式开头,说明这不是偶发问题,是Prompt设计层面缺少对表达方式的约束。

12.4 用量化指标看得更准:Recall@k 和 MRR

为什么三层打分法不够: 上面的评分打的是"这道题回答好不好"这个终态结果的分——但如果一道题答错了,你不知道是"检索根本没找到对的资料"(检索的锅),还是"找到了但AI没用好、语气不对"(生成的锅)。这两种问题的修复方法完全不同:前者要去改知识库数据或检索配置(第5章/第6章),后者要去改Prompt(第11章)。混在一起打一个总分,容易定位错方向、改错地方。

解法:先给检索单独打分,用两把量化的尺子。

Recall@k(召回率):正确的那条知识库数据,
    有没有出现在检索结果的前k条里——看的是"该找的找到没有"

MRR(平均倒数排名):正确的那条数据排第几
    (排第1得1分,第2得0.5分,没召回得0分),
    再对所有题取平均——看的是"找到了,但排得够不够靠前"

一个看"全不全",一个看"靠不靠前",两个一起,检索质量就不再是"感觉准不准",而是一个能反复对比的客观数字。

怎么算(不用写代码,目前用已有的"召回测试"功能就够)

  1. 给10道测试题,每道先标好"标准答案应该来自知识库的哪一条数据"(比如第2题"鲈鱼多少钱一条",标准答案就是商品知识库里"鲈鱼"那一行)

  2. 第5章讲过的「召回测试」功能,把每道题的问题输进去,看检索返回的前3条(Top K=3)里,有没有包含你标好的那条"标准答案",如果有,排第几

  3. 按公式手算:

    Recall@3 = 命中的题数 ÷ 总题数
    
    MRR = 每道题的(1/排名,没命中记0)加起来 ÷ 总题数
    

示范算一遍(数字是教学示范,不是你们的真实检索结果,实测请以自己跑出来的为准):

假设10道题里,8道题的正确数据排在检索结果第1位,
1道题排在第2位,1道题完全没检索到——

Recall@3 = 9 ÷ 10 = 0.9(10道里9道在前3条内找到了)

MRR = (8×1 + 1×0.5 + 1×0) ÷ 10 = 8.5 ÷ 10 = 0.85

换一套切分/检索方案(比如把向量检索换成混合检索),再拿这同一批题跑一遍,两组数字一对比,到底哪个方案更好就不再是"感觉",是数据说话。

诊断思路:回答不好,先看Recall,这是含金量最高的一条

Recall本身就低(该找的没找到)
    → 问题在检索/切片这一端,生成再强也白搭
      (呼应第5章那条铁律:"召回率是上限",
      正确chunk没进候选池,后面所有优化都救不回来)

Recall很高(该找的都找到了),但最终回答还是不好
    → 问题不在检索,出在生成这一端(Prompt或模型),
      该去优化第11章那套Prompt设计

这个诊断思路的价值在于:把"回答不好"这一个笼统的问题,拆成了"检索的锅"还是"生成的锅"两个可以分别定位、分别修复的方向——不分段看,你连该往哪使劲都不知道,只能瞎改一通碰运气。

离线评估 vs 线上指标(了解即可,教学项目暂不需要)

离线评估:用固定的测试题集在本地反复跑,算Recall/MRR——
    上线前用来对比不同方案、反复优化

线上指标:系统真跑起来之后盯的——响应延迟(P95/P99)、
    QPS吞吐、用户满意度——上线后用来监控不出事,
    企业级、真实上线的项目才需要盯这个,教学项目用不上

评估五维度(企业级视角,光看"答得对"通常不够)

① 召回/准确(检索段):检索用Recall@k、MRR;生成用BLEU、ROUGE对比参考答案
② 可信度(生成段):答案里有几成内容能在检索到的原文里找到依据(覆盖率)
③ 响应速度:平均延迟,以及P95/P99尾延迟(95%、99%的请求多久内返回)
④ 可扩展性:数据涨到百万级、并发上来后,QPS还扛不扛得住
⑤ 用户体验(生成段):人工满意度评分、答案可读性

教学项目重点关注①(召回/准确),这也是Recall@k和MRR要解决的;②-⑤属于企业级上线才需要认真考量的维度,先知道有这几个视角,不用现在就都做到。

面试怎么用

"你怎么评估你的RAG系统效果?"
    → 不要只说"我人工测了10道题、打了个分",
      可以说"我除了人工打分,还标注了每道题的标准答案chunk,
      算了Recall@k和MRR两个量化指标,
      能分开定位是检索问题还是生成问题"
      ——比只会说"感觉还不错"更有说服力

"MRR是什么?"
    → 直接能答出定义和公式,是这一块最基础的面试题

12.5 三个案例简述(完整版见附录C)

前面十道测试题跑完,实际迭代优化时留下了三个很有代表性的案例,完整的排查过程、原始记录(包括一次模型<think>思考过程的完整还原)放进了附录C,这里只留结论:

案例一·复述式开头:知识类回答统一以"你是想问...吧"开头,显得生硬
    → 修复:Prompt里加一条"不要用复述句开头,直接回答"
    → 结果:相关题目从4/5统一提升到5/5

案例二·数据切片粒度问题:知识库把"通用问法"和"具体场景问法"
    混在同一条数据里,导致答非所问
    → 第一次只加新数据没改旧数据,没修好;
      第二次同步修正旧数据才真正解决
    → 核心方法论:数据治理不是"加数据",必须同步"改"和"清理"

案例三·幻觉解剖:知识库忘记"启用",检索返回空,AI没有说"不知道",
    而是编了一段以假乱真的回答,还原了它`<think>`过程的完整心理活动
    → 揭示幻觉不是能力不足,是"宁可编也不说不知道"的行为倾向
    → 修复:Prompt约束要同时覆盖"检索结果为空"和"检索结果不相关"
      两种情况,之前只覆盖了后者

这三个案例都很适合直接用在带教和面试里,完整版看附录C

12.6 多轮对话测试:验证Query改写节点

前面十题都是单轮问答,测不出第7章新加的Query改写节点有没有真的起作用——这个节点解决的恰恰是多轮对话里的省略/指代问题,需要专门补一组多轮测试。

第一轮:想买点水果,有什么推荐
      → 期望:AI推荐车厘子和凤梨

第二轮(追问,带省略):有货吗
      → 打开Dify预览测试里"Query改写"节点的运行详情,
        检查它这一步实际输出了什么
      → 期望输出:"车厘子和凤梨有货吗"这样补全后的完整问题
      → 最终回答应该基于车厘子/凤梨的真实信息作答,
        不能答非所问变成推荐草莓(这是没做Query改写时的真实反面案例)

如果测试结果不对,按这个顺序排查:

1、先看"Query改写"节点的输出——如果输出还是"有货吗"三个字没有变化,
   说明对话历史没有正确传进这个节点,回去检查节点的"对话历史"选项有没有打开

2、如果"Query改写"节点输出正确(已经补全成完整问题),
   但后面检索/生成回答还是答非所问,说明是下游节点的变量引用漏改了,
   回去检查[第8章](08-intent-classification-node.html)、[第10章](10-knowledge-retrieval-node.html)、
   [第11章](11-generation-and-output-node.html)里是不是还有地方引用的是
   `{{#开始.query#}}`而不是`{{#Query改写.text#}}`

这组多轮测试建议作为标准测试题之外的补充项,每次改动Query改写节点的Prompt之后,都单独跑一遍这两轮对话验证效果。

12.7 测试记录表格模板

题号 问题 回答摘要 硬错误 软错误 体验问题 评分(1-5)
1
2
...

12.8 这个项目现在具备的完整能力

✓ Query改写节点,能处理多轮对话里的省略/指代问题
✓ 三层意图分流架构(导购/知识/模糊),三条分支独立运作
✓ 双知识库协同检索(商品+生活),模糊类问题能同时调用
✓ 完整的数据治理经验:切片粒度问题的发现与修复
✓ 完整的工程排障经验:403权限错误、条件分支逻辑错误、
  变量引用方式错误等多类真实问题的定位与解决
✓ 系统性测试方法:10题批量测试+三层打分法+Recall@k/MRR量化指标+多轮对话测试+对比分析
✓ 两轮真实的迭代优化案例,且第二个案例包含"第一次没做对"的完整过程

至此,从第3章到本章,完整跑通了一个RAG项目最核心的闭环。这套主干之外,完整的企业级系统还差什么、这段经历在面试里怎么讲,可以参考附录B