Chapter 01

概念与闭环:把知识从权重里搬出来

起点页给了一张漏斗全景图。这一章把图上每个框拆开,建立 RAG 的词汇表,并锚定贯穿全教程的两条主线:召回→精度漏斗,以及 grounding 概率契约。

本章你将建立的 schema

  • RAG 闭环:知识从训练时的权重,搬到推理时的检索
  • 索引侧 / 检索侧 / 生成侧 三段各自在算什么
  • 召回→精度漏斗:为什么分两阶、各自优化什么
  • grounding 是概率契约:检索质量是答案上限,但完美检索仍可能幻觉

贯穿全章用同一个场景:你在给公司搭一个内部问答助手。语料是几百页的员工手册 PDF。用户问:"出差住宿的报销上限是多少?"下面每个概念,都用这个问题走一遍。

1.1为什么是 RAG:知识解耦

RAG = 在生成时,把相关知识从一个外部索引里检索出来、放进 prompt,让模型基于这些证据回答,而不是只靠它训练时记住的东西。

为什么需要它

大模型的知识冻结在训练截止那一刻,且压进了权重里——它不知道你公司的报销政策,也不知道上周改的版本。两条老路都不好走:把手册塞进每次 prompt,几百页超出 context、且贵;把手册微调进模型,训练成本高、知识一变就得重训、还无法给出"答案来自手册第几页"的溯源。RAG 选第三条:知识留在外部、可随时更新,生成时只检索相关的那几段放进 prompt。

底层机制(比文档深一层):Lewis 等人 2020 年提出 RAG 时,用的框架是参数化记忆(parametric memory)与非参数化记忆(non-parametric memory)的分工。模型权重是参数化记忆——知识以参数形式编码、容量固定、更新等于重训。RAG 接上一块非参数化记忆——一个外部索引(向量索引 + 原文),知识以"可检索条目"形式存在、容量可扩、更新只是写库。生成时,模型把检索到的条目当成临时的、可信度更高的上下文来用。RAG 真正改变的不是"模型更聪明了",而是知识的存放位置和更新方式。

LLM 权重 参数化记忆 · 冻结 外部索引 非参数化记忆 · 可更新 Prompt 上下文 隐性知识 + 证据 答案 隐性 检索证据
图 1.1RAG 给 LLM 接上第二个知识来源:权重里的参数化记忆冻结在训练时,外部索引是非参数化记忆、可随时更新。注意:两条线都流进 prompt,但只有红色这条(外部索引)能在不重训模型的前提下换掉知识——这正是 RAG 的全部价值所在。
类比 · 带边界声明

像开卷考试:闭卷(纯 LLM)只能写脑子里背下的;开卷(RAG)允许翻书,但你得先翻到对的那一页,而且翻到了也可能抄错、抄漏。类比失效处:考生知道自己在抄哪本书,而 LLM 并不"知道"证据从哪来——它只是把 prompt 里的 token 当成更可能出现的下文,这一点在 §1.7 会变成关键。

1.2RAG 闭环:索引侧与查询侧

RAG 系统由两个时间错开的阶段组成:离线的索引侧(建库)和在线的查询侧(应答),它们唯一的交汇点是索引。

为什么需要它

把"建库"和"应答"分开,是因为两者的频率和成本完全不同。分块、嵌入几百页手册很贵,但只需做一次(或文档变更时增量做);而用户提问随时发生、要求毫秒级响应。把贵的、可复用的工作挪到离线,是几乎所有检索系统的基本骨架。

底层机制(比文档深一层):索引侧是一条"写"路径——文档 → 分块 → 嵌入 → 写入索引;查询侧是一条"读"路径——查询 → 嵌入 → 检索 → (重排)→ 生成。关键在于:嵌入模型必须是同一个,否则离线 chunk 向量和在线 query 向量落在不同空间,近邻搜索失去意义。也正因为知识只活在索引里,"更新知识"等于"重跑索引侧的写路径",模型权重一动不动——这把 §1.1 的"知识解耦"落到了工程结构上。

离线 在线 文档 分块 嵌入 索引 向量 + BM25 写入 查询 嵌入 检索 生成 query 向量 读取召回
图 1.2RAG 闭环分两个时间:离线把文档分块、嵌入、写进索引(建一次、反复用);在线把查询嵌入、检索、生成。注意:索引是两条线唯一的交汇点——离线写、在线读;更新知识只需重跑离线这条线,模型权重不动。

1.3分块 chunking:检索的最小单元

分块是把长文档切成若干段"可检索单元",每段单独嵌入、单独被检索。

为什么需要它

整本手册当一个单元,既塞不进 context,也无法精确命中——用户问报销上限,你不想把整本手册都给模型。分块让检索的粒度对齐到"一个问题大致需要的那一小段"。

