怎么测试rag系统答得准不准

接入与开发

讲清怎么给 RAG 系统做准确性评测:怎么造题、怎么判对错、怎么在小样本上跑出可复现的结论。

很多人第一次接 RAG,Demo 里问两句觉得挺准,上线后用户一问就发现答偏、答漏、答得没出处。问题不在模型,在于从来没人定义过「答对」到底长什么样。这篇给测试和开发者一套能落地的评测做法:从哪凑题、判分怎么定、跑多少条够看、结果怎么记录才可复现。

很多人第一次接 RAG,Demo 里问两句觉得挺准,上线后用户一问就发现答偏、答漏、答得没出处。第一反应往往是「是不是向量模型选错了」,其实多数时候问题不在模型,在于从来没人定义过「答对」到底长什么样。没有判定口径,改动就只能靠感觉,改完变好变坏都说不清。

这篇给测试和开发者一套能落地的评测做法:从哪凑题、判分怎么定、跑多少条够看、结果怎么记录才可复现。适合刚接手 RAG 项目、要向上汇报效果、或者准备做回归测试的人;如果你连知识库都还没切分好、文档还在收集中,那先把数据准备做完再来看评测,否则结论没有参考价值。

先定义什么叫「答对」,别急着跑

把「答对」当成一个黑盒判断,是评测里最先踩的坑。一条回答不准,可能是压根没检索到该用的片段,可能是检索到了但模型没用上,也可能是用上了却理解错了。三种表现的修法完全不同,所以判定必须分层,不能只给一个总分。

检索层
给的上下文片段里,有没有包含能推出标准答案的那一段
利用层
模型生成的回答,是不是真的依据了这些片段,而不是自己编
表达层
依据对了,最终说出来的结论有没有说反、说漏条件、丢关键限定

判法要事先写死。常见三种:关键词命中判、拿标准答案做语义比对判、人工逐条看。同一批改动,用关键词判可能是进步,用语义判可能是退步,因为模型换了个说法但没答到点上。选定一种口径后,中间不要临时更换。

还要给「不适用」留出口。问题本身超出知识库范围时,正确行为是明确说不知道,而不是硬答。这类题必须单独成组统计,否则模型学会了瞎编,反而在总体得分上更占便宜。判断标准很简单:标准答案里写「知识库未覆盖」的题,模型给了肯定结论就算错。

评测题从哪来:三份清单凑出第一批用例

出题是最费时间也最容易被跳过的一步。第一批题不用多,但来源要覆盖真实分布,否则测出来的是「你会出的题」而不是「用户会问的题」。下面三类来源各出一批,混在一起跑。

  • 从真实日志里抽:把线上问过的问题按主题聚类,每类抽几条,最贴近真实分布;没有线上数据就找业务同事要他们平时最常问的十来个问题
  • 从文档里反向造:每篇核心文档手动出几条只有读了这篇才答得出的问题,专门暴露检索漏召回;再故意问几个需要跨两篇文档才能答的问题
  • 造对抗题:近义改写、口语化提问、故意带错前提的提问各来几条,这些在日常对话里很常见,却是分块和召回策略最容易翻车的地方
  • 单独留一组超纲题:问知识库里根本没有的内容,看模型会不会老实说不知道
题目类型主要暴露的问题什么情况下不适用
日志聚类题整体召回率与高频场景覆盖日志量太少时聚类没意义,直接人工挑
文档反推题检索漏召回、分块切断了答案文档本身结构混乱时先去整理文档
对抗改写题同义表达能力、口语化提问的召回产品只有固定表单式提问时优先级可以降低
超纲拒答题模型硬答、幻觉倾向知识库本身在持续变化时,标准答案要定期更新

数量上,第一批每个类别几条就够定位问题。题目数量再多,只要判分口径不统一,跑出来的也是一堆没法解释的数字。想了解社区里不同实现方案的差异,可以到 /tools/speed-test 对照着看,但别把工具结果直接当成你自己的评测结论。

跑评测时把检索和生成分开看

一起跑「端到端」,只能得到一个对错结果,无法告诉你是哪一环坏了。正确做法是拆成两段独立测,各自有明确的输入输出,再交叉比对。

  1. 先只测检索给定问题,看返回的片段里有没有标准答案所在的那一段。这一步不调生成模型,快且便宜,能立刻判断是召回不行还是模型不行;命中率低就先别再调提示词。
  2. 再固定检索结果测生成把正确答案的原文手工塞进上下文,看模型能不能照它答对。如果这样还答错,问题在提示词或上下文拼装,跟向量库没关系。
  3. 两段都过、合起来不过基本可以锁定在拼接顺序、上下文被截断,或者重排把好片段压下去了。逐条对比两次运行的中间结果就能看出来,不用改模型。
  4. 一次只改一个变量调分块、换向量模型、改提示词分开跑。一次改三个,改完变好变坏都归不了因,等于白跑一轮。

中间结果要留下。检索返回的片段标识、拼进上下文的最终顺序、生成时用的提示词版本,都存下来。没有这些,下一次回归跑出的差异只能靠猜。

判分方式与结果记录:让下一次能对比

小规模先用人工判。几十条的量级,一个人半小时能过完,比搭一套自动判分框架划算得多。等题目上百条、要天天跑回归,再考虑上模型判分,同时按比例抽样人工复核。

  • 判分模型和被测模型分开,别让同一个模型既当运动员又当裁判
  • 判分提示词里写清判定标准和正反例子,并固定版本号管理;口径一变,历史分数就没法比
  • 把「错误类型」标上:没召回、召回了没用、用了但说错、该拒答却硬答
  • 每条记录至少留四个字段:问题、检索返回的片段标识、原始回答、人工判定结果

只存一个总分,回头发现某类题集体出错时根本查不到原因。错误类型打标跑几次之后,哪类占比最高一目了然,比盯总分有用得多。模型判分有个已知的「不适用」情况:标准答案是开放式论述题时,判分模型自己的一致性会明显下降,这类题老老实实人工看,或者干脆别放进自动回测集。

如果团队还在选模型或中转服务,评测集先跑通再选会更稳,选型时可以顺路到 /rankings 核对当时各家在同类任务上的公开表现,但记住那是别人的题、别人的口径,只能当参考。

下一步把上面的判定口径和题目清单写成一份两页的评测说明,固定下来当回归基线;然后到站内的中转与官方服务对比页面核对当时的可用选项和价格数字,再决定评测跑在哪个环境上。

常见问题

没有标准答案的开放问题怎么判准不准?

换个判法,别判「答得对不对」,判「有没有依据」。把回答里每个关键说法跟检索到的原文片段对一遍,能对上就是有据,对不上就是无据。再单独看它有没有把无据的部分讲得像有据,这类含糊其辞的答法在开放问题里比直接答错更麻烦。

多少条评测题才够用?

看目的。定位问题阶段每个类别几条就够暴露方向;要判断一次改动是变好还是变坏,题目至少覆盖所有主要问法和文档类型,否则改动的收益会被抽样波动盖掉。与其纠结总数,不如保证每类问题都有代表,并且每次跑的是同一批题。

用另一个大模型来判分靠谱吗?

能做初筛,不能当唯一依据。它擅长判「回答有没有覆盖关键点」,不擅长判「这个说法在原文里到底成不成立」,遇到表述绕的容易放水。可行做法是让它判、让它标理由,你抽一小部分人工复核,发现它判偏了就回去改判分提示词。

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