LlamaIndex 语法详解与 RAG 系统构建指南

发布时间:2026/6/26 6:09:31

LlamaIndex 语法详解与 RAG 系统构建指南 LlamaIndex 语法详解与 RAG 系统构建指南前言LlamaIndex 是一个专为大语言模型设计的数据框架核心能力是将私有数据文档、数据库、API与 LLM 连接起来。本文基于 4 个实战脚本系统讲解 LlamaIndex 的核心语法和关键概念。1. 环境配置与全局设置1.1 基础依赖fromdotenvimportload_dotenv load_dotenv()importosfromllama_index.coreimportSettingsfromllama_index.coreimportVectorStoreIndex,SimpleDirectoryReaderfromllama_index.llms.openai_likeimportOpenAILikefromllama_index.embeddings.dashscopeimportDashScopeEmbedding,DashScopeTextEmbeddingModels1.2 Settings 全局配置Settings是 LlamaIndex 的核心配置对象设置一次全局生效# LLM 配置Settings.llmOpenAILike(modelqwen-plus,api_basehttps://dashscope.aliyuncs.com/compatible-mode/v1,api_keyos.getenv(DASHCOPE_KEY),is_chat_modelTrue)# Embedding 配置Settings.embed_modelDashScopeEmbedding(model_nameDashScopeTextEmbeddingModels.TEXT_EMBEDDING_V3,embed_batch_size6,embed_input_length8192)参数含义说明modelLLM 模型名qwen-plus / gpt-4 / claude 等api_baseAPI 地址兼容 OpenAI 协议的地址is_chat_model是否对话模型True 使用 chat 接口model_nameEmbedding 模型text-embedding-v3 等embed_batch_size批量大小DashScope 限制最大 10embed_input_length最大输入长度单条文本 token 上限踩坑DashScopeEmbedding 底层 SDK 需要DASHSCOPE_API_KEY环境变量如果.env中变量名不同需显式设置dashscope.api_key os.getenv(DASHCOPE_KEY)。2. 文档加载Reader2.1 SimpleDirectoryReader基础加载器# 基础用法documentsSimpleDirectoryReader(data).load_data()# 进阶用法documentsSimpleDirectoryReader(data,required_exts[.txt,.pdf],# 只读取特定格式recursiveTrue,# 递归子目录exclude_hiddenTrue# 排除隐藏文件).load_data()支持格式.txt、.pdf、.docx、.csv、.pptx、.html、.json等。2.2 SmartPDFLoader智能 PDF 解析普通 PDF 解析只提取纯文本丢失布局信息。SmartPDFLoader 通过 LLMSherpa 服务识别 PDF 的章节、段落、表格结构fromllama_index.readers.smart_pdf_loaderimportSmartPDFLoader llmsherpa_api_urlhttps://readers.llmsherpa.com/api/document/developer/parseDocument?renderFormatallpdf_urldata/1910.13461v1.pdf# 支持 URL 或本地路径documentsSmartPDFLoader(llmsherpa_api_urlllmsherpa_api_url).load_data(pdf_url)布局识别效果普通解析SmartPDFLoader纯文本丢失结构保留章节、段落、表格层级表格变纯文本保留表格行列关系无元数据每个 chunk 带chunk_type标签2.3 自定义 Reader当内置加载器不满足需求时继承BaseReader实现自定义加载器fromllama_index.core.readers.baseimportBaseReaderfromllama_index.core.schemaimportDocumentfromtypingimportList,Optional,DictclassCustomReader(BaseReader):def__init__(self,*args,**kwargs):super().__init__(*args,**kwargs)defload_data(self,file_path:str,extra_info:Optional[Dict]None)-List[Document]:# 自定义解析逻辑results[]# ... 解析文件 ...documentDocument(text解析后的文本,extra_info{source:file_path,type:custom})results.append(document)returnresults关键规则继承BaseReader实现load_data()方法返回List[Document]通过extra_info传递元数据3. 文档与节点Document vs Node3.1 Document完整文档对象fromllama_index.coreimportDocument docDocument(textCEO 可以直接请假无需向直接领导汇报,metadata{author:wilson yin,title:CEO 请假申请,id:1234567890})Document 的属性属性类型说明textstr文档文本内容metadataDict元数据作者、标题、来源等id_str自动生成或手动指定的唯一 IDembeddingList[float]向量表示构建索引后生成3.2 TextNode文档片段fromllama_index.core.schemaimportTextNode# 手动创建节点n1TextNode(textdoc.text[0:8],doc_iddoc.id_)n2TextNode(textdoc.text[9:16],doc_iddoc.id_)Document 与 Node 的关系Document完整文档 ↓ NodeParser 切分 Node文档片段 ↓ Embedding 向量化 向量索引中的条目对比项DocumentNode粒度完整文档文档的一个片段创建方式手动或 Reader 加载切分器自动生成或手动创建用途输入给切分器输入给索引和检索元数据原始元数据继承自 Document 切分器添加的元数据4. 文本切分器NodeParser切分器决定文档如何被切分为 Node直接影响检索质量。4.1 TokenTextSplitter按 Token 切分fromllama_index.core.node_parserimportTokenTextSplitter splitterTokenTextSplitter(chunk_size32,# 每块最多 32 个 tokenchunk_overlap4,# 块间重叠 4 个 tokenseparator\n# 优先在换行符处切分)nodessplitter.get_nodes_from_documents([doc])fornodeinnodes:print(node.text)# 切分后的文本print(node.metadata)# 继承自 Document 的元数据参数说明chunk_size32 → 每块最多 32 个 token约 50-100 中文字符 chunk_overlap4 → 相邻块重叠 4 个 token避免关键信息被切断 separator\n → 优先在换行符处切分保持段落完整性切分效果示例原文 ### 第七条 事假 1. 员工因私事必须本人处理的可申请事假。 2. 事假需提前申请并获直属主管批准... 切分后chunk_size32 Node 1: ### 第七条 事假\n1. 员工因私事必须本人处理的可申请事假。 Node 2: 2. 事假需提前申请并获直属主管批准紧急情况可事后补办手续。 Node 3: 3. 事假为无薪假按日扣除相应工资。 Node 4: 4. 每月事假原则上不超过 3 天全年累计不超过 15 天...4.2 SentenceSplitter按句子切分fromllama_index.core.node_parserimportSentenceSplitter sentence_splitterSentenceSplitter(chunk_size512,# 每块约 512 字符chunk_overlap50# 块间重叠 50 字符)适用场景中文文档默认推荐按句子边界切分保持语义完整性。4.3 SentenceWindowNodeParser句子窗口切分fromllama_index.core.node_parserimportSentenceWindowNodeParser sentence_window_splitterSentenceWindowNodeParser.from_defaults(window_size3,# 窗口大小前后各 3 句window_metadata_keywindow,# 窗口文本的元数据键original_text_metadata_keyoriginal_text# 原文本的元数据键)原理检索时用单句匹配精准生成时用窗口上下文完整。检索时匹配单句 事假为无薪假 生成时使用窗口 事假需提前申请...事假为无薪假...每月事假不超过 3 天配合后处理器使用fromllama_index.core.node_parserimportMetadataReplacementPostProcessor query_engineindex.as_query_engine(similarity_top_k5,streamingTrue,node_postprocessors[MetadataReplacementPostProcessor(target_metadata_keywindow)])4.4 SemanticSplitterNodeParser语义切分fromllama_index.core.node_parserimportSemanticSplitterNodeParser semantic_splitterSemanticSplitterNodeParser(buffer_size1,# 缓冲句子数breakpoint_percentile_threshold95,# 语义差异阈值embed_modelSettings.embed_model# 需要 Embedding 模型)原理计算相邻句子的语义相似度在相似度骤降处切分。句子 A ←→ 句子 B相似度 0.92同一话题不切分 句子 B ←→ 句子 C相似度 0.31话题转换在此切分适用场景长文档、主题切换频繁的文档。4.5 MarkdownNodeParserMarkdown 切分fromllama_index.core.node_parserimportMarkdownNodeParser markdown_splitterMarkdownNodeParser()原理按 Markdown 标题层级#、##、###切分保持文档结构。4.6 切分器对比总结切分器切分依据适用场景是否需要 EmbeddingTokenTextSplitterToken 数量英文/混合文本❌SentenceSplitter句子边界中文文档通用❌SentenceWindowNodeParser句子 窗口需要上下文的问答❌SemanticSplitterNodeParser语义相似度长文档、主题切换✅MarkdownNodeParserMarkdown 标题Markdown 文档❌5. 向量索引与检索5.1 构建索引# 从文档构建indexVectorStoreIndex.from_documents(documents)# 从节点构建indexVectorStoreIndex(nodes)# 持久化保存index.storage_context.persist(persist_dir./storage)# 加载已保存的索引fromllama_index.coreimportStorageContext,load_index_from_storage storage_contextStorageContext.from_defaults(persist_dir./storage)indexload_index_from_storage(storage_context)5.2 检索器Retriever# 基础检索器retrieverindex.as_retriever(similarity_top_k5)# 检索nodesretriever.retrieve(怎么休事假)fori,nodeinenumerate(nodes):print(fNode{i1}(相似度:{node.score:.4f}):{node.text[:50]}...)检索结果示例5.3 查询引擎Query Engine# 基础查询query_engineindex.as_query_engine()responsequery_engine.query(怎么休事假)print(response)# 流式查询streaming_engineindex.as_query_engine(streamingTrue)responsestreaming_engine.query(怎么休事假)response.print_response_stream()# 对话引擎多轮问答chat_engineindex.as_chat_engine()responsechat_engine.chat(我想请事假需要什么流程)6. 后处理器PostProcessor后处理器在检索后、生成前对节点进行过滤或重排提升答案质量。6.1 SimilarityPostprocessor相似度过滤fromllama_index.core.postprocessorimportSimilarityPostprocessor# 创建后处理器设置相似度阈值similarity_postprocessorSimilarityPostprocessor(similarity_cutoff0.71)# 应用后处理器filtered_nodessimilarity_postprocessor.postprocess_nodes(nodes)print(f原始 Node 数:{len(nodes)}, 过滤后 Node 数:{len(filtered_nodes)})效果6.2 其他常用后处理器后处理器作用使用场景SimilarityPostprocessor按相似度阈值过滤去除低相关性结果KeywordNodePostprocessor按关键词过滤确保结果包含特定词MetadataReplacementPostProcessor替换元数据句子窗口切分后恢复上下文LongContextReorder重排长上下文避免中间丢失问题SentenceEmbeddingOptimizer优化句子嵌入提升检索精度6.3 在查询引擎中使用后处理器query_engineindex.as_query_engine(similarity_top_k10,# 先检索 10 个node_postprocessors[SimilarityPostprocessor(similarity_cutoff0.7),# 过滤到相似度 0.7KeywordNodePostprocessor(required_keywords[事假])# 确保包含关键词])处理流程用户提问 → 检索 Top-10 → 相似度过滤 → 关键词过滤 → LLM 生成答案7. 完整实战企业知识库问答系统7.1 系统架构7.2 完整代码fromdotenvimportload_dotenv load_dotenv()importosimportdashscopefromllama_index.coreimportSettingsfromllama_index.coreimportVectorStoreIndex,SimpleDirectoryReaderfromllama_index.llms.openai_likeimportOpenAILikefromllama_index.embeddings.dashscopeimportDashScopeEmbedding,DashScopeTextEmbeddingModelsfromllama_index.core.node_parserimportSentenceSplitterfromllama_index.core.postprocessorimportSimilarityPostprocessor# 配置dashscope.api_keyos.getenv(DASHCOPE_KEY)Settings.llmOpenAILike(modelqwen-plus,api_basehttps://dashscope.aliyuncs.com/compatible-mode/v1,api_keyos.getenv(DASHCOPE_KEY),is_chat_modelTrue)Settings.embed_modelDashScopeEmbedding(model_nameDashScopeTextEmbeddingModels.TEXT_EMBEDDING_V3,embed_batch_size6,embed_input_length8192)Settings.transformations[SentenceSplitter(chunk_size256,chunk_overlap32)]# 加载文档documentsSimpleDirectoryReader(data).load_data()# 构建索引indexVectorStoreIndex.from_documents(documents)# 创建查询引擎带后处理器query_engineindex.as_query_engine(similarity_top_k5,node_postprocessors[SimilarityPostprocessor(similarity_cutoff0.7)])# 查询responsequery_engine.query(怎么休事假)print(response)7.3 运行效果Q: 怎么休事假 A: 员工因私事必须本人处理的可申请事假。需提前向直属主管提出申请并获得批准 如遇紧急情况可事后补办手续。事假为无薪假按日扣除相应工资。 每月事假原则上不超过 3 天全年累计不得超过 15 天。 Q: 元旦休假几天 A: 元旦休假 1 天。 Q: 春节休假几天 A: 春节休假 3 天。8. LlamaIndex 核心语法速查8.1 导入路径# 核心组件fromllama_index.coreimportSettings,Document,VectorStoreIndex,SimpleDirectoryReaderfromllama_index.coreimportStorageContext,load_index_from_storage# Schemafromllama_index.core.schemaimportTextNode,Document# NodeParser切分器fromllama_index.core.node_parserimport(TokenTextSplitter,SentenceSplitter,SentenceWindowNodeParser,SemanticSplitterNodeParser,MarkdownNodeParser)# PostProcessor后处理器fromllama_index.core.postprocessorimport(SimilarityPostprocessor,KeywordNodePostprocessor,MetadataReplacementPostProcessor)# Reader加载器fromllama_index.readers.smart_pdf_loaderimportSmartPDFLoaderfromllama_index.core.readers.baseimportBaseReader# LLM Embeddingfromllama_index.llms.openai_likeimportOpenAILikefromllama_index.embeddings.dashscopeimportDashScopeEmbedding8.2 核心 API操作API说明加载文档SimpleDirectoryReader(path).load_data()返回List[Document]创建文档Document(text..., metadata{...})手动创建文档切分文档splitter.get_nodes_from_documents(docs)返回List[Node]构建索引VectorStoreIndex.from_documents(docs)自动向量化持久化index.storage_context.persist(dir)保存到磁盘加载索引load_index_from_storage(ctx)从磁盘加载创建检索器index.as_retriever(top_k5)返回 Retriever创建查询引擎index.as_query_engine()返回 QueryEngine创建对话引擎index.as_chat_engine()返回 ChatEngine检索retriever.retrieve(query)返回List[NodeWithScore]查询query_engine.query(query)返回 Response后处理postprocessor.postprocess_nodes(nodes)过滤/重排节点8.3 数据流文件 → Reader → Document → NodeParser → Node → Index → Retriever → PostProcessor → LLM → Response9. 常见问题与最佳实践9.1 切分粒度选择场景推荐切分器chunk_size中文文档SentenceSplitter256-512英文文档TokenTextSplitter128-256长文档SemanticSplitterNodeParser自动MarkdownMarkdownNodeParser按标题需要上下文SentenceWindowNodeParserwindow_size39.2 相似度阈值调优# 阈值过高过滤掉相关结果SimilarityPostprocessor(similarity_cutoff0.9)# 太严格# 阈值过低包含不相关结果SimilarityPostprocessor(similarity_cutoff0.5)# 太宽松# 推荐范围SimilarityPostprocessor(similarity_cutoff0.7)# 平衡9.3 性能优化# 1. 持久化索引避免重复构建index.storage_context.persist(persist_dir./storage)# 2. 批量 Embedding减少 API 调用Settings.embed_modelDashScopeEmbedding(embed_batch_size10)# 3. 流式输出提升用户体验query_engineindex.as_query_engine(streamingTrue)10. 总结核心概念概念作用关键类Reader加载数据源SimpleDirectoryReader、BaseReaderDocument完整文档DocumentNodeParser切分文档SentenceSplitter、TokenTextSplitterNode文档片段TextNodeIndex向量索引VectorStoreIndexRetriever语义检索as_retriever()PostProcessor结果过滤SimilarityPostprocessorQueryEngine检索 生成as_query_engine()学习路径1. 环境配置 → Settings 全局设置 2. 文档加载 → SimpleDirectoryReader 3. 文档切分 → SentenceSplitter / TokenTextSplitter 4. 索引构建 → VectorStoreIndex 5. 检索查询 → Retriever / QueryEngine 6. 结果优化 → PostProcessor 7. 高级功能 → 自定义 Reader / 多模态 / Agent

相关新闻