当前位置: 首页 > news >正文

68.高级RAG-父子索引优化

内容参考于:图灵AI大模型全栈

索引优化在高级RAG中很重要,它是在数据摄取阶段和索引构建阶段,提升索引数据的结构、检索效率、质量让检索到的结果更加准确、更加相关

索引优化核心目标是:

提高检索的准确性和召回率

减少无关数据,降低幻觉

可以更加好的处理长文档、复杂结构文档

文档地址:https://developers.llamaindex.ai/python/framework-api-reference/indices/

父子索引

在LLamaindex中是一种层级化(Hierarchical)的索引策略,用来解决大文档检索时丢失上下文的问题

思路是:

子节点(Child):它的文本会很小块,一般256到512个tokens,用来相似度高的内容,如果文档过长会丢失语义

父节点(Parent):它的文本会更大,一般1024到2048个tokens或整个文档,用来提供完整详细的上下文

在检索时,它会先通过子节点检索,找到子节点后关联出它的父节点,来实现高相似度并不会缺失上下文

安装指令

pip install llama-index-vector-stores-chroma

效果图:

文档信息存储的结构

如下图ref_doc_info是当前数据来源于什么文档

如下图data里就是父子文档的数据

如下图元数据

注意元数据的内容在data中,如下图红框

下图红框的1表示来自于哪一个文档,2表示上一个节点,3是下一个节点,5是子节点的数据

5里面的内容

它还有个4,4表示父节点

它的结构图:

代码运行效果

Merging 3 nodes into parent node.意思是合并了3个节点

Parent node id: aaa5e141-8397-40a7-87ac-17254eb6ec5c.意思是父节点id是aaa5e141-8397-40a7-87ac-17254eb6ec5c

Parent node text:是父节点的文本

代码

# 引入LlamaIndex核心组件 # VectorStoreIndex:向量索引核心类,用于构建、查询向量知识库 # SimpleDirectoryReader:目录读取器,自动加载文件夹内各类文档(txt/pdf/md等) # StorageContext:存储上下文,统一管理向量库、文档存储、元数据存储 # load_index_from_storage:从本地磁盘加载已持久化保存的索引,避免重复向量化 from llama_index.core import VectorStoreIndex, SimpleDirectoryReader, StorageContext, load_index_from_storage # 数据摄入流水线,摄取管道,封装文档加载→切分→向量化全流程,便于复用配置 from llama_index.core.ingestion import IngestionPipeline # 分层节点解析器(AutoMerging Retrieval 核心) # HierarchicalNodeParser:分层切割文档,生成粗粒度父节点 + 细粒度子叶子节点 # get_leaf_nodes:筛选出所有底层细粒度子节点,仅将叶子节点存入向量库 from llama_index.core.node_parser import HierarchicalNodeParser, get_leaf_nodes # SimpleDocumentStore:本地文档存储,用来保存完整分层节点(父子节点全部留存) from llama_index.core.storage.docstore import SimpleDocumentStore # AutoMergingRetriever:自动合并检索器 # 检索到细碎子节点后,自动向上合并父节点上下文,解决切片丢失上下文问题 from llama_index.core.retrievers import AutoMergingRetriever # RetrieverQueryEngine:检索增强查询引擎,把检索器接入大模型实现问答 from llama_index.core.query_engine import RetrieverQueryEngine # Chroma向量存储实现,负责存放embedding向量 from llama_index.vector_stores.chroma import ChromaVectorStore # chromadb:Chroma数据库原生客户端,用于创建/获取持久化集合 import chromadb # os模块:操作系统接口,用来判断文件夹是否存在、路径管理 import os from base_llm import embed_model, llm # 创建Chroma 向量数据库 chroma_client = chromadb.PersistentClient( path="./chroma_db" ) # 数据的名字叫 parent_child_demo chroma_collection = chroma_client.get_or_create_collection( "parent_child_demo" ) # 创建向量数据库存储对象,用来操作数据库的 vector_store = ChromaVectorStore( chroma_collection=chroma_collection ) # 判断索引是否存在 if os.path.exists("./storage"): print("开始加载索引...") # 注意: # 不要自己重新 docstore # 要从 persist_dir 自动恢复 storage_context = StorageContext.from_defaults( persist_dir="./storage", vector_store=vector_store, ) # 加载索引 index = load_index_from_storage( storage_context=storage_context, embed_model=embed_model, ) print("索引加载成功") else: print("开始构建索引...") # 加载文档 documents = SimpleDirectoryReader( input_files=["./data_file/小说.txt"] ).load_data() # 层级切分,2048位置标识父节点的大小,512的位置表示子节点的大小(2048是512的父节点),128表示子节点的大小(512是128的父节点) node_parser = HierarchicalNodeParser.from_defaults( chunk_sizes=[2048, 512, 128] ) # 初始化摄取管道 # 这里只做切分 # 不提前做 embedding pipeline = IngestionPipeline( transformations=[ node_parser, ] ) # 生成所有 nodes nodes = pipeline.run( documents=documents ) # 获取最子节点 # 只有 leaf nodes 参与向量化 leaf_nodes = get_leaf_nodes(nodes) # 创建 docstore # 保存所有层级节点 docstore = SimpleDocumentStore() # 父子节点添加到文档存储中 docstore.add_documents(nodes) # 存储管理器,用来操作存储的 storage_context = StorageContext.from_defaults( vector_store=vector_store, docstore=docstore, ) # 创建索引 # 这里只会给 leaf_nodes 生成 embedding index = VectorStoreIndex( leaf_nodes, storage_context=storage_context, embed_model=embed_model, ) # 持久化 # 会保存: # - docstore,所有父子节点 # - index_store,索引 # - vector_store,向量 index.storage_context.persist( persist_dir="./storage" ) print("索引构建完成") # 基础检索器 # 先召回子节点 base_retriever = index.as_retriever( similarity_top_k=5 ) # AutoMergingRetriever合并器 # 自动向上合并,通过子节点找父节点 # 如果检索出来的子节点超过0.5(百分之50)来自于同一个父节点,那就返回父节点 # 如果小于百分之50就不返回父节点,还是使用子节点 retriever = AutoMergingRetriever( # 基础检索器 vector_retriever=base_retriever, # 完整的内容(带父节点的内容) storage_context=index.storage_context, # 是否展示细节 verbose=True, # 设置阈值,也就是百分之50 simple_ratio_thresh=0.5 ) # QueryEngine,查询引擎 query_engine = RetrieverQueryEngine.from_args( # 查询的数据源 retriever=retriever, # 大语言模型 llm=llm, ) # 问题 query = "萧炎父亲是谁" # 回答问题 response = query_engine.query(query) print("\n================== 回答 ==================\n") print(response) # 查看检索文档,这里是返回合并之后的文档,就是说会包含父文档 nodes = retriever.retrieve(query) print("\n================== 检索出的文档,注意这里是合并之后的文档 ==================\n") for node in nodes: print(node.model_dump_json(indent=2)) print()

