【RAG】RAG,你真的了解RAG吗?RAG全链路拆解。

老鸽 2026-08-07 20:26 1

引言


实在不好意思这么晚才更新新的文章……这几天忙的事情比较多所以就耽搁了,而且其实昨天就开始写了但是写了一半不小心退出了没保存还得重写(因为我一般在自己的博客平台写,没设置自动保存之类的功能)(悲)。今天给大家带来的是对于RAG全链路,从chunking、embedding、存储……到最终的输出给LLM充当证据生成答案,都会有所涉及。


此外,在这篇文章种我必须要反驳一个观点:所谓的RAG已死。自从2025一来,尤其是今年claude code的源码爆出后,每隔几天就会有一篇公式化的以“RAG已死”的文章出现在知乎/稀土之类的平台,我大致看过几篇,都是同一套打法:先以claude code使用grep或者那个karpathy的llm wiki为引子,公式化地讲解一下其技术原理,然后开始说RAG怎么怎么样弱势,RAG已死!这样的文章,既没有理解RAG的本质,也不理解他所提的这些技术和RAG的区别和联系,没有自己的思考,拾人牙慧(我去我太会用成语了)。“RAG已死”,本质上是个伪命题,本文就会单独开一章来反驳“RAG已死”这个观点。


RAG是什么


很多人对 RAG 的理解,仍然停留在“文档切分、向量化存储、相似度计算、Top-K 召回”这套传统流程上。虽然这确实是我们最常见,使用也最广泛的一套RAG框架。本文讲解的大部分知识点也会围绕这套传统流程来。


但严格来说,RAG 的本质并不是某一套固定工作流,而是一种更抽象的工程范式。RAG 是 Retrieval-Augmented Generation 的缩写,核心是“检索—增强—生成”:只要系统能够先获取外部信息,再将其用于增强模型上下文,并最终完成生成,就可以被归入 RAG 的范畴。比如说,skills的渐进式披露,Agent Memory都可以算是一种RAG。


因此,RAG 并不限定具体的检索方式,也不限定增强手段,更不限定它在系统中扮演的角色。它可以是传统的向量检索问答,也可以是 Agent 调用知识工具、数据库查询、搜索引擎检索、多跳推理或结构化数据增强。

所以,“RAG 已死”这种说法本身就是片面的。真正可能被淘汰的,是某些早期、单一、粗糙的 RAG 实现方式,而不是 RAG 这一思想本身。具体如何反驳“RAG 已死”,我们后面会单独开一章讲解,这里不多赘述。

我们后续的章节,会根据RAG的完整流程来进行展开,会涉及到的内容大致如下所示(这个图是我八百年前画的了所以和文章内容不一定完全一致)



chunking的艺术,怎么进行好的chunking


chunking 是什么


我们都知道RAG的本质是给LLM提供一个外部知识库用来补充上下文,但是不可能直接把整个知识库(如一个文档)塞进模型的上下文,这样会隐藏关键信息,还会占用模型上下文窗口。因此我们需要将文档进行切分(即chunking)为一个个文段(即chunk),这样方便将用户问题和各chunk一一比对,找出回答问题所需的关键信息(这个就是检索)。这就是chunking


chunking的粒度


对文档进行chunking并不是随便切的,而是得先选好一个粒度,即切分出的chunk的长度,粒度太大或太小都会出现一系列问题,这其中的平衡需要仔细把握


chunking粒度太大


chunking粒度太大,会导致包含大量无关内容、向量语义被稀释、相似度匹配不够精准、占用更多上下文窗口、生成时容易受到噪声干扰等问题。这样说有点抽象,我们举个具体的例子来说明。假设有这样一个较长的chunk


1.本园安全措施保障绝对没有问题,动物没有出逃的可能性,尤其是小型草食动物大多被关押在不可触摸的封闭性环境里。因此,如果您看见路边有逃跑的兔子,请立刻带着您的孩子远离并报告工作人员,不要靠近,不要触摸,尤其是兔子发现并且开始高速靠近你的时候。
2.猿类的园区只有一条街道,且只展示猿类动物。如果您发现了两条街道,且展示动物包括兔子,请选择左边那条,并尽可能快速地结束对该园区的参观。
3.大象是一种体型巨大、有着扇子一般的耳朵、鼻子很长、腿粗得像柱子的生物,而且不是白色的。请确保你在大象园区看见的是且只有大象。
4.动物园的饮料店不提供“兔子血”,如果您在货架上看见了,请不要购买。

