LLM之RAG实战(四十一)| 使用LLamaIndex和Gemini构建高级搜索引擎

       Retriever 是 RAG(Retrieval Augmented Generation)管道中最重要的部分。在本文中,我们将使用 LlamaIndex 实现一个结合关键字和向量搜索检索器的自定义检索器,并且使用 Gemini大模型来进行多个文档聊天。

通过本文,我们将了解到如下内容:

  • 深入了解 RAG 管道中 Retriever 和 Generator 组件在上下文生成响应中的作用;
  • 学习集成关键字矢量搜索技术以开发自定义检索器,从而提高 RAG 应用程序中搜索的准确性;
  • 熟练掌握使用 LlamaIndex 进行数据摄取,提供给LLMs上下文信息;
  • 了解自定义检索器在通过混合搜索机制减轻LLM响应中的幻觉方面的重要性;
  • 探索高级检索器实现,例如rerank和 HyDE,以增强 RAG 中的文档相关性;
  • 了解如何在 LlamaIndex 中集成 Gemini LLM 和嵌入,以生成响应和存储数据,从而提高 RAG 功能;
  • 开发自定义检索器配置的决策技能,包括在 AND 和 OR 操作之间进行选择以优化搜索结果。

一、retriever的重要性

       要开发自定义retriever,确定最适合我们需求的retriever类型至关重要。这里,我们将实现一个集成关键字搜索和矢量搜索的混合搜索。

       矢量搜索根据相似性或语义搜索来识别用户查询的相关文档,而关键字搜索则根据术语出现的频率来查找文档。使用 LlamaIndex 可以通过两种方式实现这种集成。为混合搜索生成自定义检索器时,一个重要的决策是在使用 AND 或 OR 操作之间进行选择:

  • AND 操作:此方法检索包含所有指定术语的文档,使其更具限制性,但确保高度相关性。可以将其视为关键字搜索和矢量搜索之间的结果交集;
  • OR 操作:此方法检索包含任何指定术语的文档,从而增加结果的广度,但可能会降低相关性。可以将其视为关键字搜索和矢量搜索之间的结果联合。

二、构建自定义retriever

       现在让我们使用 LlamaIndex 构建自定义retriever,大致需要如下步骤:

2.1 安装所需的包

       在我们的例子中,使用 LlamaIndex 来构建自定义检索器,使用 Gemini 来构建嵌入模型和LLM推理,并使用 PyPDF 来构建数据连接器,因此,需要安装所需的库。

!pip install llama-index!pip install llama-index-multi-modal-llms-gemini!pip install llama-index-embeddings-gemini

2.2 设置Google API密钥

       利用 Google Gemini 作为大型语言模型来生成响应,并作为嵌入模型,使用 LlamaIndex 将数据转换和存储在vector数据库或内存中。

