← 返回博客
David6 分钟阅读

给自己的 RAG 检索跑了个分:第一次冒烟就抓出两个线上 bug

知识库产品最该量的是检索质量,可我们手里只有功能测试。这篇讲琅嬛怎么建检索评测:200 条人工标注的真实查询、双轨道四格矩阵、同指纹逐位可复现,以及它第一天就抓出的线上 bug 和终于被数据证实的混合检索。

RAG 评测检索混合检索知识库

琅嬛发布 v1.1.0 之后,我盘点了一遍家底,发现一件不太说得出口的事:这个产品的核心是检索,而我们手里所有测试,没有一件能回答「检索好不好」。

单测验证的是函数对不对,集成测试验证的是链路通不通。分块合同从 v1 改到 v3,RRF 融合上了,rerank 接了。每个架构决策都有理由,但没有任何一个被数字验证过。相当于造了一辆车,仪表盘上只有「发动机在转」,没有时速表。

所以这个周期我们把这块表补上了。这篇讲怎么建的、建的过程中发生了什么。剧透一下:评测第一次冒烟,就抓出两个用户会真实踩到的线上 bug。

一把不掺水的尺子

评测这东西,写代码是小事,标注数据才贵。我们没标一个字,直接用了 MIRACL-zh:维基百科中文语料,人工标注过段落级相关性,Apache-2.0 协议。从里面确定性抽出 200 条真实搜索查询,随机种子和数据集指纹都写进报告,任何人拿到同一份数据,跑出来就是同一套题。

光有一个总分不够,检索的损耗发生在不同环节,所以题目拆成两条轨道。一条把 5,298 份单段落文档单独入库,量向量、全文检索、RRF 融合本身的水平;另一条把 709 篇完整文章按真实长文档入库,量分块、父子 chunk、检索的全链路。前者接近零件精度,后者接近整车路况。两把尺子量出来的差距,本身就是信息。

每条轨道跑四格:纯向量、纯全文、混合、混合加重排。指标用检索领域标准的 recall@10、MRR、nDCG,全程没有 LLM 参与打分。LLM 当裁判的那点不确定性,恰恰是这套评测想消灭的东西。

还有一条底线是确定性。同一份指纹——数据集、分块参数、模型、代码版本完全相同——跑两遍,换端口、换临时实例,指标剔除时间戳后逐位一致。做不到这一点,你看到的任何涨跌都可能是噪声,「改了之后变好了」就还是一句玄学。

第一次冒烟,两个线上 bug

评测 harness 自己也需要验证,所以第一步用无语义的 mock embedding 跑冒烟:如果 harness 有偏,分数应该贴着随机基线。结果严丝合缝,尺子是直的。

但冒烟做的事不止量尺:它要拉起一个真实的 standalone 实例、真的建库、真的写入。就在这条链路上,两个藏了很久的 bug 现形了。

第一个,standalone 模式创建知识库,必 500,原因是 SQLite 的前向外键少了延迟检查声明。第二个更隐蔽:向量检索压根没工作,vec 向量扩展没有链进生产二进制。两个都随 v1.1.1 修掉了。

有意思的是,为什么以前的测试没抓住它们。因为以前的测试不走这条路:单测把数据库 mock 掉了,集成测试走的是 PostgreSQL 部署。评测 harness 天然扮演了一个新用户——按文档从零拉起一套完整系统,于是踩到了只有新用户才会踩的坑。

真实模型上场,全文检索交了白卷

换上真实的 bge-m3,200 条查询跑完,表格里出现一排刺眼的 0.0000:FTS 通道,全线零召回。不是某类查询表现差,是一条都没中过。

再看 hybrid,分数 0.9799,和纯向量一模一样,一位不差。也就是说,名义上的混合检索,实际只有向量一路在干活,全文检索是个空转的装饰。而这个状态下系统不报错、不告警,日志一片绿,用户看到的搜索结果「看起来也还行」。

这个 bug 的机理和修法,值得单独展开,写在这篇复盘里。

同一轮还有两个发现。一个是把 Qwen3-Embedding 换上来对照,差距只有 0.4 个百分点——检索质量的瓶颈根本不在换模型,这个结论替我们省下了不知多少折腾。另一个是长文档轨道比段落轨道掉了约 19 个百分点,分块全链路存在真实损耗,这笔账要留到归因环节慢慢算。

修复之后,架构假设第一次闭环

FTS 修复上线,同指纹重跑,数字变成这样:全文检索从 0 分回到 0.13,不多,但活了;hybrid 到 0.9826,第一次严格高于纯向量的 0.9799。差距不到千分之三,但这是「混合检索值得做」第一次被自己的数据证实,而不是被架构图证实。

重排模型上去之后,段落级 MRR 推到 0.9975——命中几乎钉死在第一位。长文档轨道的最强组合同样是混合加重排,recall@10 到 0.79。顺带一提,我们还做了两组分块参数实验,结论是扰动只有正负 0.5 个百分点,不构成改默认值的理由。调分块参数救不了检索,这话以后单独展开讲。

分数怎么读,别读错了

有件事必须说清楚:这些绝对分数不能拿去和公开排行榜比。我们的段落轨道是在五千多段的采样池上检索,MIRACL 官方榜单是四百多万段的全池,池子越大分数越低。拿采样池的 98% 去喊「超过某某榜单」,是自欺欺人。

这套评测的价值是用同一把尺子量自己:每次改动,同指纹跑一遍,diff 两份 metrics.json,涨了跌了都归因得清清楚楚。它也确实从「验证架构」变成了日常回归——后面改分词、扩停用词,都得先过这一关。

琅嬛怎么落

评测体系是独立二进制,不进主链路,仓库里 make eval 一条命令:拉起被测实例、导入数据集、跑四格矩阵、出报告。琅嬛的推荐配置——混合检索默认开、workspace 级 rerank、维持默认分块——就是从这批数据里长出来的,不是拍出来的。

完整的评测报告在 GitHub 仓库里公开,含全部指纹和历史轮次,欢迎拿自己的数据集来跑。想直接体验这套检索,下载页有各平台的二进制。

延伸阅读

Related · 延伸阅读