2026/6/11 5:46:35
网站建设
项目流程
免费做字体的网站好,做博客网站要怎么配置的服,网站建设开发费怎么做账,做app和网站哪个比较好用一、引言大模型在生成信息时可能出现幻觉问题#xff0c;生成看似合理但实际错误或不存在的内容#xff0c;同时#xff0c;模型存在知识边界限制#xff0c;其知识受限于训练数据的时间截点和覆盖范围#xff0c;无法获取实时信息或特定领域深度知识。为解决这些问题生成看似合理但实际错误或不存在的内容同时模型存在知识边界限制其知识受限于训练数据的时间截点和覆盖范围无法获取实时信息或特定领域深度知识。为解决这些问题通常采用检索增强生成RAG技术结合外部知识库实时检索来修正和补充模型知识通过提示工程明确约束生成范围建立事实核查和置信度评估机制。这些方法显著提升了生成内容的准确性和可靠性扩展了模型的实际应用边界而 LlamaIndex 与 LangChain 作为 RAG 生态的两大核心工具前者擅长文档索引与语义检索后者强于 LLM 工作流编排与提示工程。传统 RAG 实践多依赖 OpenAI 等云端模型存在数据安全风险与 API 成本问题今天我们还是以本地化 Qwen1.5-1.8B-Chat 模型为基座通过两个递进式示例深度解析 LlamaIndex 与 LangChain 的集成逻辑从极简版 “功能验证” 到生产级 “工程化落地”揭示这两个框架如何各司其职、协同增效构建全本地化、高可控的智能文档问答系统。二、核心要点1. 基础介绍LlamaIndex核心能力文档处理、分块、向量索引、语义检索核心优势文档理解与检索一体化索引管理轻量化实际应用文档加载、分块配置、向量索引构建 / 加载、上下文检索LangChain核心能力LLM 封装、提示工程、工作流编排核心优势模块化链设计适配多类 LLM输出解析灵活实际应用本地 Qwen 模型封装、提示模板定义、RAG 链编排、交互式问答2. 集成分工LlamaIndex 与 LangChain 的集成遵循 “分工协作” 原则LlamaIndex负责“数据层”文档→分块→向量化→索引→上下文检索LangChain负责“推理层”上下文问题→提示模板→LLM生成→回答解析两者通过 “检索结果上下文文本” 完成数据流转形成 RAG 闭环。3. 关键概念向量索引将文档片段转为 Embedding 向量并存储通过VectorStoreIndex构建新增持久化逻辑检索器Retriever基于问题语义匹配向量索引使用index.as_retriever并封装为VectorIndexRetrieverLLM Pipeline 封装将本地 Qwen 模型转为 LangChain 兼容接口通过HuggingFacePipeline实现Runnable 链LangChain 的声明式工作流通过RunnablePassthrough实现 “问题→检索→提示→生成” 的自动化流转索引持久化新增StorageContext处理将索引保存到./storage避免重复加载文档/向量化三、示例分析我们结合两个示例由浅入深、循序渐进的差异化讲解设计逻辑和价值体现1. 轻量化 RAG1.1 基础定位本地化 RAG 实现聚焦 “快速验证核心流程”剥离所有工程化冗余仅保留 RAG 的核心闭环文档加载→索引构建→上下文检索→LLM 生成回答。1.2 核心功能完成本地 Qwen1.5-1.8B-Chat 模型的下载与基础封装通过 LlamaIndex 实现文档加载、向量索引构建内存级和语义检索借助 LangChain 完成提示模板定义与本地 LLM 调用以固定问题 “文档中提到的 RAG 核心步骤有哪些” 完成单次问答验证。1.3 示例特点代码量少逻辑线性无函数封装仅检索 / 问答简单封装索引仅存于内存程序重启后需重新加载文档、构建索引无异常处理、无交互式问答仅满足 “能跑通、能回答” 的基础需求。2. 工程化 RAG2.1 基础定位可落地的工程化版本在示例 1 的基础上补充工程化能力聚焦 “实用性、可复用性、稳定性”适配真实场景下的 RAG 系统需求。2.2 核心功能继承示例 1 的本地模型 / Embedding 本地化核心新增 LlamaIndex 全局配置分块大小、重叠度优化文档处理效果实现索引持久化保存到./storage避免重复构建索引封装检索器、索引管理、RAG 链等核心逻辑为可复用函数基于 LangChain 声明式 RAG 链实现 “检索→提示→生成→解析” 自动化流转新增交互式问答循环、异常捕获提升用户体验与系统稳定性。2.3 示例特点代码模块化索引管理、检索器、RAG 链、主流程分离便于维护与扩展支持增量使用索引持久化大幅降低重复运行的时间 / 资源消耗具备直接部署使用得能力交互性、异常处理、配置可定制。3. 差异对比核心目标基础版验证本地化 RAG 核心流程是否可行升级版实现可落地、可复用的本地化 RAG 系统索引管理基础版内存临时索引程序重启后丢失升级版索引持久化到本地首次构建后复用代码结构基础版线性代码为主仅简单函数封装升级版模块化函数封装索引管理、检索器、RAG 链职责分离LlamaIndex 配置基础版仅配置 Embedding分块 / LLM 使用默认值升级版全局配置分块参数LlamaIndex 直接集成本地 LLMLangChain 能力基础版手动拼接提示、调用 LLM无输出解析升级版声明式 RAG 链自动流转StrOutputParser 解析输出交互方式基础版单次固定问题测试升级版交互式循环问答支持 exit 退出异常捕获扩展能力基础版几乎无扩展空间仅能修改问题/文档升级版支持元数据过滤、混合检索、模型量化等扩展适配真实场景四、代码分解1. 本地 Qwen 模型加载# 核心代码段 local_model_path snapshot_download(MODEL_NAME, cache_dirCACHE_DIR) tokenizer AutoTokenizer.from_pretrained(local_model_path, trust_remote_codeTrue) model AutoModelForCausalLM.from_pretrained( local_model_path, trust_remote_codeTrue, device_mapauto )关键分析trust_remote_codeTrueQwen 模型依赖自定义代码必须开启device_mapauto自动适配 GPU/CPU示例未指定 CUDA 时自动降级到 CPU 运行模型下载逻辑首次运行从 ModelScope 下载约 3.6GB后续读取本地缓存无需重复下载。2. 本地化的 Embedding 模型# 配置本地Embedding中文优化 Settings.embed_model HuggingFaceEmbedding( model_nameD:/modelscope/hub/models/sentence-transformers/paraphrase-MiniLM-L6-v2, model_kwargs{device: cpu}, embed_batch_size16 )model_name指定本地已下载的 Embedding 模型路径这里是paraphrase-MiniLM-L6-v2轻量且适配中文语义存储在 ModelScope 本地缓存目录model_kwargs{device: cpu}指定模型运行在 CPU 上无 GPU 也可使用若有 GPU 可改为cuda加速embed_batch_size16批量处理文本向量化的批次大小平衡处理速度与内存占用。为 LlamaIndex 的向量索引构建、语义检索提供基础文档 / 问题需转为向量才能做相似度匹配实现完全本地化向量化无需调用外部 APIparaphrase-MiniLM-L6-v2轻量化且语义表征效果好适合中小规模 RAG 系统。3. LlamaIndex 索引构建与检索3.1 简单版# 索引构建无持久化 documents SimpleDirectoryReader(input_dir./docs).load_data() index VectorStoreIndex.from_documents(documents) # 检索函数 def get_context(query): retriever index.as_retriever(similarity_top_k3) nodes retriever.retrieve(query) return \n\n.join([node.text for node in nodes])特点极简流程适合快速验证 RAG 核心逻辑索引仅存在于内存程序退出后丢失检索器直接由索引转换无扩展配置如元数据过滤。3.2 升级版# 索引管理函数核心升级 def build_or_load_index(doc_dir: str ./docs, index_dir: str ./storage): if not os.path.exists(index_dir): documents SimpleDirectoryReader(input_dirdoc_dir, recursiveTrue).load_data() index VectorStoreIndex.from_documents(documents) index.storage_context.persist(persist_dirindex_dir) # 持久化 else: storage_context StorageContext.from_defaults(persist_dirindex_dir) index load_index_from_storage(storage_context) # 加载本地索引 return index # 检索器优化 def get_optimized_retriever(index, top_k: int 3): retriever VectorIndexRetriever( indexindex, similarity_top_ktop_k # 可扩展元数据过滤、相似度阈值等 ) return retriever特点索引持久化通过storage_context.persist将索引保存到./storage解决 “重复构建索引” 的效率问题文档加载增强recursiveTrue支持递归读取子目录文档required_exts过滤文件格式检索器封装VectorIndexRetriever支持更多扩展配置如示例中注释的元数据过滤为生产场景预留扩展空间全局分块配置Settings.chunk_size512/chunk_overlap50优化分块粒度避免语义断裂。4. LangChain RAG 链设计4.1 简单版-手动拼接# 提示模板 prompt ChatPromptTemplate.from_messages([ (system, 仅根据上下文回答问题...上下文{context}), (human, {question}) ]) # 问答逻辑手动调用 def answer_question(question): context get_context(question) final_prompt prompt.format(contextcontext, questionquestion) response llm.invoke(final_prompt) return response特点手动完成 “检索→提示拼接→LLM 调用”流程直观但耦合度高无输出解析直接返回 LLM 原始生成结果仅支持单次固定问题测试无交互性。4.2 升级版-声明式链# RAG链构建核心升级 def build_rag_chain(retriever): def retrieve_context(query: str) - str: nodes retriever.retrieve(query) return \n\n.join([node.text for node in nodes]) prompt ChatPromptTemplate.from_messages([...]) # 增强指令约束 rag_chain ( {context: RunnablePassthrough() | retrieve_context, question: RunnablePassthrough()} | prompt | langchain_llm | StrOutputParser() # 输出解析为纯文本 ) return rag_chain特点声明式链编排通过RunnablePassthrough实现 “用户问题” 同时传递给 “检索函数” 和 “提示模板”无需手动拼接输出解析StrOutputParser将 LLM 生成的复杂结果转为纯文本提升回答可读性提示模板增强新增多规则约束如 “无信息时明确说明”减少 LLM 幻觉交互式问答主函数新增循环逻辑支持持续提问异常捕获避免程序崩溃。5. 升级价值体现升级版新增Settings.llm HuggingFaceLLM(...)实现 LlamaIndex 直接调用本地 Qwen 模型而非仅依赖 LangChain 的 LLM 封装核心价值LlamaIndex 的检索优化如混合检索、路由检索可直接使用本地模型统一 LLM 配置避免 LlamaIndex 与 LangChain 分别配置模型的冗余问题为后续扩展如 LlamaIndex 的 QueryEngine奠定基础。6. 示例运行6.1 轻量化RAG系统import os from modelscope.hub.snapshot_download import snapshot_download # LlamaIndex核心模块 from llama_index.core import SimpleDirectoryReader, VectorStoreIndex from llama_index.embeddings.huggingface import HuggingFaceEmbedding from llama_index.core import Settings # LangChain核心模块 from langchain_community.llms.huggingface_pipeline import HuggingFacePipeline from langchain_core.prompts import ChatPromptTemplate # HuggingFace模型加载 from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline # 1. 本地Qwen模型配置核心改造 # 模型信息 MODEL_NAME qwen/Qwen1.5-1.8B-Chat CACHE_DIR D:\\modelscope\\hub # 模型下载/缓存目录 # 下载模型首次运行自动下载后续跳过 print(正在加载/下载Qwen模型...) local_model_path snapshot_download(MODEL_NAME, cache_dirCACHE_DIR) # 加载Tokenizer和Model适配Qwen1.5 tokenizer AutoTokenizer.from_pretrained( local_model_path, trust_remote_codeTrue, cache_dirCACHE_DIR ) model AutoModelForCausalLM.from_pretrained( local_model_path, trust_remote_codeTrue, cache_dirCACHE_DIR, device_mapauto, # 自动分配GPU/CPU torch_dtypeauto ) # 配置LlamaIndex本地Embedding替代OpenAI Embedding Settings.embed_model HuggingFaceEmbedding( model_nameD:/modelscope/hub/models/sentence-transformers/paraphrase-MiniLM-L6-v2, # 中文轻量Embedding model_kwargs{device: cpu} ) # 2. LlamaIndex加载文档构建索引 # 加载单个PDF/TXT文档放入./docs目录 documents SimpleDirectoryReader(input_dir./docs).load_data() # 构建向量索引自动分块本地向量化 index VectorStoreIndex.from_documents(documents) # 3. LlamaIndex检索相关上下文 def get_context(query): # 检索相似度前3的文档片段 retriever index.as_retriever(similarity_top_k3) nodes retriever.retrieve(query) # 拼接上下文 return \n\n.join([node.text for node in nodes]) # 4. LangChain本地Qwen模型提示模板 # 构建HF Pipeline适配LangChain qwen_pipeline pipeline( text-generation, modelmodel, tokenizertokenizer, max_new_tokens512, # 最大生成token数 temperature0.1, # 生成随机性 top_p0.95, repetition_penalty1.15, device_mapauto ) # 封装为LangChain兼容的LLM llm HuggingFacePipeline(pipelineqwen_pipeline) # 提示模板适配Qwen的指令格式 prompt ChatPromptTemplate.from_messages([ (system, 仅根据上下文回答问题无相关信息则说“无法回答”。上下文{context}), (human, {question}) ]) # 5. 问答逻辑 def answer_question(question): context get_context(question) # 组装提示并调用本地Qwen模型 final_prompt prompt.format(contextcontext, questionquestion) response llm.invoke(final_prompt) return response # 6. 测试 if __name__ __main__: query 文档中提到的RAG核心步骤有哪些 print(问题, query) print(回答, answer_question(query))6.2 工程化的RAG系统import os from dotenv import load_dotenv from modelscope.hub.snapshot_download import snapshot_download # LlamaIndex核心模块 from llama_index.core import ( SimpleDirectoryReader, VectorStoreIndex, StorageContext, load_index_from_storage, Settings ) from llama_index.core.retrievers import VectorIndexRetriever from llama_index.llms.huggingface import HuggingFaceLLM # LlamaIndex适配HF模型 from llama_index.embeddings.huggingface import HuggingFaceEmbedding # LangChain核心模块 from langchain_community.llms.huggingface_pipeline import HuggingFacePipeline from langchain_core.prompts import ChatPromptTemplate from langchain_core.runnables import RunnablePassthrough from langchain_core.output_parsers import StrOutputParser # HuggingFace模型加载 from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline # 1. 本地模型配置核心改造 # 模型信息 MODEL_NAME qwen/Qwen1.5-1.8B-Chat CACHE_DIR D:\\modelscope\\hub # 模型下载目录 # 下载模型首次运行自动下载后续跳过 print(开始下载/加载模型...) local_model_path snapshot_download(MODEL_NAME, cache_dirCACHE_DIR) print(f模型本地路径{local_model_path}) # 加载Tokenizer和Model适配Qwen1.5 tokenizer AutoTokenizer.from_pretrained( local_model_path, trust_remote_codeTrue, cache_dirCACHE_DIR ) model AutoModelForCausalLM.from_pretrained( local_model_path, trust_remote_codeTrue, cache_dirCACHE_DIR, device_mapauto, # 自动分配GPU/CPU torch_dtypeauto ) # 2. 全局配置 # LlamaIndex全局配置 Settings.chunk_size 512 # 文档分块大小 Settings.chunk_overlap 50 # 分块重叠 # 配置LlamaIndex的LLM为本地Qwen Settings.llm HuggingFaceLLM( modelmodel, tokenizertokenizer, context_window4096, # Qwen1.5-1.8B上下文窗口 max_new_tokens512, # 最大生成token数 generate_kwargs{temperature: 0.1}, # 生成参数 model_kwargs{device_map: auto} ) # 配置本地Embedding中文优化 Settings.embed_model HuggingFaceEmbedding( model_nameD:/modelscope/hub/models/sentence-transformers/paraphrase-MiniLM-L6-v2, model_kwargs{device: cpu}, embed_batch_size16 ) # LangChain配置将本地Qwen封装为LangChain LLM # 构建HF Pipeline qwen_pipeline pipeline( text-generation, modelmodel, tokenizertokenizer, max_new_tokens512, temperature0.1, top_p0.95, repetition_penalty1.15, device_mapauto ) # 封装为LangChain LLM langchain_llm HuggingFacePipeline(pipelineqwen_pipeline) # 3. 索引管理 def build_or_load_index(doc_dir: str ./docs, index_dir: str ./storage): 构建或加载向量索引避免重复构建 if not os.path.exists(index_dir): # 加载文档支持PDF/TXT递归读取 reader SimpleDirectoryReader( input_dirdoc_dir, required_exts[.pdf, .txt], recursiveTrue ) documents reader.load_data() print(f加载文档数量{len(documents)}) # 构建向量索引 index VectorStoreIndex.from_documents(documents) # 持久化索引到本地 index.storage_context.persist(persist_dirindex_dir) print(索引构建并保存完成) else: # 加载本地索引 storage_context StorageContext.from_defaults(persist_dirindex_dir) index load_index_from_storage(storage_context) print(加载本地索引完成) return index # 4. 检索器配置 def get_optimized_retriever(index, top_k: int 3): 获取优化的向量检索器 retriever VectorIndexRetriever( indexindex, similarity_top_ktop_k, # 可选元数据过滤如只检索指定文档 # filters[MetadataFilter(keysource, valueexample.pdf)] ) return retriever # 5. LangChain RAG链构建 def build_rag_chain(retriever): 构建本地化RAG链 # 检索上下文函数 def retrieve_context(query: str) - str: nodes retriever.retrieve(query) return \n\n.join([node.text for node in nodes]) # 提示模板适配Qwen的指令格式 prompt ChatPromptTemplate.from_messages([ (system, 你是智能文档问答助手严格遵循以下规则 1. 仅使用提供的上下文回答用户问题 2. 如果上下文没有相关信息明确说明“无法从文档中找到相关答案” 3. 回答简洁、准确使用中文表述。 上下文{context} ), (human, {question}) ]) # 构建RAG链 rag_chain ( {context: RunnablePassthrough() | retrieve_context, question: RunnablePassthrough()} | prompt | langchain_llm | StrOutputParser() ) return rag_chain # 6. 主函数交互式问答 def main(): # 步骤1构建/加载索引 index build_or_load_index(doc_dir./docs, index_dir./storage) # 步骤2初始化检索器 retriever get_optimized_retriever(index, top_k3) # 步骤3构建RAG链 rag_chain build_rag_chain(retriever) # 步骤4交互式问答 print(\n 本地化RAG问答系统Qwen1.5-1.8B-Chat ) print(输入 exit 退出问答) while True: query input(\n请输入问题) if query.lower() exit: print(退出系统...) break # 调用RAG链生成回答 try: response rag_chain.invoke(query) print(f\n回答\n{response}) except Exception as e: print(f回答生成失败{str(e)}) if __name__ __main__: main()五、总结LlamaIndex 与 LangChain的深度集成本质是专业工具做专业事的应用化实践LlamaIndex 解决了 RAG 的数据处理与检索的痛点LangChain 解决了LLM 调用与流程编排的痛点。今天我们通过两个递进式示例从极简验证到生产级落地完整展现了双工具集成的核心逻辑与本地化改造路径既保留了 RAG 的核心价值解决 LLM 幻觉又实现了全流程的本地化可控为RAG 系统的落地提供了构建的思路也可进行针对性的自定义优化以达到更精确的效果。