RAG 评估不是大厂专利。10 条手工标注的测试查询,两个指标(Hit Rate + MRR),30 分钟就能建立你的检索质量基线。
先有基线,再谈优化
「我的 RAG 效果好不好?」——这个问题的答案不能凭感觉。
你需要一个数字——改了分块大小后命中率变了吗?加了 BM25 后 MRR 涨了多少?没数据就没决策依据。
RAG 评估的最小可行方案:
- 准备 10-50 条测试查询
- 每条查询标注一个「必须出现在检索结果中」的关键词
- 跑检索 → 检查关键词是否命中 → 计算指标
- 改参数 → 再跑 → 对比
两个核心指标
Hit Rate(命中率)
Top-K 结果中,有多少查询至少命中了一个正确答案?
Hit Rate = 命中的查询数 / 总查询数
例:10 条查询,8 条的 Top-3 结果中包含正确答案 → Hit Rate = 80%
Hit Rate 告诉你「检索能不能找到答案」。 这是最基础的指标——搜不到答案,后面 LLM 再强也没用。
MRR(Mean Reciprocal Rank)
正确答案出现在第几位?排名越靠前,分数越高。
MRR = (1/第一个正确答案的排名) 的平均值
例:
查询1:正确答案在第1位 → 1/1 = 1.0
查询2:正确答案在第3位 → 1/3 = 0.33
查询3:没找到正确答案 → 0
MRR = (1.0 + 0.33 + 0) / 3 = 0.44
MRR 告诉你「检索结果好不好用」。 答案在第 1 位比在第 5 位好得多——LLM 看 Top-3 结果,第 5 位意味着根本不会被喂给 LLM。
我的评估实现
在 RagEvaluator 中实现了完整的评估管线:
// 10 条测试查询 + 预期关键词
Map<String, String> testQueries = Map.of(
"轴承温度过高是什么原因?", "润滑",
"电机振动超标怎么排查?", "振动",
"传感器信号漂移怎么处理?", "漂移",
// ... 共 10 条
);
// 分别测三种策略
var results = ragEvaluator.evaluate(testQueries, knowledgeBase);
评估的方式很简单:检索 Top-10 → 检查预期关键词是否出现 → 记录排名 → 计算指标。
不需要人工给每条查询打 1-5 分,不需要标注「这篇文档有多相关」。只需要判断「要找的东西找到了没有」——二进制判断,零歧义。
为什么 10 条查询就够?
因为你要的不是统计显著性,是方向感。
大厂跑 10000 条查询是为了 0.1% 的精度变化。你做 RAG 调优,需要的是判断「分块 500 好还是 1000 好」「加 BM25 有没有提升」——10 条查询足够给你明确的方向。
我定了一个简单的质量门槛:
| Hit Rate | 判断 |
|---|---|
| < 60% | 检索管线有问题——检查分块、Embedding 模型 |
| 60-80% | 基本可用——加混合检索或 Query Rewriting |
| 80-95% | 生产就绪——继续优化分块和提示词 |
| > 95% | 评估数据可能太简单了 |
命令行一站式评估
# 摄入知识库后,一键跑评估
curl -X POST http://localhost:8080/api/rag/evaluate
# 返回:
# {
# "totalQueries": 10,
# "DENSE_hitRate": "60.0%", "DENSE_MRR": "0.420",
# "BM25_hitRate": "70.0%", "BM25_MRR": "0.480",
# "FUSED_hitRate": "90.0%", "FUSED_MRR": "0.680"
# }
三个策略的对比一目了然——Dense 不够用,加 BM25 到 70%,RRF 融合到 90%。
下一步
有了评估管线,优化就有方向了:
- Hit Rate 低 → 换 Embedding 模型或加分块实验
- MRR 低 → 加重排序(Cross-Encoder 或 LLM Rerank)
- 特定查询一直失败 → 人工看是问题用词还是文档缺失
改进建议:每次改 RAG 管线前跑一次评估,记下数字。一个月后回头看,你会有一个完整的「检索质量演进日志」。
一句话总结
RAG 评估不需要大数据,需要的是规范。10 条查询 + Hit Rate + MRR,30 分钟建立基线,之后的每一次优化才有据可依。没有基线的优化是盲调,有基线的优化是工程。
代码仓库:github.com/LaoLiang-agent/industrial-agent-long
本文由 LaoLiang 原创,首发于掘金/知乎/微信公众号。转载请联系作者。