LlamaIndex实现RAG增强:融合检索(Fusion Retrieval)与混合检索(Hybrid Search)

news2025/5/16 1:15:12

🧠 向所有学习者致敬!

“学习不是装满一桶水,而是点燃一把火。” —— 叶芝


我的博客主页: https://lizheng.blog.csdn.net

🌐 欢迎点击加入AI人工智能社区!

🚀 让我们一起努力,共创AI未来! 🚀


在这里插入图片描述

RAG Hybrid Search与Fusion Retrieval的技术对比及工作流程图:
Hybrid Search (混合搜索)

  • 定义:结合关键词检索和向量检索的搜索方法
  • 特点:同时利用传统BM25算法(精确匹配)和神经网络嵌入(语义匹配)
  • 示例:Elasticsearch + 向量数据库的联合查询

Fusion Retrieval (融合检索)

  • 定义:对多种检索结果进行加权融合的算法
  • 特点:通过线性加权/学习排序(Rank Fusion)整合不同检索系统的结果
  • 示例:Reciprocal Rank Fusion (RRF)算法

核心区别对比

维度RAG Hybrid SearchFusion Retrieval
目标通过混合检索策略提升召回率通过多路结果融合提升准确率
工作阶段检索阶段(预处理层)后处理阶段(结果层)
技术实现同时执行关键词+向量检索,合并结果多路独立检索后加权/重排序
计算开销较高(并行执行两种检索)中等(依赖独立检索系统的输出)
典型应用开放域问答、知识密集型任务多模态检索、跨语言检索

工作流程图

在这里插入图片描述

关键差异解析

  1. 架构层级差异

    • Hybrid Search在检索阶段完成多策略整合(如BM25+向量),降低生成模型噪声
    • Fusion Retrieval在检索完成后进行结果融合(如RRF算法),强调异构系统互补性
  2. 性能权衡

    • Hybrid需维护双索引,但减少冗余计算(如ColBERT的混合压缩)
    • Fusion支持异步检索(可并行化),但融合算法复杂度高(如RECIPROAL RANK FUSION)
  3. 适用场景

    • Hybrid适合单一数据源下的多角度语义覆盖
    • Fusion适合跨系统/跨模态检索(如文本+图像联合检索)

基于LlamaIndex实现RAG融合检索Fusion Retrieval

本代码实现了一个融合检索系统,将基于向量的相似性搜索与基于关键词的BM25检索相结合。该方法旨在综合两种技术的优势,提升文档检索的整体质量和相关性。

动机

传统检索方法通常依赖语义理解(基于向量)或关键词匹配(BM25)。每种方法都有其优缺点。融合检索通过结合这两种方法,构建更强大、更精确的检索系统,能够有效处理更广泛的查询场景。

核心组件

  1. PDF文档处理与文本分块
  2. 使用FAISS和OpenAI嵌入创建向量存储
  3. 构建基于关键词的BM25索引
  4. 融合BM25和向量搜索结果以优化检索效果

方法细节

文档预处理

  1. 加载PDF文档并使用SentenceSplitter进行分块
  2. 通过替换\t为空格和清理换行符来净化文本块(针对特定格式问题)

向量存储创建

  1. 使用OpenAI嵌入生成文本块的向量表示
  2. 基于这些嵌入创建FAISS向量存储,实现高效的相似性搜索

BM25索引创建

  1. 使用与向量存储相同的文本块创建BM25索引
  2. 实现与基于向量方法并行的关键词检索

查询混合检索

在创建两种索引后,查询混合检索将它们结合起来,实现混合检索
在这里插入图片描述
在这里插入图片描述

方法优势

  1. 提升检索质量:结合语义搜索和关键词匹配,系统能同时捕捉概念相似性和精确关键词匹配
  2. 灵活调整:通过retriever_weights参数可调节向量搜索与关键词搜索的权重平衡
  3. 鲁棒性强:组合方法能有效处理更广泛的查询场景,弥补单一方法的不足
  4. 高度可定制:系统可轻松适配不同的向量存储或关键词检索方法

结论

融合检索代表了文档搜索的强大方法,结合了语义理解和关键词匹配的优势。通过同时利用基于向量和BM25的检索方法,它为信息检索任务提供了更全面、灵活的解决方案。这种方法在需要兼顾概念相似性和关键词相关性的领域具有广泛应用潜力,如学术研究、法律文档搜索或通用搜索引擎。
在这里插入图片描述

导入库

import os
import sys
from dotenv import load_dotenv
from typing import List
from llama_index.core import Settings
from llama_index.core.readers import SimpleDirectoryReader
from llama_index.core.node_parser import SentenceSplitter
from llama_index.core.ingestion import IngestionPipeline
from llama_index.core.schema import BaseNode, TransformComponent
from llama_index.vector_stores.faiss import FaissVectorStore
from llama_index.core import VectorStoreIndex
from llama_index.llms.openai import OpenAI
from llama_index.embeddings.openai import OpenAIEmbedding
from llama_index.legacy.retrievers.bm25_retriever import BM25Retriever
from llama_index.core.retrievers import QueryFusionRetriever
import faiss

