聊到 RAG(检索增强生成),圈内人常说的话是“跑通一个 Demo 不难,难的是一路演进到能上线”。这个判断我十分认同。从最早把文档切碎塞进向量库、做几个相似度检索再加进 Prompt,到后来围绕召回质量、排序策略、查询理解做精细化打磨,RAG 在三四年里走完了一条相当清晰的演进路径。这篇先梳理前半程:朴素 RAG 是怎么搭起来的,它为什么很快不够用,进阶 RAG 又在哪些环节做了修补,再往后怎么演变成模块化 RAG。内容适合正在做应用落地的小伙伴,也适合刚开始接触 RAG、想建立一张完整技术地图的新手。
1. 为什么 RAG 会成为大模型应用的标配
1.1 大模型的三块“短板”
大语言模型最让人着迷的地方,是它“什么都懂一点”。可一旦要把它放进真实业务里,三个问题立刻浮出水面。
第一是知识时效性。模型参数里的知识有一个明确的截止时间点,之后发生的事情它一概不知。第二是幻觉,模型在不确定答案时,会以非常流利的方式“编”出一个看似合理的回答,而且很难通过提示词彻底根除。第三是私有知识不可用。企业内部文档、专业领域的积累、实时更新的业务数据,模型在训练时根本没见过,自然无法回答。
这三块短板,催生了 RAG 的原始动机:与其逼模型把知识“背”进参数里,不如在回答前先从外部知识库里把相关资料“查”出来,拼进上下文,让模型看完资料再作答。这个思路的本质,是让模型从一个“闭卷答题的考生”变成“拿着教科书翻到对应章节再答题的考生”,准确率自然不一样。
1.2 RAG 和微调:为什么多数团队先选 RAG
有人会问:为什么不直接微调?把知识通过训练写进权重里不是更“原生”吗?
微调确实有效,但有两个硬伤。一是成本高,每次知识更新都要重新准备数据集、重新训练和评估,周期以周计算;二是效果不可控,把文档“记”进参数是个黑盒过程,你很难定位模型到底记住了哪一段,也很难解释它为什么答错。
RAG 的优势在于解耦。知识库更新,只需要重新索引文档,不需要动模型;回答过程可追踪,模型引用了哪一段资料是明确的;冷启动成本低,一个向量库加一个模型接口就能跑起来。所以大多数团队在做技术选型时,会先把 RAG 作为第一站,只有在 RAG 效果确实不够、或者对响应风格有特殊要求时,才考虑用微调兜底。这两者并不互斥,但 RAG 确实是性价比最高的起点。
2. 演进第一站:朴素 RAG 的三段式架构
2.1 朴素的索引环节:切块、向量化与元数据
RAG 最早期的实现,业内习惯叫朴素 RAG(Naive RAG)。它的流程非常直白:加载文档、按固定大小切块、用嵌入模型把每段文本转成向量、写入向量数据库。整个过程像搭一个最小可用的原型。
这里面最容易被低估的是“切块”。我见过不少团队第一步就栽在这里:拿一个 PDF 丢进默认的文本加载器,按 500 字符硬切,结果一句话被拦腰截断,一个表格被拆得七零八落。这样的块送进向量检索,召回质量基本靠运气。
后来大家摸索出几个经验:第一,优先按文档结构切,比如按标题、段落、章节边界,而不是纯按字符数;第二,给每一块补一点重叠区(overlap),避免关键语义正好落在边界上;第三,保留元数据——来源文件名、章节路径、页码、更新时间。这些元数据一开始看似没用,等做到引用溯源、结果过滤时才知道它们多重要。
嵌入模型的选择同样关键。通用的嵌入模型对日常语言表现不错,但在垂直领域里经常“水土不服”:专业术语的语义距离算不准,检索出来的结果排序很怪。如果资金和算力允许,在领域语料上微调一个专用嵌入模型,往往比换更贵的通用模型收益更大。这块属于典型的花小钱办大事,我后面还会细说。
索引构建完毕后,朴素 RAG 就进入第二阶段:检索。
2.2 朴素的检索与生成环节:TopK 的作用与上下文拼接
检索环节的核心逻辑很简单:把用户的问题也转成向量,在向量库里做相似度搜索,取前 K 个最相似的文本块,作为上下文拼接进 Prompt。
这个 K 值怎么定?太小了容易漏,召回不到关键答案;太大了容易灌,无关信息混进上下文,模型反而被带偏。我实测下来的感受是:K 从 3 调到 10,答案的完整度明显上升,但超过 10 以后,带来的是 token 开销上涨和回答准确率下降——因为上下文里噪声太多,模型分不清该信哪句。
生成环节更直白:把“问题 + 检索到的若干文本块”一起交给语言模型,同时明确告诉它“请基于以下资料回答,不要自行编造”。这就是最原始的 RAG 闭环。这个闭环能解决一部分幻觉问题,但离“稳定可靠”还差得远,接下来要说的短板,是每个做过朴素 RAG 的人都会遇到的。
2.3 朴素 RAG 的致命短板
朴素 RAG 最大的问题可以总结成一句话:召回不精准、结果不稳定。
假设你的知识库里有两段文档,一段是“某产品 2023 年的销售数据”,一段是“某产品 2024 年的销售数据”,两者文本高度相似。朴素 RAG 用向量相似度检索,很可能把两段都召回来,模型看到两个不同年份的数据,回答出来的结果轻则含糊,重则直接报错。这种“时间线混战”在金融、政策、技术文档场景里频繁出现。
另一个典型问题是查询复杂时检索失效。用户问“上个季度营收下降的原因和后续调整策略”,这个 query 涉及“营收下降”“原因分析”“调整策略”多个信息点。朴素 RAG 只做一次整体向量检索,很难把三个点对应的文档片段都高质量地找到,最后往往是“答非所问”。
还有一个隐性问题是上下文冲突。即便召回的段落都相关,段落之间也可能存在观点不一致、时效性不同、粒度差异大的情况。朴素 RAG 不做任何协调,直接把一堆材料丢给模型,模型只能靠自己的理解去“和稀泥”。这些痛点,直接把 RAG 推进到了下一个阶段:进阶 RAG。
3. 演进第二站:进阶 RAG 的三大抓手
3.1 预检索优化:分块策略与索引增强
进阶 RAG 的第一个优化方向,是把功夫花在检索之前。既然问题的根源之一是“切块太粗暴”,那就在索引阶段把块切得更聪明。
常用的策略有三种。第一种是语义切分,不再按固定字符数硬切,而是用句子的语义完整性做边界判断,让一个块尽量表达一个完整意思;第二种是结构化切分,针对 PDF、网页、Markdown 文档,先解析出标题层级,再按标题子树切块,这样每一块自带上下文结构;第三种是父子分块,父块保存更完整的上下文,子块负责参与检索,命中子块后把父块内容交给模型。第三种策略非常实用,能同时兼顾“检索的精准度”和“回答的上下文完整度”。
索引增强方面还有一个技巧:为每个文本块自动生成若干条摘要或候选问题,把摘要和原文本一起写入索引。检索时,query 更容易命中摘要或问题索引,再映射回原文块。这个思路相当于给每个文档块加了一扇更容易被敲开的“侧门”,召回率提升非常明显。
3.2 检索中优化:查询改写与混合检索
如果说预检索优化是“把仓库整理好”,检索中优化就是“让找东西的人更会问”。
最经典的做法是 query 改写。用户的问题往往口语化、有指代、信息不全,直接拿原始 query 去做向量检索,效果很难保证。一个常见方案是:让语言模型先把用户问题改写成一个更适合检索的查询语句,比如把“它的性能怎么样”改写为“某产品在某场景下的性能表现”。另一个思路是生成多个相关子查询,覆盖问题的不同侧面,分别检索后合并结果。再有就是假设性文档嵌入(HyDE)的思路:先让模型根据问题生成一个“伪答案”,再把伪答案拿去和文档做相似度匹配。这个办法听起来绕,实测在开放式问题上经常比直接用问题检索更准。
检索环节本身的优化,核心是混合检索。纯向量检索擅长语义相似,但关键词精确匹配、人名/编号/产品型号这类场景反而表现不佳。现在主流的做法是向量检索配合关键词检索(BM25 类算法),两条路各跑一遍,再把结果融合。融合方式可以直接取并集,也可以按分数加权合并。混合检索在技术文档、代码库、客服场景中几乎是必选项——用户搜“SDK-2024 报错”,关键词匹配的价值远大于语义匹配。
3.3 后检索优化:重排序与上下文压缩
检索做完,选出来的 TopK 就一定是好答案吗?不一定。向量相似度高的片段,未必是对问题最有用的片段。于是后检索阶段诞生了两个关键操作。
第一个是重排序(Rerank)。用一个专门的排序模型对召回的候选片段重新打分,而不是单纯依赖向量相似度。重排序模型通常会结合 query 与候选片段做深度交互,判断相关性更准确。实操中最常用的配置是:先向量召回 Top 100,再用重排序模型精排取 Top 5。这个“粗排 + 精排”的双阶段策略,在信息检索领域已经被验证过无数次,RAG 里同样适用。代价是重排序模型增加了延迟和算力开销,但这个钱大多数人花得值。
第二个是上下文压缩。即使重排后的 Top 5 都相关,每段可能都有大量冗余。上下文压缩要做的,是把每个候选片段进一步裁剪,只保留与问题直接相关的句子,再拼接给模型。这能明显降低 token 消耗,同时减少无关信息对模型判断的干扰。许多框架里已经内置了“压缩器”组件,内部也是调模型做抽取式压缩,属于拿来即用的能力。
进阶 RAG 的这三步优化,覆盖了“索引前、检索中、检索后”全链路,效果对比朴素 RAG 可以说是质的提升。但它的结构仍然是一条固定的流水线,遇到更复杂的场景,会发现难以扩展。这就轮到模块化 RAG 登场了。
4. 演进第三站:模块化 RAG 的乐高哲学
4.1 从固定流水线到可编排模块
如果你把进阶 RAG 的实现细节放在一起看,会发现它本质上是一条“索引 → 查询改写 → 向量检索 → 关键词检索 → 融合 → 重排 → 压缩 → 生成”的固定流水线。每一步都有价值,但也被这条链路的顺序绑死了。
模块化 RAG 的核心思想,是把流水线拆成多个可独立替换、自由组合的模块。除了索引、检索、生成三大件之外,还引入了路由模块、记忆模块、验证模块、知识图谱模块等。每个模块像一块乐高积木,你可以根据业务场景决定用哪些、按什么顺序拼、是否引入循环。这种做法思路的转变在于:RAG 不再是一个固定的架构,而是一个可编排的框架。
为什么这种转变重要?举一个实际场景:企业知识库往往包含多个数据源——内部 wiki、工单系统、合同文档、产品手册。不同来源适合不同的检索方式。固定流水线只能“一把尺子量所有库”,模块化则可以加一个路由模块,先判断用户问题属于哪个领域,再路由到对应的索引库和检索策略。再比如多轮对话场景,固定流水线每次检索都只看当前这一问,上一轮聊过的背景被丢弃。模块化可以加入记忆模块,把对话历史压缩成摘要,参与当前检索,实现跨轮引用。
4.2 常见模块组合模式与典型应用
模块化 RAG 的组合模式,我见过几种典型的。
第一种是“路由 + 多库检索”,适合数据源多、类型杂的企业场景。路由模块先做意图分类或领域分类,把问题分发到不同索引库,每个库可以用不同的分块策略和检索方式。这样各库的最优配置互不干扰,整体精度明显提升。
第二种是“验证回路”。生成模块给出答案后,不直接结束,交给验证模块检查答案与检索片段是否有矛盾。如果发现模型引用了不存在的细节,或者答案与检索内容冲突,就触发重新检索甚至再次生成。这种“生成 → 验证 → 再检索 → 再生成”的循环结构,是把 RAG 从单向管道变成闭环回路的典型设计,能够显著压住幻觉。
第三种是“记忆 + 多轮检索”。把多轮对话中已经确认的事实、用户偏好、未解决的问题都写入记忆模块,下一轮检索时把记忆摘要作为检索条件的一部分。这样用户说“那刚才那个方案再详细讲讲”,系统也能知道“刚才那个方案”指的是什么,而不是把这句指代不明的话直接丢给向量库。
模块化 RAG 的价值,不在于它引入了多少新组件,而在于它提供了一种“按需组装”的思维方式。简单场景可以只组装三四个模块,复杂场景可以组装十几模块并加入循环。同一个项目里,不同业务线甚至可以共用一套基础组件、各自组装不同的 RAG 流程。这种灵活性,正是它成为当前 RAG 工程化主流思路的核心原因。
5. 演进路线对比与选型参考
5.1 三大范式横向对比
把朴素 RAG、进阶 RAG、模块化 RAG 放在一起对比,可以看得更清楚:
| 维度 | 朴素 RAG | 进阶 RAG | 模块化 RAG |
|---|---|---|---|
| 架构形态 | 固定三步骤流水线 | 固定流水线但每步精细化 | 可编排、可循环的模块组合 |
| 核心优化点 | 无 | 预检索、检索中、后检索 | 路由、记忆、验证、图谱等 |
| 检索策略 | 单一向量检索 | 混合检索 + Query 改写 | 按场景自定义组合 |
| 效果上限 | 低,受限于粗粒度召回 | 中高,适合多数知识库场景 | 高,适合复杂、动态场景 |
| 落地成本 | 极低,一两天跑通 | 中等,需要调参和组件选型 | 较高,需架构设计与模块开发 |
| 适用场景 | Demo、内部小工具 | 企业知识库问答、文档助手 | 多源数据、多轮对话、高正确率要求 |
这张表看得比较直观:每一级演进,都是在解决上一级暴露出来的问题,同时带来新的成本。没有哪一级是“最先进”的,只有“适不适合当前阶段”。
5.2 新人上手怎么选
如果你刚接触 RAG,我的建议很直接:先按朴素 RAG 跑通一个最小闭环,不追求效果,先理解“切块 → 向量化 → 检索 → 生成”这条链路里每一个环节在做什么。很多新人在第一步就想着上最复杂的模块化架构,结果被一堆概念淹没,连最基本的相似度检索效果差的原因都说不清楚。
跑通最小闭环之后,再用进阶 RAG 的思路逐步优化:先看召回结果,发现切块不合理就改切块;发现查不准就上混合检索加重排;发现模型被无关内容干扰就做上下文压缩。每做一步,都要用评测集量化效果变化,而不是靠“感觉变好了”。
模块化 RAG 更适合有一定积累之后再尝试。当单个知识库已经无法满足业务需求,当你开始频繁增加新数据源、新检索逻辑,当你想引入验证回路来压制幻觉,这时候再动手拆模块、做编排,理解深度会完全不一样。RAG 这几年的演进,本质上是在回答一个问题:怎么让模型在回答之前,尽可能多地看到正确的东西、尽可能少地受到错误东西的干扰。这个目标始终没变,变的是接近它的方式。
我个人的体会是,RAG 技术的每次迭代,都不是推翻重来,而是在前一个版本上打补丁。朴素 RAG 打下基础,进阶 RAG 做精链路,模块化 RAG 放开组合。把这个演进逻辑吃透,再看新出来的各种 RAG 变体,基本都能一眼看穿它是在哪个环节做了什么创新。下一篇我再拆解工程化落地阶段绕不开的评测指标、调优实验设计和线上部署问题,那些才是真正决定 RAG 项目能不能从 Demo 走向生产环境的关键。