2026年7月2日 周四晚上19:30,报名腾讯会议了解“如何构建自进化的动态知识库(Brain)”(限30人)
免费POC, 零成本试错
FDE知识库

FDE知识库

学习大模型的前沿技术与行业落地应用


收藏

LlamaIndex实现的高级检索增强生成

发布日期:2024-04-08 08:22:33 浏览次数: 4192
作者:数智笔记

微信搜一搜,关注“数智笔记”

如何通过在Python中实现有针对性的高级RAG技术来解决简单RAG流水线的局限性

简单RAG和高级RAG的区别(作者绘制,灵感来自[1])

最近一项关于检索增强生成(RAG)的调查[1]总结了三种最近发展起来的范式:

  • 简单RAG,
  • 高级RAG,以及
  • 模块化RAG。

高级RAG范式包括一组针对简单RAG已知局限性的技术。本文首先讨论这些技术,可以分为预检索、检索和后检索优化

在下半部分,您将学习如何使用Python中的Llamaindex实现一个简单RAG流水线,然后通过选择以下高级RAG技术将其改进为高级RAG流水线:

  • 预检索优化:句子窗口检索
  • 检索优化:混合搜索
  • 后检索优化:重新排序

什么是高级RAG

随着RAG领域的最新进展,高级RAG作为一种新的范式已经发展起来,通过有针对性的增强来解决简单RAG范式的一些局限性。正如最近的一项调查[1]总结的那样,高级RAG技术可以分为预检索、检索和后检索优化。

简单RAG和高级RAG的区别(作者绘制,灵感来自[1])

预检索优化

预检索优化主要关注数据索引优化和查询优化。数据索引优化技术旨在以有助于提高检索效率的方式存储数据,例如[1]:

  • 滑动窗口使用块之间的重叠,是最简单的技术之一。
  • 增强数据粒度应用数据清理技术,例如删除无关信息、确认事实准确性、更新过时信息等。
  • 添加元数据,例如日期、目的或章节,用于过滤目的。
  • 优化索引结构涉及不同的数据索引策略,例如调整块大小或使用多索引策略。本文将实现的一种技术是句子窗口检索,它将单个句子嵌入检索并在推理时用更大的文本窗口替换它们。

句子窗口检索

此外,预检索技术不仅限于数据索引,还可以涵盖推理时的技术,例如查询路由、查询重写和查询扩展。

检索优化

检索阶段旨在识别最相关的上下文。通常,检索基于向量搜索,它计算查询和索引数据之间的语义相似性。因此,大多数检索优化技术围绕嵌入模型展开[1]:

  • 微调嵌入模型定制嵌入模型以适应特定领域的上下文,特别是对于具有不断发展或罕见术语的领域。例如,BAAI/bge-small-en是一个高性能嵌入模型,可以进行微调(参见微调指南)。
  • 动态嵌入适应单词使用的上下文,而不像静态嵌入那样为每个单词使用单个向量。例如,OpenAI的embeddings-ada-02是一个复杂的动态嵌入模型,可以捕捉上下文理解[1]。

除了向量搜索之外,还有其他检索技术,例如混合搜索,它通常指的是将向量搜索与基于关键字的搜索相结合的概念。如果您的检索需要精确的关键字匹配,这种检索技术非常有用。

后检索优化

对检索到的上下文进行额外处理可以帮助解决超出上下文窗口限制或引入噪声等问题,从而阻碍对关键信息的关注。RAG调查[1]总结的后检索优化技术有:

  • 提示压缩通过删除无关内容和突出重要上下文来减少总提示长度。
  • 重新排序使用机器学习模型重新计算检索到的上下文的相关性分数。

重新排序

先决条件

本节讨论了在本文中跟随的所需软件包和API密钥。

所需软件包

本文将指导您如何使用Python中的LlamaIndex实现一个简单和一个高级RAG流水线。

pip install llama-index

在本文中,我们将使用LlamaIndexv0.10。如果您正在从较旧的LlamaIndex版本升级,您需要运行以下命令以正确安装和运行LlamaIndex:

pip uninstall llama-index
pip install llama-index --upgrade --no-cache-dir --force-reinstall

LlamaIndex提供了一种选项,可以将向量嵌入存储在JSON文件中以进行持久化存储,这对于快速原型设计非常有用。但是,由于高级RAG技术旨在用于生产就绪的应用程序,因此我们将使用向量数据库进行持久化存储。