sys.path.append(os.path.abspath(os.path.join(os.getcwd(), '..'))) # 将父目录添加到路径中(适用于笔记本环境)
# 从.env文件加载环境变量
load_dotenv()

# 设置OpenAI API密钥环境变量
os.environ["OPENAI_API_KEY"] = os.getenv('OPENAI_API_KEY')

# Llamaindex全局设置(LLM和嵌入模型)
EMBED_DIMENSION=512
Settings.llm = OpenAI(model="gpt-3.5-turbo", temperature=0.1)
Settings.embed_model = OpenAIEmbedding(model="text-embedding-3-small", dimensions=EMBED_DIMENSION)

读取文档

path = "../data/"
reader = SimpleDirectoryReader(input_dir=path, required_exts=['.pdf'])
documents = reader.load_data()
print(documents[0])

创建向量存储

# 创建FAISS向量存储用于保存嵌入
fais_index = faiss.IndexFlatL2(EMBED_DIMENSION)
vector_store = FaissVectorStore(faiss_index=fais_index)

文本清理转换

class TextCleaner(TransformComponent):
    """
    在数据摄取管道中使用的转换组件
    用于清理文本中的杂乱内容
    """
    def __call__(self, nodes, **kwargs) -> List[BaseNode]:
        
        for node in nodes:
            node.text = node.text.replace('\t', ' ') # 将制表符替换为空格
            node.text = node.text.replace(' \n', ' ') # 将段落分隔符替换为空格
            
        return nodes

数据摄取管道

# 管道实例化,包含:
# 节点解析器、自定义转换器、向量存储和文档
pipeline = IngestionPipeline(
    transformations=[
        SentenceSplitter(),
        TextCleaner()
    ],
    vector_store=vector_store,
    documents=documents
)

# 运行管道获取节点
nodes = pipeline.run()

检索器

BM25检索器

bm25_retriever = BM25Retriever.from_defaults(
    nodes=nodes,
    similarity_top_k=2,
)

向量检索器

index = VectorStoreIndex(nodes)
vector_retriever = index.as_retriever(similarity_top_k=2)

融合两种检索器

retriever = QueryFusionRetriever(
    retrievers=[
        vector_retriever,
        bm25_retriever
    ],
    retriever_weights=[
        0.6, # 向量检索器权重
        0.4 # BM25检索器权重
    ],
    num_queries=1, 
    mode='dist_based_score',
    use_async=False
)

关于参数:

  1. num_queries:查询混合检索器不仅能组合检索器,还能从给定查询生成多个问题。此参数控制传递给检索器的查询总数。设置为1时禁用查询生成,最终检索器仅使用初始查询。
  2. mode:此参数有4种选项:
    • reciprocal_rerank:应用互逆排序(由于缺乏标准化,不适合此类应用,因为不同检索器返回的分数范围不同)
    • relative_score:基于所有节点中的最小和最大分数应用MinMax缩放,将分数缩放到0到1之间,最后根据retriever_weights进行加权
      min\_score = min(scores)
      \\ max\_score = max(scores)
      
    • dist_based_score:与relative_score的唯一区别在于MinMax缩放基于分数的均值和标准差,缩放和加权方式相同
       min\_score = mean\_score - 3 * std\_dev
      \\ max\_score = mean\_score + 3 * std\_dev
      
    • simple:此方法简单取每个块的最大分数

使用案例示例

# 查询
query = "气候变化对环境有哪些影响?"

# 执行混合检索
response = retriever.retrieve(query)

打印最终检索节点及分数

for node in response:
    print(f"节点分数:{node.score:.2}")
    print(f"节点内容:{node.text}")
    print("-"*100)

基于LlamaIndex实现RAG混合检索

混合检索(Hybrid Search)结合了 关键词检索(如BM25)向量相似度检索(如稠密向量),通过两者的互补性提升召回准确性。

  • BM25 处理精确关键词匹配,适合直接相关查询;
  • 向量检索 捕捉语义相似性,处理模糊或隐含的语义需求。
    在这里插入图片描述

2. LlamaIndex实现混合检索的步骤

步骤1:安装依赖与数据准备
pip install llama-index
pip install llama-index[milvus]  # 若使用Milvus作为向量数据库
步骤2:构建索引
  • BM25索引(关键词检索):基于文本内容的关键词匹配。
  • 向量索引(稠密向量检索):将文本编码为向量并存储到数据库(如Weaviate、Milvus)。
