一、多路召回与重排序:工程级的检索优化
要让 Agent RAG 真正好用,检索质量是关键。工程实践中,最有效的提升策略是多路召回 + 重排序。
多路召回策略:三种检索方式融合
用户查询并行触发三路:向量检索(语义相似度,捕捉同义表达)、关键词检索 BM25(精确匹配,捕捉专有名词)、结构化查询](SQL/元数据过滤,精准条件筛选)。三路结果汇入重排序器,用 Cross-Encoder 精细打分,输出 Top-K 高质量上下文注入 LLM。
为什么需要多路召回?
单纯的向量检索有盲区——它对语义相似度很敏感,但对精确关键词不够好。例如:
- 用户问"第 3.2.5 条款的内容"——向量检索可能找不到,但关键词检索能精确定位
- 用户问"关于资金安全的政策"——关键词检索找不到,但向量检索能命中语义相关的段落
三路召回各司其职:
- 向量检索:捕捉语义相似性,处理同义表达
- 关键词检索(BM25):精确匹配,处理专有名词、型号、条款编号
- 结构化查询:利用元数据(时间、类别、作者)精准过滤,缩小检索范围
重排序(Reranker)
三路召回可能带来几十个候选文档块。重排序器的任务是从中精选出最相关的 Top-K。
Bi-Encoder(向量检索的核心):把查询和文档分别向量化,计算相似度。速度快,但精度较低——因为查询和文档没有交叉注意力。
Cross-Encoder(重排序的核心):把查询和候选文档拼接在一起,让模型同时"看到"两者,给出相关性分数。精度高得多,但速度慢——只适合对少量候选做精排,而不是全库检索。
实际系统的标准做法:向量检索/关键词检索(快,覆盖广)→ 多路合并 → Cross-Encoder 重排(精,准)→ Top-K 注入 LLM。
二、Self-RAG:让 Agent 知道自己"不知道"
在医疗、法律、金融]等高精度要求场景,幻觉是零容忍的。Self-RAG是目前最有效的幻觉抑制方案之一。
它的核心创新:让模型在生成过程中主动插入"反思令牌",评估检索结果质量和回答可靠性。
Self-RAG 完整流程图
五步流程:1.判断是否需要检索(不需要则直接生成)→ 2.执行多路召回 → 3.判断检索结果是否相关(不相关则重检索,有循环箭头)→ 4.生成附引用来源的答案 → 左侧有"最终自我核查"的反向路径。
Self-RAG 的四个关键判断
① 是否需要检索(Retrieval Token)
不是所有问题都需要查文档。"2 + 2 等于多少"不需要检索,"公司的差旅报销标准"才需要。模型自主判断,避免不必要的检索开销。
② 检索结果是否相关(ISREL Token)
对每个检索到的文档块打分:这个段落真的和问题相关吗?过滤掉无关内容,只保留真正有用的部分。
③ 答案是否有文档支撑(ISSUP Token)
生成答案后,模型检查:这句话有文档依据吗?如果某个陈述没有文档支撑,模型应该标注"无法确认"而不是硬编。
④ 答案整体质量评分(ISUSE Token)
综合评估答案的有用性——不只是准确,还要完整、清晰、真正回答了用户的问题。
三、RAG 管道的关键工程决策
分块策略怎么选?
fromlangchain.text_splitterimportRecursiveCharacterTextSplitter# 递归字符分割(最常用)splitter=RecursiveCharacterTextSplitter(chunk_size=512,# 每块大小(Token 数)chunk_overlap=50,# 重叠大小,防止边界截断separators=["\n\n","\n","。","!","?"," "]# 优先按段落切)# 语义分割(质量更高,速度更慢)fromlangchain_experimental.text_splitterimportSemanticChunkerfromlangchain_openaiimportOpenAIEmbeddings semantic_splitter=SemanticChunker(embeddings=OpenAIEmbeddings(),breakpoint_threshold_type="percentile"# 在语义跳变处切割)经验法则:
- 纯问答场景:
chunk_size=512, overlap=50是个好起点 - 需要完整上下文(如合同条款):
chunk_size=1024, overlap=100 - 代码文档:按函数/类边界切,而不是固定大小
Embedding 模型怎么选?
| 模型 | 语言支持 | 向量维度 | 适用场景 |
|---|---|---|---|
| text-embedding-3-small | 多语言 | 1536 | 通用,性价比高 |
| text-embedding-3-large | 多语言 | 3072 | 高精度要求 |
| bge-m3(开源) | 多语言 | 1024 | 私有部署,中文优秀 |
| jina-embeddings-v3 | 多语言 | 1024 | 长文档效果好 |
关键原则:确定了就不要换。一旦换模型,历史索引全部失效,需要重新向量化整个知识库。
检索数量 K 怎么设置?
- K 太小:可能漏掉关键信息
- K 太大:塞满上下文,LLM 被无关内容干扰,成本也高
经验参考:
- 简单问答:K=3~5
- 复杂分析:K=8~12
- 使用重排序后:先召回 K×3,重排后取 K