RAG 与检索
模型的权重,是它所训练语料的一份有损、冻结的快照。检索增强生成(RAG)的做法,就是在模型旁边放一份实时、可查询的语料,回答时再把恰当的段落放进提示。RAG 流水线把一个问题变成几百个证据词元:先把语料分块并索引,再嵌入查询、检索并融合候选、重排,最后依据选出的段落生成答案。每个阶段都防止一种特定失败,也各自付出一种代价。后来的系统不断修补流水线的薄弱处,而决定它能留下多少证据的,是两股力量:一个藏身于语料中的对手,以及一个不断增长的上下文窗口。
知识在权重之内,还是在权重之外
一个前沿模型,知道它的预训练配比里有什么,截至配比被冻结的那一天为止,并被 第 5 章 所讲的有损压缩模糊掉。它不知道某个组织的私有文档,不知道截止日期之后发生了什么。当被问到一个它只记得一半的事实时,它会给出一个流畅、自信、却是错的答案。把知识微调进权重,既昂贵、更新又慢,而且依然有损。更稳妥的做法,是把知识留在权重之外,按需取用。
这就把问题重新表述成了信息检索与生成的联姻。给定一个问题和一份数百万段落的语料,找出真正能回答这个问题的那一小组段落,把它们放进上下文窗口,让模型读取并引用。难点全在检索:语料很大,搜索必须是亚线性的;问题与答案很少共享确切的字眼,单凭词法匹配很脆弱;上下文窗口有限又昂贵,只能传入少数几个段落,而它们最好都是对的。检索,就是把一个问题变成那几百个能改变答案的证据词元。Lewis 等为检索增强生成命名,并把它构想成参数化记忆(模型的权重)与非参数化记忆(一个可检索的索引)的结合,在知识密集型任务上把检索器和生成器一同训练 (Lewis et al. 2020)。
沿流水线向下,一次一个阶段
从那个想法里形成的朴素 RAG 流水线,有四个阶段:离线把语料分块并索引、在线嵌入查询、检索出最近的分块、再以它们为条件生成答案。每个阶段的存在,都是为了回答某个特定失败:若没有它,就只能退回更朴素的做法,而那种失败正是那种做法的软肋。它们也各自带着一个有拐点的控制参数。我们按顺序逐一走过。
分块之所以存在,是因为文档太长,没法整体嵌入或检索。单个向量无法以一个问题所需的粒度去表示一份百页报告,也没法把整份报告放进提示。于是语料被切成分块,通常几百个词元,每个分块单独索引。分块大小是一个直接的权衡,没有普适答案:分块太大,相关的句子会被淹没在不相关的句子里,还无谓耗掉上下文预算;分块太小,又会把句子从那段能消歧它的上下文里切断。拐点取决于文档结构和问题类型,这正是重叠窗口、以及结构感知的切分(按章节、按段落)存在的原因,用来缓和边界问题。第三种缓和手段是给分块本身补上下文:上下文检索(contextual retrieval)在建立嵌入索引与关键词索引之前,先为每个分块前置一句由大语言模型生成的定位说明,Anthropic 报告称这能把 top-20 检索失败率降低 49% (Anthropic 2024)。
稠密检索回答的是词法匹配的脆弱。一个双编码器(dual-encoder)把查询和每个分块嵌入到同一个向量空间,并经过训练,使一个问题和它的答案落得彼此很近,哪怕它们不共享任何字眼。一段文本如何变成那个向量,是 第 45 章 的主题。Karpukhin 等在 Dense Passage Retrieval 中表明,一个只在几千条问题-段落对上训练的双编码器,在开放域 QA 的 top-20 检索准确率上,就以很大幅度胜过强 BM25 稀疏检索(BM25) 词法基线,也就是一种稀疏关键词打分方法 (Karpukhin et al. 2020)。相关性变成了嵌入空间里的一个点积或余弦相似度,也就是两个向量之间的接近度分数:
其中 与 是查询编码器和分块编码器。两个编码器可以绑定,也可以分开,而分块嵌入只在离线时算一次,之后就冻结进索引。这里的控制参数是稠密对稀疏:稠密检索能跨改写泛化,却会在确切词元上失手,这一点交给下一个阶段去纠正。
向量存储回答的是搜索的成本。面对数百万个分块向量,给每个查询都对每一个向量算点积,太慢了。近似最近邻索引用一个很小、有界的召回损失,换来数量级的提速。占主导的结构是 分层可导航小世界图(HNSW):Malkov 与 Yashunin 的索引构建一个多层邻近图,从稀疏的顶层一路向下贪婪地搜索,给出对数级的查询时间 (Malkov and Yashunin 2018)。一个向量存储,就是 HNSW(或它的某个量化变体)加上元数据过滤,再加上让索引与语料保持同步的那套管道。这里的控制参数是召回对延迟:精确最近邻是对的,但太慢,而索引参数是在召回与延迟之间取舍,不是一个固定设置。
混合搜索(hybrid search)回答的是稠密检索的盲点。嵌入能跨改写泛化,却会丢掉确切的词元:一个零件号、一个罕见的名字、一个代码标识符、一个被稠密模型抹平掉的字面字符串。稀疏词法检索,也就是倒排索引上的 BM25,在这些词项上是精确的,正好互补。混合搜索把两者都跑一遍,再融合排名,常用倒数排名融合(reciprocal rank fusion),让被任一方法排到高位的分块都能浮上来。它付出两个索引加一个融合步骤来兼得两半,这份成本通常是值得的。
不妨给某个分块在两份列表里都只排个中游名次,看倒数排名融合怎么仍把它浮到只在一份列表里排第一的项之上。
# 倒数排名融合:score = 对各列表求和 1/(k + rank)。
def rrf(rankings, k=60):
scores = {}
for ranking in rankings:
for rank, doc in enumerate(ranking, start=1):
scores[doc] = scores.get(doc, 0.0) + 1.0 / (k + rank)
return sorted(scores, key=scores.get, reverse=True)
dense = ["A", "B", "C", "D"] # 嵌入排到高位的
sparse = ["E", "C", "F", "A"] # BM25 排到高位的
fused = rrf([dense, sparse])
print("dense :", dense)
print("sparse:", sparse)
print("fused :", fused)
print("C wins: ranked 3rd and 2nd, never 1st, but agreed on by both.")
重排回答的是低成本检索与精确评分之间的落差。双编码器之所以快,是因为查询和分块直到最后那个点积之前都不曾相遇,而这也正是它不精确的原因:它没法建模查询的词和分块的词之间那种细粒度的交互。一个交叉编码器(cross-encoder)重排器,把查询和分块一起喂过一个 transformer,对它们的联合表示评分,这精确得多,却也太慢,没法在整个语料上跑。于是流水线先以较低成本检索出几百个候选,再昂贵地对头部候选重排,而这份短名单的长度就是控制参数:只在检索出的短名单上跑交叉编码器,就能用一小部分成本获得大部分精确度。ColBERT 介于两者之间:它的后交互架构保留逐词元的嵌入,做一个低成本的 MaxSim 交互,以检索时的成本恢复出交叉编码器大部分的精确度 (Khattab and Zaharia 2020)。
拖动短名单深度,看答案精确度先快速爬升、随后变平:头十几个被重排的候选承载了大部分增益,更长的短名单只是搭进交叉编码器的算力,换来递减的回报。
这三种架构的成本与精确度,直接源自同一个设计选择:查询和分块在网络里何处首次相遇,如 图 44.4 所示。
四个阶段首尾相接,就构成一个筛选流水线,如 图 44.5 所示。
每个阶段都比下一个成本更低、覆盖更宽,或更昂贵、更精确,而这个顺序之所以这样排,就是为了让昂贵的阶段永远只看到一份短名单。这是默认设计,它的强处恰恰就是它的刚性:嵌入一次、检索一次、生成一次,每个控制参数都事先定好。
三个弱点对应三条改进线
那份刚性,也正是流水线容易失效之处。朴素流水线把各阶段解耦,让每个阶段恰好运行一次,这给了它三个结构性弱点,而这个领域的大部分演化,就是每个弱点对应一条研究脉络,如 图 44.6。
第一个弱点是只能做局部推理。朴素 RAG 检索的是与查询最相似的分块,这对答案落在少数几个段落里的问题管用,对答案散布在整个语料里的问题就失手了。当被问到「这些文档的主要主题是什么?」时,相似度搜索无从下手,因为没有任何单个分块是在讲这些主题。GraphRAG 把这件事重新构想为以查询为中心的摘要:它用一个模型从语料里抽出一张实体与关系的图,跑 Leiden 社区检测来分层地切分这张图,再预先为每个社区做摘要。一个全局问题,于是改成对社区摘要而非原始分块做 map-reduce 来回答。作者表明,在百万词元量级语料上的意义建构问题上,这改善了答案的全面性与多样性 (Edge et al. 2024)。LightRAG 保留了图的想法,但削减了成本:一种双层检索,把低层的实体检索和高层的概念检索结合在一个图索引之上,并带增量更新,使一篇新文档不必逼着系统全量重建索引 (Guo et al. 2024)。
第二个弱点是静态、单次的控制流。朴素 RAG 总是检索,而且恰好检索一次,从不检查检索到的东西是否有用。修法是把一个控制器放进回路。Self-RAG 训练模型发出反思词元,由它们来决定要不要检索,再在用每个被检索到的段落之前,就其相关性与支持度做批判 (Asai et al. 2023)。CRAG 在检索与生成之间加了一个轻量评估器,给检索到的分块打分,当它们不达标时,触发一次纠正性的网页搜索,而不是从弱证据上硬生成 (Yan et al. 2024)。这些是从朴素通往智能体的桥梁。
第二步再向前推进,就得到智能体式 RAG。Singh 等在对智能体 RAG 的综述里描述了这个终点:检索回路变成一个智能体,它规划、把一个问题分解成子查询、挑选要查询哪些工具与索引、对中间结果反思,并一直迭代到攒够证据 (Singh et al. 2025)。检索不再是一条固定流水线,而成了智能体所运行的一个策略,借助 第 38 章 的智能体架构,以及当涉及多个专门检索器时 第 43 章 的协调。同样的段落,经过重新排序与重新查询,用法可以很不一样。这整条轴线上的控制参数是朴素对智能体:单次的流水线成本低、可预测、低延迟;一个智能体回路能回答更难的问题,但会成倍放大词元成本与延迟,还会引入它自己的失效模式。大部分生产流量并不需要这个智能体;需要它的那一小部分,则获益巨大。
智能体式的控制还暴露出一个漏斗从未质疑过的假设:检索是否真的需要一份索引。编码智能体大体上已经把索引丢掉了。当语料本身是一个智能体能自行导航的文件系统时,它就在同一个「规划、行动、观察」的回路里,用 grep、glob 和文件读取直接搜索实时状态;一项针对智能体运行框架的研究发现,在这种设定下 grep 式搜索的准确率总体高于向量检索,差距大小取决于框架及其工具调用方式 (Sen et al. 2026)。这笔交易两头都摆在明面上:不用分块、没有嵌入漂移、没有重建索引的滞后、状态永远新鲜,代价是每次查询都要付出多轮工具调用与词元。这个模式的适用前提,是语料自带可以导航的结构,比如一个代码仓库或一套 API;到了网页规模,没有什么可以 grep,漏斗仍是唯一的入口。
被检索到的文本是不可信的输入
加入检索,移动了安全边界。一旦来自语料的不可信文本流进提示,那段文本就能携带指令。SafeRAG 直接对此做基准测试,把攻击分成银噪声、上下文间冲突、软广告和白色拒绝服务,并发现在许多 RAG 组件上,哪怕只是注入一些简单段落,也能绕过检索器与过滤器,拉低答案质量 (Liang et al. 2025)。被检索到的内容是不可信的输入,必须照此对待,这一点直接连到 第 56 章。这是流水线靠调参消除不掉的弱点:没有任何分块大小或重排深度能让一条被植入的指令变得安全,因为问题出在信任,而非排名。
长上下文会让检索过时吗?
压在检索上的第二股力量,外表更友善,却更根本:上下文窗口在不断增长,而一个足够大的窗口,也许会让整条流水线变得多余。
活跃的争论是,长上下文会不会让检索过时。随着上下文窗口接近、乃至越过百万词元,一派主张最简单的设计取胜:丢掉检索那套机制,把整份语料放进提示,让注意力去做搜索。另一派主张检索依然必要,理由有三个,都是窗口解决不了的:成本,因为给每个查询在百万词元上做注意力,远比取几千个词元昂贵;时效,因为语料变化的速度快过重新提示的速度,而索引可以增量更新;规模,因为真实语料超出任何窗口。证据不利于纯粹的长上下文立场:Liu 等在「Lost in the Middle」中表明,模型用放在上下文中部的证据,明显比用放在两端的差,所以一个满窗并不是一个简短、排好序的窗的均匀替代品 (Liu et al. 2023)。客观地看,两者正在收敛。长上下文让检索更粗、更宽容,检索则让长上下文负担得起、保持时新。窗口这一侧见 第 35 章,被检索到的证据如何被组装进提示,见 第 46 章。
一旦追问谁来为这个窗口买单,争论就有了清楚的答案,而答案来自检索远下方的一层。
检索在经济上之所以仍然必要,是被下面一层决定的。第 31 章 的注意力服务成本,以及它所填充的 第 32 章 的键值缓存,让上下文窗口里的每一个词元,都成为每次请求都要付的一笔经常性开销。正是那份成本,禁止了最简单的设计,也就是把整份语料放进提示,并催生一条检索流水线,让它交付几百个高价值词元,而不是几十万个平庸词元。检索流水线的形状,由一个上下文词元服务起来要花多少钱所决定。
放进系统
一个最小的朴素 RAG 回路很短,而这份简短正是要点:精妙之处活在索引、嵌入与重排器里,而不在控制流里。
def answer(query, k=5):
q = embed(query)
dense = ann_index.search(q, n=100) # HNSW 召回
sparse = bm25.search(query, n=100) # 确切词项
fused = reciprocal_rank_fusion(dense, sparse)
top = cross_encoder.rerank(query, fused)[:k]
return generate(prompt=build_context(query, top))
三个实现层面的现实,决定它在实践里能不能奏效。第一是索引时效:离线的分块与嵌入步骤,必须随语料变化而增量运行,否则检索会悄悄地供应过时的证据。第二是评估,它比看上去更难,因为一个 RAG 系统可能栽在检索处(正确的分块从未被取到),也可能栽在生成处(正确的分块取到了,却被忽略或误读),这两者要分开测量。检索质量用 recall at k 和 nDCG 这样的排名指标来衡量;答案质量则用对所检索证据的忠实度、以及答案相关性来衡量,通常如 第 50 章 那样交给一个模型评判,并带上 第 47 章 里关于智能体评估与轨迹评估的那些告诫。第三是溯源契约:因为每个论断都应能追溯到一个被检索到的分块,流水线必须把引用一路带到答案,这既是 Lewis 等当初为 RAG 立下的卖点 (Lewis et al. 2020),也是对当初促成它的那种自信幻觉的主要防线。
RAG 坐在智能体工作记忆的旁边,而不在其内。被检索到的上下文是临时的,按请求组装、用完即弃,这把它和 第 39 章 的持久状态区分开来。检索是智能体如何够到它并不持有的知识;记忆是它如何留住它已经学到的东西。两者相互组合,而最强的系统两者都用。
延伸阅读
- Lewis et al., “Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks,” 2020. arXiv:2005.11401RAG 将预训练参数化 seq2seq 模型与通过 DPR 检索的非参数化 Wikipedia 稠密索引相结合,在开放域问答上达到最优,并比纯参数化基线生成更具事实性的文本。
- Karpukhin et al., “Dense Passage Retrieval for Open-Domain Question Answering,” 2020. arXiv:2004.04906
- Khattab & Zaharia, “ColBERT: Efficient and Effective Passage Search via Contextualized Late Interaction over BERT,” 2020. arXiv:2004.12832
- Malkov & Yashunin, “Efficient and Robust Approximate Nearest Neighbor Search Using Hierarchical Navigable Small World Graphs,” 2018. arXiv:1603.09320HNSW 提出了一种基于多层邻近图的近似最近邻搜索索引,实现对数复杂度的分层可导航小世界图结构。
- Edge et al., “From Local to Global: A Graph RAG Approach to Query-Focused Summarization,” 2024. arXiv:2404.16130GraphRAG 通过大语言模型从语料库中构建实体知识图谱,利用层次社区检测生成社区摘要,再以 map-reduce 方式回答向量检索增强生成(RAG)无法处理的全局意义建构查询。
- Guo et al., “LightRAG: Simple and Fast Retrieval-Augmented Generation,” 2024. arXiv:2410.05779LightRAG 将图结构文本索引与双层检索增强生成(RAG)相结合,通过捕捉实体关系并支持增量知识库更新,提升对复杂查询的回答连贯性。
- Asai et al., “Self-RAG: Learning to Retrieve, Generate, and Critique through Self-Reflection,” 2023. arXiv:2310.11511
- Yan et al., “Corrective Retrieval Augmented Generation,” 2024. arXiv:2401.15884CRAG 提出一种即插即用的纠正式检索增强生成(RAG)方法,使用轻量检索评估器对检索文档进行质量判断,并在文档不相关时回退到网络搜索。
- Singh et al., “Agentic Retrieval-Augmented Generation: A Survey on Agentic RAG,” 2025. arXiv:2501.09136本综述提出检索增强生成(RAG)的智能体化分类体系,追溯从朴素 RAG 到嵌入自主智能体的流水线的演进,并分析设计权衡、应用场景与开放挑战。
- Liang et al., “SafeRAG: Benchmarking Security in Retrieval-Augmented Generation of Large Language Model,” 2025. arXiv:2501.18636SafeRAG 是一个评测检索增强生成(RAG)安全性的基准,提出四种新型攻击任务(银噪声、跨上下文冲突、软广告、白色拒绝服务),可绕过现有检索器、过滤器和大语言模型(LLM)的防御。
- Liu et al., “Lost in the Middle: How Language Models Use Long Contexts,” 2023. arXiv:2307.03172
- Anthropic, “Introducing Contextual Retrieval,” 2024. anthropic.com上下文检索在嵌入与 BM25 索引之前,为每个文本块前置一句由大语言模型生成的定位说明,将 top-20 检索失败率降低 49
- Sen et al., “Is Grep All You Need? How Agent Harnesses Reshape Agentic Search,” 2026. arXiv:2605.15184对智能体框架内检索策略的受控比较:对实时状态的 grep 式搜索总体上比向量检索准确率更高,差距大小取决于框架与工具调用方式。
评论
登录后评论