from llama_index import GPTSimpleVectorIndex, SimpleDirectoryReader
from llama_index.retrievers import VectorIndexRetriever, BM25Retriever

# 加载数据
documents = SimpleDirectoryReader('data/').load_data()

# 创建BM25索引(默认)
bm25_index = GPTSimpleVectorIndex(documents)  # 实际BM25索引需配置参数

# 创建向量索引(需配置向量数据库)
vector_index = GPTSimpleVectorIndex(
    documents,
    service_context=service_context  # 需配置Embedding模型
)
步骤3:配置混合检索器

LlamaIndex通过 HybridRetriever 或自定义逻辑组合两种检索结果:

from llama_index.retrievers import HybridRetriever

# 初始化两个单独的检索器
vector_retriever = VectorIndexRetriever(vector_index)
bm25_retriever = BM25Retriever(bm25_index)

# 创建混合检索器(可调整alpha参数权重)
hybrid_retriever = HybridRetriever(
    vector_retriever=vector_retriever,
    bm25_retriever=bm25_retriever,
    alpha=0.5  # 权重参数,调整向量与BM25的贡献比例
)
步骤4:执行混合检索
query = "在发现高血压显著降低的研究中,使用了哪些测量血压的方法?"
results = hybrid_retriever.retrieve(query)

3. 关键参数与调优

**(1) Alpha值调优
  • 作用:控制向量检索和BM25检索的权重比例。
  • 推荐实践
    • 通过实验确定最优值(如 alpha=0.20.6)。
    • 使用LlamaIndex的评估模块(如MRR、命中率)进行量化优化。
**(2) 索引配置
  • BM25优化:调整分块策略(如语义分块提升召回质量)。
  • 向量索引优化
    • 选择合适的Embedding模型(如text-embedding-ada-002);
    • 确保向量数据库支持混合查询(如Milvus 2.4+版本)。

4. 实现注意事项

  1. 数据库兼容性
    • 混合检索需要底层数据库支持联合查询(如Milvus 2.4+)。
  2. 性能权衡
    • 混合检索可能增加计算开销,需平衡召回率与效率。
  3. 重排器(Reranker)
    • 可添加重排器(如RerankRetriever)对混合结果进一步排序,提升相关性。

5. 参考案例与资源

  • BM25+向量的两路召回实现
    参考中LlamaIndex的HybridFusionRetrieverPack或自定义检索器配置。
  • Alpha调优实验
    IBM研究指出,混合检索在单/多文档场景中均表现更优,尤其当alpha=0.2/0.6时。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2327251.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

蓝桥杯冲刺:一维前缀和

系列文章目录 蓝桥杯系列:一维前缀和 文章目录 系列文章目录前言一、暴力的写法:二、一维前缀和的模板: 具体实现: 三、具体例题:求和 1.题目参考:2.以下是具体代码实现: 总结 前言 上次我介绍…

Ubuntu24.04-中文输入法的切换

Ubuntu24.04在安装后自带中文全拼输入法。。 根据官方的说明,需使用 shift super 空格 切换输入法,但在之前使用windows或者ubuntu的早些版本,多使用 Ctrl 空格 的方式切换输入法,本文就介绍如何进行输入法快捷键切换的配置&a…

技术回顾day3

1.获取文件信息、获取视频信息 走的都是同一个方法:baseController里面的getFile。 在getFile方法里面进行判断文件的类型,判断是不是m3u8类型或者ts类型做一些额外的处理。 获取信息底层就是读取文件,然后写入response的OutputStream ou…

埃文科技企业AI大模型一体机——昇腾体系+DeepSeek+RAG一站式解决方案

面对企业级市场海量数据资产与复杂业务场景深度耦合的刚需,埃文科技重磅推出基于华为昇腾算力DeepSeek大模型的企业一体机产品,提供DeepSeek多版本大模型一体机选择,为企业提供本地昇腾算力DeepSeek大模型RAG知识库的一体化解决方案&#xff…

JavaWeb开发基础知识-Servlet终极入门指南(曼波萌新版)

(✪▽✪)曼波~~~~!欢迎来到Servlet新手村!准备好开启Web开发的奇妙冒险了吗?让曼波用最有趣的方式带你飞~ 🚀 🌈 第①章 什么是Servlet? // 本质就是一个Java类! public class HelloServlet e…

游戏引擎学习第198天

回顾并为今天的内容设定 今天我们有一些代码需要处理。昨天我们进行了一些调试界面的整合工作,之前我们做了一些临时的、粗糙的操作,将一些东西读进来并放到调试界面中。今天,我们并不打算进行大规模的工作,更多的是对之前的代码…

Walrus 基金会启动 RFP 计划,推动生态发展

