News

RAGs中的混合搜索:融合关键词与语义,大幅提升检索精度

RAGs中的混合搜索:融合关键词与语义,大幅提升检索精度

在构建高效的检索增强生成(RAG)系统时,如何精确地从海量文档中提取相关信息是核心挑战。传统的RAG方法通常依赖于单一的向量数据库进行语义相似度检索,而关键词搜索则侧重于精确匹配。然而,这两种方法都有其局限性,混合搜索(Hybrid Search)应运而生,旨在融合两者的优势。

以一个包含Python错误代码及其定义和用例的文档集为例,当用户查询“什么是ERR_404_AUTH?”时:

  • 经典RAG(仅向量检索): 会从向量数据库中检索所有与认证和错误相关的上下文文档,可能包含大量不直接相关的通用信息。
  • 词法搜索(Lexical Search): 会精确搜索包含“What”、“is”、“ERR_404_AUTH”等词语的文档,但可能忽略语义上相关但词汇不完全匹配的内容。
  • 混合搜索: 将同时搜索关键词“ERR_404_AUTH”,并通过语义相似度检索相关文档,从而实现更精准的匹配。

利用BM25进行关键词检索

BM25是关键词搜索的一种扩展,可以视为TF-IDF的增强版。在LangChain中,BM25Retriever的实现非常直接。以下是结合LangChain进行BM25检索的步骤和原理:

# pip install rank_bm25
from langchain_community.retrievers import BM25Retriever
from langchain_core.documents import Document

# 假设这是通过文本分割器生成的文档块
chunks = [
    Document(page_content="The AX-705 engine uses a 4-stroke cycle."),
    Document(page_content="Maintenance for AX-705 requires synthetic oil."),
    Document(page_content="Four-stroke engines are common in modern cars.")
]

# 步骤:构建BM25索引(倒排索引)
bm25_retriever = BM25Retriever.from_documents(chunks)
bm25_retriever.k = 2  # 检索Top 2结果

构建混合“集成”检索器

为了充分利用关键词的精确性和语义的泛化性,可以将向量检索器与BM25检索器合并,创建一个混合“集成”检索器(Ensemble Retriever)。

from langchain.retrievers import EnsembleRetriever

# 假设'chroma_retriever'是已经创建好的向量检索器
hybrid_retriever = EnsembleRetriever(
    retrievers=[bm25_retriever, chroma_retriever],
    weights=[0.3, 0.7]  # 为关键词赋予30%的重要性,语义赋予70%的重要性
)

BM25的内部工作机制

当调用 `hybrid_retriever.invoke("AX-705 engine")` 时,BM25部分会执行以下四个步骤:

  1. 分词(Tokenization): 查询“AX-705 engine”被拆分为词元,例如 ["ax-705", "engine"]。
  2. 查找(Lookup): 检索器在其“倒排索引”(一个字典结构)中查找哪些文档块包含这些精确的字符串。
  3. 评分(Scoring - f(q, d)): 使用BM25公式计算每个匹配项的得分:
    • 稀有性: “AX-705”在数据库中较稀有,因此比“engine”的权重更高。
    • 饱和度: 即使文档中多次出现“engine”,其得分也不会线性飙升,这可以防止“关键词堆砌”过度影响排名。
    • 长度惩罚: 如果一个短小的文档块(例如10个词)同时匹配了查询中的两个词,它会比一个冗长的文档块(例如1000个词)获得更高的排名。
  4. 排序(Ranking): 根据计算出的得分,返回排序后的文档块列表。
↗ 阅读原文