十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

RAG实战指南:用Jupyter Notebook搭建知识库问答系统

RAG实战指南:用Jupyter Notebook搭建知识库问答系统 很多人第一次接触 RAG 时以为它就是“把文档扔给向量库再把检索结果拼进 Prompt 交给大模型”这么简单。但真正动手做一遍知识库应用你会发现文档解析、分块策略、Embedding 选型、检索质量、命中评估每一个环节都可能让最终回答跑偏。这也是为什么社区里出现了大量 RAG 相关的 Notebook 项目——它们把完整的检索增强生成流程拆成一个个可以独立执行的 Cell让开发者一边运行一边观察中间结果比直接看文档或调 API 快得多。这篇文章就以RAG Refresher Notebook为主线讲清楚一个典型的 RAG 项目应该包含哪些模块、每一步在解决什么问题、如何用 Jupyter Notebook 把整条链路跑通以及真正容易踩坑的地方在哪里。读完你可以用它快速搭建一套自己的知识库问答原型也能理解后续做精细化调优时应该从哪里下手。1. 这篇文章真正要解决的问题做知识库问答最常见的三条技术路线是微调大模型、直接把长文本塞进上下文、引入 RAG。你是不是也遇到过下面这些情况公司内部有一套产品文档、运维手册或业务规范希望让大模型基于这些资料回答问题但直接问 ChatGPT它根本不知道这些私有内容。考虑过微调但训练数据要标注、算力要投入、迭代周期也长只是想先验证一下效果不值得为一个小场景专门走一遍完整微调流程。尝试过把所有文档都塞进 Prompt但文本一长Token 消耗大、响应变慢而且模型经常被无关内容干扰回答不够稳定。RAG 的解法思路是先检索、后生成先从外部知识库中找出与问题最相关的文本片段再把这些片段作为参考上下文交给大模型。这样既不需要重新训练模型也能把最新文档、私有资料引入回答过程中。相比微调RAG 的优势在于知识更新成本低、可控性强、便于追踪答案来源。但 RAG 不是“零门槛”。很多项目从能跑到效果可用之间还有一段距离。最常见的三个坑是文档加载后变成一堆乱码或碎片、分块大小不合适导致检索结果答非所问、Embedding 模型选得不匹配导致语义检索精度很低。因此这篇文章的价值不在于告诉你 RAG 是什么而在于给你一条“分步验证”的路径用 Notebook 的形式一步步看清楚每个环节做了什么、输出的中间结果长什么样、哪里需要调。本文适合以下读者刚入门 RAG想快速跑通一个最小可用知识库问答 Demo。已经在做知识库应用但检索效果不理想想系统排查是分块问题、Embedding 问题还是检索策略问题。需要在团队内部快速验证 RAG 是否适合某个业务场景不想一上来就搭庞大工程。2. RAG 与 Notebook 的核心概念与适用场景2.1 什么是 RAGRAG 的全称是 Retrieval-Augmented Generation也就是检索增强生成。它把“信息检索”和“文本生成”组合在一起生成答案之前先从知识库中检索相关证据再让大模型基于证据作答。一个标准的 RAG 流程可以分解为五个环节环节做什么常见工具/方法文档加载读取 PDF、Word、Markdown、HTML 等原始文件PyPDF、Docx、BeautifulSoup、LangChain Loader文本分块把长文档切成适合检索和向量化的短片段RecursiveCharacterTextSplitter、TokenSplitter向量化用 Embedding 模型把文本片段映射为向量OpenAI Embedding、BGE、Sentence-Transformers向量存储与检索把向量存入数据库根据问题相似度召回相关片段Chroma、FAISS、Milvus、Weaviate生成回答把召回片段组装成上下文交给大模型生成答案GPT 系列、Qwen、ChatGLM、Claude需要澄清一个常见误解RAG 不是“向量检索”的同义词。向量检索只是 RAG 中间的一个环节。完整的 RAG 还包括数据清洗、分块设计、检索后处理如重排、Prompt 组装和生成策略。一个检索做得很好但生成时没有正确引用资料的 RAG仍然可能输出错误答案。2.2 为什么用 Notebook 来做 RAG这里的 Notebook 指的是 Jupyter Notebook一种以“单元格”为单位的交互式 Python 环境。你可以把代码、说明文字、运行结果同时放在一个文档里并且可以按格子顺序执行。相比直接写一个.py脚本使用 Notebook 做 RAG 项目有明显优势中间结果可见文档加载后可以立刻打印前 500 字检查是否乱码分块后可以看每个块的实际内容向量化后可以检查向量维度。这些在传统脚本里往往要写一堆调试逻辑才能看到。分段执行RAG 的每个环节相对独立用 Notebook 可以只重新运行某一个格子不用把整个流程重新跑一遍。比如只调整了分块大小不需要重新加载文档。方便记录实验过程Notebook 本身就是“代码 文字 输出”的混合文档非常适合记录调参过程和实验结果便于分享给团队或回顾。不过 Notebook 也有自己的边界。它更适合原型验证、学习和实验如果要部署成生产环境的高并发 API 服务通常还是要把逻辑抽离成标准 Python 模块再配合 FastAPI 等框架提供服务。2.3 Jupyter Notebook 与 JupyterLab 的关系很多初学者会搞混 Notebook 和 JupyterLab。简单来说JupyterLab 是 Jupyter Notebook 的下一代交互式开发环境它保留了 Notebook 的单元格交互方式同时提供了文件管理、终端、代码编辑器等更完整的功能界面。两者都可以打开.ipynb文件。对于本文的 RAG 项目用哪个都可以操作逻辑基本一致。如果你是通过 Anaconda 安装的启动时选择 Jupyter Notebook 或 JupyterLab 都没问题。3. RAG Notebook 环境准备与前置条件在开始之前先确认你的本机环境满足以下条件。本文不会强制绑定某个具体版本号因为 RAG 生态更新很快刻意写死版本反而不利于你落地。比较稳妥的方式是确认 Python 版本不低于 3.9然后使用最新的稳定依赖。依赖用途安装方式Python 3.9运行环境官网或 Anacondajupyter / notebook打开 Notebookpip install notebooklangchain封装 RAG 流程的工具链pip install langchainlangchain-community加载器和向量库集成pip install langchain-communitysentence-transformers本地 Embedding 模型pip install sentence-transformerschromadb向量数据库pip install chromadbopenai调用大模型 API可选pip install openai如果你使用 Anaconda它会自带 Jupyter Notebook不需要单独安装。如果你用的是原生 Python 环境可以执行pip install notebook jupyter notebook安装成功后浏览器会自动打开 Notebook 工作台。如果你需要创建项目的独立目录可以先新建一个文件夹再在该目录下启动 Notebook。我个人建议为每个 RAG 实验项目单独建目录因为后面会涉及文档文件、向量库持久化文件、模型缓存等混合在一起很容易乱。这里说明一下国内访问 HuggingFace 下载模型时有时会超时后面我会在常见问题里给出处理建议。如果你准备使用 OpenAI 等大模型 API请提前确认账户和网络访问方式符合你的使用环境规定。4. RAG 核心流程拆解从文档到答案在写代码之前我们先把 RAG 的每个环节看透。很多人代码能跑通但不知道每个参数在控制什么导致效果不好时无从下手。4.1 文档加载原始资料怎么变成可处理的文本文档加载是 RAG 的第一个环节也最容易被轻视。你的原始文档可能是 PDF、Word、Markdown、TXT、HTML甚至是网页内容。不同类型的文件需要不同的加载器。从材料看LangChain 提供了大量文档加载器TextLoader用于纯文本PyPDFLoader用于 PDFUnstructuredMarkdownLoader用于 MarkdownBSHTMLLoader用于 HTML。加载器的核心目标只有一个把文件内容变成干净的纯文本。这里真正容易踩坑的地方是PDF 文件可能是扫描件或图片型 PDF直接加载得到的不是文字而是空白或乱码。遇到这种情况需要先用 OCR 工具做字符识别。另外加载后的文本里往往包含页眉、页脚、水印、目录等噪声这些内容会影响后续检索质量。建议在加载后打印前几行检查一下确认没有异常再继续。4.2 文本分块为什么不能把整篇文章作为一个向量很多人不理解为什么必须分块。原因主要有两点Embedding 模型通常有输入长度限制例如 512 个 Token超过会被截断。一个句子或一个小段落本身携带的信息足够回答大多数问题而整篇文章的向量过于“平均”检索时反而不容易命中准确位置。想象你要在一本三百页的书中找出某个人物的出场描写如果把整本书压缩成一个向量检索精度必然下降。分块策略里有三个关键参数参数含义影响chunk_size每个块包含的字符数或 Token 数太小则信息不完整太大则引入噪声chunk_overlap相邻块之间重叠的部分防止关键信息刚好落在切分边界被截断分隔符策略按什么优先级切分如段落、句子、空白决定分块是否符合语义结构LangChain 中常用的RecursiveCharacterTextSplitter就是按优先级递归切分先尝试按段落分隔符\n\n切不够大小再按句点、感叹号再不够按空格。这种策略的好处是尽量保持语义完整。从实践角度来看chunk_size 的初始值建议设为 300 到 800 个字符或 200 到 500 个 Tokenoverlap 设为 50 到 100。具体值需要根据你的文档类型和查询粒度调整没有万能答案。4.3 向量化与向量存储文本如何变成可搜索的坐标向量化也叫 Embedding是把文本转换成一组浮点数向量。语义相近的文本在向量空间中的距离更近。你需要选一个 Embedding 模型。常见的选择有OpenAI 的text-embedding-3-small等在线模型效果较好但需要调用 API。开源本地模型如 BGE 系列、Sentence-Transformers 系列可离线部署适合隐私敏感场景。根据不同语言场景选择对应模型中文场景下 BGE 中文模型通常比通用英文模型效果好。向量存储方面Chroma 和 FAISS 是入门常用的选择。Chroma 支持持久化到本地目录适合原型验证FAISS 是纯向量索引库查询速度极快但不自带数据库管理功能。生产环境通常考虑 Milvus、Weaviate、Elasticsearch 等更完整的方案。4.4 检索如何从知识库中找到最相关的片段检索是整个 RAG 的关键环节。最基础的方式是相似度检索计算问题的向量与知识库中所有向量的相似度返回 TopK 个最相近的片段。但相似度检索有它的局限性有时最相关的片段在语义上接近但不完全匹配或者检索出的几个片段内容重复覆盖的信息面不足。这时可以考虑 MMRMaximum Marginal Relevance检索它在相似度和多样性之间做平衡避免返回一堆重复度很高的片段。如果你想让检索效果更好还可以在检索后增加一个重排Rerank阶段用专门的交叉编码器模型对上一步召回的候选片段重新打分排序。这个我们会在最佳实践部分展开。4.5 生成检索结果如何变成最终答案检索完成之后需要把命中的片段按一定格式拼接到 Prompt 中并明确告诉大模型请基于提供的资料回答不要编造。这里有一个判断准则如果检索不到相关资料宁可让模型明确说“资料中未找到相关信息”也不要让它强行编一个答案。这个约束要在 Prompt 里写清楚。此外如果你的业务场景要求答案可溯源可以在 Prompt 中要求模型标注引用来源或把每个片段的文件名、章节信息一起传进去。5. RAG Notebook 完整示例与代码实现下面我们用一个最小可运行的 Notebook 示例把上面讲的流程串起来。示例中的知识库是一个纯文本文件sample_knowledge.txt里面包含几段产品文档内容。我们会在 Notebook 中完成分块、向量化、检索、生成的全过程。5.1 创建测试文档在 Notebook 的同一目录下新建一个sample_knowledge.txt文件写入几段有明确主题的文本例如RAG 系统通常包含文档加载、文本分块、向量化、检索和生成五个核心环节。 文档加载层负责把 PDF、Word、Markdown 等不同格式的文件解析为纯文本。 文本分块的目的是控制向量的信息粒度过大的分块会引入噪声过小的分块则可能导致信息不完整。 向量化模块使用 Embedding 模型将文本转换为向量语义相近的文本在向量空间中的距离也更近。 检索模块根据用户问题从向量库中召回相关片段常用的方式有相似度检索和 MMR 检索。 生成模块将检索结果与用户问题组装成 Prompt交给大语言模型生成最终回答。这个文件内容比较小但足够跑通整个流程。实际项目中你可以替换为自己公司的真实文档。5.2 安装依赖并导入工具库在 Notebook 的第一个 Cell 中安装依赖!pip install langchain langchain-community chromadb sentence-transformers openai然后新建一个 Cell导入工具库import os from langchain_community.document_loaders import TextLoader from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain_community.embeddings import HuggingFaceEmbeddings from langchain_community.vectorstores import Chroma这里有两个需要注意的细节。第一LangChain 的社区集成在不断变化有些类名可能从一个版本迁移到另一个版本如果导入报错可以先升级到最新版再查看官方文档确认类路径。第二HuggingFaceEmbeddings 依赖sentence-transformers库如果导入报错优先检查它是否安装成功。5.3 加载文档# 加载本地文本文件 loader TextLoader(sample_knowledge.txt, encodingutf-8) documents loader.load() print(f加载完成共有 {len(documents)} 个文档对象) print(--- 前 200 字预览 ---) print(documents[0].page_content[:200])执行结果预期类似加载完成共有 1 个文档对象 --- 前 200 字预览 --- RAG 系统通常包含文档加载、文本分块、向量化、检索和生成五个核心环节。 文档加载层负责把 PDF、Word、Markdown 等不同格式的文件解析为纯文本。如果这里输出的内容是一堆乱码或空白说明文档加载本身有问题需要换加载器或检查编码。这一步虽然简单但值得认真看一眼。5.4 文本分块# 使用递归字符分割器 text_splitter RecursiveCharacterTextSplitter( chunk_size200, chunk_overlap50, separators[\n\n, \n, 。, , , , ] ) chunks text_splitter.split_documents(documents) print(f分块完成共得到 {len(chunks)} 个片段) print(--- 第一个片段 ---) print(chunks[0].page_content) print(--- 第二个片段 ---) print(chunks[1].page_content)这里 chunk_size 设置为 200 是为了在小文档中产生多个块方便观察。如果设置成 800上面这段内容可能全部落在一个块里你反而看不到分块效果。在真实项目中你需要根据文档平均长度和查询粒度重新调整。关键点在于观察相邻块之间是否有重复内容以及每个块是否在语义上相对完整。如果某个块从一句话中间戛然而止说明分隔符或 chunk_size 的设置不够合理。5.5 向量化并存储到向量库# 使用本地 Embedding 模型无需 API Key embedding_model HuggingFaceEmbeddings( model_namesentence-transformers/paraphrase-multilingual-MiniLM-L12-v2 ) # 创建 Chroma 向量库并持久化到本地目录 vectorstore Chroma.from_documents( documentschunks, embeddingembedding_model, persist_directory./chroma_db ) print(f向量库创建完成持久化目录./chroma_db)执行后你会在当前目录看到一个chroma_db文件夹里面就是向量数据。本地 Embedding 模型的首次运行需要从 HuggingFace 下载模型文件根据网络环境可能需要几分钟。如果下载很慢或失败我们在常见问题中会给出办法。用本地模型的好处是整个过程不需要任何 API Key文档数据也不会离开你的电脑适合验证和隐私敏感场景。5.6 执行检索# 用户问题 query 文本分块的作用是什么 # 相似度检索返回最相关的 3 个片段 retrieved_docs vectorstore.similarity_search(query, k3) for i, doc in enumerate(retrieved_docs): print(f--- 检索结果 {i 1} ---) print(doc.page_content) print()预期检索结果中应该包含与“文本分块”语义最接近的片段。如果检索结果明显不相关检验思路是问题本身是否太模糊分段是否合理Embedding 模型是否适合当前语言这里不要急着改代码先观察输出再判断原因。如果你希望检索结果更有多样性可以改用 MMRretrieved_docs vectorstore.max_marginal_relevance_search(query, k3, fetch_k10)5.7 组装 Prompt 并调用大模型生成检索只是前半段后半段是生成。下面用 OpenAI API 来演示你可以替换成其他兼容接口的模型。from openai import OpenAI client OpenAI(api_keyYOUR_API_KEY) # 将检索到的片段组装为上下文 context \n\n.join([doc.page_content for doc in retrieved_docs]) prompt f你是一个严谨的问答助手。请只根据以下提供的资料回答问题。 如果资料中没有足够的信息请直接回答“资料中未找到相关信息”不要编造。 【资料】 {context} 【问题】 {query} 【回答】 response client.chat.completions.create( modelgpt-4o-mini, messages[ {role: system, content: 你是一个严谨的知识库问答助手。}, {role: user, content: prompt} ], temperature0.2 ) answer response.choices[0].message.content print(--- 模型回答 ---) print(answer)在这个示例中temperature0.2是为了让回答更稳定、更贴近资料减少自由发挥。生成时你需要根据自己使用的模型和接口调整参数。如果你没有大模型 API也可以尝试用本地模型替代。但本地模型对显存和内存要求较高需要单独配置。文章后续会提一下这个方向但不会在最小示例中展开避免分散主线。5.8 完整的 Prompt 组装思路上面的代码只是一个最小示例。实际项目中你通常还需要在 Prompt 中说明出处例如在每段资料前标注[1]、[2]要求回答时引用编号。在 Prompt 中告诉模型如果资料之间存在矛盾应该如何处理。在 Prompt 中限定回答的语言、风格和长度。这个部分建议单独封装成一个函数方便后续调整 Prompt 模板。不要把一长串 Prompt 直接写在业务代码里团队协作时很难维护。6. 运行结果与效果验证跑通代码只是第一步更重要的是判断你的 RAG 流水线是否真的“可用”。整个过程不是只看模型回答是否流畅而是要分环节验证。6.1 分环节验证清单在 Notebook 中逐个 Cell 执行后建议按下面的清单检查检查环节判断标准文档加载打印前 200 字无乱码、无空白、无大量噪声文本分块每个块语义相对完整块之间重叠区域不超过预期向量化向量维度与模型输出一致无报错检索与问题语义相关的内容出现在 Top3 中生成回答内容可以在给定资料中找到依据而非模型自由发挥6.2 如何判断检索是否成功检索环节是 RAG 效果的分水岭。如果检索结果不相关后面 Prompt 写得再好也没用。一个有效的验证方法是打印出检索到的每一个片段自己先判断这些片段是否真的回答了问题。例如对于问题“文本分块的作用是什么”检索结果应该包含类似“文本分块的目的是控制向量的信息粒度”这样的内容。如果检索回来的却是“向量化模块使用 Embedding 模型……”这种只涉及相邻话题的片段说明分块策略或 Embedding 模型可能有问题。6.3 如何判断生成是否成功生成的回答需要满足两个条件忠实性回答内容能够映射到某一条或某几条检索片段而不是模型自己在编。完整性对于需要多个方面回答的问题模型是否把检索片段中相关的关键信息都纳入了回答。如果生成的回答流畅但完全没用上检索资料很可能是 Prompt 中的指令不够强模型选择忽略资料自由发挥了。这时可以调整 Prompt 中的措辞强调“请严格按照资料内容回答”“如果没有相关信息请明确说明”。6.4 失败的排查入口如果整个流程跑挂了第一步永远是看报错信息不要猜测。常见的情况是某个包版本不兼容导致 import 失败或者某一步的数据格式不对。在 Notebook 中报错信息会直接显示在对应 Cell 下方先看是哪一行出错再据此排查。7. RAG Notebook 常见问题与排查思路在写这个项目的过程中我把最容易遇到的实际问题整理成了表格方便你对照处理问题现象可能原因排查方式解决方案Notebook 启动后浏览器白屏Jupyter 版本或浏览器兼容问题查看终端日志尝试更换浏览器升级notebook包用无痕窗口访问import langchain_community报错langchain-community 未安装或版本过旧检查当前环境pip install -U langchain-community下载 HuggingFace 模型超时网络无法稳定访问 HuggingFace检查网络连接配置镜像源或提前下载模型到本地目录加载 PDF 后内容是空白文件为扫描版需要 OCR打开 PDF 确认是否可复制文字接入 OCR 工具如 PaddleOCR分块后每个块内容太碎chunk_size 太小或分隔符优先级不合适打印块内容和长度分布调大 chunk_size调整分隔符列表检索结果和问题不相关Embedding 模型与语言/领域不匹配用几个标准问题测试检索 Top3换用中文领域模型检查问题表达是否清晰模型回答与资料无关Prompt 指令不够强或温度偏高检查检索结果是否相关查看 Prompt 内容强化 Prompt 约束降低 temperature向量库目录重复导致数据错乱重新运行时重复写入或读到旧数据检查persist_directory下是否有旧文件删除旧目录重新创建或改用 HashMap 自增 id使用本地大模型时内存不足模型参数过大或设备不满足要求查看内存占用换更小的模型或使用量化版本单独把两个问题展开讲一下。第一个是 HuggingFace 模型下载超时。HuggingFaceEmbeddings 第一次运行会下载模型文件国内网络环境下经常失败。比较稳妥的办法是提前手动下载到本地目录然后在代码中指定本地路径。具体下载方式建议参考模型仓库说明不同模型的文件构成略有区别。第二个是 Chroma 持久化目录的清理。如果你修改了分块逻辑后重新运行创建向量库的 CellChroma 不会自动清理旧向量可能导致检索结果中混入旧数据。最稳妥的做法是在创建向量库之前删除旧的持久化目录import shutil # 删除旧向量库目录重新创建 shutil.rmtree(./chroma_db, ignore_errorsTrue)这种 reset 操作在原型阶段很方便但如果在生产环境使用需要谨慎设计数据更新策略而不是简单删除整个库。8. RAG 项目的最佳实践与工程建议8.1 文档加载与清洗RAG 效果的上限很大程度上取决于文档质量。不要以为“只要把 PDF 喂进去就行”。在生产项目中文档清洗通常包括去页眉页脚、去目录、去水印、去重复段落、规范表格和代码块。一个很常见的场景是产品文档里很多页面重复出现公司名称和版权声明这些噪声如果没有清洗检索时可能反复命中这些无关内容。建议在实际项目中建立一个“加载后检查”的步骤每次新增文档源时打印前 500 字和可视化的分块结果人工确认质量没问题再进入下一步。8.2 分块策略选择分块没有放之四海而皆准的参数。不同文档类型、不同查询粒度、不同 Embedding 模型对分块大小的敏感度不一样。我给出的建议是先按下面的规则设置初始值再结合效果调整面向 FAQ 或短文本问答chunk_size 可以偏小300 到 500 字符。面向长文章、技术文档、报告chunk_size 可以放大到 800 到 1200 字符同时增加 overlap。如果文档有明确的结构标题、章节优先按结构分块而不是单纯按字符切分。也可以用“基于 Token 的分割器”替代字符分割器因为 Embedding 模型的长度限制通常按 Token 计算。RecursiveCharacterTextSplitter有一个length_function参数可以传入基于 Token 的计算函数。8.3 Embedding 模型选型Embedding 模型是检索质量的核心。选型时考虑三件事语言支持、领域适配、部署成本。如果你处理的是中文文档建议优先尝试国产开源模型例如 BGE 系列如果你的文档有大量专业术语比如医疗、金融、法律最好在小规模标注样本上对比不同模型的检索准确率。不要默认“英文模型处理中文也行”。很多英文预训练模型在中文语义上的表现明显弱于专门的中文模型检索效果差异在实际项目中很容易感受到。8.4 检索质量优化如果你发现检索结果不够精准可以从以下几个方向依次调试调整 TopK 值K 太小可能漏掉答案K 太大会给生成阶段引入噪声。使用混合检索结合关键词检索BM25和向量检索对包含特定术语的问题更有效。加入重排模型第一次召回 20 到 50 个候选再用重排模型精排取前 3 到 5 个送入生成。增加多样性控制MMR 等策略避免返回多个内容重复的块。重排Rerank是 RAG 进阶中非常值得投资的一步。它的工作原理是第一次检索用双塔模型效率高但精度一般召回大量候选第二次用交叉编码器精度高但速度慢对候选逐对计算与问题的相关度然后重新排序。虽然增加了一个阶段但效果提升往往非常明显。8.5 评估指标怎么判断 RAG 好不好热搜词里反复出现“rag知识库指标有哪些、如何理解各指标”这说明很多人在搭建 RAG 后不知道怎么评估。RAG 的评估通常分为两个维度检索评估看召回的内容是否相关常用指标是 Hit Rate命中的问题比例、MRR倒数排名衡量答案排得多靠前、NDCG考虑排序位置的加权指标。生成评估看生成答案的质量常用指标是忠实性答案是否基于检索内容、相关性答案是否回应问题、完整性关键点是否都覆盖。这些指标可以通过人工评测也可以用大模型作为裁判对答案打分。对刚起步的项目建议先人工标注 50 到 100 个测试问题跑通评测流程再逐步引入自动化评测工具。8.6 生产环境注意事项如果你打算把 RAG 项目从 Notebook 迁移到生产环境有几点必须注意向量库选型从 Chroma 换到 Milvus、Weaviate 或 Elasticsearch 时要考虑数据量、并发量和运维成本。数据更新机制文档更新后如何增量更新索引而不是全量重建需要设计明确方案。安全性如果知识库中包含敏感内容需要考虑权限隔离和数据脱敏。大模型调用时不要把全部上下文随意发给第三方 API。可观测性记录每次查询的检索片段、打分情况和最终答案便于回溯和分析问题。成本控制生成阶段的 Token 消耗取决于上下文长度合理控制 TopK 和分块大小同时能降低成本。8.7 从 RAG 到 Agentic RAGRAG 的下一步是 Agentic RAG让模型不仅仅做一次检索而是根据问题自主决定是否要多次检索、是否要改写查询甚至是否要调用额外工具。这样能处理更复杂的多跳问题但也带来了更高的延迟和不确定性。对大多数业务场景建议先做好基础 RAG再考虑引入 Agent 化能力。9. 总结与后续学习方向RAG Refresher Notebook这样的项目本质上是一个用 Jupyter Notebook 串起来的 RAG 全流程速览文档加载、分块、向量化、检索、生成每一步都可以运行、观察、调整。它的价值不在于代码本身有多复杂而在于让你能快速理解 RAG 的每个环节并且用最小成本验证思路。如果你现在手头有现成的业务文档建议直接替换示例里的知识库跑一遍完整流程然后从这些问题开始调优检索 Top3 是否真正命中核心信息如果没命中是分块问题还是 Embedding 问题模型回答有没有严格依据资料针对不同的失败类型再去查对应的优化方案。接下来的深入学习方向可以根据你的实际需要选择知识库质量与分块优化针对长文档、结构化文档做更精细的解析与切分。RAG 评估体系建立自己的测试问题集用指标衡量每次改动是变好还是变坏。重排模型与混合检索在向量检索之外引入 BM25 和 Rerank提升检索精度。Agentic RAG 与多轮问答让系统支持追问、澄清和意图规划更适合复杂业务场景。多模态 RAG处理包含图片、表格、图表的文档把非文本信息也纳入检索范围。如果只想记住一个提示那就是RAG 的质量瓶颈通常不在大模型而在检索。花时间打磨文档清洗、分块策略和检索链路往往比换更大参数的模型更能显著提升知识库问答的效果。建议收藏这篇文章等你在实际项目里遇到问题时再回来对照排查流程。
返回列表