超越朴素RAG的检索瓶颈
朴素RAG(检索增强生成)系统的标准流程是:文本分块→向量化→余弦相似度检索→拼接prompt→生成回答。但在生产环境中,这种方案的检索准确率往往不超过60%。本文分享如何通过混合检索和重排序将准确率提升到85%以上。
混合检索:双路召回
稀疏检索:BM25的回归
BM25基于词项频率和文档频率,对精确关键词匹配有天然优势。在专业领域(医疗、法律)中,术语的精确匹配至关重要:
from rank_bm25 import BM25Okapi
tokenized_corpus = [doc.split() for doc in corpus]
bm25 = BM25Okapi(tokenized_corpus)
scores = bm25.get_scores(query.split())
稠密检索:语义理解的利器
稠密检索通过Embedding模型捕获语义相似性,能处理同义词和跨语言匹配。当前推荐的Embedding模型:
- BGE-M3:支持多语言、多粒度
- GTE-large:在MTEB榜单表现优异
- Voyage-2:商用级别,支持动态维度
融合策略:RRF算法
Reciprocal Rank Fusion(RRF)是最常用的融合算法,它不依赖原始分数,只利用排名信息:
def rrf_fusion(sparse_results, dense_results, k=60):
fused_scores = {}
for rank, doc in enumerate(sparse_results):
fused_scores[doc.id] = fused_scores.get(doc.id, 0) + 1 / (k + rank + 1)
for rank, doc in enumerate(dense_results):
fused_scores[doc.id] = fused_scores.get(doc.id, 0) + 1 / (k + rank + 1)
return sorted(fused_scores.items(), key=lambda x: x[1], reverse=True)
RRF的优势在于无需调参,且对两个检索系统的分数尺度不敏感。
重排序:精排阶段
粗排阶段获取Top-50候选后,需要用更精确但更慢的模型进行重排序。
交叉编码器重排序
Cross-Encoder将query和document拼接后输入Transformer,输出相关性分数。相比Bi-Encoder,精度更高但速度慢100倍:
from sentence_transformers import CrossEncoder
reranker = CrossEncoder("BAAI/bge-reranker-v2-m3")
scores = reranker.predict([(query, doc.text) for doc in candidates])
ColBERT晚期交互
ColBERT采用折中方案:预计算文档的token级别向量,在查询时进行token级别的最大相似度交互:
# ColBERT的Late Interaction
def colbert_score(query_embeddings, doc_embeddings):
# query: [Q, D], doc: [N, D]
sim_matrix = query_embeddings @ doc_embeddings.T # [Q, N]
max_per_query = sim_matrix.max(axis=1) # [Q]
return max_per_query.sum()
ColBERT在保持接近Cross-Encoder精度的同时,速度提升约10倍。
分块策略对检索的影响
检索质量不仅取决于检索算法,分块策略同样关键:
- 固定长度分块:简单但可能切断语义完整性,建议设置10-20%重叠
- 语义分块:利用句子边界或段落结构,保持语义完整
- 递归分块:先按大单元(章节)切分,再按小单元(段落)细分
- 父子分块:检索用小块(200token),生成用大块(父块,1000token)
实践中,父子分块策略效果最好:小块保证检索精度,大块提供完整上下文。
检索质量评估体系
建立RAG评估体系需要以下指标:
- 检索阶段:Recall@K、MRR(Mean Reciprocal Rank)、NDCG
- 生成阶段:Faithfulness(忠实度)、Answer Relevancy(答案相关性)、Context Precision(上下文精度)
推荐使用RAGAS框架进行自动化评估:
from ragas import evaluate
from ragas.metrics import faithfulness, answer_relevancy, context_precision
result = evaluate(
dataset={"question": [...], "answer": [...], "contexts": [...]},
metrics=[faithfulness, answer_relevancy, context_precision]
)
结语
RAG系统的优化是一个系统工程,从分块策略到检索融合再到重排序,每个环节都有优化空间。混合检索+重排序的组合方案已成为生产级RAG系统的标配。下一步,Self-RAG和Adaptive-RAG等动态检索策略将进一步推动RAG质量的提升。