假设此时用户提问“动物园的饮料店提供哪些饮料?”,正常来说,模型应该会回复“文中没有说明饮料店具体提供哪些饮料,只明确说动物园的饮料店不提供‘兔子血’;如果在货架上看见‘兔子血’,不要购买。”之类的内容。


(作者脑子是不是有病)


但是,由于 chunk 过大,饮料店相关内容在其中占比很小,导致这部分语义在整体向量表示中的权重被削弱,进而出现所谓的“向量语义稀释”问题。导致后续的检索流程中,由于饮料店相关信息的向量语义被稀释,导致与用户问题的向量相似度不高,进而没有被模型选中补充上下文,最终导致模型不知道饮料店具体信息,导致回复质量下降。反之,如果稀释没那么严重,使得该chunk侥幸被选中,此时由于chunk较大,无关信息占比较大,模型生成时容易受到“大象”、“猿类”、“兔子”等信息噪声的干扰,导致回复质量下降;同时,由于chunk较大且无关信息较多,大量无关信息占用了模型上下文窗口,造成了资源浪费和成本上升。


chunking粒度太小


反过来,chunking粒度太小也会导致一系列的问题,如上下文不完整、代词,条件,结论可能失去指代关系、embedding 缺乏足够语义信息、需要召回更多片段才能还原原意

片段数量增加,索引和检索成本上升。我们同样以具体例子来说明‘

假设有如下几个粒度较小的chunk


请立刻带着您的孩子远离并报告工作人员,不要靠近,不要触摸

且展示动物包括兔子,请选择左边那条,并尽可能快速

结束对该园区的参观。
3.大象是一种体型巨大、有着扇子一般的耳

可以看到,这些 chunk 都存在明显的上下文缺失问题:



  • chunk 1 丢失了前提条件,例如“如果您看见路边有逃跑的兔子”,导致读者无法判断这条指令在什么情况下适用。

  • chunk 2 丢失了“那条”所指代的对象,例如“街道”,也没有完整保留“结束对该园区的参观”这一结论。

  • chunk 3 不仅丢失了前文条件,还出现了跨段截断,导致语义混乱。

    如果模型的 top_k 较小,检索阶段可能无法召回这些 chunk 所依赖的相关片段,从而造成关键信息缺失,影响回答质量。为了弥补这种信息断裂,系统往往需要召回更多 chunk 来补充上下文,这又会进一步增加检索开销和索引成本。


不难发现,chunking的粒度是需要我们仔细把握,追求那个微妙平衡的,否则我们是绝对无法在动物园中活下来的!(0人懂你的梗)


追求结构化的chunking?


我们在实际使用RAG过程中,所使用的外部知识库通常不会是一大串文字,而一般是有结构性质的文档。此时,我们可以通过保留文档结构和层级信息,以增强后续检索效果,如下所示:

假设一篇文档的框架如下


标题 1
标题 2
标题 3
正文

我们可以先以最小标题为单位进行切分,再针对每各最小标题下的内容进行按粒度的切分(其实也可以不继续切分了),如下所示


{
"document_title": "员工手册",
"section_path": [
"第三章 财务制度",
"3.2 差旅报销",
"3.2.1 报销材料"
],
"block_type": "paragraph",
"text": "报销材料包括交通票据、住宿发票、行程单和审批单。交通票据有如下要求:……",
"order": 35
}

我们一般会同时将chunk的所处章节信息作为chunk内容和正文拼接在一起进行向量化和作为筛选过滤条件单独存储。这样一来,既避免了一次chunk中混杂不同章节的信息导致关键信息被隐藏;也因为一chunk限制在一章节内,避免了上下文被中断;同时,当缺少证据时,可以依据当前检索到的chunk的章节信息,依此作为过滤条件筛选chunk进行检索以补充证据,避免了指代,条件,结论不明确的问题;我们还可以先让模型依据问题判断信息可能所处的章节,以此为过滤条件进行检索,有效地提高了检索效率,降低检索成本。真是一举多得啊!


