微信扫码
与创始人交个朋友
我要投稿
简单RAG和高级RAG的区别(作者绘制,灵感来自[1])
最近一项关于检索增强生成(RAG)的调查[1]总结了三种最近发展起来的范式:
高级RAG范式包括一组针对简单RAG已知局限性的技术。本文首先讨论这些技术,可以分为预检索、检索和后检索优化。
在下半部分,您将学习如何使用Python中的Llamaindex实现一个简单RAG流水线,然后通过选择以下高级RAG技术将其改进为高级RAG流水线:
随着RAG领域的最新进展,高级RAG作为一种新的范式已经发展起来,通过有针对性的增强来解决简单RAG范式的一些局限性。正如最近的一项调查[1]总结的那样,高级RAG技术可以分为预检索、检索和后检索优化。
简单RAG和高级RAG的区别(作者绘制,灵感来自[1])
预检索优化主要关注数据索引优化和查询优化。数据索引优化技术旨在以有助于提高检索效率的方式存储数据,例如[1]:
句子窗口检索
此外,预检索技术不仅限于数据索引,还可以涵盖推理时的技术,例如查询路由、查询重写和查询扩展。
检索阶段旨在识别最相关的上下文。通常,检索基于向量搜索,它计算查询和索引数据之间的语义相似性。因此,大多数检索优化技术围绕嵌入模型展开[1]:
BAAI/bge-small-en
是一个高性能嵌入模型,可以进行微调(参见微调指南)。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
我们将使用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流水线。您可以在此Jupyter Notebook中找到完整的简单RAG流水线。有关使用LangChain的实现,您可以继续阅读本文(使用LangChain的简单RAG流水线)。
首先,您可以在全局设置对象中定义一个嵌入模型和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()
接下来,您将在根目录中创建一个名为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()
from llama_index.core.node_parser import SimpleNodeParser
node_parser = SimpleNodeParser.from_defaults(chunk_size=1024)
# 从文档中提取节点
nodes = node_parser.get_nodes_from_documents(documents)
接下来,您将构建索引,将所有外部知识存储在开源向量数据库 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,
)
最后,您将将索引设置为查询引擎。
# QueryEngine 类配备了生成器
# 并且方便检索和生成步骤
query_engine = index.as_query_engine()
现在,您可以在数据上运行一个简单的 RAG 查询,如下所示:
# 运行简单的 RAG 查询
response = query_engine.query(
"Interleaf 发生了什么?"
)
在本节中,我们将介绍一些简单的调整,可以将上述简单的 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
执行两个操作:
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 流程只需要三个简单的步骤:
BAAI/bge-reranker-base
模型。node_postprocessors
列表中。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+中大型企业
2024-12-17
llamaindex实战-ChatEngine-Context(上下文)模式
2024-12-01
LlamaIndex,让AI唤醒你的数据
2024-11-29
llamaindex实战-Agent-自定义工具函数
2024-11-22
llamaindex实战-Agent-让Agent调用多个工具函数(本地部署)
2024-11-19
llamaindex实战-Workflow:工作流入门(本地部署断网运行)
2024-11-15
llamaindex实战-Agent-在Agent中使用RAG查询(本地部署)
2024-11-07
深度解析 REAcT Agent 的实现:利用 LlamaIndex 和 Gemini 提升智能代理工作流
2024-11-04
手把手教你用Coze零代码搭建一个智能搜索智能体,高时效性、保姆级!
2024-07-09
2024-04-20
2024-06-05
2024-04-25
2024-04-28
2024-05-09
2024-07-20
2024-04-26
2024-06-19
2024-04-08