
我们聊点得罪人的。RAG 现在火到什么程度随便一个技术群、一场 Meetup不从嘴里蹦两句“向量化”“召回率”“精排”你都不好意思跟人打招呼。GitHub 上更是重灾区几条流水线模板反复套加载文档、切片、Embedding、塞向量库、语义检索、拼 Prompt——整套流程跑通好像一天就能搞定然后标题再起得惊天动地“基于 RAG 的企业级知识库智能问答系统”。但你拆开看十有八九就是同一个洋葱换了几层皮在卖。我可以负责任地说RAG 烂大街的从来不是技术本身而是那条毫无技术含量可言的流水线。真正把项目撑起来的从来不是那套标准流程而是流程之外那六处极容易被忽略、却又决定成败的分水岭。今天我不写教程不贴流水线 demo专门把这六处拆开给你看。你项目卡在哪一步对照着自己查。1. 数据准备文本拆出来只是开始你要做的是“清洗成能用的知识”先泼一盆冷水你从 PDF、Word、网页里用工具抽出来的那堆文本不是知识是垃圾。本地 RAG 问答效果烂十个里面有七个死在数据准备这一步——你的拆分工具再本地、再快拆出来的东西没法直接用一切都是白搭。很多人的做法是这样的拿到 PDF用 PyMuPDF 把文字抽出来一句“太棒了跑通了”直接丢进切分器。结果问答的时候问它“合同有效期是几年”它来一句“根据文档内容本合同有效期根据实际情况确定”再追问具体年限它就开始胡编。原因很简单原文是“本合同有效期三年自签订之日起计算”你抽取的时候把字体嵌入信息搞乱了句子尾巴丢了或者被注释和页眉页脚污染了切出来的 chunk 根本缺胳膊少腿。真正能用的数据清洗至少要做三件事。第一件事是区分文本里的“结构”和“噪声”。PDF 里的页眉页脚、页码、水印、版权声明这些不是知识是噪声必须清掉。Word 里的批注、修订记录同样要剔除。我见过最崩溃的案例是有人把一份带批注的合同导进知识库AI 一本正经地回答“此处需甲方确认后生效”因为检索到的 chunk 里包含批注文字但这批注在原始文档里压根不是给读者看的。第二件事是表格和图表的特殊处理。文本抽取工具抽出来的表格全是乱的这不用我多说。但你可能没意识到RAG 知识库能不能存图片这个问题的答案不只是“能存”而是“你怎么存”决定了好不好用。常见的做法是提取表格文字转成 Markdown 表格但这个处理方法费劲又不讨好。我教你一个偏方表格在解析后如果结构复杂就把它转成“每个单元格加上行列信息”的文本描述。举个实际例子一张产品参数表型号A100功率120W重量2.3kg直接一行抽出可能没问题但遇到嵌套表头比如“功耗 / 待机3W / 满载120W”切分器一拆上下文就断了。所以遇到复杂表我会把它重构成“在待机状态下型号 A100 的产品功耗为 3W在满载状态下功耗为 120W”这样的描述性句子再入库。第三件事也是很多人完全忽略的——给 chunk 打“标题补丁”。原文的层级结构你的切分器是不知道的。它只会机械地按长度切。结果是“第三章 违约责任”“第四条 逾期利息”这些标题被切到上一个 chunk下一个 chunk 只有孤零零的正文。检索的时候模型只知道正文却不知道该违约责任是谁对谁的。所以切分后要做一遍后处理把每一个 chunk 的父级标题、二级标题拼接进 chunk 的开头。这个操作简单但对检索效果是决定性的。数据清洗的本质是把“机器能读的文本”变成“机器能理解的知识”。流水线给你的是前者分水岭决定让你拿到后者。2. 知识切分别套用标准 chunk size去观察你文档的“语义断点”市面上所有 RAG 框架的默认切分参数都长一个样chunk_size500overlap50顶多再换召回方式。但真实业务里的文档不是按“500 字符”来写段落的。你拿一套参数切所有文档那就等于把所有文档都当成同一头牛来切刀法再准照样切不到关节上只会把骨头剁碎。判断切分好坏的唯一标准是“语义完整性”。一个 chunk 内部应该自洽把一个意思说完并且不依赖前后 chunk 才能理解。这句话好说但实操怎么做我的做法是先做“结构锚点切分”再做“长度微调”。具体来说第一步按 Markdown 标题层级、多级列表、表格行、代码块等结构性标记把文档切成一棵层级树。这一步的目的是保住文档本身的逻辑骨架。第二步检查每一段到底有多长。如果某一段太长了比如法律法规条款再从语义断点处二次切分。语义断点是什么就是“一”“1.”“首先/其次/最后”“但是”这些转折词和序列词而不是固定的字符数。第三步做 overlap 拼接。注意overlap 不是无脑把上一段的尾部塞到下一段的头部而是重叠的下限是“一个完整句子的长度”——我通常以句号、问号、感叹号作为最小切分点。确保重叠进去的内容是一个完整的语义单元而不是半截句子。举个例子我曾经处理过一份 IT 运维手册里面每条操作步骤都长这样步骤 1登录服务器。步骤 2进入 /var/log 目录。步骤 3执行 tail -f app.log。如果按 500 字符切这三步会被整体塞进一个 chunk没毛病但如果是 200 字符切可能“步骤 2”会被劈成两半检索到“进入 /var”模型根本不知道进入之后干嘛。而如果按“步骤编号”作为断点切每一步独立成 chunk检索哪个步骤都不丢上下文。还有个坑99% 的人踩过表格的切分。表格按行切开每行一个 chunk看起来工整但你问“A100 的功率是多少”模型会检索到“A100 | 功率 | 120W”所在行上下文里没有表头“产品参数表”这个信息所以依然答得稀里糊涂。正确的做法在第 1 节已经提过——把表格转成描述性文本标题前置于 chunk再做切分效果立竿见影。别忘了切分参数不是“调一次跑一年”的静态值。不同文档类型要不要区分度合同和 FAQ 的切分策略完全是两回事。至少要做到按文档类型配置切分规则这是最基础的分水岭。你连文档类型都不分一套参数梭哈到底就别怪模型答非所问了。3. 跳过重排序Rerank的语义检索开源知识库的上限天花板很多人跑通 RAG 后第一反应是“这效果也太差了”第二反应是“肯定是 Embedding 模型不行换个更强的”。我不能说这方向完全错但大概率你花的力气用错了地方。绝大多数情况下瓶颈不在向量检索而在缺少一个“重排序Rerank环节”。先解释一下为什么向量检索会“不够用”。Embedding 的作用是把文本的高维语义压缩成低维向量但这个压缩是有损的——“上海”和“魔都”的向量距离能很近因为语义相近“羽毛球”和“球拍”也近因为主题相关。但问题是检索的时候向量相似度判断的是“整体语义相似”而不是“是否包含答案的关键证据”。你问“合同有效期是几年”向量检索出来的可能是“合同有效期条款如下”虽然文字压根没写答案但整段话和问题在“合同”主题上足够相似它就敢把这段排第一。这个时候如果前面的高相关 chunk 被排到第 3、第 4 位你把 top_k 设太小它就被截掉了设太大又会在最后一步塞进一堆无关上下文干扰生成。Rerank 就是干这个的——用一个专门的交叉编码器模型把“问题-候选文档”成对打分重新排序。交叉编码器会把问题和文档拼成一个句子一起过模型能够捕捉到词级、短语级的精确匹配关系。所以哪怕某个 chunk 整体的语义相似度不高但里面恰好有一句“合同有效期三年”它也能被抬到最高分。实操配置上有几个参数我非常推荐你重点关注候选集大小top_k before rerank向量检索阶段取多少条候选太小了没用比如只取 3 条即使里面有真正的答案但因为排在第 4直接出局后面 rerank 再好也回天乏术。我一般预留 40~80 条的候选空间。别怕算力后面还有精排兜底。重排序后的 top_n喂给大模型多少条这个要视模型的上下文窗口和你问题的复杂程度定。我的经验是业务场景下 4~6 条最稳再多容易让模型淹没在无关信息里反而开始胡编。阈值过滤重排序打分低于某个阈值的直接扔掉别硬塞给模型。我之前做知识库问答时遇到过极具迷惑性的一幕某候选文档分数 1.4 分很低但那段确实提了“有效期三年”是高分的候选文档在没提“三年”这回事。你说按分数该扔按答案该留——这就是 Rerank 模型的分数体系含义带来的复杂情况具体怎么调优后面再展开。Rerank 在开源生态里最常用的方案明星项目是 BGE-Reranker-v2-m3BAAI 出品。如果你只是自建知识库可以找它的轻量版 bge-reranker-base。但注意Rerank 模型的推理较慢如果知识库文档量大建议单独部署一个只跑重排序的服务别和向量检索、大模型推理挤在一个进程里。这一步做到了你才真正地从“向量搜索”迈入了“语义检索精确匹配”的混合阶段。没有 Rerank 的 RAG 就是裸奔不是跑通就叫完成了。4. 混合检索向量和关键词之争本身就是一个伪命题说到这肯定有人想问那我用 BM25 关键词检索不也行吗这里就牵出另一个热词——混合检索。我不止一次在技术问答里看到“RAG 知识库和结构知识库区分以及应用场景”这类问题。它的隐藏意思是很多人隐约知道不同检索方式、不同知识组织形态合在一起才能应对真实场景。向量检索好在哪里坏在哪里好在能处理同义改写、口语化表达坏在无法精确匹配实体、编号。比如你问“HK90 型传感器”向量检索可能匹配到“HK90 系列温湿度传感器”它把“型”和“系列”当成了相近语义就把两篇文档混在一起了。但你问的是精确型号关键词命中才靠谱。BM25 关键词检索好在哪里坏在哪里好在精确匹配、速度快、无需向量化坏在检索不出同义词。你问“传感器坏了该怎么办”BM25 可能因为文档里只有“故障”“异常”搜不出来。所以正确答案从来不是二选一而是混合检索——向量检索召回的 40 条和 BM25 召回的 40 条做合并去重后一起进重排序。这就是所谓的“召回阶段多条腿走路精排阶段统一拉齐”。我还见过更激进的方案——把 BM25 的得分和向量相似度做线性加权比如 0.3 倍 BM25 分 0.7 倍向量分再排序。但这种做法不如直接统一交给 Rerank 模型因为简单的线性加权没法正确处理两个分布不同的分数体系。在工程实施上通常会选择向量数据库内置的混合检索能力。市面上常见的向量库比如 Milvus、Qdrant、Elasticsearch都支持 BM25稠密向量的混合检索配置。我看过有人在 Mac 上用轻量的 Chroma 做本地知识库发现它不支持混合检索于是前端加了一个 grep 式的关键词过滤效果也还行但扩展性有限。如果你要上生产毫不犹豫选支持混合检索的向量库如果只是本地 demo你要清楚自己的瓶颈在哪不要后期数据量一上来才抓瞎。5. 知识库形态的进阶从扁平切片到图谱Graph与结构化组织我们来认真回应那个热搜词——“KG 知识库、RAG 知识库和结构知识库区分以及应用场景”。很多人以为建知识库就是把文档丢进去切片、向量化、建索引但这只是最基础、最苍白的一种形态。真实世界的知识是有关系的实体之间有关联概念之间有层级属性有约束。平铺开来的向量切片天然抓不住这些结构。我先给你一个判断标准快速区分三种知识库形态知识库形态核心组织方式擅长解决的问题典型短板向量 RAG 知识库文本块切片 向量索引开放式问答、语义检索、概括总结抓不住实体关系、多跳问题容易答错结构化知识库SQL/图表格、记录、节点边精确查询、固定属性问题、报表统计不支持模糊语义缺乏生成能力知识图谱Graph实体-关系-属性三元组多跳推理、关系判断、分类汇总构建成本高覆盖不全时召回很烂热词里的“Ontology RAG”其实是把本体Ontology思想引入 RAG 的一种进阶做法。先给领域建一个“概念骨架”比如医疗领域有“患者-诊断-药物-禁忌”电商领域有“商品-类目-价格-库存”再把文档里的实体抽取出来挂到这些概念节点上。这样问“这个药和那个药能不能一起吃”模型可以沿着图谱路径去查“药物-相互作用-禁忌”这一关系而不是靠向量猜。我知道会有人反驳构建知识图谱成本高运维复杂不是通用场景的最佳选择。你说得对全量构建确实费劲。所以更现实的做法是**“向量化为主图谱为辅”的混合架构**常规语义检索走向量 RAG遇到需要多跳推理、精确关系判断的问题比如“A 供应商的哪个零件出了问题影响到 B 项目的哪个环节”走图谱查路径二者结果合并进 Prompt。我还做过一个取巧的领域知识库实操方案不建完整图谱只做“概念层级树 属性表”。把产品文档中的型号、系列、参数、适用范围这些结构化信息拆成表把非结构化操作说明继续做向量切片各管一摊。我管它叫“轻量结构化增强的 RAG”。这个方案构建成本低得多但弥补了纯切片 RAG 对精确属性回答的天然不足。遇到“给我列出所有 50W 以上的型号”这类查询如果走纯向量检索你大概率得到一堆语义相近但数据对不上的答案但如果加了属性表这个 Query 可以转换成 SQL 或图查询问题立刻迎刃而解。所以别被“RAG 知识库”这个概念框死它只是知识服务的一种形态。真正的分水岭是你有没有意识到你的场景里存在结构化知识并主动去构建和调用它们。6. 评测与迭代不量化就优化的 RAG 项目都是裸泳最后一个分水岭也是最容易被忽视的评测体系。没有评测就没有迭代。你改了切分参数、换了检索策略、把 prompt 调了个温度效果到底是变好了还是变坏了凭感觉是不行的尤其 RAG 的生成结果是非确定性的你感觉“好像比上次好了”可能只是这次抽到的随机样本顺眼。要把 RAG 真正做扎实评测体系是绕不开的。关于这个我必须说得稍微专业一点。现在最有名且仍在维护的 RAG 评测方案是 LangChain 社区里 Rafa 同学贡献的RAGAS它把 RAG 的评测拆成三个天然适用于生成任务的维度——忠实度、答案相关性、上下文相关性。这套框架为什么重要因为只评测“答案对不对”跟“答案学会了没有”是两码事RAGAS 把二者拆开你才知道问题到底出在哪个环节。我筹备自己项目的评测集时一般是三条路并行3 条路并行构建 Golden Set一是从真实用户日志里挑高频问题二是自己对着文档提 50~100 个“故意刁难”的跨段问题比如“A 方案的步骤二在 B 方案里叫什么名字”三是找文档中明确定义但表达和问题用词不一样的问题测同义改写能力。质量路线每条问题预先标注标准答案再人工给每条回答按“准确、部分准确、错误、编造”分等打分统计整体准确率。再配合 RAGAS 跑忠实度、相关性等自动化指标。效率路线统计单次问答的端到端耗时和 token 消耗。很多人觉得这不算评测指标但我认为对实际落地是重要参考。本地部署知识库在 Mac 上跑得慢半拍如果用户等超过 5 秒才出答案技术上再完美用户也不会觉得好用。我实际跑过一次特别印象深刻的迭代.日志里有人问“退款多久到账”标准回答是“3~5 个工作日”但当时系统答“1~2 个工作日”——因为知识库里同时存在一张“售后承诺表”写着 1~2 天和一份“退款流程文档”写着 3~5 天向量检索把相关性都给拉齐了Rerank 选择了分数更高的承诺表。诊断完我是这么修的给“售后承诺表”这条数据加一个“适用场景元数据若用户问题中出现具体业务背景优先匹配流程文档”同时把 Rerank 候选集的阈值适当上调。改完后准确率从 68% 涨到 91%。没有评测集这问题根本定位不到——因为看起来每次回答都对只有翻日志我才发现“自己以为对”。这里的核心观点是RAG 项目的迭代能力 你的数据回流能力 评测闭环能力。每跑一次新模型、每换一种切分策略都要用你的测试集基线跑一遍。把“准确率”从 75% 提到 85% 很难但每次修改都有数据支撑的提效这才是真正可积累的技术资产。聊到这里我把这六处分水岭完整过了一遍数据清洗与结构化、语义化切分、重排序、混合检索、图谱与结构化增强、评测闭环。我个人在实际操作中的体会是这六处没有一个是“加个 API 就能解决”的银弹。它们每个环节都是在跟文档结构的真实情况较劲你的表格乱不乱你的段落是否自带内在逻辑你的业务是靠语义检索还是靠精确匹配你的查询是单跳还是多跳……这些问题的答案只有你的文档知道。最后再分享一个小经验。如果你现在手头正好有一个 RAG 项目别急着把六处一次性全上。先用评估集把现状基线测出来哪一项短板最明显就先补哪一项。最常见的死亡路线是数据没清洗先花钱上了个大模型chunk 切得稀碎先纠结 embedding 换不换。记住分水岭不在模型在系统设计。把六件事做扎实最终的答案会告诉你一切值得。