看到这里的佬友可能会想到一个东西,skills的渐进式披露:当skills过多时,将各skills的简要功能介绍和所处位置集成为一个菜单,模型阅读这个菜单选择具体skill后再将具体的skill.md展示给模型。这和我们这里的结构化chunking是不是很像?skills的渐进式披露本质上也是一种RAG!当然这是我的个人观点,没有官方背书(


PDF的chunking……?


有时我们的外部知识库会是pdf格式的,此时就会复杂的多,因为PDF是为“呈现”而设计的,它记录的是字符在页面上的位置和绘制指令,本身没有段落、表格等语义概念。而且有时还会遇到PDF为图片无法直接获取文字,PDF内有图片,图片内有关键信息无法省略等问题。我们需要通过OCR等工具进行提取并使其格式化段落化。

我个人最常用的是LlamaParse这个工具,它的优势很多,效果也相当不错:



  • 广泛的支持格式:支持多种文件格式,包括PDF、Word (.docx)、PowerPoint (.pptx)、Excel (.xlsx)、HTML及图片等。

  • 结构化输出:输出格式丰富,包括格式良好的Markdown、JSON(包含完整结构、表格、图像等)以及纯文本。

  • 强大的复杂元素处理:能高精度地解析表格、图表和图像中的信息,并能使用OCR识别图片中的文字。

  • 自然语言指令:以用自然语言告诉它如何解析,例如“这是一本漫画书,请按连贯的对话重构”

    这应该不算打广告吧(,总之我是推荐首选这个的!


embedding(嵌入)


文档完成 chunking 之后,就会进入 embedding 环节。Embedding 的作用,是将原本无法直接计算相似度的文本,转换成检索系统可以理解和比较的表示形式,方便后续进行召回、排序和匹配。

在 RAG 中,embedding 通常可以分为两类:稀疏表示和稠密表示。


稀疏表示一般对应关键词检索,例如 BM25、TF-IDF、倒排索引等。它主要依赖词项是否出现以及出现频率来判断相关,更关注“用户问的词,在文档里有没有出现”。


稠密表示则通常指我们常说的向量 embedding。它会通过 embedding 模型,将文本编码成一个固定长度的向量,例如 768 维、1024 维或更高维。相比稀疏表示,稠密向量不只看字面词是否匹配,而是更关注语义是否接近。比如用户问“差旅报销需要哪些材料”,文档中写的是“出差后需提交交通票据、住宿发票和审批单”,即使两者措辞不同,稠密向量也有机会判断它们语义相关。目前常用的稠密嵌入模型包括BGE,GTE等等


稠密/稀疏embedding模型的原理


稠密embedding模型的原理大家应该一看就知道了:Transformer中的encoder部分,虽然以前也有使用BERT系的,但是现在主流的嵌入模型基本上都是使用的Transformer了,这里我们不多赘述。至于稀疏embedding模型的原理,我们以目前主流的BM25为例来讲解



\text{Score}(D, Q) = \sum_{i=1}^{n} \text{IDF}(q_i) \times
\frac{ \text{tf}(q_i, D) \times (k_1 + 1) }{
\text{tf}(q_i, D) + k_1 \times \left( 1 - b + b \times \frac{|D|}{\text{avgdl}} \right)
}


  • q_i 查询词

  • D 当前被评分的chunk

  • Q 代表用户的查询词集(由多个$q_i$组成)


我们来逐步讲解这个公式是什么意思:


\text{IDF}(q_i) 用于衡量一个词的“稀缺性”或“重要性”,比如说,我们常见的“是”,“的”这些几乎每个chunk都会出现的词,其对文档之间的区分度就很小。如果不降低其得分,只要用户的查询中包含这些高频词,每个chunk的得分都会偏高。所以,对于常见的词,IDF值通常会较小。相反,一个只在少数文档中出现的词(比如一个专业术语),IDF值会很高,意味着这个词能更好地区分文档,提高其IDF值会提高查询该词时其所处chunk的得分,可以更快速的检索出其相关信息。


\text{tf}(q_i, D) 即词频,衡量一个查询词在当前文档中出现的次数。一个词在文档中出现得越多,文档与这个词就越相关,得分也就越高。


但是,如果不对词频对得分的贡献的增长速度加以限制,就会导致一系列问题,比如说,你向一个联网llm提问:“苹果手机质量如何”,llm提取到关键词“苹果手机”在网络上搜寻相关资料作为证据,此时有一篇小红书笔记A是针对苹果手机的细致评测,其中“苹果手机”一次出现20次,另一篇笔记B是一个神经病发的灌水贴,里面重复了“苹果手机”一词6767次,这就导致,如果不给词频得分的上限加以限制,此时笔记B的得分将会是笔记A的上千倍!这肯定是不合理的(这也是BM25之前的稀疏嵌入模型TF-IDF的问题所在)。因此BM25加入了一个参数k1,将公式转变为 \frac{f \times (k_1 + 1)}{f + k_1}(暂时忽略那一大串包含b的公式)


我们来看,当某个词在文档中疯狂重复,词频 f 趋向于无穷大($f \to \infty$)时,这个值会变成多少:



\lim_{f \to \infty} \frac{f \times (k_1 + 1)}{f + k_1}

分子分母同时除以 f



= \lim_{f \to \infty} \frac{k_1 + 1}{1 + \frac{k_1}{f}}

f 无穷大时,分数 \frac{k_1}{f} 趋近于 0,所以整个式子的极限就是 k_1 + 1


也就是说无论这个词在文档里出现 100 次、1 万次还是 100 万次,这个词频得分项永远不可能超过 k_1 + 1


最后是长度归一化因子 \left( 1 - b + b \times \frac{|D|}{\text{avgdl}} \right) 其中avgdl为平均文档长度。


为什么要加入长度归一化因子呢?我们假设如下场景:用户向一个联网llm进行提问:“苹果手机性能如何”,假设llm不按粒度切分,而是按照网络搜索得到的文章为单位进行embedding,此时llm分别搜寻到知乎文章A,B,A在200字左右,其中提到了10次“苹果手机”,文章B2000字左右,其中提到了15次“苹果手机”,如果只看数量的话,文章B的得分势必会比A更高。但从人类的角度看,文章A中“苹果手机”出现的更密集,说明其主要针对苹果手机这一词进行撰写,而文章B“苹果手机”虽然出现次数多,但比较稀疏,可能就是一篇不同手机对比的文章。即使文章A可能针对性更强,但是由于B中词语出现次数更多,模型会更青睐B。文章越长,同一词语出现的次数是呈上升趋势的,因此不能简单的认为不同长度chunk下的同一词语出现次数的贡献是等价的。为解决这个问题,BM25引入了长度归一化因,使模型更加关注词语出现的密度。(我总感觉这一段我讲的废话好多( )


接下来讲解一下为什么 \left( 1 - b + b \times \frac{|D|}{\text{avgdl}} \right) 可以实现长度归一化,我们用a来代换原公式中的 \frac{|D|}{\text{avgdl}},可得1-b(a-1),0 < a < +∞,可以发现,当chunk长度小于平均值时,a < 1,此时结果整体较小,由于这个结果是放在BM完整得分公式分母中的,因此最终得分会变大。反之,当chunk长度大于平均值时,该公式结果较大,作为分母会导致最终得分减小。这就实现了长度归一化。


稠密与稀疏同样重要


稠密和稀疏embedding基本上是同时需要的,它们各自优缺点鲜明,结合使用才能优势互补。假如只有稠密向量,可能会导致专有名词或少见名词的遗漏,比如说中药“石刁柏”,如果稠密embedding模型没有进行过专业的中药材方面的训练,在没有上下文的情况下,它很难想到石刁柏其实就是我们平常吃的芦笋。在具体chunk中embedding模型尚且可以根据上下文使得该chunk向量与芦笋靠近,但是在用户的提问中,没有上下文补充,用户提问的向量会偏向于“石头”,“柏树”之类的东西。最终导致模型无法检索到有用信息,导致回答质量下降。如果只有稀疏向量,面对同义词,模糊描述会导致检索不完全,而面对同名不同义的词,又会检索错误。因此,在普通的问答模型的RAG中,稠密与稀疏embedding都会使用。


存储


大型的RAG肯定是不能够直接用文件来存储的,一般会涉及到向量数据库的使用,常见的向量数据库包括Milvus / Zilliz、Chroma、Weaviate等等。它们之间的优劣这篇文章不涉及,因为其实我也不知道(?


索引算法


学过数据库的佬友都知道,索引是一种优化技术,旨在提高数据检索的速度。索引的核心作用类似于书籍的目录,它允许系统快速定位到数据的存储位置,而无需遍历整个数据库。同样的,为了提高模型检索效率,我们在进行向量存储时,也会用到一些专门的索引算法。包括HNSW,IVF,倒排索引等等,其实这一块不用太深究,大致知道有哪些索引即可。大家就当看个乐吧


HNSW


HNSW是Hierarchical Navigable Small World的缩写,即分层可导航小世界,在后面的讲解中你就可以知道为什么这样起名了。


HNSW在内存中构建了多层图结构,每层都是一个网络(节点是向量,边是连接关系)

底层(Layer 0):包含全部数据节点,节点之间的边连接最密集(短边居多),负责进行最精细、最准确的搜索。

上层(Layer 1, 2, …):节点数量呈指数递减(类似跳表)。越往上,节点越少,节点之间的边连接越长(长边居多)。


每个向量在插入时,会通过一个指数概率分布随机分配一个最高层级 L。这意味着大部分数据只存在于底层,少数数据会出现在高层。这些高层节点可以方便检索时快速导航最近的节点,并作为下一层的入口节点进一步寻找相近节点


HNSW的搜索过程就像开车去一个陌生地点,先从高速路走,再转入省道,最后进入小区小路


第一步:自上而下寻路

搜索从最高层的某个入口节点开始。在当前层,算法采用贪婪搜索,沿着该层的边反复跳跃,找到该层离目标向量最近的节点。由于高层节点少、连接跨度大,这一步能快速定位到目标所在的大致区域。


第二步:逐层精炼

完成高层的搜索后,算法带着这个“最近节点”作为入口,进入下一层,继续贪婪搜索。因为下一层节点更多、更密集,搜索范围会进一步缩小。这个过程一直持续到到达第 0 层


第三步:底层精细搜索

在最底层包含了所有数据,算法继续贪婪搜索,最终在局部范围内找到全局最近的若干个邻居节点(即 Top-K 结果)。


HNSW的一个优势为查询极快,因为其不需要遍历全量数据,通过分层跳跃极大减少了距离计算次数。另一个是召回率极高,因为其底层包括所有数据,而且检索相当于从顶层向底层逐步逼近目标chunks,很少会遗漏相关chunk。


而缺点也很显而易见,HNSW中,数据库除了各节点的向量信息外,还要存储节点之间的连接关系,即邻居节点的指针,导致内存占用量极大。另一个是构建与更新速度慢,一个新节点加入后,要在其出现的每一层搜索与连接邻居,构建速度相对较慢。


IVF


IVF更像是你在图书馆中找特定书籍,你会先去寻找该书的分区,再去分区特定书架寻找该书。IVF在构建时使用K-Means聚类算法,将全部数据向量划分为 多个簇。每个簇会生成一个中心向量,并建立一个“倒排列表”,记录该簇下所有向量的ID。

在检索时,会计算目标向量与所有簇中心的距离,找到距离最近的 n 个簇。只在这 n 个簇的倒排列表内部进行搜索,找出最相似的Top-K向量。

IVF和HNSW的优势和劣势基本上是反过来的,这里不多赘述


倒排索引


与HNSW,IVF不同,倒排索引是专门为稀疏(关键词)设计的精确数据结构,负责关键词匹配。

它的结构极分为两个部分:



  • 词项词典(Term Dictionary):记录所有出现过的不重复关键词(比如“苹果”、“手机”、“芯片”)。

  • 倒排列表(Posting List):记录每个关键词出现在哪些文档中(以及出现的位置、频率等)。


检索流程非常直观:当用户搜索“苹果手机”时,系统直接在词典里找到“苹果”和“手机”这两个词,然后分别取出它们的倒排列表,最后取交集(或并集),就能瞬间锁定包含这些词的文档。再对这些文档打分取topk(打分算法就是我们之前说的BM25)


检索


说了这么多,大家应该也很容易明白检索的流程了,我们最常用的检索算法就是“双塔召回”,双塔结构顾名思义由两个对称的网络组成:



  • Query Tower (查询塔):输入用户提出的问题 q,输出一个固定长度的稠密向量 V_q

  • Doc Tower (文档塔):输入语料库中的文档/切片 d,输出一个固定长度的稠密向量 V_d


这两个塔的目标是将文本映射到同一个低维连续向量空间中。如果查询和文档的语义相关,它们在该空间里的距离就会很近。这里的距离我们一般就使用欧氏距离/余弦相似度/向量内积作为标准。

目前基本所有问答类RAG都是使用混合检索,即同时进行稠密检索和稀疏检索(还是BM25),将最终得分加权组合得到TopK


查询优化


检索部分最重要的其实是这个

查询优化的本质是在将用户原始问题发送给检索器之前,对其进行一系列处理、改写或增强的技术。因为不是所有模型使用者都是那么聪明(笨笨),说话都那么清楚明白的,这时候就需要LLM提前帮用户把话说明白,这样才方便后续的检索,你在使用大模型的过程中,模型Thinking时就是在做这个哦。


查询优化主要包括改写、扩写、重写、多查询、子查询和HyDE

前面三个比较好懂,我们主要讲解后面三个。


多查询


多查询即用户输入一个问题,系统利用LLM自动生成该问题的多个语义相同、但表述方式不同的变体。保证召回率,如:


原始查询:“如何学习Python编程?”

生成的多查询变体:



  • “Python入门学习路线”

  • “零基础学Python的步骤”

  • “Python编程自学教程”


子查询


有时用户一次性会询问多个问题,如果直接对整个问题进行embedding的话,会降低检索效果(这个应该不用我解释了),因此需要LLM先把这些问题拆开来,一一进行检索。如:

原始查询:“2023年诺贝尔文学奖得主是哪国人?他的代表作是什么?”

拆解的子查询:



  • “2023年诺贝尔文学奖得主是谁?”(得到答案:约恩·福瑟)

  • “约恩·福瑟的国籍是什么?”(得到答案:挪威)

  • “约恩·福瑟的代表作有哪些?”(得到答案:《有人将至》等)


HYDE


其实就是让LLM假装自己已经知道答案,如用户询问:“A是什么”查询时,大模型根据自己的知识生产一个伪文档,以“A是B”进行查询,提高召回率


重排(Rerank)


说了这么多,但我们之前的检索其实还是相当于一遍粗筛,根本原因还是在于“语义相似”不等于“问题相关”:检索找的是语义上相似的文档,但它们可能并没有直接回答用户的具体问题。同时,模型为了保证不漏掉任何信息,在检索阶段会带回大量文档(如Top 50-100)。这其中混杂着大量不相关的内容,如果全部塞给LLM,不仅会浪费其上下文窗口,增加成本,还可能让模型被错误信息干扰,降低回答质量。因此我们还需要进行重排。


我所熟知的重排方法包括两种,一种是Cross-Encoder(交叉编码器),一种是基于LLM的重排。




  • Cross-Encoder(交叉编码器)模型:这是目前精度最高的方法。它将“查询”和“文档”拼接在一起,输入到一个模型中进行深度联合分析,从而输出一个精确的相关性分数。其代价是计算开销大、速度慢,通常需要对每个“查询-文档”对做一次独立的推理。典型代表有 bge-reranker(没错,bge到处都是) 系列和 Cohere Rerank。




  • 基于LLM的重排:直接利用强大的LLM进行重排。通过设计特定的提示词(Prompt),让LLM对候选文档列表进行阅读、比较和排序。这种方法能利用LLM强大的推理能力,但成本更高、速度更慢。某种意义上和其目的背道而驰了(吗




来势汹汹的图式(知识图谱)RAG


依我个人拙见,我感觉在未来图式RAG将会在agent中扮演更加重要的角色。首先从直观来看,普通的RAG仍然处于相似度匹配的阶段,确实已经可以解决目前阶段绝大部分问题了。但是,对于需要理解关系、结构和推理链的问题,图式RAG更加丰富的信息量明显更具优势。模型可通过知识图谱了解各向量之间具体的语义关系,而不是向量距离。通过关系边的传播,可以检索到更加隐秘与关键的信息,面对多跳场景也更具有优势。或者说,各类知识文档本身就是一个巨型的关系网络,只是文档的形式强制将其压成了文本片段,图式 RAG 则保留了“谁和谁有什么关系”,这会让模型回答更接近真实业务逻辑。


目前阶段已经有很多成熟的图式RAG产品了,如GraphRAG,LightRAG,HippoRAG,Apache Geaflow(严格来说这个不算RAG,只是图式RAG中有用)等,图式RAG也已经开始正式参与进Agent开发中,如Mem0使用简易Graph存储模型长期记忆。


在未来,Agent面临的任务或许会越来越考验逻辑严密性与,我相信图式RAG会发挥其优势的。


反驳:RAG根本没死


回到最初的话题,为什么我觉得“RAG已死”是个彻底的伪命题。

首先,我们在第一章“RAG是什么”中就讲到了:“只要系统能够先获取外部信息,再将其用于增强模型上下文,并最终完成生成,就可以被归入 RAG 的范畴。”,所谓的“RAG已死”,将RAG狭隘的定义为外部文档充当上下文,属于典型的以偏概全。


再来看看他们用来说明RAG已死的技术是什么吧

首先一个就是目前code agent最常用的grep,grep命令本身不就是一种关键词检索吗?code agent利用grep命令获取所需的代码片段用于执行任务,这正是RAG的定义啊。其次是Karpathy 的 llm wiki,用这个来踩RAG更是诡异。Karpathy 的 LLM Wiki指的是 Karpathy 在 2026 年 4 月提出的一种个人/团队知识库模式:让 LLM 不只是“临时检索资料并回答”,而是持续把资料编译成一个可维护、可链接、会累积的 Wiki。这个本质就是个会增量更新的RAG啊。用本质RAG的东西来贬低RAG,是典型的自我反驳。


RAG早就从传统文档进化成了一种范式,Agent Memory需要RAG,skills的渐进式披露需要RAG,自我反思与进化也需要RAG……RAG从来都没死过,它到处都是!


今天的文章就结束了,这是我最近以来,或者说有史以来写的最长的一篇文章了……希望对大家有帮助!


好吧想了下还是叠个甲(,以上关于反驳“RAG已死“的观点包含大量主观见解,不要砂我

最新回复 (19)
  • Grogu 08-07 20:32
    1

    感谢佬友分享 ^-^


    RAG 不会死,最关键是 RA 不会死,G 的概念也不会死 ^-^

  • 老鸽 楼主 08-07 20:35
    2

    说起来为什么我电脑端用于展示某回复是否已经阅读过的小蓝点无法消失了,不是很懂(

  • chen2 08-07 20:36
    3

    感谢分享,很好的入门文章,期待续集^-^

  • Grogu 08-07 20:37
    4

    刷新,或者手动过盾


    https://linux.do/challenge


    这个话题还会继续更新补充吗 ^-^

  • 老鸽 楼主 08-07 20:38
    5

    我更新的话一般是会新开一个话题的说(

  • 无赋 08-07 20:39
    6

    完整看完了,质量很不错诶。

    我看下来除了部分公式看不明白(高数都学不明白的我),总体感觉很清晰。 ^-^

    最后提到的“rag已死”的论调,我以前单纯以为是新的工具替换了旧的工具,现在看来可能可以理解工具的进化迭代?本质逻辑还是一致的^-^

  • tee 08-07 20:40
    7

    看不太懂 还得要多学习有关于这方面的东西

  • keke001li 08-07 20:48
    8

    RAG写的很形象,但是很多开发估计只能理解概念没法亲身做一个这样的链路工程。

  • Tim_123 08-07 20:50
    9

    支持佬的观点,现在网上动不动就喊RAG已死,其实根本没搞懂RAG的本质。不管技术怎么演进,外部知识注入大模型的刚需一直都在,只是实现方式越来越多样化了而已。前排催更,期待后续的硬核长文!

  • 老鸽 楼主 08-07 20:59
    10

    没人懂我使用动物园怪谈举例的幽默感吗^-^(bushi

  • Gon 08-07 21:07
    11



    始皇:已阅

  • qinsheng77 08-07 21:23
    12

    太及时了,最近刚好准备公司产品的RAG,佬友们有什么建议?框架之类的

  • 苏柏亚 08-07 21:32
    13

    太正确,现在RAG其实已经在企业里面有很多的应用了,特别是要确保问答的准确率,以及要求问答的可溯源的严肃场景,现在在医疗、法律、金融等等场景有很大用处,现在agentic rag也很流行。

  • dddys 08-07 21:55
    14

    讲的真的很好,包括像grill me 这个skill也是rag的思路,从检索问题到通过确认用户问答再收敛

  • catShark 08-07 22:26
    15

    和佬的见解一致,RAG所指代的思路是没有问题的。在知识库很大,模型上下文没法全部装下的情况下,使用RAG是必然的


    忘记从哪里看到的了,说使用RAG不如直接将所有和关键字有关的文档都完整的扔到上下文中。从实践的角度上看,我所接触到的知识库项目也确实这样弄的效果更好(估计用这些功能的人应该没多少。。。导致问题没有暴露出来)


    说RAG已死,说的应该是在这个概念刚出现时的各种开源实现(ragflow之类)有一点“死”了。拆分材料都是按照字数分块拆的,召回更是搞搜索引擎那种关键字搜索的方式实现的。这和我所理解的RAG完全不是一个东西,我理解的RAG是:“在一团互相粘连的渔网中扯出一个点,我能顺着这个点找到网中的鱼”,但当时的实现更像是“在一团渔网中随便剪出来一块,有没有鱼全靠运气”

    另外RAG死的另一个原因应该是目前只有搞新概念才能用LLM挣钱,既然RAG的概念已经虎不住人了,自然“死”了


    另外的一点思考:关于图,我个人对这种形式的数据结构很感兴趣。


    对于一个业务系统,如果有三个图(我常常把单一“图”理解为一个2d超平面):



    • 贴近使用者一侧,用一个图来描述各种业务知识之间的关系(业务图,水平放置)。

    • 贴近开发者一侧,用一个图来描述每个代码块之间的关系(代码图,水平放置)。

    • 在这两个图之间,用一个图来将业务知识和代码块之间的关系(关系图,垂直放置)。


    如果这样的一个模型能成功被一个agent读取并使用,它就不会再受到模型的“概率”限制(应该也可以理解为模型能力的限制吧)。


    举个例子:我要修改系统的A功能


    现状:使用A功能的关键字搜索,整个代码库中搜索有关的内容,放在LLM上下文中,由LLM决定受影响的地方(全靠模型的能力决定,而模型的决定都是靠概率)


    使用图后:从业务A这个名字开始,从整个“业务图”中,将所有和其有关系的业务过程均取出来,此时无需进入到“代码图”中就能定位到所有业务层面何其有关的修改点,过程中LLM只需要做简单分类问题(A功能的改动,是否会影响到B?只需要判断是否),在业务层面定位到所有受影响的点之后,再通过“关系图”进入到和这些点相关的“代码图”中,此时“代码图”中也会做和“业务图”中相同的事情,简单分类各个代码块是否需要做改动。最终得到代码层面受影响的地方完成改动(模型不需要很大的上下文,按图索骥就找到了所有真实需要改动的地方)

  • fyy1024 08-08 08:47
    16

    感谢大佬分享对rag的理解,很好的理解

  • George1202 08-08 10:03
    17

    难得见到这么优质的内容了,RAG应该是agent必要模块之一 ^-^

  • onepiececrush 08-08 10:17
    18

    早上起来第一件事打开 L站,从上到下翻了半天,就只点开了佬这篇文章。优秀如你,希望佬后续能继续分享干货~相信不少友都喜欢看这类纯粹的技术文(已点赞收藏+关注)

  • sylxb 08-08 10:19
    19

    佬友太有实力了,正需要这类知识的学习

* 帖子来源Linux.do
返回