跳到主要内容LlamaIndex 中构建 RAG 应用完整指南 | 极客日志PythonAI算法
LlamaIndex 中构建 RAG 应用完整指南
本文介绍了在 LlamaIndex 框架中构建检索增强生成(RAG)应用的完整流程。内容包括环境依赖安装、文档加载与 Document 对象解析、LLM 与 Embedding 模型配置、Node 节点解析策略对比(基础解析与句子窗口解析)、VectorStoreIndex 索引构建、RetrieverQueryEngine 查询引擎设置以及索引的持久化存储与加载。重点阐述了 SentenceWindowNodeParser 如何通过捕获上下文窗口提升检索质量,并提供了具体的代码示例和优化建议,帮助用户高效实现基于私有数据的智能问答系统。
灭霸1 浏览 LlamaIndex 中构建 RAG 应用完整指南
什么是 LlamaIndex
LlamaIndex 是一个专门用于构建基于大语言模型(LLM)的应用程序的数据框架。它的主要功能是帮助开发者摄取、结构化并访问私有或特定领域的数据,从而实现检索增强生成(RAG, Retrieval-Augmented Generation)。通过 LlamaIndex,可以将非结构化数据转化为 LLM 可理解的上下文,显著提升回答的准确性和相关性。
核心流程概览
在 LlamaIndex 中使用 RAG 通常遵循以下五个基本步骤:
- 加载文档:从本地文件、数据库或 API 获取原始数据。
- 解析文档:将文档拆分为
Node 节点,以便进行索引。
- 构建索引:利用嵌入模型将节点转换为向量并存储。
- 配置查询引擎:设置检索器和响应合成器。
- 执行查询:输入问题,获取基于上下文的生成式回答。
环境依赖安装
首先,需要安装必要的 Python 包。以下命令适用于大多数 Linux 和 macOS 环境,Windows 用户需注意编译依赖。
pip install llama-index -qU
pip install openai
pip install pypdf
pip install doc2txt
pip install llama-cpp-python
pip install transformers
pip install accelerate
如果是 Jupyter Notebook 环境,请使用 !pip 前缀。
导入模块与基础配置
初始化项目时,需要导入核心组件并配置日志输出,便于调试。
import os
import openai
from getpass import getpass
import logging
import sys
from pprint import pprint
logging.basicConfig(stream=sys.stdout, level=logging.INFO)
logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stdout))
from llama_index import (
VectorStoreIndex,
SimpleDirectoryReader,
load_index_from_storage,
StorageContext,
ServiceContext,
Document
)
from llama_index.llms import OpenAI, HuggingFaceLLM
from llama_index.prompts import PromptTemplate
from llama_index.text_splitter import SentenceSplitter
from llama_index.embeddings import OpenAIEmbedding, HuggingFaceEmbedding
from llama_index.schema import MetadataMode
from llama_index.postprocessor import MetadataReplacementPostProcessor
数据加载与 Document 对象
Document 是 LlamaIndex 中的基础容器,用于保存来自各种来源的数据,如 PDF、API 输出或数据库记录。
使用 SimpleDirectoryReader 可以方便地加载本地目录下的文件。
documents = SimpleDirectoryReader('./Data/').load_data()
print(f"加载了 {len(documents)} 个文档")
pprint(documents)
加载完成后,每个文档对象包含文本内容和元数据。例如,PDF 文件会被解析为文本数组,元数据中包含文件名、路径、大小等信息。
print(documents[0].get_content())
print(documents[0].metadata)
配置 LLM 与 Embedding 模型
设置 LLM
可以选择使用云端 API(如 OpenAI)或本地部署的模型(如 Hugging Face)。以下示例展示如何配置本地 HuggingFaceLLM。
from llama_index.llms import HuggingFaceLLM
from llama_index.prompts import PromptTemplate
llm = HuggingFaceLLM(
model_name="HuggingFaceH4/zephyr-7b-beta",
tokenizer_name="HuggingFaceH4/zephyr-7b-beta",
context_window=4096,
max_new_tokens=512,
model_kwargs={'trust_remote_code': True},
generate_kwargs={"temperature": 0.0},
device_map="auto"
)
配置 Embedding 模型
Embedding 模型负责将文本转换为向量,是向量检索的基础。推荐使用 BGE 系列等高性能开源模型。
from llama_index.embeddings.huggingface import HuggingFaceEmbedding
embed_model = HuggingFaceEmbedding(model_name="BAAI/bge-large-en-v1.5")
Node 节点解析策略
在 LlamaIndex 中,Node 对象表示源文档的'块'或部分,被视为一等公民。根据需求,可以选择不同的解析策略。
1. 标准节点解析 (Base Nodes)
默认情况下,可以使用 SimpleNodeParser 将整个文档或按固定长度拆分。这种方法适用于文档较短或上下文不需要跨段落的情况。
from llama_index.node_parser import SimpleNodeParser
base_node_parser = SimpleNodeParser()
base_nodes = base_node_parser.get_nodes_from_documents(documents)
2. 句子窗口节点解析 (Sentence Window)
对于长文档,简单的切分可能导致上下文丢失。SentenceWindowNodeParser 旨在将文档解析为句子节点,并为每个节点捕获周围句子的窗口信息。这对于上下文感知的文本处理非常有用。
from llama_index.node_parser import SentenceWindowNodeParser
sentence_node_parser = SentenceWindowNodeParser.from_defaults(
window_size=3,
window_metadata_key="window",
original_text_metadata_key="original_text"
)
nodes = sentence_node_parser.get_nodes_from_documents(documents)
- 上下文增强:检索到目标句子时,同时获取其前后的上下文,减少断章取义。
- 元数据关联:节点元数据中包含了
window 字段,可在后续查询中用于替换或补充内容。
构建索引与服务上下文
ServiceContext 是管理管道中资源(如 LLM、Embedding、Node Parser)的容器。
ctx_sentence = ServiceContext.from_defaults(
llm=llm,
embed_model=embed_model,
node_parser=sentence_node_parser
)
ctx_base = ServiceContext.from_defaults(
llm=llm,
embed_model=embed_model,
node_parser=base_node_parser
)
VectorStoreIndex
VectorStoreIndex 是最常用的索引类型,它利用向量相似度进行快速检索。它将节点文本转换为向量并存储在向量数据库中。
sentence_index = VectorStoreIndex(
nodes,
service_context=ctx_sentence
)
base_index = VectorStoreIndex(
base_nodes,
service_context=ctx_base
)
查询引擎与后处理器
RetrieverQueryEngine
该引擎结合检索器和响应合成器工作。检索器负责从索引中获取相关节点,合成器负责生成自然语言回答。
sentence_query_engine = sentence_index.as_query_engine(
similarity_top_k=5,
verbose=True,
node_postprocessor=[
MetadataReplacementPostProcessor("window")
],
)
base_query_engine = base_index.as_query_engine(
similarity_top_k=5,
verbose=True,
)
MetadataReplacementPostProcessor
此处理器用于将节点内容替换为元数据中的字段。与 SentenceWindowNodeParser 配合使用时效果最佳,能确保生成的回答包含完整的上下文背景。
执行查询示例
query = "使用 Python 检测图像中的人脸的示例代码。"
response_sentence = sentence_query_engine.query(query)
print(response_sentence)
response_base = base_query_engine.query(query)
print(response_base)
预期结果:
句子窗口解析器通常会提供更连贯的代码片段和解释,因为它利用了上下文窗口信息;而基础解析器可能仅返回直接匹配的句子,缺乏上下文衔接。
持久化存储与加载
为了复用已构建的索引,避免重复消耗计算资源,可以将索引保存到磁盘。
保存索引
persist_dir = "./storage/sentence_index"
sentence_index.storage_context.persist(persist_dir=persist_dir)
加载索引
from llama_index import StorageContext, load_index_from_storage
SC_retrieved = StorageContext.from_defaults(persist_dir=persist_dir)
retrieved_index = load_index_from_storage(
SC_retrieved,
service_context=ctx_sentence
)
retrieved_query_engine = retrieved_index.as_query_engine(
similarity_top_k=5,
node_postprocessor=[MetadataReplacementPostProcessor("window")]
)
final_response = retrieved_query_engine.query(query)
print(final_response)
常见问题与优化建议
- Embedding 模型选择:如果中文支持不佳,请切换至中文优化的 Embedding 模型(如
text2vec 或 bge-m3),否则检索准确率会大幅下降。
- Chunk Size 调整:默认的切片大小可能不适合所有文档。可以通过
SentenceSplitter 自定义 chunk_size 和 chunk_overlap,平衡上下文完整性与检索精度。
- LLM 温度设置:在 RAG 场景下,建议将
temperature 设置为较低值(如 0.0-0.3),以减少幻觉,确保回答严格基于检索到的上下文。
- 元数据过滤:在复杂系统中,可以利用
node_postprocessor 添加元数据过滤器,仅检索特定来源或类型的文档。
总结
本文详细介绍了如何在 LlamaIndex 框架下构建 RAG 应用。从环境搭建、数据加载、节点解析策略选择(特别是句子窗口技术)、索引构建到查询引擎配置及持久化存储,涵盖了核心开发流程。通过合理配置 ServiceContext 和后处理器,可以显著提升大模型在私有数据上的问答表现。
相关免费在线工具
- 加密/解密文本
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
- RSA密钥对生成器
生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
- Mermaid 预览与可视化编辑
基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
- curl 转代码
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online