http://www.jsqmd.com/news/1284932/

相关文章:

  • 隐藏技巧:Kafka云原生技术解析与性能优化秘籍
  • 3大核心功能揭秘:BilibiliCommentScraper如何帮你获取完整B站评论数据
  • C++命令行解析库cmdline:轻量级工具开发利器
  • 2026年7月海口本地工厂全铝定制/海南全铝定制厂家推荐案例_海口龙华湘派家居定制厂 - 品牌宣传支持者
  • 基于Dify与RAG技术构建游戏智能助手实战指南
  • 简单计算器-计算竞对每日推广花费
  • Arduino入门实战:从硬件思维到项目开发的全流程解析
  • Cognistack的自述:我是谁
  • VMware vcpu-0错误排查:从虚拟化原理到系统化修复指南
  • Python lxml库从入门到精通:高效处理XML与HTML数据
  • RK3568 Android 15嵌入式Linux驱动开发实战:从内核到HAL完整指南
  • 服装档口数字化转型:微信抖音双平台运营实战指南
  • Arduino开发板选型与项目实战:从Uno到ESP32的创客入门指南
  • Python 3.10安装与环境配置指南
  • 激光焊接设备选型:工程验证能力比参数表更重要
  • 微信生态开发入门:公众号与小程序的注册、关联与避坑指南
  • NBM7100A双级DC-DC架构在物联网低功耗设计中的应用
  • Wireshark实战:TCP异常报文深度解析与网络故障排查指南
  • FPGA时序约束实战:set_max_delay与set_min_delay的精准应用
  • 2026年常州市恩斯凯轴承有限公司:国产轴承配套服务领域的专业之选 - 卓企推荐
  • 2026年薪酬设计机构哪家强?高性价比选型指南来了
  • 从LED驱动到MCU控制:一个硬件工程师的汽车尾灯模组实战设计全解析
  • C++线性代数库Eigen:从核心原理到工程实践
  • AI产业链分化加剧,全球资产配置该怎么调整?
  • 城市周末活动策划指南:从信息筛选到体验升级的完整方法论
  • 2026年7月全铝定制/海口防白蚁全铝定制厂家推荐评估_海口龙华湘派家居定制厂 - 行业平台推荐
  • [学习]微服务
  • 如何3分钟免费激活Windows系统:KMS_VL_ALL_AIO智能激活脚本终极指南
  • STM32G4 UART通信深度解析:从DMA到协议设计的工程实践
  • 虚实共建引擎 vs 传统数字孪生:技术代差带来的商业价值跃迁