由于我们需要元数据存储和混合搜索功能,除了存储向量嵌入之外,我们还将使用开源向量数据库Weaviate(v3.26.2),它支持这些功能。

pip install weaviate-client llama-index-vector-stores-weaviate

API密钥

我们将使用Weaviate嵌入式,您可以在不注册API密钥的情况下免费使用它。但是,本教程使用了一个嵌入模型和来自OpenAI的LLM,您将需要一个OpenAI API密钥。要获取API密钥,您需要一个OpenAI帐户,然后在API密钥下“创建新的秘密密钥”。

接下来,在根目录中创建一个名为.env的本地文件,并在其中定义您的API密钥:

OPENAI_API_KEY="<YOUR_OPENAI_API_KEY>"

然后,您可以使用以下代码加载您的API密钥:

# !pip install python-dotenv
import os
from dotenv import load_dotenv,find_dotenv

load_dotenv(find_dotenv())

使用LlamaIndex实现简单RAG

本节讨论了如何使用LlamaIndex实现一个简单的RAG流水线。您可以在此Jupyter Notebook中找到完整的简单RAG流水线。有关使用LangChain的实现,您可以继续阅读本文(使用LangChain的简单RAG流水线)。

步骤1:定义嵌入模型和LLM

首先,您可以在全局设置对象中定义一个嵌入模型和LLM。这样做意味着您不必在代码中再次显式指定模型。

  • 嵌入模型:用于为文档块和查询生成向量嵌入。
  • LLM:用于根据用户查询和相关上下文生成答案。
from llama_index.embeddings.openai import OpenAIEmbedding
from llama_index.llms.openai import OpenAI
from llama_index.core.settings import Settings

Settings.llm = OpenAI(model="gpt-3.5-turbo", temperature=0.1)
Settings.embed_model = OpenAIEmbedding()

步骤2:加载数据

接下来,您将在根目录中创建一个名为data的本地目录,并从LlamaIndex GitHub存储库(MIT许可证)下载一些示例数据。

!mkdir -p 'data'
!wget '<https://raw.githubusercontent.com/run-llama/llama_index/main/docs/examples/data/paul_graham/paul_graham_essay.txt>' -O 'data/paul_graham_essay.txt'

然后,您可以加载数据以进行进一步处理:

from llama_index.core import SimpleDirectoryReader

# Load data
documents = SimpleDirectoryReader(
        input_files=["./data/paul_graham_essay.txt"]
).load_data()

步骤3:将文档分块为节点

from llama_index.core.node_parser import SimpleNodeParser

node_parser = SimpleNodeParser.from_defaults(chunk_size=1024)

# 从文档中提取节点
nodes = node_parser.get_nodes_from_documents(documents)

步骤 4:构建索引

接下来,您将构建索引,将所有外部知识存储在开源向量数据库 Weaviate 中。

首先,您需要连接到 Weaviate 实例。在本例中,我们使用 Weaviate Embedded,它允许您在没有 API 密钥的情况下免费在笔记本中进行实验。对于生产环境的解决方案,建议您自己部署 Weaviate,例如 通过 Docker 或使用 托管服务。

import weaviate

# 连接到 Weaviate 实例
client = weaviate.Client(
    embedded_options=weaviate.embedded.EmbeddedOptions(), 
)

接下来,您将使用 Weaviate 客户端构建一个 VectorStoreIndex,用于存储和交互数据。

from llama_index.core import VectorStoreIndex, StorageContext
from llama_index.vector_stores.weaviate import WeaviateVectorStore

index_name = "MyExternalContext"

# 构建向量存储
vector_store = WeaviateVectorStore(
    weaviate_client = client, 
    index_name = index_name
)

# 设置嵌入存储
storage_context = StorageContext.from_defaults(vector_store=vector_store)

# 设置索引
# 构建 VectorStoreIndex,负责将文档分块并将块编码为嵌入以供将来检索
index = VectorStoreIndex(
    nodes,
    storage_context = storage_context,
)

步骤 5:设置查询引擎

最后,您将将索引设置为查询引擎。

# QueryEngine 类配备了生成器
# 并且方便检索和生成步骤
query_engine = index.as_query_engine()

步骤 6:在数据上运行一个简单的 RAG 查询

现在,您可以在数据上运行一个简单的 RAG 查询,如下所示:

