恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
从零搭建RAG系统:基于LangChain与Chroma的本地知识库问答实战
首页
资讯中心
/
从零搭建RAG系统:基于LangChain与Chroma的本地知识库问答实战
从零搭建RAG系统:基于LangChain与Chroma的本地知识库问答实战
发布时间:2026/8/18 10:48:45
大家好我是专注于技术实战分享的博主。在探索大模型应用落地的过程中你是否遇到过这样的困境模型回答看似流畅但内容经常“一本正经地胡说八道”缺乏对特定领域知识的精准把握或者当你想让模型基于公司内部文档、产品手册进行问答时却发现它对这些私有数据一无所知这正是传统大模型应用的痛点——知识更新滞后、无法利用外部知识库。检索增强生成RAG正是解决这一痛点的关键技术。它通过“检索”与“生成”的结合让大模型具备了“查阅资料”的能力从而生成更准确、更可信、更具时效性的回答。本文将带你从零开始深入浅出地搭建一套完整的RAG系统。我们将不仅理解其核心架构更会通过一个可运行的实战项目手把手完成从文档处理到智能问答的全流程。无论你是想入门RAG的新手还是寻求项目落地的开发者都能从中获得一套可直接复用的解决方案。1. RAG核心概念为什么它是大模型应用的“必选项”在深入实战之前我们必须先厘清RAG是什么以及它为何如此重要。1.1 RAG是什么检索增强生成Retrieval-Augmented Generation, RAG是一种将信息检索技术与大语言模型LLM生成能力相结合的技术框架。其核心思想可以概括为一个简单的公式RAG 检索Retrieval 增强Augmentation 生成Generation。通俗地讲你可以把RAG系统想象成一位拥有超强记忆力和理解力的“研究员”。当用户提出一个问题时检索这位研究员不会凭空回答而是立刻去一个庞大的资料库通常是向量数据库中快速查找与问题最相关的文档片段。增强他将找到的这些关键资料片段与用户原始问题一起整理成一份清晰的“背景材料”。生成最后他基于这份“背景材料”运用自己的语言组织能力LLM生成一个准确、详实、有据可依的最终答案。这个过程有效解决了大模型的两个固有缺陷幻觉Hallucination和知识静态性。模型不再依赖其内部可能过时或不完整的参数化知识而是动态地从外部知识源获取信息来支撑其回答。1.2 RAG的核心价值与应用场景核心价值准确性提升答案基于检索到的真实文档大幅减少事实性错误。知识可追溯生成的答案可以关联到源文档方便验证和溯源增强可信度。低成本知识更新要更新模型知识只需更新向量数据库中的文档无需重新训练或微调代价高昂的大模型。突破上下文窗口限制可以将海量文档存储在外部数据库中仅将最相关的片段送入模型从而处理远超模型单次上下文长度的知识。典型应用场景智能客服与问答机器人基于产品手册、FAQ文档回答用户问题。企业知识库助手让员工快速查询公司制度、技术方案、会议纪要等内部文档。学术与研究辅助基于论文库进行文献综述和问答。法律、金融文档分析快速从合同、财报中提取和总结关键信息。1.3 RAG vs. 微调如何选择这是开发者常遇到的抉择。简单对比如下RAG擅长处理大量、动态变化、需要溯源的知识。它像是给模型配了一个随时可更新的“外部硬盘”。优势是知识更新快、成本低、可解释性强。微调Fine-Tuning擅长改变模型的风格、格式或深度掌握某个狭窄领域的内在模式。它像是重塑了模型的一部分“大脑神经元”。优势是响应风格更定制化对复杂推理任务可能更有效。在许多实际项目中RAG与微调是互补的可以结合使用。例如先用微调让模型适应特定领域的对话风格再结合RAG为其提供精准的事实依据。2. 环境准备与项目规划我们将构建一个基于本地文档的问答系统。为了清晰和可复现我们选择主流的、易于上手的开源技术栈。2.1 技术栈选型说明编程语言Python。因其在AI和数据科学领域的丰富生态。核心框架LangChain。它提供了构建LLM应用的标准接口和组件能极大简化RAG流程的编排。嵌入模型text-embedding-ada-002(OpenAI API) 或BAAI/bge-small-zh-v1.5(本地Hugging Face模型)。前者效果稳定、使用简单后者免费、可离线运行。本文演示将使用本地模型以保证完全离线可运行。向量数据库Chroma。轻量级、易嵌入、纯Python实现非常适合原型开发和学习。大语言模型GPT-3.5-Turbo (OpenAI API) 或 ChatGLM3-6B (本地)。同样为演示完整性我们将使用OpenAI API需密钥但会给出切换成本地模型的指引。文档加载与处理LangChain提供的PyPDFLoader,UnstructuredFileLoader等。2.2 环境与依赖安装请确保你的Python版本在3.8以上。我们使用conda或venv创建独立的虚拟环境。# 1. 创建并激活虚拟环境 (以conda为例) conda create -n rag_demo python3.10 conda activate rag_demo # 2. 安装核心库 pip install langchain langchain-community langchain-openai chromadb pypdf unstructured # 3. 安装嵌入模型所需依赖 (以sentence-transformers为例) pip install sentence-transformers # 4. 如果需要使用本地LLM例如ChatGLM可能需要额外安装transformers, torch等 # pip install transformers torch2.3 项目结构规划创建一个清晰的项目目录有助于管理代码和文档。rag_tutorial/ ├── docs/ # 存放原始文档PDF、TXT、MD等 │ ├── product_manual.pdf │ └── company_policy.txt ├── data/ # 存放处理后的向量数据库数据 ├── src/ # 源代码 │ ├── __init__.py │ ├── document_processor.py # 文档加载与分割 │ ├── vector_store.py # 向量化与存储 │ └── qa_chain.py # 问答链构建 ├── config.py # 配置文件API密钥等 ├── main.py # 主程序入口 └── requirements.txt # 项目依赖3. RAG系统架构深度拆解一个典型的RAG系统流程可以分解为以下两个核心阶段这也是我们代码实现的蓝图原始文档 - [文档加载] - [文本分割] - [向量化] - [存入向量数据库] - 索引构建阶段线下 用户问题 - [向量化] - [向量检索] - [检索结果] - [组合成Prompt] - [LLM生成] - 答案 - 查询生成阶段线上3.1 索引构建阶段从文档到向量这个阶段是“知识入库”的过程通常是离线完成的。文档加载支持多种格式PDF、Word、HTML、Markdown、TXT。关键在于准确提取文本并保留必要的元数据如来源、页码。文本分割这是影响RAG效果的关键步骤。大模型有上下文长度限制不能将整本书扔进去。我们需要将长文档切分成有意义的“块”。策略常用RecursiveCharacterTextSplitter它尝试按字符递归分割优先保持段落和句子的完整性。关键参数chunk_size: 每个块的最大字符数。通常设置在500-1000之间需权衡信息完整性与检索精度。chunk_overlap: 块之间的重叠字符数。设置一定的重叠如100-200可以防止上下文在边界被割裂提高检索连贯性。向量化将文本块转换为计算机能理解的数值形式——向量或称嵌入。语义相似的文本其向量在空间中的距离也相近。模型选择嵌入模型的质量直接决定检索的准确性。对于中文BAAI/bge系列是很好的开源选择。向量存储将生成的向量及其对应的原始文本块、元数据持久化存储到向量数据库中并建立索引以便快速检索。3.2 查询生成阶段从问题到答案这个阶段是线上实时响应的过程。问题向量化将用户输入的问题使用与索引阶段相同的嵌入模型转换为向量。语义检索在向量数据库中计算问题向量与所有存储向量之间的相似度如余弦相似度返回最相似的K个文本块。这就是“检索”的核心。上下文增强将检索到的Top K个文本块与用户原始问题一起按照预设的模板组合成一个新的、信息更丰富的Prompt提示词。Prompt模板示例“请基于以下上下文回答问题。如果上下文不包含答案请说‘根据已知信息无法回答’。上下文{context} 问题{question}”答案生成将组装好的Prompt发送给大语言模型LLM由模型生成最终的自然语言答案。4. 完整实战搭建本地知识库问答系统现在我们按照上述架构一步步用代码实现。4.1 步骤一文档加载与智能分割首先我们处理docs/目录下的文档。创建src/document_processor.py# src/document_processor.py import os from langchain_community.document_loaders import PyPDFLoader, TextLoader, UnstructuredMarkdownLoader from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain.schema import Document class DocumentProcessor: def __init__(self, docs_dir: str, chunk_size: int 800, chunk_overlap: int 150): 初始化文档处理器 :param docs_dir: 原始文档目录路径 :param chunk_size: 文本块大小 :param chunk_overlap: 块间重叠大小 self.docs_dir docs_dir # 初始化文本分割器 self.text_splitter RecursiveCharacterTextSplitter( chunk_sizechunk_size, chunk_overlapchunk_overlap, length_functionlen, separators[\n\n, \n, 。, , , , , , ] # 中文友好分隔符 ) def load_and_split_documents(self): 加载目录下所有支持格式的文档并进行分割 all_docs [] supported_extensions {.pdf: PyPDFLoader, .txt: TextLoader, .md: UnstructuredMarkdownLoader} for filename in os.listdir(self.docs_dir): file_path os.path.join(self.docs_dir, filename) ext os.path.splitext(filename)[1].lower() if ext in supported_extensions and os.path.isfile(file_path): print(f正在处理文件: {filename}) try: loader_class supported_extensions[ext] loader loader_class(file_path) documents loader.load() # 加载原始文档 # 对每个文档进行分割 split_docs self.text_splitter.split_documents(documents) all_docs.extend(split_docs) print(f - 分割为 {len(split_docs)} 个文本块) except Exception as e: print(f - 处理文件 {filename} 时出错: {e}) print(f所有文档处理完成共得到 {len(all_docs)} 个文本块。) return all_docs if __name__ __main__: # 测试代码 processor DocumentProcessor(docs_dir../docs) chunks processor.load_and_split_documents() # 打印前两个块的内容预览 for i, chunk in enumerate(chunks[:2]): print(f\n--- 块 {i1} ---) print(chunk.page_content[:200] ...) # 预览前200字符 print(f元数据: {chunk.metadata})关键解释我们使用RecursiveCharacterTextSplitter并配置了中文常用的标点作为分隔符使分割更符合中文语言习惯。chunk_size和chunk_overlap是需要根据实际文档内容调整的超参数。对于技术文档块可以稍大对于对话记录块可能需要小一些。每个分割后的Document对象都包含page_content文本内容和metadata来源、页码等这些信息会一并存入向量库。4.2 步骤二向量化与持久化存储接下来我们将文本块转换为向量并存入Chroma数据库。创建src/vector_store.py# src/vector_store.py import os from langchain_community.embeddings import HuggingFaceEmbeddings from langchain_community.vectorstores import Chroma from langchain.schema import Document from typing import List class VectorStoreManager: def __init__(self, persist_directory: str ../data/chroma_db): 初始化向量存储管理器 :param persist_directory: 向量数据库持久化目录 self.persist_directory persist_directory # 初始化嵌入模型使用本地开源模型 self.embeddings HuggingFaceEmbeddings( model_nameBAAI/bge-small-zh-v1.5, # 中文优化的小模型 model_kwargs{device: cpu}, # 使用CPU有GPU可改为cuda encode_kwargs{normalize_embeddings: True} # 归一化提升余弦相似度计算效果 ) def create_and_persist_from_documents(self, documents: List[Document]): 从文档列表创建向量存储并持久化 print(开始创建向量存储...) # 创建向量存储会自动调用嵌入模型进行向量化 vectorstore Chroma.from_documents( documentsdocuments, embeddingself.embeddings, persist_directoryself.persist_directory ) # 显式持久化到磁盘 vectorstore.persist() print(f向量存储创建并持久化到: {self.persist_directory}) return vectorstore def load_existing_vectorstore(self): 加载已存在的向量存储 if not os.path.exists(self.persist_directory): raise FileNotFoundError(f持久化目录不存在: {self.persist_directory}) print(f从 {self.persist_directory} 加载已有向量存储...) vectorstore Chroma( persist_directoryself.persist_directory, embedding_functionself.embeddings ) return vectorstore if __name__ __main__: # 测试假设已有处理好的文档块 from document_processor import DocumentProcessor processor DocumentProcessor(docs_dir../docs) test_docs processor.load_and_split_documents() if test_docs: manager VectorStoreManager() # 首次运行创建并持久化 # vectorstore manager.create_and_persist_from_documents(test_docs) # 后续运行直接加载 vectorstore manager.load_existing_vectorstore() # 测试检索 test_query 公司的休假政策是什么 results vectorstore.similarity_search(test_query, k2) print(f\n针对问题 {test_query} 检索到的结果) for i, doc in enumerate(results): print(f\n--- 结果 {i1} (相关性分数估算) ---) print(doc.page_content[:300]) print(f来源: {doc.metadata.get(source, N/A)})关键解释我们选用BAAI/bge-small-zh-v1.5作为嵌入模型它在中文语义相似度任务上表现优异且模型较小适合本地运行。Chroma.from_documents方法封装了向量化、存储和索引构建的全过程。persist_directory参数指定了数据库保存的路径下次启动时可以直接加载无需重新向量化节省大量时间。4.3 步骤三构建问答链这是将检索与生成串联起来的核心。我们使用LangChain的RetrievalQA链。创建src/qa_chain.py# src/qa_chain.py from langchain.chains import RetrievalQA from langchain_openai import ChatOpenAI from langchain.prompts import PromptTemplate from vector_store import VectorStoreManager import sys import os sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from config import OPENAI_API_KEY, OPENAI_BASE_URL # 假设配置在config.py中 class QASystem: def __init__(self, use_local_llm: bool False): 初始化问答系统 :param use_local_llm: 是否使用本地LLM如ChatGLM否则使用OpenAI API # 1. 加载向量存储 self.vectorstore_manager VectorStoreManager() self.vectorstore self.vectorstore_manager.load_existing_vectorstore() # 2. 定义检索器设置返回的文档数量 self.retriever self.vectorstore.as_retriever(search_kwargs{k: 3}) # 返回最相关的3个片段 # 3. 初始化大语言模型 if use_local_llm: # 此处为使用本地模型的示例需额外安装和配置 # from langchain_community.llms import ChatGLM # self.llm ChatGLM(endpoint_urlhttp://localhost:8000) # 假设本地服务 print(本地LLM模式暂未配置将使用OpenAI API。) self.llm self._init_openai_llm() else: self.llm self._init_openai_llm() # 4. 构建Prompt模板 self.prompt self._build_custom_prompt() # 5. 创建QA链 self.qa_chain self._create_qa_chain() def _init_openai_llm(self): 初始化OpenAI LLM # 注意需要先在config.py中配置你的API密钥和Base URL如果使用代理 return ChatOpenAI( modelgpt-3.5-turbo, temperature0.1, # 低温度使输出更确定、更基于上下文 openai_api_keyOPENAI_API_KEY, openai_api_baseOPENAI_BASE_URL # 可选如果你有自己的代理 ) def _build_custom_prompt(self): 构建自定义提示词模板 template 请严格根据以下提供的上下文信息来回答问题。如果上下文信息中没有明确答案请直接说“根据提供的资料我无法回答这个问题”。不要编造信息。 上下文信息 {context} 问题{question} 请根据上下文信息给出答案 return PromptTemplate.from_template(template) def _create_qa_chain(self): 创建检索增强的QA链 qa_chain RetrievalQA.from_chain_type( llmself.llm, chain_typestuff, # 最简单的方式将所有检索到的文档“塞”进Prompt retrieverself.retriever, chain_type_kwargs{prompt: self.prompt}, return_source_documentsTrue # 非常重要返回源文档用于溯源 ) return qa_chain def ask(self, question: str): 向系统提问 print(f\n用户问题{question}) print(正在检索并生成答案...) try: result self.qa_chain.invoke({query: question}) answer result[result] source_docs result[source_documents] print(f\n系统回答{answer}) print(\n--- 答案溯源 ---) for i, doc in enumerate(source_docs): print(f[来源{i1}] {doc.metadata.get(source, 未知)} (页码/段落: {doc.metadata.get(page, N/A)})) # print(f 内容片段: {doc.page_content[:150]}...) # 可选预览源内容 return answer, source_docs except Exception as e: error_msg f处理问题时发生错误{e} print(error_msg) return error_msg, [] if __name__ __main__: # 测试问答系统 qa_system QASystem(use_local_llmFalse) while True: user_input input(\n请输入您的问题输入quit退出: ) if user_input.lower() quit: break if user_input.strip(): qa_system.ask(user_input)关键解释RetrievalQA链是LangChain提供的“一站式”解决方案它内部集成了检索、Prompt组装和LLM调用。chain_typestuff是最直接的方法适合检索到的文档总长度不超过LLM上下文窗口的情况。对于更长的上下文可以考虑map_reduce或refine等方法。return_source_documentsTrue是可解释性的关键它让我们知道答案来源于哪些文档片段。Prompt工程我们设计了一个强调“基于上下文”和“拒绝回答未知问题”的模板这是减少模型幻觉的有效手段。4.4 步骤四配置与主程序入口创建config.py用于管理敏感信息和配置以及main.py作为启动入口。创建config.py# config.py # 在此处配置你的OpenAI API密钥 # 重要切勿将真实的API密钥提交到版本控制系统如Git OPENAI_API_KEY sk-your-actual-openai-api-key-here # 请替换为你的真实密钥 # 如果你通过代理访问OpenAI可以在此设置Base URL OPENAI_BASE_URL https://api.openai.com/v1 # 默认值可按需修改创建main.py# main.py import sys import os sys.path.append(os.path.dirname(os.path.abspath(__file__))) from src.document_processor import DocumentProcessor from src.vector_store import VectorStoreManager from src.qa_chain import QASystem def build_knowledge_base(): 构建知识库索引首次运行或文档更新后执行 print( 开始构建知识库索引 ) processor DocumentProcessor(docs_dir./docs) all_chunks processor.load_and_split_documents() if not all_chunks: print(未加载到任何文档请检查./docs目录。) return vector_manager VectorStoreManager(persist_directory./data/chroma_db) vector_manager.create_and_persist_from_documents(all_chunks) print( 知识库索引构建完成 ) def run_qa_system(): 运行交互式问答系统 print( 启动RAG问答系统 ) print(正在加载向量知识库和模型...) qa_system QASystem(use_local_llmFalse) # 使用OpenAI API print(系统准备就绪请输入您的问题。\n) while True: try: user_question input(用户: ) if user_question.lower() in [exit, quit, 退出]: print(感谢使用再见) break if user_question.strip(): qa_system.ask(user_question) except KeyboardInterrupt: print(\n程序被中断。) break except Exception as e: print(f系统错误: {e}) if __name__ __main__: # 检查是否首次运行向量库不存在 if not os.path.exists(./data/chroma_db): print(检测到首次运行需要先构建知识库索引。) build_knowledge_base() # 运行问答系统 run_qa_system()4.5 运行与验证准备文档将你的PDF、TXT等文档放入./docs文件夹。首次运行在项目根目录下执行python main.py。程序会自动检测并开始构建向量索引。交互问答索引构建完成后进入交互界面。输入你的问题例如“总结一下产品的主要功能”或“根据文档申请流程需要几步”。系统会返回答案并显示来源。后续运行再次运行python main.py程序会直接加载已有的向量库快速启动。预期效果对于知识库中明确包含的信息系统能给出准确回答并指出出处对于知识库外的信息系统会明确表示无法回答。这正是一个可靠RAG系统应有的表现。5. 常见问题与排查思路在实际搭建和运行过程中你可能会遇到以下典型问题。问题现象可能原因排查与解决思路ModuleNotFoundError: No module named ‘langchain_community’依赖未正确安装或版本冲突。1. 确认在正确的虚拟环境中。2. 运行pip install langchain-community。3. 检查requirements.txt确保所有依赖版本兼容。向量检索结果不相关1. 嵌入模型不匹配索引和查询用的模型不同。2. 文本分割策略不佳块太大或太小。3. 检索的top_k值不合适。1.确保一致性索引和查询必须使用完全相同的嵌入模型和参数。2.调整分割尝试不同的chunk_size(如500, 800, 1000) 和chunk_overlap(如100, 150)。3.调整检索量增大search_kwargs{k: 5}可能获得更多上下文但也可能引入噪声。LLM回答“根据上下文无法回答”但你知道文档里有1. 检索到的片段确实不包含答案。2. Prompt模板设计不佳模型未充分利用上下文。3. 上下文过长模型忽略了关键信息。1.检查检索结果在qa_chain.py中临时打印source_documents的内容看检索是否正确。2.优化Prompt在Prompt中更强烈地指示模型“必须使用上下文”例如“答案必须完全依据上下文上下文如下”。3.尝试其他Chain类型对于长上下文可试用chain_typemap_reduce。处理PDF时中文乱码或提取为空PDF解析器对某些格式特别是扫描件或特殊编码支持不好。1. 尝试使用UnstructuredPDFLoader(pip install unstructured[pdf])。2. 对于扫描件PDF需要先进行OCR识别这涉及更复杂的流程如使用pytesseract。3. 将PDF转换为纯文本文件再处理。使用OpenAI API时连接超时或报错1. API密钥错误或失效。2. 网络问题无法访问API。3. 达到速率限制。1. 检查config.py中的OPENAI_API_KEY是否正确。2. 检查网络连接如需在config.py中正确配置OPENAI_BASE_URL代理地址。3. 查看OpenAI控制台确认额度是否充足或稍后再试。程序运行缓慢1. 使用CPU运行嵌入模型或本地LLM。2. 文档数量极大首次向量化耗时。1. 如果有NVIDIA GPU将嵌入模型和本地LLM设置为GPU运行 (model_kwargs{device: cuda})。2. 首次索引构建后后续查询会很快因为只需对问题向量化。6. 进阶优化与最佳实践一个基础的RAG系统搭建完成后可以从以下几个方面进行优化以提升其生产环境可用性。6.1 检索策略优化混合检索结合语义检索向量相似度和关键词检索如BM25。语义检索理解意图关键词检索保证字面匹配。LangChain的EnsembleRetriever可以轻松实现。重排序初步检索出较多文档如20个使用一个更小、更快的“重排序模型”对结果进行精排将最相关的3-5个送入LLM能显著提升答案质量。元数据过滤在检索时加入过滤条件。例如只检索“来源为某产品手册2024版”或“类型为故障解决”的文档。这需要在前面的文档处理阶段为每个块打好元数据标签。6.2 文本分割优化基于语义的分割使用更高级的分割器如SemanticChunkerLangChain实验性功能它尝试根据嵌入向量的相似度变化来分割使每个块在语义上更完整。保留层次结构对于有标题结构的文档分割时保留章节信息作为元数据检索时可以利用这些信息。6.3 Prompt工程优化指令明确化在Prompt中明确指令格式如“用中文回答”、“分点列出”、“如果上下文不足请明确指出”。提供示例在Prompt中加入一两个问答示例Few-Shot Learning引导模型遵循期望的格式和风格。分角色提示例如“你是一个严谨的技术支持专家你的回答必须基于给定的技术文档。”6.4 生产环境考量向量数据库升级Chroma适合原型生产环境可考虑Milvus、Qdrant、Weaviate或Pinecone云服务它们支持分布式、持久化、更高的并发和更丰富的查询功能。异步处理对于大量文档的索引构建使用异步IO来提高处理速度。缓存机制对常见问题的答案或中间向量结果进行缓存减少对LLM和向量数据库的重复调用降低成本和延迟。监控与评估建立评估体系监控回答的准确性、相关性和用户满意度。可以使用LLM本身如GPT-4作为裁判对问答对进行自动评分。安全与权限企业级应用需考虑知识库的访问权限控制确保不同用户只能检索其权限范围内的文档。6.5 工程化建议配置化管理将模型路径、API密钥、Chunk大小等参数抽取到配置文件如YAML或环境变量中。日志记录详细记录用户的查询、检索到的文档、生成的答案以及耗时便于问题排查和系统优化。异常处理对网络超时、API限流、空检索结果等异常情况进行妥善处理给出友好的用户提示。单元测试为文档加载、分割、检索等核心模块编写单元测试保证代码健壮性。7. 总结与展望通过本文我们完成了一个RAG系统从理论到实战的完整构建。我们从理解RAG解决“幻觉”和“知识更新”的核心价值出发逐步拆解了其“索引-检索-增强-生成”的架构并使用LangChain、Chroma和开源嵌入模型搭建了一个本地可运行的问答系统。关键收获RAG的核心在于利用外部知识库动态增强LLM的能力而非依赖其静态参数。文本分割和嵌入模型是影响检索质量的两个基石需要根据实际数据仔细调优。Prompt模板是控制LLM行为、减少幻觉的关键开关。可解释性返回源文档是RAG相比纯生成模型的巨大优势在严肃场景中必不可少。下一步可以探索的方向多模态RAG不仅处理文本还能处理图片、表格中的信息。Agentic RAG让RAG系统具备自主决策能力例如判断是否需要多轮检索、是否需要调用工具计算器、搜索API来完善答案。更复杂的链式结构使用LangChain的LangGraph等工具构建有状态、可循环的复杂问答工作流。与微调结合在特定领域先用领域数据对基础模型进行轻量微调再结合RAG可能达到最佳效果。RAG技术正在快速发展新的框架、模型和优化策略不断涌现。但万变不离其宗掌握本文所述的核心流程和优化思路你就能快速适应新的工具构建出更强大、更可靠的智能应用。建议你立即动手用自己的文档跑通这个流程并在过程中尝试调整参数、优化Prompt感受每一个环节对最终效果的影响。