给 RAG 检索加重排前,我会先把召回池和证据账本拆开
最近给一个企业知识库做检索质量回归时,我又遇到一个熟悉的问题:业务同学只看最终答案,研发同学只看向量库 topK,大家都说加 rerank 后更准,可真正出错时,很难解释某个 chunk 为什么进了答案上下文。我的处理方式是先暂停接入生产流量,把召回池、重排结果和证据账本拆出来,让每一次回答都能回放。

原创示意图:把 RAG 重排上线链路拆成召回池、重排打分、证据账本和评测回归四个可回放阶段。 来源:Codex image generation
问题背景
在 RAG 链路里,重排通常发生在检索之后、答案生成之前。LlamaIndex 的 node postprocessor 文档把这类模块放在 retrieval step 和 response synthesis step 之间,用来对 nodes 做转换、过滤或重排。Cohere 的 Rerank 文档给出的接口也很直观:输入 query、documents、top_n 和 model,输出重新排序后的文档。Qdrant 的 hybrid and multi-stage queries 文档说明,多阶段搜索可以先拿到一批候选,再用更准确的表示重新打分。
这些机制都指向同一件事:rerank 改变的是候选顺序和截断位置。它可以提升答案上下文质量,也可能把原本能兜住问题的低分 chunk 挤出去。如果线上只保存最终 topN,事故复盘时就会丢掉最关键的中间证据。
踩坑点
第一个坑是只看最终命中率。某次知识库问答里,答案引用看起来更干净,但用户追问细节时反而漏掉了边界条款。回看日志才发现第一阶段召回池里有相关 chunk,rerank 后被排到了截断线外。这里需要同时观察 Context Recall 和 Context Precision。Ragas 文档里,Context Recall 关注相关信息有没有被取回,Context Precision 关注相关 chunks 是否排在更靠前的位置。
第二个坑是分数不可比。向量相似度、BM25 分数、rerank relevance score 的含义不同,直接拼在一张表里会误导排查。我更愿意把它们记录成分阶段证据:retrieverScore 解释第一阶段召回,rerankScore 解释重排,finalRank 解释最终进入 prompt 的顺序。
第三个坑是缺少可回滚开关。上线当天如果发现长尾问题,只有总开关会让团队在全部关闭和继续冒险之间摇摆。我会给 rerank 增加 namespace、知识库、query intent 三个粒度的开关,并把开关状态写进每次回答的 trace。
解决思路
我把链路拆成四张账本。第一张是 recall ledger,记录 query hash、retriever 类型、召回 topK、chunkId、documentVersion、retrieverScore 和 metadata filter。第二张是 rerank ledger,记录 rerank 模型、输入候选数量、输出 topN、rerankScore 和被截断的 chunkId。第三张是 prompt evidence,记录最终进入上下文的 chunk 顺序、引用范围和 token 占用。第四张是 eval ledger,记录同一批 golden questions 在开关前后的 recall、precision、人工判定和失败样例。
这样拆完后,排查路径会清楚很多。召回池回答有没有捞到材料,rerank 账本回答排序有没有改变,prompt evidence 回答模型实际看到了什么,eval ledger 回答这次改动能不能继续扩大流量。
关键步骤
落地时我先把检索接口的返回类型从简单数组改成带阶段信息的对象。每个候选 chunk 都带 chunkId、docId、docVersion、sourceSpan、retrieverScore 和 retrievalStage。进入 rerank 前冻结一份候选快照,后续任何截断都只能追加 event,不能覆盖原始召回池。
接着把 rerank 变成可观测的后处理节点。它接收候选池,输出新的 rank 和 score,同时保留 oldRank。对于被挤出 topN 的 chunk,我会写入 droppedCandidates,方便回归样例显示:这个答案错在没召回,错在重排,还是错在生成阶段没有引用。
最后是发布闸。新 rerank 策略先跑离线 golden set,再灰度到低风险知识库。发布面板只展示三类信号:Context Recall 是否明显下降,Context Precision 是否提升,人工标注的失败样例是否集中在某个文档类型。只要 recall 下降超过阈值,即使答案看起来更短更顺,也先回滚对应 namespace。
可复用经验
RAG 的 rerank 上线,核心是让排序变化有证据。第一阶段召回池要能回放,重排分数要能按阶段解释,最终 prompt 要能追到 chunk 版本,评测要同时看 recall 和 precision。做完这几件事后,线上问题会从感觉不准变成可定位的链路问题:召回没捞到、重排挤掉了、截断太激进,还是生成阶段没有忠实引用。
我现在做 RAG 检索改造,会先问四个问题:候选池有没有完整保存,rerank 前后 rank 有没有对照,被截断 chunk 有没有记录,评测指标有没有同时覆盖召回和排序。四个答案清楚后,再讨论模型和参数,工程风险会低很多。