底层机制(比文档深一层):chunk 大小是一组无法同时取胜的取舍。切太小(比如一句话):单段嵌入语义锐利,但一个完整答案被切碎,检索到一句却丢了它依赖的上下文("上限是 800 元"——但哪个城市档?)。切太大(比如整章):上下文完整,但一段里塞了多个主题,嵌入向量是这些主题的"平均",对任何单一问题都不够锐利,反而排不进前列。所以分块不是预处理小事,而是漏斗第一段的入口决策——它直接决定了"理想答案片段"能不能成为一个可被召回的单元。03 章会把分块策略展开。

例 · 报销场景

手册里报销规则是一张表:不同城市档对应不同上限。按固定 200 字硬切,很可能把"一线城市 800 元"和它的表头"住宿费上限"切到两个 chunk——检索到数字却丢了它修饰的对象。这就是 03 章会讲的"边界感知分块"要解决的问题。

1.4嵌入 embedding:把语义变成坐标

嵌入把一段文本映射成一个高维向量,使"语义相近"变成"向量空间里距离相近"。

为什么需要它

用户说"住宿能报多少钱",手册写"住宿费上限"——字面不同,意思相同。关键词匹配会漏掉,嵌入则让两者向量靠近,从而可被同一次近邻搜索捞到。这是 RAG 能"按意思找"而非"按字面找"的基础。

底层机制(比文档深一层):嵌入模型(一个编码器)把变长文本压成一个定长向量——比如 1024 维。这个压缩是有损的:它保留了语义主旨,却丢掉了精确的表面形式。这带来一个 02 章会详细拆的后果——dense 向量擅长"意思像",却对"1099-MISC""SKU-7741"这类罕见、必须精确匹配的 token 很不可靠,因为它们的精确字形在压缩中被抹平了。记住这个"有损瓶颈",它是后面 hybrid 检索存在的理由。

想一想

用户问 "1099-MISC 表格怎么填",语料里正好有一段讲 1099-MISC。如果只用 dense embedding 检索,它一定能排在最前面吗?(先停十秒)

展开答案(先自己答)

不一定。dense 向量擅长语义相似,但 1099-MISC 是一个罕见、靠精确字形识别的 token;嵌入的有损压缩可能让它和一堆"报税相关但不是这张表"的段落挤在一起,真正那段未必排第一。

这正是 02 章要讲的:BM25 这类基于精确词项的检索,恰好补上 dense 的这个盲区——于是有了 hybrid。

1.5检索 retrieval:漏斗的第一阶(召回)

检索 = 给定 query 向量(和/或关键词),从全语料里快速捞出一批最可能相关的候选 chunk。

为什么需要它

语料可能上百万段,不可能让昂贵的模型逐段细看。检索是一道廉价、快速、宁可多捞的初筛——它的首要目标是召回(recall):别把正确答案漏在门外。漏了,后面再贵的环节也救不回来。

底层机制(比文档深一层):检索的本质是在向量空间里做近似最近邻搜索(ANN),用相似度(余弦 / 点积)近似"语义相关"。它之所以能在毫秒级扫完百万级语料,靠的是离线建好的索引结构——代价是只给"近似"答案,且如 §1.4 所说,对精确字形不敏感。检索这一阶有 dense、sparse(BM25)、hybrid 三种主要打法,02 章逐一下探它们各自的机制和盲区。这里只需记住它在漏斗里的角色:宽口、廉价、保召回。

1.6重排 reranking:漏斗的第二阶(精度)

重排 = 对检索出的 top-k 候选,用一个更贵但更准的模型重新打分排序,只把最相关的少数几段留给生成。

为什么需要它

检索为了保召回,会捞回不少"沾边但不对"的候选。把这一百段全塞给 LLM,既超 context、又引入噪声(03 章会讲噪声如何拖垮生成)。重排在这批候选上做精排,首要目标是精度(precision):把真正相关的顶上来、噪声压下去。

底层机制(比文档深一层):检索用的是"分别编码再算距离"的方式(query 和 doc 各自变成向量,省得能预先算好),代价是 query 和 doc 之间没有逐词交互。重排换一种更贵的算法——把 query 和候选 doc 拼在一起送进模型,让两者逐词互相"看",因此能判断细粒度的相关性。代价是它必须对每个候选单独跑一次,无法预计算,只能用在 top-k 这一小撮上。"为什么检索做不到重排的精度、重排做不到检索的规模",是 02 章的核心机制题。漏斗角色:窄口、较贵、保精度。

1.7生成与 grounding 契约

生成 = 把重排后的少数证据 chunk 拼进 prompt,让 LLM 基于这些证据作答;grounding 指答案应"扎根"于给定证据,而非凭空发挥。

为什么需要它

