RAG系统的效果瓶颈往往不在生成模型,而在检索链路。如果召回的片段本身不相关,LLM即使生成能力再强,也无法输出正确答案。这也是为什么检索质量调优,应该成为RAG工程落地的第一优先级。
但检索质量差是一个宽泛的问题描述。具体到工程实践中,它通常表现为以下几种情况:
- 检索结果与查询主题相关,但缺少关键细节;
- 检索结果看似相关,但信息粒度不对,无法支撑答案;
- 查询表述模糊,导致Embedding向量无法准确捕获意图;
- 多个强相关片段被排在后面,Top-K截断后丢失。
针对这些问题,有效的调优方向集中在四个环节:Embedding模型、分块策略、重排序和查询改写。下面逐个拆解。
1. Embedding模型:先确认瓶颈,再决定更换
Embedding模型决定了文本向量化的质量,也决定了检索阶段的召回上限。如果Embedding本身无法区分语义差异,后续所有调优都会事倍功半。
但在更换Embedding模型之前,需要先确认当前系统的瓶颈是否真的在Embedding上。一个可行的排查方法是:
- 手工构造一批与业务场景接近的查询,覆盖不同表达方式;
- 使用当前的Embedding模型对候选文档做检索,观察Top-5或Top-10结果;
- 判断错误结果是语义理解错误,还是排序问题。
如果发现模型无法理解领域术语、同义表达或上下文语义,那么更换Embedding模型是合理的选择。反之,如果语义理解基本正确,但相关文档没有被排到前面,那么问题可能出在分块策略或排序机制上。
选择Embedding模型时,需要关注以下几点:
- 模型对领域文本的适配程度,通用模型在垂直领域上往往表现一般;
- 向量维度对存储和检索延迟的影响;
- 模型是否支持中文(取决于业务语料语言);
- 模型的输入长度限制,这会直接影响分块策略的设计。
这里需要明确一点:不同Embedding模型之间没有绝对的优劣,只有是否适合当前业务场景。评估时应该使用自己业务数据上的标注集或人工评测样本,而不是依赖模型排行榜。
领域适配评估示例:假设业务是医疗问答,可以收集100个真实用户问题,并人工标注每个问题对应的正确文档片段。然后分别用通用Embedding模型和医疗领域微调的Embedding模型进行检索,对比Top-5命中率。如果领域模型在术语、同义词上的表现明显更好,则更换模型是值得的。构建标注集时,可以邀请业务专家参与,确保标注质量。
2. 分块策略:决定检索的最小信息单元
分块策略直接影响检索单元的粒度。块太大,单个片段包含过多噪声,向量表示被稀释;块太小,单个片段又可能缺乏完整语义,导致检索结果碎片化。
分块策略的核心问题是:什么样的块大小和块边界,才能让Embedding模型表达出清晰且完整的语义。
常见的处理方向包括:
- 按固定字符数切分:简单直接,但容易切断句子或段落,造成语义不完整;
- 按段落或语义结构切分:保留完整语义单元,但需要处理不同文档结构带来的长度差异;
- 设置块重叠:相邻分块保留一定重叠内容,避免关键信息恰好落在分块边界;
- 按文档层级组织:章节、小节、段落分层,检索时可以优先命中更精确的层级。
从工程角度看,固定字符数切分仍然是最常用的起步方案,因为它实现简单、可控性强。但实际调优时,并不存在一个通用的最优分块大小。合理的做法是:
- 基于当前语料的平均句子长度和段落长度,确定几个候选分块大小;
- 在同一组查询上做对比实验,观察检索命中率;
- 根据失败案例,针对性地调整分块边界和块重叠比例。
参数参考与实验对比:以下是一个典型的分块参数实验设计,供参考(具体数值需根据语料调整):
| 分块大小(字符) | 重叠(字符) | Top-5命中率 | 平均检索延迟 | 备注 |
|---|---|---|---|---|
| 200 | 0 | 62% | 15ms | 基线 |
| 300 | 50 | 68% | 18ms | 推荐 |
| 500 | 100 | 65% | 22ms | 块过大 |
实验时,固定其他环节不变,仅调整分块参数,使用同一组查询样本,记录命中率和延迟。通过对比,可以找到适合当前语料的平衡点。
分块策略的调优重点,不应该放在“找到一个完美数字”上,而应该放在“减少语义被截断”和“保持检索单元信息完整”这两个目标上。
3. 重排序:在召回之后,用更精确的模型修正顺序
Embedding检索是高效的召回手段,但它排序的精确度有限。尤其在Top-K结果集较大的情况下,Embedding模型可能只保证相关文档被召回,却无法保证它们的相对顺序足够准确。
重排序(Rerank)解决的就是这个问题:先通过Embedding召回一批候选文档,再用一个更精确的排序模型对候选文档重新打分,从而修正顺序。
引入重排序后,常见的做法是:
- 召回阶段:使用Embedding检索获取Top-50或Top-100候选片段;
- 重排序阶段:使用重排序模型对候选片段计算与查询的精确相关度;
- 最终输入:取重排序后的Top-3或Top-5片段作为LLM的上下文。
这种两阶段策略的核心收益在于:召回阶段可以放宽限制,避免把相关文档挡在门外;重排序阶段再用精确匹配能力压缩结果集,保证输入给LLM的都是高相关信息。
在实际落地中,重排序的引入会带来额外的计算开销,主要体现在:
- 重排序模型需要对每个候选片段执行一次推理,候选数量直接影响延迟;
- 需要维护额外的模型部署和服务;
- 重排序模型通常对输入长度有限制,过长的片段可能需要截断处理。
因此,重排序并不是简单地加一个模型,而是要结合系统的延迟要求和召回质量,确定合理的候选数量。
参数参考:在延迟敏感的场景下,建议召回Top-50,重排序后取Top-5;如果延迟预算充足,可以召回Top-100,重排序后取Top-10。具体数值需通过实验确定。
4. 查询改写:在检索之前,先让查询更可检索
一个经常被忽视的问题:用户的原始查询,未必是适合Embedding检索的表述。
用户可能输入短关键词、口语化描述、包含指代词的问题,或者一次查询中混杂了多个意图。这些情况都会导致Embedding检索的准确率下降,因为查询向量本身就没有表达清楚语义。
查询改写(Query Rewriting)的思路是:在将查询发送给检索模块之前,先通过LLM将原始查询改写为更完整、更明确、更适合检索的表述。
一个简单的改写逻辑可以是:
- 扩展短查询,补充上下文信息;
- 将口语化表达改写为书面化表达;
- 将指代词替换为具体实体;
- 将模糊问题拆分为多个子查询。
需要强调的是,查询改写并不是对所有查询都有收益。对于已经清晰、具体、无歧义的查询,改写可能带来不必要的延迟,甚至可能引入错误信息。
正确使用查询改写的方式是:
- 先区分查询类型,建立“是否需要改写”的判断条件;
- 只在原始查询可能存在表达不完整或歧义时触发改写;
- 将改写后的查询与原查询同时用于检索,或者先用改写查询检索,失败后再用原查询兜底。
从工程上看,查询改写更像是一个前置优化模块,而不是RAG系统的必选组件。它的价值取决于业务中真实查询的表达质量。
5. 调优顺序与整体策略
面对一个检索质量差的RAG系统,不建议同时调整所有环节。那样不仅难以定位问题,也无法判断每项调整的实际收益。
一个可行的调优顺序是:
- 先检查分块策略:确认检索单元是否语义完整,排除最基础的切分问题;
- 再评估Embedding模型:用业务样例判断向量语义能力是否匹配需求;
- 然后引入重排序:提升Top-K候选的排序精度;
- 最后考虑查询改写:解决查询表达层面的质量问题。
每一步调整都应该有明确的对照实验:
- 固定其他环节不变,只修改目标环节;
- 使用同一组真实查询样本;
- 对比调整前后的检索命中率、答案质量指标和端到端延迟。
这样才能确定每一项优化是否真的有效。
6. 边界与注意点
最后需要说明几个容易踩坑的地方:
第一,不要用离线指标完全替代端到端评估。检索命中率高不一定代表最终答案质量好,因为LLM如何利用检索到的上下文,同样会影响输出结果。
第二,不同优化手段之间存在耦合。例如,改变分块策略后,原有重排序模型的效果可能会变化;引入查询改写后,原有的缓存策略可能需要调整。每次改动后,最好重新跑一遍完整的评估流程。
第三,不要盲目追求大模型或复杂策略。在大多数场景中,一个合理配置的Embedding + 分块策略 + 轻量重排序,已经能解决大部分检索质量问题。复杂的查询改写和多路召回,只有在明确的业务需求下才值得引入。
RAG检索质量调优,本质上是一个持续迭代的工程过程。没有一劳永逸的最佳配置,只有不断根据业务数据和失败案例,逐渐逼近更优的检索方案。