我花了两周时间把一份《RAG进阶实战》专栏策划案推翻重写了三遍,才从一版"看起来很全、实际没法落地"的大纲里爬出来。背后的真实原因很简单:RAG这个领域,网上教程已经多到泛滥,但绝大多数还停留在"什么是RAG、十分钟搭一个问答机器人"的阶段。真到了知识库投产、检索优化、多模态资料处理、知识图谱融合这些进阶场景,能找到的靠谱内容非常稀缺。这个专栏要做的,就是把RAG从"能跑"带到"跑得稳、跑得准",顺便把大家每天在群里反复问的问题——比如RAG知识库和结构化知识库到底怎么区分、RAG知识库能不能存图片、Mac上怎么搭建一套本地知识库——一次性讲透。
1. 专栏策划的起点:RAG进阶到底进阶在哪里
1.1 为什么这个时间点适合做RAG实战专栏
先说一个行业观察:RAG已经过了概念普及期,正在进入深水区。2023年大家讨论的是"RAG能解决幻觉问题吗",2024年讨论的是"怎么把召回率从60%提到90%",到了现在,企业真正关心的已经变成了知识更新、多租户隔离、权限控制、成本优化、评测回归这些工程问题。
我自己手头同时推进过三个RAG项目,一个做企业内部制度问答,一个做供应链知识图谱问答,还有一个做多模态资料库。三个项目遇到的问题完全不同:第一个卡在文档切分和快速检索上,第二个卡在实体关系建模和结构化数据融合上,第三个直接面对"图片到底怎么进知识库"这个灵魂拷问。这些才是RAG进阶的真实战场。
所以这个专栏的定位不是RAG教程,而是RAG实战。它要把大家默认"应该会、实际上没人讲透"的那层东西掀开:知识点不按API使用方法组织,而是按问题域组织。每个章节都围绕一类真实工程问题展开,给出可复现的方案和可量化的效果。
1.2 专栏的核心读者和内容分层
做内容策划第一件事不是列目录,而是想清楚读者是谁。我把目标读者切成三类:
第一类是刚搭过Demo但效果不理想的人。他们用LangChain或LlamaIndex跑通了一个简单问答,换了企业真实文档后效果崩塌,不知道问题出在切分、嵌入模型还是检索策略上。这类读者需要的是诊断方法和优化路径。
第二类是要做企业知识库的技术负责人。他们面对的是几百份制度文档、混合权限、动态更新频率,需要知道知识库选型、结构化数据融合、权限隔离怎么做,还要能跟业务方讲清楚能力边界。
第三类是算法和架构方向的工程师。他们想深入理解混合检索、重排序、查询改写、多模态向量化这些技术细节,甚至需要设计一套评测体系来验证系统效果。
内容分层也对应这三类:入门篇讲基础概念和最小实现,进阶篇讲检索优化和知识库设计,工程篇讲评测、部署、权限和更新机制,原理篇则讲嵌入模型、重排序、图谱融合背后的逻辑。每篇都带可运行的代码或配置,避免"纯原理空谈"。
1.3 先定交付物,再定目录
策划案改了三次,最大的转折是我把设计顺序倒过来了:先定义每个阶段读者能交付出什么,再反推目录。
第一阶段的交付物是一个人能跑通的私有知识库问答系统,文档进、答案出,带引用溯源。第二阶段交付物是优化后的检索管线,召回率、命中率、忠实度都有量化报告。第三阶段交付物是一个多模态资料库原型,图片、表格、长文档都能被检索和问答。第四阶段交付物是一套知识库评测集和回归测试方法。
有了这四份交付物,目录自然就出来了:数据准备与切分、知识库构建、检索优化、问答生成、评测迭代。这个逻辑也跟真实的项目推进节奏一致——你不可能在没做好数据清洗和索引设计的情况下,就指望重排序能解决所有问题。
2. 知识库选型:RAG知识库与结构化知识库到底怎么区分
2.1 先理清名字:向量库、知识库、知识图谱
在正式讨论选型前,必须把几个被混用了很久的词拆开。很多人把"向量数据库"直接等同于"知识库",这是最常见的误解。
向量数据库(比如Chroma、Qdrant、Milvus)是一个存储和检索向量数据的引擎,它本身不关心你的知识长什么样。RAG知识库是"非结构化文档 + 切分 + 嵌入向量 + 向量索引 + 检索逻辑"的组合体。你可以用向量数据库来承载RAG知识库,但知识库的价值在于它背后的数据组织方式,而不只是向量存储本身。
知识图谱(KG)则完全不同。它通过"实体—关系—实体"的三元组来描述知识,比如"张三—任职于—技术部"。知识图谱天然适合表达多跳关系,比如"找出所有跟某供应商有合作关系的二级供应商",但构建成本高,且对非结构化文本的覆盖能力弱。
还有一个经常被忽略的概念是ontology,也就是本体。本体是对某个领域的概念、属性、关系进行显式的、形式化的定义。简单说,本体是知识图谱的"骨架规范",它规定了这个领域里有哪些概念、概念之间有哪些关系。
这些概念搞清楚之后,再回头看"RAG知识库和结构化知识库有什么区别",答案就清晰了:它们不是替代关系,而是面向不同数据形态和查询需求的技术路线。
2.2 场景对照:什么时候用RAG知识库,什么时候用结构化知识库
我在专栏设计里专门做了一张场景对照表,用来帮读者快速判断选型方向。
| 业务场景 | 推荐方案 | 原因 |
|---|---|---|
| 制度文档、会议纪要、FAQ问答 | RAG知识库 | 语义检索对非结构化文本友好 |
| 产品参数、设备型号、精确口径查询 | 结构化知识库 | 需要精确匹配和强一致口径 |
| 人员组织架构、供应链上下游关系 | 知识图谱 | 多跳关系推理是图谱强项 |
| 法律法规、行业规范检索 | RAG知识库 + 元数据过滤 | 长文本语义相关,但需要条款定位 |
| 医疗、金融等强领域约束场景 | RAG + ontology/图谱混合 | 需要领域概念约束避免实体歧义 |
判断依据其实就三条:第一,数据本身是不是结构化的;第二,查询是模糊语义匹配还是精确逻辑匹配;第三,是否需要多跳推理。如果答案是"文档为主、语义为主、单跳或浅层推理",RAG知识库是性价比最高的选择。如果数据本来就是表格或Schema化的,或者查询需要严格精确,别硬塞进RAG,用一个关系型数据库或图谱反而更稳。
我在企业里见过最典型的失败案例,就是把一份Excel产品价目表切碎后丢进向量库,然后期望模型能精确回答"某某型号在2024年第三季度的价格"。结果模型经常把新旧版本价格混在一起。这个场景用结构化知识库,一个SQL查询就结束了。
2.3 ontology RAG:最容易被忽略但很关键的一层
ontology RAG是热搜词里出现频率很高的一个概念,也是我认为进阶内容里最值得做的部分。
所谓ontology RAG,通俗讲就是在RAG的检索和生成环节引入本体约束。玩具项目可以不做,但到了医疗、法律、金融这类强领域,实体歧义和关系链断裂会直接毁掉问答效果。举个例子:"阿司匹林对儿童的影响"和"阿司匹林对成人退烧的影响",在纯向量检索里可能因为语义相近而互相干扰。如果有一个本体定义了"药品—适用人群—不良反应"的约束,检索阶段就可以先把不匹配的人群关系过滤掉。
具体落地有两种常见路径。第一种是先构建轻量KG,用图谱结构辅助检索:把高频实体和关系抽出来,查询时先在图谱上做实体链接和子图召回,再把召回结果融合进RAG的上下文。第二种是只用本体Schema做过滤:定义合法的概念和关系,检索时把embedding相似度匹配的结果限制在本体约束的范围内,不需要完整构建知识图谱。
我在专栏里会给出一套简化实现:用LLM从文本中抽取实体和关系,存入图数据库,再写一个Router,根据查询类型决定走纯向量检索、图谱检索还是混合检索。这一章最难的不是技术实现,是让读者建立"什么时候值得做ontology"的判断力。所以我特别加了一个反向提醒:如果文档领域简单、实体歧义低,强行引入本体会增加维护成本,不要为了技术炫技而上图谱。
3. 数据组织实战:RAG知识库能不能存图片、怎么存
3.1 先说结论:可以,但不是你想的那种存法
"RAG知识库能存储图片嘛"是我在技术社群里被问得最多的问题之一。直接回答:能,但知识库里真正存的并不是"图片文件本身",而是图片的向量表示、文字描述、存储路径和元数据。
如果你理解为"把图片直接塞进向量库,然后问答时模型能看图",那就把问题想简单了。RAG的检索单元是文本和向量,大模型生成的依据也是文本上下文。要让图片参与RAG,核心逻辑是把图片转成"可检索、可注入上下文"的形式。
在实际项目中,图片参与RAG有三种成熟路径,分别适合不同目标。
3.2 三种落地方案的对比
我通常用一张表把三种方案讲清楚:
| 方案 | 核心思路 | 适合场景 | 局限 |
|---|---|---|---|
| A:多模态向量化 | 用CLIP或类似模型把图片直接编码为向量,支持以图搜图和图文联合检索 | 图片资料库、电商商品检索 | 模型较重,不支持图片内容细节问答 |
| B:图文描述转文本 | 图片先经过VLM模型生成文字描述,描述文本走标准嵌入流程 | 文档中的插图、图表说明 | 依赖描述质量,可能丢失细节 |
| C:OCR + 结构化元数据 | 图片文字用OCR识别,元数据(来源、日期、拍摄对象)写入结构化字段 | 扫描件、票据、截图、文档图表 | 对纯图像内容无能为力 |
方案A解决的是"找得到",如果用户想查"跟这张工装风格类似的照片",多模态向量是唯一选择。但要注意,CLIP这类模型的向量维度通常比文本模型高,存储和检索成本也跟着涨。
方案B实操里最常用。我处理企业文档里的大量架构图、流程图时,通常让视觉模型先输出一段结构化描述,再把这描述和图片所在章节的文本拼在一起,作为一个chunk存进去。这样用户问"这张图里系统的调用链路是什么",模型不仅能搜到图片,还能看图说话。这里有个细节提醒:图片的文本描述一定要和上下文合并,不要单独成为一个孤立chunk,否则检索时缺少语境支撑。
方案C适合两类场景:一是扫描件和票据,需要精确读取文字;二是文档表格,需要把表格内容转成可检索的文本。OCR之后还要做字段对齐,否则提取出来的内容是一堆无结构字符串,检索效果同样拉胯。
3.3 表格、长文档、多级目录的处理细节
如果只解决图片问题、不处理表格和长文档,知识库还是建不好。我把这三个数据形态放在同一章,因为它们的本质问题相同:结构化信息如何在非结构化管线里保留语义。
表格的处理,我的经验是三步:先识别表格范围,再把表格转为Markdown或"键值对"文本,最后把表格连同前后文的标题和说明合并成一个chunk。千万别把整份包含几十个表格的Excel整文件塞进去,也不要把表格拆得比手机屏幕还碎,检索时会既丢上下文又产生大量无关片段。
长文档的处理核心是层级切分。我习惯按"篇章—节—小节—段落"维护文档树,每个chunk里带着层级路径信息,比如"第三章/2.1节/设备选型依据"。这样检索时既能按照标题定位,也能通过层级关系过滤和聚合。这种做法在LangChain里对应的是HierarchicalDocumentSplitter、在LlamaIndex里是HierarchicalNodeParser,但更重要的是理解背后的层级保留思路。
多级目录处理还有一个小技巧:把每个chunk的父级标题和完整路径写入metadata,而不是只存正文。许多检索失败案例都源于chunk丢失了上下文位置,用户明明知道答案在某章某节,检索却把内容从完整语境里剥离出来。这些问题很琐碎,但恰恰是进阶实战里最值钱的经验。
4. Mac上搭建RAG知识库:一套可复制的轻量方案
4.1 框架选型:不能只看Star数
"怎么在Mac上搭建RAG知识库"这个话题能上热搜,说明很多人的第一诉求是在本地跑一套能用的系统。我先说框架选型,再给完整路径。
主流的RAG框架现在几个方向:LangChain生态最大、组件最全,但抽象层级多,新手容易被各种Chain和Tool绕晕;LlamaIndex对文档索引和检索做了大量原生优化,做知识库类的项目体验更顺手;Haystack是工业级搜索架构,组件稳定但社区相对小;Dify和FastGPT偏向低代码平台,适合快速搭产品原型,但自定义检索管线的灵活性受限。
我自己的选型标准只有三条:一是文档索引能力是否原生,二是检索管线的可编程性是否够强,三是换嵌入模型和重排序模型是否方便。按这个标准,教学场景我推荐从LlamaIndex或LangChain入手,生产场景反而更建议自研管线或使用Dify这类平台做快速验证。框架从来不是核心,数据准备和检索策略才是。
4.2 从零到一:Mac本地搭建的完整步骤
Mac本地搭建的核心是"尽量本地化、选轻量组件"。我用一套组合给大家做参考:Ollama作为模型服务,Chroma作为向量库,LlamaIndex作为管线编排。
第一步,安装Ollama。通过Homebrew执行安装,然后拉取两个模型:一个负责生成,一个负责嵌入。负责生成我用qwen2.5:7b,负责嵌入用bge-m3。注意,Mac的显存和内存有限,7B已经是兼顾效果和资源的好选择,更大尺寸的模型在12G内存的机器上会明显卡顿。
brew install ollama ollama pull qwen2.5:7b ollama pull bge-m3第二步,安装Python依赖。向量库我用Chroma,因为它单机轻量、不需要单独起服务,非常适合学习环境。
pip install chromadb llama-index ollama第三步,建索引。下面是一段极简的示例代码,先读取文档目录,设置好嵌入模型和向量库,然后建索引。
from llama_index.core import SimpleDirectoryReader from llama_index.core import VectorStoreIndex from llama_index.core import Settings from llama_index.embeddings.ollama import OllamaEmbedding from llama_index.llms.ollama import Ollama Settings.embed_model = OllamaEmbedding(model_name="bge-m3") Settings.llm = Ollama(model="qwen2.5:7b", temperature=0.1) documents = SimpleDirectoryReader("./docs").load_data() index = VectorStoreIndex.from_documents(documents) index.storage_context.persist("./storage")第四步,查询。从本地持久化目录加载索引,直接提问。
from llama_index.core import StorageContext, load_index_from_storage storage_context = StorageContext.from_defaults( persist_dir="./storage" ) index = load_index_from_storage(storage_context) query_engine = index.as_query_engine() response = query_engine.query("项目管理流程中的变更审批需要几个环节?") print(response)这套方案在Mac上完全跑得动,目录里放上几十篇PDF或Markdown文档,建索引耗时通常在几分钟内。需要提醒的是,Ollama首次拉取模型会占用不少磁盘空间,bge-m3大概1G多,qwen2.5:7b大概4G多,建议提前确认磁盘余量。
4.3 嵌入、切分、重排的参数心得
框架跑通只是开始,参数调优才是进阶。我整理几个经过实测的经验值。
切分这块,固定按字符数切分最省事但效果也最糙。我的习惯是优先按标题和语义边界切,把chunk size控制在200到600字之间,overlap取10%到20%。overlap太小,边界语义容易断;overlap太大,索引膨胀明显。对于中文文档,建议先做段落分割,再合并短段落,尽量避免把一句话拆成两半。
嵌入模型方面,中文任务优先选BGE系列或同类中文优化模型,直接用英文为主训练的嵌入模型处理中文,检索效果会明显下降。不要盲目追求更大的向量维度,bge-m3输出是1024维,已经能支撑绝大多数业务场景。
检索策略方面,纯向量检索不够,我强烈建议叠加BM25关键词检索做混合召回,再在融合结果上加一层重排序。具体做法是先各取top50,融合后重排序取top5,效果比单路向量检索扎实很多。重排序模型可以使用BGE Reranker系列,运行时会带来一定延迟,但精度提升非常值得。
这些都是我反复调过的参数。写在专栏里时,我会附上一个完整的"参数速查表",让读者在跑通基础版本后,能用最短时间完成第一轮优化。
5. RAG的瓶颈不在模型,在工程
5.1 检索质量的三个坎
网络上关于RAG瓶颈的讨论很多,我的体会是:模型能力已经够用,瓶颈集中在检索阶段的工程细节。
第一个坎是召回率低。很多情况下,用户提问的用词和文档的表述差异很大,纯向量检索找不到相关内容。解决方法有多路召回、查询改写、同义词扩展。查询改写是最实用的:用一个轻量LLM把用户问题拆解成多个子查询,分别去检索再合并结果,召回率提升特别明显。
第二个坎是上下文噪声。召回结果里混着大量弱相关片段,直接塞给模型,答案会被带偏。解决之道是重排序,把真正相关的片段提到最前面,同时在Prompt里要求模型"只依据给定文档作答,不要使用外部知识"。这一步能同时改善答案相关性和忠实度。
第三个坎是数据层问题。重复文档、旧版本残留、扫描件识别错误,都会让检索结果混乱。知识库上线前一定要做去重和版本清理。我见过一个客户,制度文档更新了三次,旧版本全在库里,导致模型经常回答过时政策。后来加了发布日期过滤并建立文档生命周期管理,问题才真正解决。
5.2 生成环节:上下文窗口与忠实度
生成环节的瓶颈和RAG的标准实现方式强相关,核心是控制上下文质量。
很多人在Prompt里把top-10的检索结果全部塞进上下文,结果模型被大量无关信息干扰。我的经验是top-k在3到6之间最合适。太少,可能缺少关键论据;太多,注意力被噪声稀释。同时,查询涉及的文档片段排序要把最相关的放在前面,模型对靠前的内容权重更高,这是利用上下文位置的技巧。
忠实度问题则要靠两层控制:一是Prompt硬约束,明确"未找到相关信息时,直接说明无法回答,禁止编造";二是引文溯源,要求模型在回答时标注引用来源编号。这个机制在评测和线上纠错阶段价值巨大,用户可以快速定位到具体段落,人工审核效率也高。
5.3 评估与迭代:没有评测体系的RAG都是玄学
一条很扎心但真实的经验:不做评测体系,RAG优化就是碰运气。我见过不少团队改切分参数、换嵌入模型后感觉"效果好了",但问具体哪里好了、好多少,答不上来。这就是没有量化评测的典型症状。
专栏里我会专门讲评测集怎么建。从真实用户问题中采样100到200条作为评测集,每条问题标注标准答案和相关的文档片段。然后定义核心指标:忠实度(答案是否严格基于检索片段)、答案相关性(是否回答到点子上)、上下文准确性(检索片段是否包含足够信息)、噪声鲁棒性(检索片段里混入无关内容时是否还能答好)。每轮优化后,把这套评测集完整跑一遍,用指标对比替代"感觉"。
评测之后还要做回归和bad case复盘。每次改动检索策略或模型,跑一次全集评测,对比前后指标变化。线上系统上线后,把用户反馈和模型回答回流到bad case池,定期聚类分析。这些方法不复杂,但能把RAG优化从玄学变成工程。
6. 专栏内容设计的落地细节
6.1 案例怎么选:从内部问答到知识图谱推理
策划专栏时,我最纠结的就是案例设计。市面上的教程案例大多是"拿一份公开小说建索引、问两个问题",缺乏真实业务复杂度。我最终定了三个递进式项目。
第一个项目是企业内部知识问答。给出一套模拟的制度文档和FAQ,包含版本变化、岗位职责、审批流程等场景。读者要完成数据清洗、层级切分、混合检索搭建,目标是回答准确率超过特定阈值。这个项目覆盖了大多数RAG知识库的真实形态。
第二个项目是知识图谱融合问答。领域设定为供应链关系,提供供应商、物料、合同、交付记录等多张表。读者需要提取实体关系图、设计路由策略、融合向量检索和图谱检索,回答"核查某物料是否同时供应给三家以上的客户"这类多跳问题。这个项目展示结构化知识库、RAG知识库和KG如何协作。
第三个项目是多模态资料库。语料包含产品手册、架构图、表格、发票扫描件。读者要设计图片和表格的处理管线,实现"查一下某型号产品的接口示意图"和"找出某月发票总额"这类跨模态问题。这个项目直面"RAG知识库能不能存图片"的完整答案。
每个项目还附了配套数据集和参考答案,确保读者做完之后有明确的交付物,而不是看完就算。
6.2 每章作业与验收标准
专栏策划被动辄"看完即会"式的标题带偏,所以我在章节设计里强加了验收标准。每章的作业不是"读后感",而是可运行的产物。
数据准备章节的作业是提交一份清洗报告,描述文档去重、格式转换、质量问题的处理情况。索引构建章节的作业是提交一份索引设计文档,写明切分策略、chunk结构、metadata字段。检索优化章节的作业是提交检索效果对比表,分别记录向量检索单路、混合检索、混合检索加重排序三组指标。每个作业都有量化验收线,不达标就回到对应章节查缺补漏。
这个设计来源于我们团队的真实工作方式。没有验收标准的培训内容,读者很容(Object steel) 真题回意学完就忘;有了明确的产出物,才算真正掌握。
6.3 更新节奏与配套资源
内容再好,节奏不对也容易烂尾。我把整个专栏规划成八周更新周期,每周两篇:一篇实战教程,一篇原理深挖。内容大纲按照第2章到第5章的思路展开,最后两周集中做综合项目和评测复盘。
配套资源包括三块:一个可以本地运行的代码仓库、一份持续更新的常用参数速查表、一个读者问题答疑汇总库。我特别建议把答疑库做成知识库本身——读者问过的问题、踩过的坑、给出的解决方案,全部用RAG知识库的方式沉淀下来,既是答疑,也是示范。
最后说一个我自己做专栏、带团队做项目时反复体会到的点:RAG真正难的部分从来不是调API,而是数据、评测和迭代这三件事。很多人一上来就想上重排序、上知识图谱、上多模态,但文档连基本的层级切分都没做好、评测集一片空白,后面所有优化都像在沙地上盖楼。如果你看完这份策划案准备动手做自己的知识库,我真心建议先从数据清洗和评测集这两个无聊但关键的部分开始,把地基打牢,后续的每一步都会顺很多。