前阵子团队内部复盘一个知识库问答项目,有人抛出一个问题:“RAG到底有几种模式?”会议室里当场分成几派:有人说8种,有人说9种,还有人翻出一张整理好的清单,说按不同模块组合下来起码25种。争到最后,谁也没能说服谁,因为大家发现——每个人嘴里的“模式”,根本不是同一个维度上的东西。
这个现象在社区里其实很常见。搜“RAG pattern”,有的文章按流程阶段分成Naive RAG、Advanced RAG、Modular RAG三种,有的按检索策略分成稀疏检索、稠密检索、混合检索,有的按具体技术方案列出路由检索、HyDE、GraphRAG、Self-RAG、CRAG……再加一些组合变体,20多种确实数得出来。数字本身不重要,重要的是这些分类背后各自对应什么业务问题、什么技术取舍。这篇文章我想把这件事掰开揉碎讲清楚:这些数字是怎么来的,实战中到底该怎么理解“模式”、怎么选型,以及哪些分类方法是真的能指导你做项目的。
1. 先别急着数数:RAG模式分类为什么会“打架”
1.1 8种、9种、25种,各是什么视角
先说结论:“8种”“9种”“25种”这几组数字,没有谁对谁错,它们只是观察角度不同。
“8种”这个口径,常见于按检索对象来划分。也就是说,你检索的是文档块、是知识图谱、是表格、是代码、是多模态内容,还是混合体?每一类检索对象对应一种模式,算下来差不多就是七八种。这个视角的好处是直观,缺点是停留在“数据长什么样”的层面,没回答“系统怎么组织、怎么优化”的问题。
“9种”这个口径,常见于按流程环节来划分。有人把RAG系统拆成九个环节:数据清洗、分块、嵌入、索引构建、查询改写、检索、重排、上下文压缩、生成。每个环节都有自己的策略组合,于是有人把“每个环节各选一种成熟策略”定义成一种模式,统计出来八九种典型组合。这个视角已经接近工程实践了,但问题在于,环节拆得越细,组合越多,9种只是“比较典型的几种”而已。
“25种”这个口径,通常来自模块化+策略矩阵的统计方式。先把RAG拆成若干模块——比如查询处理模块、检索模块、重排模块、生成模块、记忆模块,再在每个模块下列出可选策略:查询改写可以用HyDE、可以用多查询扩展、可以用历史对话改写;检索可以用向量检索、可以用BM25、可以用知识图谱遍历;生成前可以做压缩、做校验、做引用溯源。把这些策略做排列组合,删掉明显不合理的,剩下20多种能被实际落地的方案,非常正常。
1.2 分类维度越多,模式自然就越多
这个“数字之争”的底层原因是:RAG严格来说不是一个“技术”,而是一套架构范式。它没有统一的协议标准,没有必须遵守的接口定义,每个人实现RAG的方式可以完全不同。
举几个例子,同样是“给问答系统加知识库”:
- 某团队采用的是最朴素的写法:PDF切块、向量化、TopK检索、整块塞进提示词,完事。
- 另一个团队会先做意图识别,简单问题直接走小模型,复杂问题才带检索。
- 还有的团队为了提升准确率,检索完先让大模型生成一个“草案答案”,再用这个草案去二次检索,找出遗漏信息,最后汇总生成。
- 另一些场景则完全不用向量数据库,直接靠知识图谱的图遍历来召回实体关系。
这几种方案,你说它们是“不同模式”还是“同一模式的不同实现”?都能说得通。所以,分类的维度可以有很多个——按演进阶段分、按检索策略分、按是否引入反思机制分、按生成控制方式分。维度选得越多,模式类别自然越多。
理解这件事之后,我的建议是:别把精力花在“把模式数清楚”上,而要把精力花在“理解每个模式在解决什么痛点”上。你知道了每个模式的适用场景,再回头去看这些分类数字,就很自然了。
2. 按演进路线理解RAG:从朴素到高级,再到模块化
2.1 朴素RAG:管道式三步走
最基础的RAG模式,流程就三步:索引(Indexing)→ 检索(Retrieval)→ 生成(Generation)。数据进来,分块、做嵌入向量、存进向量库;用户提问,问题向量化,在向量库里做相似度检索,取出TopK个块;把用户问题和检索到的文本块拼进提示词,交给大模型生成回答。
这套流程实现简单,跑通一个Demo可能只需要半天,所以很多团队的第一版RAG都是这么做的。但它的问题会在真实场景里暴露得特别快:
首先是召回质量不稳定。向量检索擅长语义匹配,但遇到关键词精确匹配、专有名词、缩写、长尾实体,效果可能明显不如传统的关键词检索。如果库里恰好没有语义相近的表述,召回来的块可能就是“貌似相关,实则无关”。
其次是上下文污染。TopK召回10个块,排在前面的块未必都是有用的。有些块和问题只搭了一点边,却被原封不动地塞给大模型,模型看着这些相关性不高的内容,很容易被带偏,甚至一本正经地用一个不相关的块编出答案。
第三是对长文档、复杂问题的泛化能力弱。一个需要跨章节综合信息才能回答的问题,靠“切块后各自检索”的方式很难拼出完整的答案线索。
2.2 高级RAG:在三个环节做文章
针对朴素RAG的问题,业界开始在每个环节加优化,这套优化后的方案被统称为“高级RAG(Advanced RAG)”。
在检索前,可以做查询改写。典型手法包括:
- HyDE:先让大模型根据用户问题生成一个“假设性回答”,再用这个假回答的嵌入向量去检索。因为假回答的表述往往比问题更详细、更接近答案文本的语域,检索命中率通常更高。
- 多查询扩展(Multi-Query):让大模型把一个问题改写成多个不同角度、不同措辞的子问题,分别检索后合并结果,降低单次检索遗漏的概率。
- 历史对话改写:结合多轮对话的上下文,将“那它多少钱?”改写为“前面提到的那款产品的价格是多少?”,让每一轮检索都能拿到完整的语义。
在检索中,可以做搜索策略融合。最典型的就是混合检索,把向量检索和BM25关键词检索的结果做融合(比如用倒排融合算法),兼顾语义匹配与精确匹配。还有些系统会引入知识图谱辅助检索,先通过实体链接找到问题涉及的概念,再沿着图结构扩展召回。
在检索后,可以做重排与压缩。重排环节引入专门训练的交叉编码器(Reranker),对召回结果逐条计算和问题的真实相关度,把最相关的内容排到最前面;压缩环节则是把多余信息过滤掉,只保留和问题最相关的那几句话,再拼进提示词。
这套流程跑下来,相比朴素版有非常明显的效果提升,但代价是系统复杂度直线上升。每一个新增模块都要单独调优、单独维护,对团队的工程能力要求高了不少。
2.3 模块化RAG:把各个组件拆出来自由组合
模块化RAG的理念很简单:不要把RAG看成一条固定的流水线,而是看成一组可插拔的模块,按场景自由组合。
打个比方,朴素RAG像一辆出厂配置固定的家用车,高级RAG像在4S店里选装配置,而模块化RAG则是给你一堆零件,让你自己决定怎么攒一辆车。有人需要四驱,有人需要大空间,有人只需要代步,按需组装。
模块化RAG可以按需增加模块,常用的有几个:
- 路由模块:先判断用户问题需不需要检索,需要检索走哪种检索器,不需要就直接生成。
- 反思模块:生成完之后让“评委模型”检查一遍答案,发现检索内容不足或回答有幻觉时,触发二次检索或重新生成。
- 记忆模块:把历史交互的摘要存起来,在多轮对话中参与检索或生成,解决跨轮指代和上下文遗忘的问题。
- 验证模块:输出答案前,要求模型标注每条信息的出处,或者自动比对答案与检索原文的一致性。
模块化思路带来的直接好处是:不同业务可以长成完全不同的RAG系统,但它们共享同一套模块架构。这也解释了为什么“模式”越拆越多——模块化意味着组合自由,组合一多,分类自然就多了。
3. 实战中我更常用的四类划分:按“要解决的问题”来选
演进路线适合用来理解RAG的全貌,但在实际做项目时,我会换一套更实用的划分方法——按“当前系统最需要解决的问题”来定义模式。这样划分,能非常快地帮团队锁定优化方向。
3.1 基线模式:先把地基打牢
这套模式对应朴素RAG,适用场景是项目刚启动、还没有明确的性能瓶颈时。我不建议一上来就上HyDE、GraphRAG、Self-RAG这些花活,原因有两个:
第一,这些复杂方案各有前提条件。HyDE需要额外的大模型调用,多了时延和成本;GraphRAG需要知识图谱的构建和维护成本;Self-RAG需要模型具备特殊的反思能力,不是所有模型都支持。在基线效果还没测清楚的情况下,引入这些模块只会让问题定位变得更困难。
第二,很多时候基线RAG的效果差,不是模式不够先进,而是工程细节没做到位。分块策略不合理、嵌入模型选型错误、TopK参数没调过、元数据过滤没设计——这些问题不改,上再多的“高级模式”都是白费。
所以我会先把基线跑通,设计好离线评测集,记录一组基础指标,再根据瓶颈决定下一步往哪个方向优化。
3.2 查询优化模式:解决“问不好”的问题
如果离线评测发现检索召回的命中率低,而且分析下来问题出在用户提问本身表述不清、和知识库内容语域差异大,那就该上查询优化模式。
实战里最常用的查询优化手段就是HyDE和多查询扩展。我自己做过一个对比实验:用同一个知识库、同一套向量检索,不优化时TopK=5的召回命中率是61%,加上多查询扩展之后提升到74%,再用HyDE进一步提到79%。代价是每次检索前的“改写”环节多了一次大模型调用,时延大约增加300到500毫秒。对问答场景来说,这个换算是值得的。
这里有一个容易踩的坑:多查询扩展不是数量越多越好。默认生成3到5个扩展查询,效果最稳定;我试过把它加到8个,召回率不再提升,反而因为合并结果太多增加了重排模块的压力,最终端到端时延涨了快一倍。一定要在数量、召回率、时延之间做权衡。
另外,如果系统是多轮对话场景,查询改写需要把对话历史的指代信息融合进去,否则单独改写单轮问题往往改不准。这个可以结合具体的历史压缩模块来做,我后面会再提。
3.3 混合检索模式:解决“召不齐”的问题
如果问题是“只靠向量检索,明明库里有关键信息但就是召不回来”,那就要上混合检索模式。
向量检索的优点是语义匹配,缺点是它天然不擅长精确匹配。比如用户问“服务条款第3.2条”,如果你的知识库文本里恰好有这个编号,向量检索很可能把它当成一个普通的句子成分,而不是精确匹配的信号。这时候BM25这种基于关键词频率的检索器反而表现更好。
混合检索的核心理路是:让向量检索和BM25并行工作,再把两路结果合并。合并时常用的算法是RRF(Reciprocal Rank Fusion,倒数排名融合),原理是给每路结果按排名赋予一个权重分,然后把两路分数相加再排序。
一个简单的RRF打分示例:
score(d) = Σ 1 / (k + rank(d))其中k是平滑常数,通常取60。比如某文档在向量检索中排第1名,在BM25中排第10名,那么它的RRF分数就是 1/(60+1) + 1/(60+10) ≈ 0.0306。相比直接拼接两路结果再手动去重,RRF不需要调权重,也不需要统一两路结果的分数尺度,实战中非常省心。
混合检索还有一个附加好处:它可以结合元数据过滤一起用。比如先按业务线、时间范围、文档类型做过滤,再在过滤后的集合里做混合检索,召回精度和速度都会更好。
3.4 生成控制模式:解决“答不准”的问题
有些项目检索明明召回了正确答案,但大模型生成时答偏了、答漏了,甚至被不相关的内容误导。这时候问题出在“生成端”,应该上生成控制模式。
我在实战中常用的做法有三个:
一是上下文压缩(Contextual Compression)。检索回来的块,先让一个轻量模型或抽取规则把和问题相关的句子摘出来,滤掉无关内容,再喂给大模型。这样能显著减少上下文污染,让模型把注意力放在真正相关的内容上。
二是提示词结构约束。在提示词里明确要求“如果检索内容不足以回答问题,请直接说不知道,不要编造”;让模型优先引用检索内容中的原话,而不是自由发挥。对很多开源模型来说,这比所谓的“提示工程技巧”要实在得多。
三是引用溯源(Grounding)。要求模型在答案中标注信息来源的块ID或原文摘录。这不仅是给用户看的,也是给评测用的——一旦答案里的信息无法和检索块对应上,评测系统就能立刻标出幻觉样本,方便后续优化。
生成控制模式不改变检索过程,改动面小、见效快,是很多团队优先落地的一类优化。
4. 关键环节的技术选型与参数权衡
不管采用哪种模式,有几个关键环节的技术选型是绕不开的。我在这些地方踩过的坑,值得写细一点。
4.1 分块与索引:决定召回的上限
分块是RAG里最容易被低估的环节。块切得太小,单个块包含的信息量不足,检索容易抓到“局部但对不上整体”的片段;块切得太大,向量表示的语义被稀释,检索精度下降,而且喂给大模型后更容易出现上下文污染。
实战里我建议分块大小在300到800个token之间起步,具体值要结合文档类型和嵌入模型的最大输入长度来定。一般流程是:
- 看嵌入模型支持的最大输入长度。很多模型是512或1024个token,分块大小不宜超过这个上限的七到八成。
- 看知识库里句子的整体长度。技术文档、规章制度句子较长,块可以适当大一些;对话记录、FAQ条款句子短,块可以小一些。
- 用评测集反复测。固定其他参数不变,分别用256、384、512、768试一遍,选出召回率和端到端效果最好的那个值。
分块时另一个容易忽略的点是重叠(Overlap)。相邻两个块之间保持50到100个token的重叠,能避免“一句话被硬生生切成两段”导致的语义割裂。这个细节能明显改善长句子的检索效果。
索引侧,除了向量索引,建议同时把原文的元数据信息存起来:来源文件名、章节号、业务标签、更新日期、权限级别等。这些元数据在后续做权限过滤、时间过滤时是必备的,提前建好能省很多事。
4.2 TopK与重排:精度与成本的平衡
TopK是检索环节最直接的旋钮。K值太小,容易漏掉关键信息;K值太大,噪声增多,大模型的输入成本上升,效果也可能变差。
我习惯的做法是:先不加重排,用TopK从1跑到10,记录召回率曲线,看看系统在哪个K值附近召回率增长变缓。这个拐点就是“信息边界”。之后再根据生成效果微调。
举个例子,某项目实测下来,TopK从4提到6,召回率从68%提升到79%;从6提到10,只进一步涨到82%。此时拐点就在6附近。盲目把K拉到10,大模型输入多了一大截,时延和成本都上涨,收益却很有限。如果项目对召回率要求更高,我不会把K继续拉大,而是会引入重排模块——用更精准的TOP排序把有价值的块提到前面。
重排(Rerank)是“预算充足后的第一优先级”。做法是:先用轻量级的双塔召回模型粗召回一大批(比如TopK=50),再用交叉编码器重排模型对这批结果逐条打分,最后取前5到8个块进入生成环节。交叉编码器虽然计算量大,但它对“问题和文档的相关性”建模比双塔模型精细得多,所以排序质量有明显提升。
重排模型的选择上,开源社区有不少可用选项,我比较看重的是模型在中文场景和垂直领域上的表现,而不是单纯看榜单分数。小模型毕竟能力有限,真金白银跑一遍评测集最有说服力。
4.3 提示词与生成控制:最后的把关
生成端的设计,核心目标是让模型既充分利用检索内容,又不被无关内容带偏。我在提示词里一般会固定三块内容:
第一块是角色与任务说明:明确模型的身份是“知识库助手”,回答依据“仅限”给定的检索内容。第二块是检索内容区,用清晰的标识符把检索块包裹起来,并在前面加一句说明,告知模型这些内容可能有噪声。第三块是生成规则:如果检索内容互相矛盾或不足以回答问题,要求模型明确说明,并允许回答“根据现有资料无法回答”。
这里有一个关键技巧:生成规则要“具体化”,不要停留在“请保证准确”这种空泛指令上。比如可以写“如果一个问题在给定资料中找不到直接答案,请先用一段话说明资料的覆盖情况,再结合相关内容给出推断,并明确标注推断部分。”这样模型在生成时就有了一条清晰的决策路径,而不是笼统地“努力准确”。
另外,如果项目允许,可以在输出端加一个答案后校验步骤:让模型自己在答案前先输出“这份答案完全基于检索内容 / 部分基于检索内容 / 存在推测成分”的自评标签,后续评测就多了一个可量化的质量信号。别小看这个技巧,很多幻觉问题的定位都能靠它快速缩小范围。
5. 不同业务场景的选型建议
5.1 通用知识库问答
通用知识库场景,比如内部wiki问答、产品FAQ、在线帮助中心,典型特征是文档类型杂、问题开放度高、对时效性要求中等。
这个场景我建议从基线模式起步,先做好分块和元数据设计,然后按评测结果逐步引入混合检索和重排。对绝大多数知识库来说,混合检索+重排这套组合带来的收益是最稳的——它能同时解决“语义找得到但关键词找不准”和“关键词找得到但语义找不到”这两类最典型的问题。
如果问题表述本身跳跃性大,再叠加一个查询改写模块。比如用户经常用“怎么申请报销”这种口语化提问,而知识库里写的是“费用报销流程”,有了查询改写,命中率会明显改善。
5.2 企业私域数据问答
企业私域数据的典型特征是:领域专有名词多、数据有权限边界、答案对准确性要求极高。比如医疗、法律、金融、工程类的问答场景。
这类场景的首选方案是窄召回+强验证。窄召回的意思是,不追求让模型见多识广,而是通过元数据过滤把检索范围限制在最相关的子集里,宁缺毋滥。强验证的意思是,生成后必须有引用溯源,每条结论都能对应到具体文档段落,方便人工复核。
此外,企业私有数据往往存在大量“多来源信息互相矛盾”的情况,比如不同版本的制度文件说法不一致。此时可以在检索后增加一套去冲突逻辑:把包含冲突信息的块单独挑出来,让模型注意到“这里有版本不一致的问题”,而不是刻意回避。这个处理方式在很多场景下比强行“智能融合”更受业务方认可。
5.3 多轮对话与智能体场景
智能体场景是当前RAG应用的热门方向。这类场景的难点在于:同一个会话里,用户可能连续问多个问题,历史信息既影响当前问题的语义,也可能与当前问题完全无关。
我的建议是给系统加一个会话状态管理模块:每轮对话结束后,把“用户意图摘要”和“本轮检索到的关键信息摘要”写入一个短期记忆区。下一轮做查询改写时,先用这些摘要辅助判别,哪些历史信息对当前问题有用,哪些应该被遗忘。这一步是很多多轮RAG失败的重灾区——历史摘要不管三七二十一全塞进去,噪声比不塞更大。
如果智能体涉及多个子任务,还需要一个规划与路由层,让系统先判断当前问题要调哪个工具、检索哪类知识,再走对应的RAG流程。这个路由层就是前面模块化RAG里的路由模块,它在智能体场景下几乎是必需品。
6. 常见误区与排坑记录
6.1 误区一:把“模式多”等同于“模式先进”
有些团队一上来就想上GraphRAG + Self-RAG + HyDE的“全家桶”,理由是“社区都在讨论,想一步到位”。但先进模式有它各自的前置条件,最典型的是:
GraphRAG适合实体关系密集、回答需要多跳推理的场景,但它需要先把非结构化文档抽取成知识图谱,这是额外且不低的成本。如果知识库内容本身是松散的FAQ,硬套图谱反而得不偿失。Self-RAG需要的反思能力在不同模型上的表现差异很大,许多开源小模型的反思输出质量并不稳定。如果模型本身能力不够,反思模块不但帮不上忙,反而会把原本正确的答案“反思”得更差。
我的经验是:模式从来不是越复杂越好,适合当前数据形态、业务诉求和团队维护能力的模式才是好模式。盲目追新不仅投入大,还可能把系统改造成一个“看起来很强、用起来很脆”的组件堆。
6.2 误区二:忽略评测就上优化
这是RAG项目最容易翻车的环节。很多人把系统搭好后,凭几个手工挑选的“看起来有代表性的问题”试了试,感觉效果不错,就直接上线。等到线上用户问题分布一出来,才发现自己精心优化的方向完全偏离了真实痛点。
我建议每做一个RAG项目,第一步是用两三天时间攒评测集,而不是急着调参。评测集不需要多大规模,但必须覆盖:
- 单跳事实题(答案在某一个文档块里);
- 多跳推理题(答案分散在多个文档块中,需要组合推理);
- 否定/排除题(知识库里没有答案,系统应拒绝回答);
- 长尾专有名词题(最能暴露混合检索和查询改写价值的一类);
- 跨语言/口语化变体题。
每一类至少准备20到30个问题。评测指标不必追求学术标准,自己定义一个简单可跑的:命中率、完整率、幻觉率、拒答率、端到端时延。这五六项指标足够指导绝大多数优化决策。没有评测集支撑的优化,基本等于开盲盒。
6.3 误区三:堆叠模式导致系统臃肿
还有一类项目,问题定位不准,于是“宁可多上几个模块求稳”。最后系统链路变得又长又脆,任何一个环节故障都可能拖垮整个问答服务。模块每多一个,整体时延就多一跳,维护成本也同步上升。
排坑的方法是:牢牢锁定“当前最痛的那一个瓶颈”。如果评测显示召回率已经很高但答案还是差,那就别再优化检索了,问题出在生成端;如果端到端时延超标,那就重点检查哪一跳最耗时间,是查询改写多模型调用、还是重排模型吞吐不够。
每个新模块上线前,都先问自己三句话:它解决的具体问题是什么?有没有评测数据支撑这个问题确实存在?上线后预计牺牲多少时延和成本?三个问题都答得上,再动手。答不上来,就先把想法记下来,等有了数据依据再决定。
7. 最后说几句实在话
做RAG项目这么久,我个人的体会是:RAG不是一道有标准答案的技术题,而是一道不断取舍的业务题。所谓“8种、9种、25种”,本质上只是不同观察者从不同角度给出的快照。真正有价值的能力,是在理解这些快照的基础上,看清自己项目的瓶颈到底在哪一环,然后带着评测数据,挑选最少、最稳、最匹配业务的模块组合。
如果你现在正在纠结“该用哪种RAG模式”,我的建议非常直接:先跑通基线,攒一版不算太烂的评测集,测出当前最大的那个短板,再回头翻这篇文章里提到的对应模式——查询有问题的看查询优化,检索有问题的看混合检索和重排,生成有问题的看上下文压缩和引用约束。按这个顺序走,你大概率会发现,很多纠结本身就会自动消失。
最后再分享一个小技巧:无论你最终选了哪种模式组合,都记得在代码里把链路版本号留下来。比如“v2.3_query-expand+hybrid-rerank”。这个习惯能让你在后续迭代时,清清楚楚知道每一次改动对应的是什么组合,评测结果也能追溯得明明白白。等系统跑了大半年再回头看,你会感谢这个随手记版本号的习惯。