检索和重排把"对的证据"递到了门口,但模型仍需被约束去用这些证据、并标明出处。grounding 提示和引用要求就是这道约束——它把"自由发挥的聊天"收束成"基于手册第 12 页回答"。

底层机制(比文档深一层):把证据放进 prompt,会改变模型下一个 token 的概率分布——让"可以从上下文里抄到的 token"变得更可能被生成。这降低了幻觉,但只是降低、不是消除:生成始终是概率采样,模型仍可能无视证据、用参数化记忆覆盖它、或在多段证据间错误拼接。这就是grounding 概率契约的全部含义——检索质量是答案质量的上限(证据没捞到,神仙也答不对),但拿到完美证据也不保证答对。理解这条,是后面 03 章"为什么要把'检索对不对'和'答得忠不忠实'分开评估"的根基。

想一想

检索 + 重排把 3 段证据递给模型,每段都正确且明确包含"一线城市住宿上限 800 元"。模型还可能答错吗?(先停十秒)

展开答案(先自己答)

会。grounding 是概率性的:模型可能用它训练时见过的"常见上限 500 元"覆盖证据;可能把另一段里"二线 600 元"的数字张冠李戴;也可能答得含糊。证据正确 ≠ 答案正确——这道缝隙正是 03 章 faithfulness 指标专门去量的东西。

1.8综合:召回→精度漏斗

把 1.3–1.7 串起来,就是这份教程的组织主线,也是最该内化的那个核心转变:RAG 是一条逐级收窄的漏斗,每一阶优化的目标不同,每个进阶技术都只插在漏斗的某一个具体环节上。

检索 · 全语料 → top-100 目标:召回最大化 · 廉价、快 重排 · 100 → 8 目标:精度最大化 · 较贵 生成 · 8 → 1 grounding · 引用 召回↑ 覆盖广 精度↑ 只留相关
图 1.3同一条漏斗的纵向视角:宽口检索保召回(便宜、覆盖广),窄口重排保精度(较贵、只留最相关),生成 grounding 收成 1 个答案。注意:召回和精度是两阶分别优化的——只有检索没有重排,噪声进生成;只有重排没有足够召回,正确答案根本没进候选。两阶缺一不可。
洞察 · 为什么这条主线最关键

一旦把 RAG 看成漏斗,后面所有技术都不再是零散的名词,而是有了坐标:查询改写 / HyDE 改的是漏斗入口(让 query 向量落得更准);hybrid + RRF 加固检索这一阶的召回;rerank 是第二阶本身;Contextual Retrieval 修的是索引侧的分块;评估分段量每一阶的产出。02–04 章就是沿这条漏斗逐段下探。

§本章 self-check

先合上教程,把答案写在纸上或编辑器里。写完再点开对照——直接点开等于把这一节当再读一遍。

  1. RAG 为什么不靠"把知识微调进模型"?它换来了什么、牺牲了什么?
  2. 索引侧和查询侧各做哪些步骤?哪一步是两者唯一的交汇点?为什么这一步用的嵌入模型必须相同?
  3. "召回→精度漏斗"里,检索阶段和重排阶段分别在最大化什么?为什么不能只保留其中一个?
  4. grounding 把幻觉降到零了吗?用一句话说清"检索质量是答案上限"这句话的含义。
答案(先做完再展开)
  1. 微调把知识压进权重(参数化记忆),更新需重训、滞后、且难溯源。RAG 把知识放外部索引(非参数化记忆):换来了可随时更新、可溯源、不重训即可换知识;牺牲了一次额外的检索开销和"检索可能捞错"的新失败面。
  2. 索引侧(离线):文档→分块→嵌入→写入索引。查询侧(在线):查询→嵌入→检索→(重排)→生成。交汇点是索引。嵌入模型必须相同,否则 chunk 向量和 query 向量不在同一空间,近邻搜索的距离失去意义。
  3. 检索最大化召回(别漏掉正确答案),重排最大化精度(把噪声压下、相关顶上)。只有检索没重排:噪声进生成、超 context;只有重排没足够召回:正确答案根本没进候选,重排再准也无米下锅。
  4. 没有。grounding 是概率性的,模型仍可能无视/覆盖/错拼证据。"检索质量是答案上限"= 证据没被检索到,生成无论如何答不对;但反过来,证据齐全也不保证答对。
进阶挑战 · 刚好够不着

已删除的文档,为什么还在答案里?

你的语料每天增删文档。某天用户拿到一段答案,出处是一份上周已删除的旧政策。结合本章"索引侧 vs 查询侧",这个问题最可能出在哪一侧的哪一步?

提示(卡住再展开)

删除发生在源文档,但查询侧读的是索引。想想:删源文件时,索引侧的写路径有没有同步把对应 chunk 的向量从索引里删掉?这类"源已变、索引没跟上"的问题,03 章会作为一类失败模式(索引陈旧 / freshness)再展开。