# 运行简单的 RAG 查询
response = query_engine.query(
    "Interleaf 发生了什么?"
)

使用 LlamaIndex 实现高级 RAG

在本节中,我们将介绍一些简单的调整,可以将上述简单的 RAG 流程转变为高级流程。本教程将涵盖以下一些高级 RAG 技术:

  • 预检索优化:句子窗口检索
  • 检索优化:混合搜索
  • 后检索优化:重新排序

由于我们只涵盖了这里的修改内容,您可以在此 Jupyter Notebook 中找到完整的端到端高级 RAG 流程。

索引优化示例:句子窗口检索

对于句子窗口检索技术,您需要进行两个调整:首先,您必须调整数据的存储和后处理方式。我们将使用 SentenceWindowNodeParser 替代 SimpleNodeParser

from llama_index.core.node_parser import SentenceWindowNodeParser

# 使用默认设置创建句子窗口节点解析器
node_parser = SentenceWindowNodeParser.from_defaults(
    window_size=3,
    window_metadata_key="window",
    original_text_metadata_key="original_text",
)

SentenceWindowNodeParser 执行两个操作:

  1. 将文档分割为单个句子,并对其进行嵌入。
  2. 对于每个句子,创建一个上下文窗口。如果指定 window_size = 3,则生成的窗口将由三个句子组成,从嵌入句子的前一个句子开始,跨越下一个句子。窗口将存储为元数据。

在检索过程中,返回与查询最匹配的句子。在检索之后,您需要通过定义 MetadataReplacementPostProcessor 并将其用于 node_postprocessors 列表中,将句子替换为元数据中的整个窗口。

from llama_index.core.postprocessor import MetadataReplacementPostProcessor

# 目标键默认为 `window`,以匹配 node_parser 的默认设置
postproc = MetadataReplacementPostProcessor(
    target_metadata_key="window"
)

...

query_engine = index.as_query_engine( 
    node_postprocessors = [postproc],
)

检索优化示例:混合搜索

在 LlamaIndex 中实现混合搜索只需要对 query_engine 进行两个参数更改,如果底层向量数据库支持混合搜索查询。alpha 参数指定向量搜索和基于关键字的搜索之间的加权比例,其中 alpha=0 表示基于关键字的搜索,alpha=1 表示纯向量搜索。

query_engine = index.as_query_engine(
    ...,
    vector_store_query_mode="hybrid"
    alpha=0.5,
    ...
)

后检索优化示例:重新排序

将重新排序器添加到您的高级 RAG 流程只需要三个简单的步骤:

  1. 首先,定义一个重新排序器模型。在这里,我们使用来自 Hugging Face 的 BAAI/bge-reranker-base 模型。
  2. 在查询引擎中,将重新排序器模型添加到 node_postprocessors 列表中。
  3. 增加查询引擎中的 similarity_top_k,以检索更多上下文段落,可以在重新排序后减少为 top_n
# !pip install torch sentence-transformers
from llama_index.core.postprocessor import SentenceTransformerRerank

# 定义重新排序器模型
rerank = SentenceTransformerRerank(
    top_n = 2
    model = "BAAI/bge-reranker-base"
)

...

# 将重新排序器添加到查询引擎中
query_engine = index.as_query_engine(
  similarity_top_k = 6,
  ...,
                node_postprocessors = [rerank],
  ...,
)


53AI,企业落地大模型首选服务商

产品:场景落地咨询+大模型应用平台+行业解决方案

承诺:免费POC验证,效果达标后再合作。零风险落地应用大模型,已交付160+中大型企业

联系我们

售前咨询
186 6662 7370
预约演示
185 8882 0121

微信扫码

添加专属顾问

回到顶部

加载中...

扫码咨询

扫码登录
登录即表示您同意《53AI网站服务协议》
服务协议

欢迎您使用【53AI 官方网站】(以下简称“本网站”或“我们”)。本《会员服务协议》(以下简称“本协议”)是您(以下简称“会员”或“用户”)与【深圳市博思协创网络科技有限公司】之间关于注册、登录及使用本网站会员服务所订立的法律协议。

在您注册或登录前,请务必审慎阅读、充分理解各条款内容,特别是免除或限制责任的条款、知识产权条款、争议解决条款等。此类条款将以加粗形式提示您注意。 当您通过微信公众号授权、手机验证码验证或其他方式成功登录本网站时,即视为您已完全理解并同意接受本协议的全部内容。

