
RAG热了大半年后台搜索词里“rag瓶颈”“rag知识库能存储图片嘛”“ontology rag”“rag智能体”这些问题一直在涨。我正好在做《RAG进阶实战》这个专栏从策划到大纲再到每个实验都重新排了一遍。这篇就当专栏的策划案和预习笔记一起放出来。这个专栏不教怎么跑通一个demo教的是怎么把一个RAG系统做到能用、能评估、能上线。适合写过几个RAG脚本、但对生产环境心里没底的人也适合正在搭企业知识库、但还没想清楚架构的人。我会把高频搜索词揉进对应章节顺带把Mac本地搭建的完整路径也讲清楚。1. 策划案定调RAG进阶到底在进什么1.1 进阶与初学的真正分界线初学阶段的RAG通常是“装一个框架读一批文档跑一个问答demo”。这个阶段的核心动作是调通链路文档切块、向量化、存库、检索、拼Prompt、生成回答。看起来每一步都有现成组件但很多人到了这一步就停住了因为“能跑”和“能用”之间隔着一条很宽的沟。进阶要进的东西不是再多学一个向量库而是把所有黑盒变成白盒。比如用户问一个问题你要能说清楚究竟是哪一段文档支撑了答案为什么召回的是这几段而不是另外几段换一个Embedding模型之后结果的差异是多少top_k从3调到8会带来多少噪声。这些问题不解决RAG项目就永远停留在演示阶段。所以我在策划专栏时定的第一条原则就是每一讲必须给出一套可操作的度量方式没有度量就没有进阶。1.2 这个专栏做给谁看解决什么问题后台搜索词里有一类特别典型“rag教程”“rag实战”“rag项目”。说实话入门教程已经很多了大家缺的是那种“有人踩过坑、告诉你哪里会翻车”的进阶经验。我把目标读者锁定在两类人一类是做后端开发已经在业务系统里集成过LLM接口但对检索链路不熟另一类是算法工程或数据分析出身熟悉模型评估但不知道知识库工程怎么做。这个专栏不追求大而全而是围绕“检索增强”这个核心做深。每讲都对应一个热搜词背后的真实疑问。比如有人问“rag知识库能存储图片嘛”这就是多模态RAG的选型问题有人问“wiki和rag有什么区别”这是知识源结构化程度的问题有人问“rag瓶颈在哪”这是评估和排错的问题。专栏把这几个问题拆成独立章节每个章节末尾都留一个可运行的小项目这样读者学完不是记住概念而是真的改过几行代码。2. 专栏内容骨架八讲怎么排才不虚2.1 八讲大纲与每讲产出我最终把专栏排成了八讲脉络是从“数据准备”到“检索优化”再到“生成增强”最后落到“评估和上线”。不按框架的模块顺序讲而是按一个RAG系统从零搭建过程中会遇到的真实问题顺序讲这样读者跟着做一遍就能得到一个完整可用的知识库项目。讲次主题核心产出第1讲重新认识RAG检索、生成与知识的三角关系一张系统架构图一份组件选型清单第2讲知识库工程文本拆解、清洗与分块策略一套本地文本解析管线和分块参数配置第3讲向量检索与召回优化Embedding、BM25与混合检索一个支持混合检索的检索模块第4讲生成环节优化Prompt设计、重排与引用溯源一份带引用来源的问答接口第5讲结构知识库与知识图谱何时不用向量库一个图谱查询和向量检索的对比实验第6讲在Mac上搭一个本地RAG知识库一套完全本地运行的项目代码第7讲RAG评估体系从指标到badcase分析一个离线评测脚本和评估报告模板第8讲智能体与多模态扩展RAG的下一个形态一个带检索决策的Agent原型这个大纲看起来跟市面上很多专栏类似但区别在于每一讲都绑定了“热搜词”。比如第5讲重点回应“kg知识库、rag知识库和结构知识库区分以及应用场景”第8讲回应“rag智能体”和“rag知识库能存储图片嘛”。这样安排的好处是读者带着问题来学完能直接带走答案。2.2 热搜词倒推出来的选题信号做内容策划最怕自嗨。我整理后台搜索词的时候发现高频问题往往就是进阶用户最真实的卡点。“rag瓶颈”这个词反复出现说明很多人已经跑通了demo但不知道系统为什么不够好。“有没有本地的rag文本拆解工具”说明大家不想把内部文档传到云端本地化是刚需。“怎么在mac上搭建rag知识库”更直接说明开发者的主力机器是Mac很多教程却默认Linux服务器。所以专栏在第6讲专门讲了Mac环境下的全链路搭建包括Apple Silicon上的模型量化、本地向量库选择、文本解析工具配置。这个选题不是因为我偏爱Mac而是因为本地开发场景确实值得单独对待。至于“ontology rag”这种词虽然搜索量不算高但能搜这个词的人通常是已经踩到了实体关系混乱、图谱查询结果不准的问题。我在第5讲把ontology拉出来单独解释不讲纯理论只讲它解决什么问题、什么时候该上。2.3 每讲配置一次动手实验专栏的另一个设计原则是每讲至少一个动手实验实验的产物可以叠加成完整项目。第2讲的文本解析管线到第3讲直接喂给检索模块第3讲的检索结果到第4讲接上重排和引用第6讲把前面所有东西收拢成一个本地运行的完整系统。这样读者每学完一讲不是得到一堆碎片代码而是往一个项目里加一个模块。我特意把实验难度控制在“能在一个晚上跑完”的范围。比如第3讲的混合检索代码量大约一百多行用现成的库就能实现不要求读者从头训练模型。进阶的关键是理解参数为什么这么设而不是把整个系统重新造一遍。所以每一讲都配了参数表、对比结果和常见报错目的就是让读者在最短时间内获得“手感”。3. 关键环节的实操拆解3.1 文本拆解不是所有工具都能处理PDF“有没有本地的rag文本拆解工具”这个问题我几乎每次分享都会被问到。文本拆解是RAG的第一步但它比大多数人想象的要麻烦。普通的PDF如果本身就是文本型直接用解析库提取就能得到不错的文字但扫描件、带复杂表格的PDF、双栏排版论文、PPT截图这些场景靠单一工具基本搞不定。我在专栏里推荐了一套组合方案优先用unstructured处理PDF和Word它对复杂表格和多栏布局的支持比传统解析库好扫描件先过OCR我实测下来PaddleOCR在中文场景很稳晰度不够的图片就先做图像增强再识别纯网页或Markdown文档用markitdown或者自己写正则提取就够了。场景推荐工具备注普通文本PDFpypdf或pdfplumber简单快速处理不了表格复杂表格/多栏PDFunstructured会把表格结构保留成HTML或markdown扫描件/图片PaddleOCR中文效果好需要本地跑或轻量服务Markdown/HTMLmarkitdown微软开源转换质量高这套组合跑下来我手里的文档解析成功率从70%左右提升到了95%以上。注意解析完成之后一定要做清洗不是拿到文本直接切块。常见问题包括页眉页脚混入正文、表格拼接后语义断裂、段落标题和正文顺序错乱。清洗的目的是让切块时不会把不该连在一起的内容强行拼起来。3.2 分块参数怎么选才不玄学很多人把分块参数当成玄学其实是有规律可循的。分块的核心矛盾在于块太小语义不完整检索容易漏块太大噪声太多还容易超出模型上下文。我在专栏里给了一套经验区间通用文档用300到800个token比较稳妥常见选择是512块与块之间的重叠overlap设为块长度的10%到20%保证跨块的长句不丢。中文场景还要额外注意很多切块工具默认按空格和标点切分中文标点如果不做处理会把一个完整句子拦腰截断。我的做法是先按句子边界切再按token数量合并成块。这里推荐sentence-transformers的分句逻辑或者llama_index里的SentenceSplitter它比纯char_split要稳得多。分块不是一次性工作它直接影响后面所有环节。我建议每调整一次分块参数就重新跑一遍离线评测集用召回率和答案正确率来验证而不是靠感觉。很多项目效果差第一嫌疑就是分块策略没调好而不是Embedding模型不够强。3.3 检索优化向量、BM25、重排缺一不可RAG进阶到一定程度几乎都会遇到纯粹靠向量检索不够用的阶段。向量检索擅长语义相似但它在关键词精确匹配上表现不稳定人名、编号、型号这类信息很容易丢。所以混合检索是生产环境里最实用的方案向量负责语义召回BM25负责词面匹配两者结果做加权合并再用重排模型精排。我在专栏里给的默认方案是BM25 Embedding然后接一个重排模型。Embedding选型上中英文混合场景推荐bge-m3或gte系列这两个在中文文本上效果不错而且支持稠密向量和稀疏向量混合。重排模型可以用bge-reranker别小看这一步我实测同一个问题加了重排之后top5准确率能提升10到15个百分点。重排的位置也很关键先用向量和BM25召回top50再用重排模型取出top5最后把top5拼进Prompt。这里不要一开始就只取top5因为召回阶段取太少会把正确答案漏掉取太多又会有噪声所以召回多、精排少这是比较稳健的思路。3.4 知识图谱RAG和ontology别跟向量库混用“rag知识库和结构知识库区分以及应用场景”这个问题很多人搞不清。向量库适合存储非结构化文本比如说明书、合同、市场报告结构化知识库适合存储关系明确的业务数据比如订单记录、用户信息这类数据用SQL或API查比用向量检索更准确知识图谱则适合多跳关系推理比如“A公司的供应商里哪些曾经给B公司供过货”。ontology在这里的作用不是说一定得搞一套哲学概念而是给图谱里的实体和关系定规矩。比如医疗场景里“症状”和“疾病”是两类实体“药物”和“疾病”之间存在“治疗”关系如果不用ontology约束同一件事会有几十种叫法图谱查起来就是一团乱麻。所以ontology是知识图谱RAG的“行话词典”也是实体归一的依据。我见过不少项目明明只需要一个SQL查询就能拿到答案却硬要套向量库做RAG结果又慢又不准。我建议在选型时先问一句这个问题的正确答案是不是存在于某张表里如果答案是肯定的优先走结构化查询只有答案分散在长文本中、没有固定字段时才轮到向量RAG上场。把这两类分开系统会简单很多。3.5 框架选型与智能体化改造市面上RAG框架不少LangChain、LlamaIndex、Haystack各有特点。我的建议是初学者别一上来就全家桶先用LlamaIndex把数据接入和检索这块理顺因为它对知识库场景封装得很好索引管理、节点解析都做得顺手。如果需要更自由的Agent编排再上LangChain或直接自己写调用逻辑。生产环境里框架的选择没有绝对标准关键看团队的熟悉程度和维护成本。“rag智能体”是最近很火的搜索词但很多人把Agent理解成“加一个函数调用就能自动完成多步任务”。实际上RAG智能体的核心是让模型自己决定“要不要检索、检索什么、检索结果够不够”再决定下一步动作。最简单的实现是给模型一个search_knowledge_base工具它在回答前先判断是否需要外部知识。这种设计在需要多轮追问、多源对比的场景里特别有用但它对Prompt和工具描述的要求更高这也是专栏第8讲重点演练的内容。4. 在Mac上从零搭一个本地知识库4.1 本地模型的部署思路“怎么在mac上搭建rag知识库”是后台搜索量很高的词我觉得是因为很多人不想把内部文档传到云端API。Mac上跑本地模型目前最省事的方案是ollama它对Apple Silicon的支持很好能直接利用MPS后端。我的建议是先用量化版模型跑通流程比如7B参数的Q4版本内存占用大约4GB普通16GB内存的MacBook都能流畅运行。# 安装 ollama brew install ollama # 拉取一个中文能力不错的小模型 ollama pull qwen2.5:7b-instruct # 启动本地服务 ollama serve这里有一个容易踩的坑不要盲目上13B或更大的模型尤其统一内存较小的机型加载大模型会疯狂吃swap回答速度慢到没法用。我实测16GB内存的MacBook Air跑7B Q4模型生成速度还算能接受跑13B就会出现明显卡顿。模型大小、量化等级、可用内存之间的关系要在项目启动前算好不然边跑边换模型很浪费时间。4.2 向量库和解析工具的选型本地向量库我推荐chroma或lancedb两者都能嵌入到Python进程里不需要额外启动服务。chroma上手快自带简单的持久化和查询接口lancedb在数据量大一点的时候性能更稳还支持直接在本地做混合检索。如果你的知识库只有几百个文档选哪个都行重点是把存储目录和集合设计清楚。文本解析工具就用之前提到的unstructured和PaddleOCR。unstructured有一个本地模式不调用云服务完全在机器上运行。PaddleOCR第一次运行会下载模型权重所以最好在网络好的时候提前跑一次。解析产出的文本统一存成Markdown或纯文本格式再进入切块流程。这样整体链路是文档变成文本文本变成块块变成向量向量存进数据库。4.3 从文本到问答的最小可运行项目下面我给一个最简代码框架读者可以在此基础上扩展。我用LlamaIndex做索引Ollama提供本地推理chroma做存储目标是能对一个文件夹里的文档发起问答。from llama_index.core import SimpleDirectoryReader, VectorStoreIndex from llama_index.core.node_parser import SentenceSplitter from llama_index.llms.ollama import Ollama # 读取本地文档 documents SimpleDirectoryReader(./docs).load_data() # 按句子边界切块块大小设为512 splitter SentenceSplitter(chunk_size512, chunk_overlap64) index VectorStoreIndex.from_documents( documents, transformations[splitter], ) # 使用本地 Ollama 模型 llm Ollama(modelqwen2.5:7b-instruct, request_timeout120.0) # 构造问答引擎 query_engine index.as_query_engine(llmllm, similarity_top_k5) response query_engine.query(这份文档里的退款政策是什么) print(response)这个例子只用了不到二十行代码但它把完整的RAG链路跑通了。进阶的地方在于你可以替换切块参数换成混合检索接入重排模型甚至把query_engine替换成自己的Agent逻辑。我建议读者在这个基础上一点点加东西而不是一开始就搭一个庞大的流水线否则出了问题都不知道从哪查起。4.4 本地项目里的性能取舍在Mac上做本地RAG性能问题是绕不开的。文本解析时PaddleOCR如果跑CPU会慢好在Mac的M系列芯片跑ONNX版本还是比较快的。向量化这块Embedding模型通常不大用CPU也能跑但批量处理文档时建议分批避免内存暴涨。生成阶段7B模型在Apple Silicon上用MPS速度不错但单并发基本就是极限别指望本地模型能扛住高并发请求。一个务实的方案是本地模型用于开发和内部小范围使用线上服务仍然调用云端API。专栏里我会教读者把接口抽象成统一调用层这样切换本地模型和云端API只需要改一个配置不需要改业务代码。这个小设计能让你在开发阶段省钱、上线阶段省心。5. 评测体系与避坑实录5.1 一套能用的离线评测集怎么做“rag瓶颈”这个词很大但绝大多数瓶颈都能归结为“没有量化只能靠感觉调参”。所以我在专栏里专门用一整讲讲评测。最简单的做法是准备30到50条高质量问答对每条问题标注正确答案来自哪个文档以及标准答案文本。然后跑一遍RAG系统统计三个指标检索命中率、答案正确率、引用准确率。指标计算方式说明检索命中率正确答案所在文档是否出现在top_k中衡量召回质量建议目标90%以上答案正确率生成答案是否包含标准答案要点可以用LLM打分或人工判断引用准确率答案引用的内容是否真的支持结论防止幻觉被引用包装我建议先人工标注一遍数量不在多在质量。30条题目覆盖不同文档、不同问题类型比如“直接问题”“对比问题”“多跳问题”分开统计结果能清晰看出系统在哪类问题上弱。比如多跳类问题命中率低说明还需要知识图谱或更长的上下文处理而不是盲目调Embedding。5.2 常见问题速查表收集了相当多RAG项目的badcase之后我把踩过的坑整理成了一张速查表专栏里会放在附录里反复用。这里先放出几个最常见的。现象大概率原因排查思路回答看起来有引用但内容是编的生成环节没有约束引用来源改为“只基于引用块回答”不满足就拒答检索结果总是缺关键信息Embedding对领域词不敏感试试混合检索给BM25更高权重top_k越大回答越差噪声块把答案冲淡了缩小top_k加入重排模型精排中文长句被切碎切块器没按句子边界处理换成SentenceSplitter注意中文标点PDF里表格数据丢失普通PDF解析处理不了表格用unstructured或单独解析表格本地模型回答很慢模型大小超过内存上限换更小的量化版本或改用云端API这里面很多问题是通过评测集暴露出来的而不是用户反馈。比如“检索结果总是缺关键信息”如果不跑hit率统计你可能永远不知道问题出在Embedding还是分块上。所以评测和排错是一体的评测不是为了打分是为了告诉你下一步该动哪一行代码。5.3 RAG的瓶颈到底卡在哪关于“rag瓶颈”我自己的判断是大部分系统卡在三处。第一是召回质量语义向量和关键词匹配没做好后面再调Prompt也救不回来第二是评估缺失没有评测集任何优化都像闭着眼睛调参第三是上下文组织即使召回了正确文档如果Prompt把不相关内容塞太多模型照样答错。想在RAG方向上继续深入正确顺序应该是先建立评估集然后回头检查分块和检索再做重排最后才优化Prompt。这个顺序我踩过一次大坑之前一上来就搞Prompt模板效果起伏很大后来才发现同一个Prompt在换一种分块方式之后效果天差地别。所以“瓶颈”往往不在你以为的地方先量化再定位这是最省时间的路。6. 专栏之外几点个人心得体会6.1 组件越多维护越重我见过一个RAG项目把向量库、图数据库、多模型、Agent框架全塞进去结果出了bug根本不知道是哪一层的问题。我的经验是能用一个简单组件解决就不要堆两个复杂组件。开局先把最基础的文件问答做稳之后再根据评测结果一点一点加东西。组件多不是成熟能控制复杂度才是成熟。6.2 RAG还能往哪个方向延伸“rag知识库能存储图片嘛”这个问题其实代表了多模态方向。目前比较实际的做法是图片先经过OCR或视觉语言模型生成描述文本把描述存进知识库做检索图片本身作为证据文件保留。这样既利用了RAG的文本检索优势又不丢视觉信息。另外RAG和Agent结合之后可以做的就不只是问答了比如根据知识库内容自动写周报、自动提取合同条款这些场景我都在专栏后面的扩展章节里给了选题和原型。6.3 给准备开新坑的人的建议如果让我给准备做RAG项目的人一条建议那就是别急着追求“高级”先把最小闭环跑稳再把评测集建起来。之后所有优化都会变得有依据。我自己做专栏策划时也是这样不是一口气把所有内容写完而是先把每一讲里最容易出错的部分反复实验、记录结果最后才形成现在这版目录。实践出真知这句话放在RAG领域尤其成立。