公司动态

69.高级RAG-元数据索引

📅 2026/7/31 4:31:03
69.高级RAG-元数据索引
内容参考于图灵AI大模型全栈元数据索引我们在构建索引的时候有一个元数据索引元数据中可以添加很多东西在检索时可以通过元数据对向量的结果进行精确过滤效果图doc_type是类型这里的类型是xx现在没有xx这个类型效果图类型该正确后它可以找到到内容这就是元数据索引的效果代码初次加载代码运行的会很慢会非常消耗Tokenfrom llama_index.core.vector_stores import MetadataFilters, MetadataFilter, FilterCondition from llama_index.core import VectorStoreIndex, SimpleDirectoryReader, StorageContext, load_index_from_storage from llama_index.core.ingestion import IngestionPipeline from llama_index.core.node_parser import HierarchicalNodeParser, get_leaf_nodes from llama_index.core.storage.docstore import SimpleDocumentStore from llama_index.core.retrievers import AutoMergingRetriever from llama_index.core.query_engine import RetrieverQueryEngine from llama_index.vector_stores.chroma import ChromaVectorStore from llama_index.core.extractors import ( TitleExtractor, QuestionsAnsweredExtractor, KeywordExtractor, ) import chromadb import os from base_llm import embed_model, llm # Chroma 配置 chroma_client chromadb.PersistentClient(path./chroma_db) chroma_collection chroma_client.get_or_create_collection(parent_child_demo) vector_store ChromaVectorStore(chroma_collectionchroma_collection) # 索引加载或构建 if os.path.exists(./storage): print(开始加载索引...) storage_context StorageContext.from_defaults( persist_dir./storage, vector_storevector_store, ) index load_index_from_storage( storage_contextstorage_context, embed_modelembed_model, ) print(索引加载成功) else: print(开始构建索引...) # 加载文档 documents SimpleDirectoryReader( input_files[./data_file/小说.txt] ).load_data() # 为文档添加基础元数据 for doc in documents: doc.metadata.update({ file_name: 斗破苍穹, doc_type: 小说, language: zh, category: 玄幻 # 可根据实际情况修改 }) # 层级节点解析器 node_parser HierarchicalNodeParser.from_defaults( chunk_sizes[2048, 512, 128] ) question_prompt_template 以下是参考内容 {context_str} 请根据上述上下文信息生成 {num_questions} 个该内容能够具体回答的问题这些问题的答案最好是该内容独有的不容易在其他地方找到。 你也可以参考上下文中可能提供的更高层次的总结信息结合这些总结尽可能生成更优质、更具有针对性的问题。请用中文输出 # 元数据提取器非常耗费Token extractors [ TitleExtractor(nodes5, llmllm), # 提取标题 QuestionsAnsweredExtractor(questions3, prompt_templatequestion_prompt_template, llmllm), # 提取可回答的问题 KeywordExtractor(keywords10, llmllm), # 提取关键词 ] # 创建摄取管道 pipeline IngestionPipeline( transformations[ node_parser, *extractors # 自动添加 metadata ] ) # 运行摄取管道 nodes pipeline.run(documentsdocuments) # 获取叶子节点用于向量索引 leaf_nodes get_leaf_nodes(nodes) # Docstore 保存所有层级节点含 metadata docstore SimpleDocumentStore() docstore.add_documents(nodes) # 存储管理器用来操作存储的 storage_context StorageContext.from_defaults( vector_storevector_store, docstoredocstore, ) # 创建索引仅叶子节点向量化 index VectorStoreIndex( leaf_nodes, storage_contextstorage_context, embed_modelembed_model, ) # 持久化 index.storage_context.persist(persist_dir./storage) print(索引构建完成) # 支持元数据过滤的 QueryEngine def create_query_engine(book_name): # 元数据过滤器 filters MetadataFilters( # 过滤器筛选条件 filters[ MetadataFilter(keyfile_name, valuebook_name), MetadataFilter(keydoc_type, value小说), ], # 过滤条件 与或非AND表示所有条件都满足才会要这条数据与or表示只要有一个条件满足才会要这条数据或not表示条件不满足才会要这条数据非 conditionFilterCondition.AND ) # 创建 Retriever 基础检索器 base_retriever index.as_retriever( similarity_top_k8, # 设置过滤 filtersfilters # 支持传入 metadata filters ) # 合并器 # 自动向上合并也就是说通过子节点找父节点 # 如果检索出来的子节点超过0.5百分之50来自于同一个父节点那就返回父节点 # 如果小于百分之50就不返回父节点还是使用子节点 retriever AutoMergingRetriever( vector_retrieverbase_retriever, storage_contextindex.storage_context, verboseTrue, simple_ratio_thresh0.5 ) # 查询引擎 return RetrieverQueryEngine.from_args( retrieverretriever, llmllm, ) query 萧炎父亲是谁 # 真实使用时下方这个需要用大模型判断是什么书 # 可以通过提示词固定通过问题返回什么书名 if 萧炎 in query: book_name 斗破苍穹 response_filtered create_query_engine(book_name).query(query) print(\n 带元数据过滤的回答 ) print(response_filtered) print(\n 检索数据 ) ret_nodes create_query_engine(book_name).retrieve(萧炎父亲是谁) for no in ret_nodes: print(repr(no)) print()