一、 定义

本网站:指由【深圳市博思协创网络科技有限公司】运营的,域名为【53ai.com】的网站及相关移动端页面。

会员服务:指本网站向注册会员提供的知识库文章查阅、内容检索及其他相关增值服务。

知识库内容:指本网站发布的包括但不限于文字、图表、数据、研究报告、行业分析等数字化内容资源。

二、 账号注册与登录

登录方式:本网站支持以下登录方式,您可根据实际情况选择:

微信公众号授权登录:您同意将您的微信OpenID信息授权给本网站,用于创建或关联会员账号。

手机验证码登录:您需提供真实有效的手机号码,并通过短信验证码完成身份验证与登录/注册。

账号安全:您的账号仅限您本人使用,禁止赠与、借用、租用、转让或售卖。因您保管不善导致的账号被盗、密码泄露等损失,由您自行承担。

实名认证:根据相关法律法规要求,我们可能要求您在特定功能下完成实名认证。如您拒绝提供,可能无法使用部分或全部服务。

未成年人保护:若您未满18周岁,请在法定监护人的陪同下阅读本协议,并在征得监护人同意后使用本服务。

三、 服务内容与规范

知识库查阅权限:会员登录后,有权按照其会员等级对应的权限范围,在线浏览、检索本网站知识库中的相关文章及内容。

服务变更:我们有权根据业务发展需要,调整、变更或终止部分服务内容,并将以网站公告、公众号消息等方式提前通知。

禁止行为:您在使用服务时不得实施以下行为:

利用技术手段批量爬取、下载、转存知识库内容;

将知识库内容用于商业目的或未经授权地向第三方传播;

干扰本网站正常运行或侵犯其他用户合法权益;

发布违法违规信息或从事违反公序良俗的活动。

四、 知识产权声明

权利归属:本网站知识库中的排版设计、软件代码等内容的知识产权均归【公司全称】或原权利人所有,受《中华人民共和国著作权法》等法律保护。

有限许可:本网站授予会员一项非独占、不可转让、不可转授权的普通许可,仅限于个人学习、研究之目的在线查阅知识库内容。

侵权追责:未经书面许可,任何单位或个人不得以任何形式复制、转载、摘编、镜像、汇编或以其他方式使用上述内容。一经发现,我们保留追究其法律责任的权利。

五、 个人信息保护

我们重视对您个人信息的保护。关于我们如何收集、使用、存储和保护您的个人信息,请单独阅读 《隐私政策》。

您通过微信公众号授权或手机号验证所提供的信息,我们将严格按照《个人信息保护法》的规定处理,仅用于身份识别、服务提供及安全验证等必要用途。

您可以随时通过网站设置或联系客服行使查阅、更正、删除个人信息及撤回授权同意的权利。

六、 免责声明

内容准确性:知识库内容仅供参考,不构成专业建议。我们不对其完整性、准确性、时效性作任何明示或暗示的保证,您应自行判断并承担使用风险。

不可抗力:因自然灾害、政策法规变化、网络故障、第三方平台接口异常(如微信接口维护、运营商短信通道故障)等不可抗力导致的服务中断或延迟,我们不承担违约责任。

第三方链接:本网站可能包含指向第三方网站的链接,该等网站的内容和服务不受我们控制,请您自行甄别风险。

七、 违约责任

如您违反本协议约定,我们有权视情节采取警告、限制功能、暂停服务、注销账号等措施,并保留要求赔偿损失的权利。

如因您的违约行为导致我们遭受行政处罚、第三方索赔或商誉损失,您应承担全部赔偿责任(包括但不限于罚款、赔偿金、律师费、公证费等)。

八、 法律适用与争议解决

本协议的订立、执行和解释均适用中华人民共和国大陆地区法律。

因本协议产生的或与本协议有关的任何争议,双方应友好协商解决;协商不成的,任何一方均可向【公司所在地】有管辖权的人民法院提起诉讼。

九、 其他

本协议构成双方就本服务达成的完整协议,取代此前任何口头或书面约定。

本协议任一条款被认定为无效或不可执行的,不影响其他条款的效力。

我们对本协议享有最终解释权,并在法律允许的范围内保留随时修改的权利。修改后的协议一经公布即生效,继续使用服务即视为同意修订内容。


已查阅