超越朴素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评估体系需要以下指标:

  1. 检索阶段:Recall@K、MRR(Mean Reciprocal Rank)、NDCG
  2. 生成阶段: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质量的提升。