Walrus 基金会正式推出 Walrus RFP 提案申请计划,为推动和支持 Walrus 生态的项目提供资金支持。该计划旨在助力构建符合协议使命的解决方案,解锁去中心化和可编程存储的潜力。 无论项目是开发新工具、探索集成,还是提出创新用例&#xff0c…

智能配电箱:重塑未来电力管理的核心枢纽

哇塞!智能配电箱可是未来电力管理的超级核心枢纽呀,正以超燃的态势引领着电力行业迈向智能化变革的新征程呢!它在众多方面所展现出的独特优势和那广阔无垠的应用前景,简直太令人激动啦!下面就来瞧瞧智能配电箱在重塑未…

透过 /proc 看见内核:Linux 虚拟文件系统与 systemd 初始化初探

当我们在终端中输入 ps、top、cat /proc/cpuinfo 等命令时,是否思考过这些信息来自哪里?为什么无需启动任何守护进程,就能实时读取系统负载、内存占用,甚至内核版本?这一切的答案,都藏在 Linux 系统中的一个…

用DrissionPage升级维基百科爬虫:更简洁高效的数据抓取方案

一、原方案痛点分析 原代码使用urllibBeautifulSoup组合存在以下问题: 动态内容缺失:无法获取JavaScript渲染后的页面内容 反爬能力弱:基础请求头易被识别为爬虫 代码冗余:需要单独处理SSL证书验证 扩展性差:难以应…

C++STL——容器-vector(含部分模拟实现,即地层实现原理)(含迭代器失效问题)

目录 容器——vector 1.构造 模拟实现 2.迭代器 模拟实现: ​编辑 3.容量 模拟实现: 4.元素的访问 模拟实现 5.元素的增删查改 迭代器失效问题: 思考问题 【注】:这里的模拟实现所写的参数以及返回值,都是…

严重BUG修复及部分体验问题优化

随着Deepseek APIPython 测试用例一键生成与导出 V1.0.6的试用不断深入,会出现程序异常崩溃的问题。经群友定位,紧急修复了bug,并适当优化部分体验性问题。针对生成的测试用例xlsx文档,可以再次选中该xlsx给大模型进行推理生成新的…

Elasticsearch 证书问题解决

报错信息 javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested targetat org.elasticsearch.client.RestClient. extractAndWrapCause(R…

2023年CIE SCI1区TOP:序列融合麻雀搜索算法ISSA,深度解析+性能实测

目录 1.摘要2.麻雀搜索算法SSA原理3.改进策略3.结果展示4.参考文献5.代码获取 1.摘要 麻雀搜索算法(SSA)是一种基于麻雀觅食和防捕行为的群体智能算法。然而,基本SSA在迭代过程中,种群多样性逐渐降低,容易陷入局部最优…

配置晟腾910b的PyTorch torch_npu环境

1.【新教程】华为昇腾NPU的pytorch环境搭建 - Lukea - 博客园 1、新建conda环境。 conda create -n pytorch python3.102、在新建好的conda环境中,安装基础的依赖。 pip install attrs cython numpy1.24.0 decorator sympy cffi pyyaml pathlib2 psutil protobuf…

conda 激活环境vscode的Bash窗口

多份conda环境注意事项,当时安装了两个conda环境,miniconda和conda,导致环境总是冲突矛盾。初始化时需要更加注意。 $ C:/Users/a_hal/miniconda3/Scripts/conda.exe init bash能够显示用哪里的conda环境命令执行。 然后直接conda activate…

火山 RTC 引擎 2 ----APPKEY

前篇文章:火山RTC引擎 --一次失望的体验 那个DEMO可以编译运行了,但是功能不能用, 一用就崩溃。 主要原因还是没有APPKEY 一、火山引擎 APPKEY 管理 1、登录后台 账号登录-火山引擎欢迎登录火山引擎,火山引擎是字节跳动旗下的云…

Springboot学习笔记3.28

目录 实战第六课:文章分类开发 新增文章分类: 具体实现: 查询文章分类: 具体实现: 获取文章分类的详情 更新文章分类: 注意点: ​编辑 对校验规则进行分组: 学习时的疑惑…

【CSS3】05-定位 + 修饰属性

本文介绍定位和CSS中的修饰属性。 目录 1. 定位 1.1 相对定位 1.2 绝对定位 1.3 定位居中 1.4 固定定位 1.5 z-index堆叠层级 2. 修饰属性 2.1 垂直对齐方式 vertical-align 2.2 过渡属性 2.3 透明度 opacity 2.4 光标类型 cursor 1. 定位 灵活改变盒子在网页中的位…

如何屏蔽mac电脑更新提醒,禁止系统更新

最烦mac的系统更新提醒了,过几天就是更新弹窗提醒,现在可以直接禁掉了,眼不见心不乱,不然一升级,开发环境全都不能用了,那才是最可怕的,屏蔽的方法也很简单,就是屏蔽mac系统更新的请…