如果没有Google API Key,可以在这里(http://ai.google.dev/)申请。

from getpass import getpassGOOGLE_API_KEY = getpass("Enter your Google API:")

2.3 加载数据并创建文档节点

       在 LlamaIndex 中,数据加载是使用 SimpleDirectoryLoader 完成的。首先,需要创建一个文件夹并将任何格式的数据上传到此数据文件夹中。在我们的示例中,我们将把一个 PDF 文件上传到 data 文件夹中。加载文档后,将文档拆分为更小的段,将其解析为节点。节点是在 LlamaIndex 框架中定义的数据架构。

       最新版本的 LlamaIndex 更新了其代码结构,现在包括节点解析器、嵌入模型和LLM设置中的定义。

from llama_index.core import SimpleDirectoryReaderfrom llama_index.core import Settingsdocuments = SimpleDirectoryReader('data').load_data()nodes = Settings.node_parser.get_nodes_from_documents(documents)

2.4 设置嵌入模型和大型语言模型

        Gemini 有各种型号,包括 gemini-pro、gemini-1.0-pro、gemini-1.5、视觉模型等。这里,我们将使用默认模型并提供 Google API Key。对于 Gemini 中的嵌入模型,我们目前使用的是 embedding-001。

from llama_index.embeddings.gemini import GeminiEmbeddingfrom llama_index.llms.gemini import GeminiSettings.embed_model = GeminiEmbedding(    model_name="models/embedding-001", api_key=GOOGLE_API_KEY)Settings.llm = Gemini(api_key=GOOGLE_API_KEY)

2.5 定义Storage context,并存储数据

       一旦数据被解析为节点,LlamaIndex 就会提供一个存储上下文,它提供默认的文档存储,用于存储数据的向量嵌入。此存储上下文将数据保留在内存中,以便以后对其进行索引。

from llama_index.core import StorageContextstorage_context = StorageContext.from_defaults()storage_context.docstore.add_documents(nodes)

       为了构建自定义检索器以执行混合搜索,我们需要创建两个索引。第一个可以执行向量搜索的向量索引,第二个可以执行关键字搜索的关键字索引。为了创建索引,我们需要存储上下文和节点文档,以及嵌入模型和LLM的默认设置。

from llama_index.core import SimpleKeywordTableIndex, VectorStoreIndexvector_index = VectorStoreIndex(nodes, storage_context=storage_context)keyword_index = SimpleKeywordTableIndex(nodes, storage_context=storage_context)

2.6 构建自定义Retriever

       要使用 LlamaIndex 构建用于混合搜索的自定义检索器,我们首先需要定义架构,尤其是配置合适的节点。需要矢量索引检索器和关键字检索器来执行混合搜索,是通过指定模式(AND 或 OR)来实现这两种检索器的组合,集成这两种技术以最大限度地减少幻觉。

       一旦节点配置好后,我们就可以使用 vector 和 keyword 检索器查询每个节点 ID 的数据。然后,根据所选模式,最终确定自定义检索器。

from llama_index.core import QueryBundlefrom llama_index.core.schema import NodeWithScorefrom llama_index.core.retrievers import (    BaseRetriever,    VectorIndexRetriever,    KeywordTableSimpleRetriever,)from typing import Listclass CustomRetriever(BaseRetriever):    def __init__(        self,        vector_retriever: VectorIndexRetriever,        keyword_retriever: KeywordTableSimpleRetriever,        mode: str = "AND") -> None:               self._vector_retriever = vector_retriever        self._keyword_retriever = keyword_retriever        if mode not in ("AND", "OR"):            raise ValueError("Invalid mode.")        self._mode = mode        super().__init__()    def _retrieve(self, query_bundle: QueryBundle) -> List[NodeWithScore]:        vector_nodes = self._vector_retriever.retrieve(query_bundle)        keyword_nodes = self._keyword_retriever.retrieve(query_bundle)        vector_ids = {n.node.node_id for n in vector_nodes}        keyword_ids = {n.node.node_id for n in keyword_nodes}        combined_dict = {n.node.node_id: n for n in vector_nodes}        combined_dict.update({n.node.node_id: n for n in keyword_nodes})        if self._mode == "AND":            retrieve_ids = vector_ids.intersection(keyword_ids)        else:            retrieve_ids = vector_ids.union(keyword_ids)        retrieve_nodes = [combined_dict[r_id] for r_id in retrieve_ids]        return retrieve_nodes

2.7 定义retriever

       定义好自定义检索器类后,我们需要实例化检索器并合成查询引擎。响应合成器用于根据用户查询和给定的文本块集生成LLM响应。Response Synthesizer 的输出是一个 Response 对象,该对象将自定义检索器作为参数之一。

from llama_index.core import get_response_synthesizerfrom llama_index.core.query_engine import RetrieverQueryEnginevector_retriever = VectorIndexRetriever(index=vector_index, similarity_top_k=2)keyword_retriever = KeywordTableSimpleRetriever(index=keyword_index)# custom retriever => combine vector and keyword retrievercustom_retriever = CustomRetriever(vector_retriever, keyword_retriever)# define response synthesizerresponse_synthesizer = get_response_synthesizer()custom_query_engine = RetrieverQueryEngine(    retriever=custom_retriever,    response_synthesizer=response_synthesizer,)

2.8 运行自定义检索查询引擎

       最后,我们已经开发好了自定义的retriever,它可以显著减少幻觉。为了测试其有效性,我们使用一个包括上下文的提示和一个不包括上下文的提示来评估生成的响应。

query = "what does the data context contain?"print(custom_query_engine.query(query))print(custom_query_engine.query("what is science?")

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

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

相关文章

明确产业定位,用科学规划铸就高品质文化产业园

科学规划是构建高品质文化产业园区的重要保障。通过明确产业定位与发展目标、科学规划空间布局、完善基础设施与配套设施、注重生态环境保护、加强人才引进与培养以及推动产业协同发展等措施的实施,可以推动文化产业园区向高品质、高效益、可持续的方向发展。 一、明…

【TB作品】51单片机 Proteus仿真 超声波读取+LCD1602显示仿真12MHZ

实验报告:51单片机 Proteus仿真 超声波读取LCD1602显示仿真 一、实验背景 本实验旨在使用51单片机(AT89C51)结合超声波传感器HC-SR04和LCD1602液晶显示屏,通过Proteus仿真平台实现超声波测距功能,并将测得的距离显示…

leetcode hot100

哈希 49.字母异位词分组 HashMap的含义比较晕,可以重做 双指针 11.盛最多水的容器 双指针的起始位置和移动条件没转过来,可以重做 15.三数之和 不太熟练,可以再做一遍 42.接雨水 还可以用dp和单调栈做 双指针法: 首先需要注意…

【DFS(深度优先搜索)详解】看这一篇就够啦

【DFS详解】看这一篇就够啦 🍃1. 算法思想🍃2. 三种枚举方式🍃2.1 指数型枚举🍃2.2 排列型枚举🍃2.3 组合型枚举 🍃3. 剪枝优化🍃4. 图的搜索🍃5. 来几道题试试手🍃5.1 选…

spark任务,使用 repartition 对数据进行了重新分区,但任务输入数据大小仍存在不均衡

目录 目录 确认 Spark 任务重新分区后的数据不均衡 1. 检查分区大小 2. 使用 DataFrame API 检查分区 3. 使用 Spark UI 查看分区情况 4. 使用日志记录分区信息 可能原因 1. 数据分布不均衡 2. 分区策略 3. 数据预处理 解决方案 1. 检查数据分布 2. 使用 coalesce…

代码随想录算法训练营Day62|冗余连接、冗余连接II

冗余连接 108. 冗余连接 (kamacoder.com) 考虑使用并查集&#xff0c;逐次将s、t加入并查集中&#xff0c;当发现并查集中find(u)和find(v)相同时&#xff0c;输出u和v&#xff0c;表示删除的边即可。 #include <iostream> #include <vector> using namespace s…

【分布式系统】注册中心Zookeeper

目录 一.Zookkeeper 概述 1.Zookkeeper 定义 2.Zookkeeper 工作机制 3.Zookkeeper 特点 4.Zookkeeper 数据结构 5.Zookkeeper 应用场景 统一命名服务 统一配置管理 统一集群管理 服务器动态上下线 软负载均衡 6.Zookkeeper 选举机制 第一次启动选举机制 非第一次…

uboot镜像之boot烧写

适用场景:单板上没有boot&#xff0c;和按地址烧写配合&#xff0c;可完成单板所有镜像的烧写。 原理:bootrom读取u-boot.bin至内存并执行此u-boot 然后运行uboot,通过uboot sf命令烧录uboot.bin到flash存储空间去. bootrom读取u-boot.bin至内存并执行此u-boot 通过uboot sf命…

【开发工具】webStrom2024版-插件

Chinese (Simplified) Language Pack / 中文语言包 英文界面变为中文界面。 Material Theme UI 界面美化 Rainbow Brackets 代码量变大时&#xff0c;总会伴随着各种括号&#xff1b;它能将括号赋予不同的颜色&#xff0c;方便我们区分。 Translation 中英互译&#xff0c;…

Codeforces Round 918 (Div. 4)(A~F)

目录 A. Odd One Out B. Not Quite Latin Square C. Can I Square? D. Unnatural Language Processing E. Romantic Glasses F. Greetings A. Odd One Out Problem - A - Codeforces 输出一个不同于其他两个数的数&#xff0c;用异或操作可以轻松解决。 void solve{int…

高考志愿填报,选专业是看兴趣还是看就业?

对于结束高考的学生来说&#xff0c;选择专业的确是一个非常让人头疼的事情。因为很多人都不知道&#xff0c;选专业的时候究竟是应该看一下个人兴趣&#xff0c;还是看未来的就业方向&#xff0c;这也是让不少人都相当纠结的问题。这里分析一下关于专业选择的问题&#xff0c;…

windows下docker安装

目录 前言 1.搭建WSL2环境 1.1打开控制面板 1.2 将WSL 2设置为默认值 2.安装docker 3.使用docker 结论&#xff1a; 前言 本文安装docker&#xff0c;将使用WSL2&#xff0c;而不是vmeare和Hyper-V&#xff0c;也不需要你另外安装Linux系统&#xff08;如Ubuntu&#x…

PostgreSQL主从同步

目录 一、主从复制原理 二、配置主数据库 2.1 创建同步账号 2.2 配置同步账号访问控制 2.3 设置同步参数 3.4 重启主数据库 三、配置从数据库 3.1 停止从库 3.2 清空从库数据文件 3.3 拉取主库数据文件 3.4 配置从库同步参数 3.5 启动从库 四、测试主从 4.1在主库…

【HTML入门】第四课 - 换行、分割横线和html的注释

这一小节&#xff0c;我们继续说HTML的入门知识&#xff0c;包括换行、横线分割以及注释&#xff08;html的注释&#xff09;。 目录 1 换行 2 分割横线 3 html注释 1 换行 html中分为块元素和行内元素。这一小节呢&#xff0c;先不说这些元素们&#xff0c;我们先说一下换…

免费分享:1981-2016全球粮食产量数据集(附下载方法)

了解主要作物的历史产量模式&#xff0c;包括趋势和年际变化&#xff0c;对于了解在粮食需求和气候变化日益增长的情况下粮食生产的现状、潜力和风险至关重要。 数据简介 1981-2016全球粮食产量数据集是农业普查统计&#xff08;粮农组织报告的国家产量统计数据&#xff09;和…

云渲染平台那个好?2024云渲染测评

1.渲染100&#xff08;强烈推荐&#xff09; 以高性价比著称&#xff0c;是预算有限的小伙伴首选。 15分钟0.2,60分钟内0.8;注册填邀请码【5858】可领30元礼包和免费渲染券) 提供了多种机器配置选择(可以自行匹配环境)最高256G大内存机器&#xff0c;满足不同用户需求。支持…

GDBFuzz:基于硬件断点的嵌入式系统模糊测试工具

关于GDBFuzz GDBFuzz是一款功能强大的模糊测试工具&#xff0c;在该工具的帮助下&#xff0c;广大研究人员可以使用硬件断点对嵌入式系统进行模糊测试。 GDBFuzz的理念是利用微控制器的硬件断点作为覆盖引导模糊测试的反馈。因此&#xff0c;GDB被用作通用接口以实现广泛的适用…

Java异常详解及自定义异常

认识异常&#xff0c;掌握异常处理主要的5个关键字&#xff1a;throw、try、catch、final、throws并掌握自定义异常 目录 1、异常概念与体系结构 1、1异常的概念 1、2异常体系结构 1、3异常的分类 编译时异常&#xff1a; 运行时异常 &#xff1a; 2、异常处理 2、1防御式…

如何确保 PostgreSQL 在高并发写操作场景下的数据完整性?

文章目录 一、理解数据完整性二、高并发写操作带来的挑战三、解决方案&#xff08;一&#xff09;使用合适的事务隔离级别&#xff08;二&#xff09;使用合适的锁机制&#xff08;三&#xff09;处理死锁&#xff08;四&#xff09;使用索引和约束&#xff08;五&#xff09;批…