33 评测集:为 RAG 准备可重复的 50 个问题
评测集:为 RAG 准备可重复的 50 个问题
没有固定评测集,RAG 优化就会变成凭感觉调参数。评测集让每次修改都能和同一批问题比较。
[TOC]
1. 这一节到底解决什么问题
前面我们已经把文档上传、解析、切片、Embedding、向量入库、向量检索和基础问答串起来了。到这里,RAG 已经不再只是一个“能回答”的 demo。
从 Day30 开始,重点要慢慢转向工程质量:
答案为什么可信
错误为什么能定位
效果为什么能比较
成本为什么能估算
部署为什么能复现
项目为什么能讲清楚
你把 topK 从 5 改成 10,感觉答案更完整了。但到底是更准了,还是只是更啰嗦了?有没有让无答案问题开始胡编?这些都要靠评测集回答。
2. 先看一个业务场景
知识库里有售后政策、接口文档、报销制度。你从真实用户问题中整理 50 个样本:有简单事实题,有跨段落题,有无答案题,也有权限边界题。之后每次改 Prompt、切片、Rerank 都跑同一批题。
这个场景里,最容易出错的地方通常不是某一行代码,而是链路边界没有想清楚。
输入是什么
依赖哪份资料
中间结果怎么保存
失败时返回什么
如何证明改动有效
带着这些问题往下看,后面的设计就不会变成空泛理论。
这一节的核心不是“准备一些测试问题”,而是建立可重复比较的样本集。
判断顺序可以这样写:
1. 先确定评测集覆盖哪些真实场景:制度问答、接口问答、错误码、资料不足、同义表达
2. 每个问题都要绑定期望来源,否则只能主观判断答案好坏
3. 样本要保留难度分层,不能只放系统容易答对的问题
4. 每次优化检索、Prompt 或 Rerank 后,都用同一批样本重跑
5. 如果新增失败样本,要记录来自用户反馈、人工测试还是线上日志
它解决的是效果比较问题:没有固定评测集时,任何优化都只能靠感觉,今天觉得变好了,明天很难证明。
3. 核心概念
1. 问题分布
评测问题不能全是简单事实题。要覆盖高频、复杂、无答案、权限和容易混淆的问题。
可以把它记成一句话:题目要像真实世界。
2. 标准答案
标准答案不是逐字匹配,而是必须命中的事实点和拒答条件。
可以把它记成一句话:评事实,不评文风。
3. 来源标注
每题都要标注正确来源,至少到文档章节或 chunk。否则无法评检索和引用。
可以把它记成一句话:来源是评测的锚点。
4. 版本管理
评测集也会变化。题目、答案、来源一旦变更,就要产生版本。
可以把它记成一句话:评测集要可追溯。
4. 整体流程
graph TD;
A["收集真实问题"] --> B["分类筛选 50 个"];
B["分类筛选 50 个"] --> C["标注答案事实点"];
C["标注答案事实点"] --> D["标注来源"];
D["标注来源"] --> E["复核"];
E["复核"] --> F["冻结版本"];
F["冻结版本"] --> G["运行基线"];
图里每个节点都应该能单独打日志、单独统计耗时、单独写测试。
这就是我一直强调的:不要把 RAG 写成一个黑盒方法。黑盒方法演示时很爽,排查时很痛苦。
5. 落地步骤
1. 设计分类比例
可以先用 60% 正常问答、20% 复杂问题、10% 无答案、10% 权限安全问题。比例可调整,但不能无意识。
落地时要留下可检查的产物:评测集分类表。
2. 写事实点
标准答案拆成事实点,例如“7 天内”“未使用”“质量问题例外”。不要只写一整段参考话术。
落地时要留下可检查的产物:key_points 字段。
3. 标注来源
记录文档、章节、页码或 chunkId。后续计算 Hit@K 和引用正确率要用它。
落地时要留下可检查的产物:source_ids 字段。
4. 冻结 v1
第一版先固定下来。之后优化系统,不要边测边改题,否则结果不可比。
落地时要留下可检查的产物:evaluation_dataset_v1。
6. 数据结构或配置示例
| 项目 | 说明 |
|---|---|
| caseId | 评测问题编号 |
| category | 问题类别 |
| question | 用户问题 |
| keyPoints | 标准答案事实点 |
| sourceIds | 正确来源 |
| shouldRefuse | 是否期望拒答 |
如果项目里已经有自己的字段命名,可以不照抄这张表。但这些信息最好都能找到对应位置,否则排查问题时会缺证据。
7. 示例
case_id: RAG-001
category: 售后政策
question: 超过 7 天还能退货吗?
expected_type: 条件回答
key_points:
- 普通商品通常 7 天内
- 质量问题存在例外
source_ids:
- policy-v3:p12should_refuse: false
示例的重点不是格式,而是思路:把规则、参数、输入、输出和失败状态显式写出来。
8. 为什么不能简单粗暴地做
不能从文档原文随手抄 50 个问题。那样问题太标准,系统很容易“考高分”,但真实用户换一种问法就失败。
很多初学者会希望有一个“最简单固定答案”。但 RAG 项目里,简单粗暴通常会把问题藏起来:短期好像能跑,长期很难维护。
9. 调试和排查路径
当结果不符合预期时,建议按这个顺序排查:
1. 输入问题是否正确
2. 权限范围是否正确
3. 检索候选是否包含正确证据
4. 排序或过滤是否把正确证据丢掉
5. Prompt 是否把证据清楚交给模型
6. 模型是否按证据回答
7. 引用是否能支持结论
8. 日志、成本、耗时是否异常
不要一看到答案不对就去改 Prompt。很多时候问题根本不在 Prompt,而是在解析、切片、过滤、召回或数据版本。
10. 工程取舍
- 50 题规模不大,但足够开始形成基线。
- 真实问题最有价值,但必须脱敏。
- 标准答案要允许不同表达,重点评事实点。
- 评测集越稳定,对比越可信。
取舍要写在文档里。因为过几周再回来看,你很可能只记得“当时这么做了”,却忘了“为什么这么做”。
11. 常见坑
- 没有无答案题,系统胡编也看不出来。
- 来源只写文档名,不够定位。
- 每次优化顺手改题,结果无法比较。
- 题目都来自同一份文档,覆盖太窄。
这些坑不是为了吓人,而是为了让你知道项目坏掉时从哪里下手。
12. 验收清单
- ☐ 50 个问题已分类
- ☐ 每题有 key_points
- ☐ 每题有 source_ids
- ☐ 包含无答案和权限问题
- ☐ 评测集有版本号
验收清单是博客里很有价值的部分。它能把一篇文章从“我讲了一个概念”变成“你可以跟着做出一个结果”。
13. 面试怎么讲
可以讲:我没有只靠手动体验判断 RAG 效果,而是准备了 50 题评测集,覆盖正常、复杂、无答案和权限问题。每次改检索或 Prompt 都跑同一批题。
如果被追问,尽量用自己的项目样本回答,不要只背定义。比如:
我当时遇到的问题是……
我先用评测集确认是不是检索问题……
后来发现是……
最后我用……方式处理,指标变化是……
这样的回答比单纯说“我用了某某框架”更像真正做过项目的人。
14. 今日练习
- ☐ 整理 50 个问题
- ☐ 为每题写 key_points
- ☐ 为每题标 source_ids
- ☐ 冻结 v1 并跑一次基线
练习做完后,建议把结果截图或记录到项目文档里。后面写 README、简历和面试话术时,这些都是现成证据。
15. 小结
评测集是 RAG 优化的尺子。没有这把尺子,所有调参都只是感觉;有了它,效果提升和回退都能被看见。
到这里,你应该能把今天的主题讲成一个完整故事:为什么需要它、它解决哪一层问题、怎么落地、怎么验证、有什么代价。