速成课 · No. 12
RAG 是你把事实交给语言模型、让它据此作答的方式,而不是指望它那模糊的记忆。它是严肃 LLM 应用里最重要的单一模式 —— 而当它出错时,模型几乎从不是元凶。真正的工作和质量都藏在检索里:你如何对要放到模型面前的文本做分块、建索引、检索和排序。
22 个概念 · 每个配一幅图 · 结尾有速查表
模型不了解你的数据,也不知道训练截止日期之后的任何事。RAG 就是把事实交给它、让它据此作答的办法 —— 所以先弄懂它要解决的问题,再看机制。
地图:七组共 22 个概念
一张地铁图:先看整张线路网,再一站一站地坐过去。
先是三个基础概念 —— 为什么模型的记忆不够用、RAG 是什么、为什么 grounding 很重要。然后是六组,每章一组:分块、embeddings 与检索、检索质量、grounding、评测,以及把它做好。
之后的每个概念都是同一个结构:英文名(记住它 —— 这就是术语)、一个生活中的画面、一幅图,以及一张带字段的卡片:是什么或问题、原理或思路、例子、注意或代价,还有关联。
Knowledge Cutoff —— 模型的记忆是冻结的
一位聪明的毕业生,多年前读完了整座图书馆 —— 但没读过你公司的文件,也没读过他毕业之后印刷的任何东西。
LLM 只知道训练数据里有的东西,冻结在某个截止日期 —— 也就是它的 knowledge cutoff。它不了解你的文档、你的产品、你客户的档案,也不知道昨天的新闻。你照样去问它,它就会**凭模糊的记忆作答,或者编出一个听上去合理的答案。**RAG 的存在正是为了解决这件事:不再依赖模型背下来的东西,而是在提问的那一刻把相关事实交给它。
- 是什么
- 模型只知道它的训练数据,冻结在某一天。
- 例子
- 它不了解你的文档、某位客户的档案,或者昨天的新闻。
- 注意
- 模型不知道时并不会沉默 —— 它会凭模糊的记忆作答,或者直接编造。
- 关联
- RAG 补上这个缺口:事实在提问的时刻送到。
RAG —— 先检索,再回答
开卷考试 —— 不靠记忆,先查出相关的几页,再根据眼前的内容写答案。
这就是 Retrieval-Augmented Generation(RAG,检索增强生成) 模式。三步:检索 —— 拿到用户的问题,取回你文档中最相关的片段;增强 —— 把它们放进上下文;生成 —— 让模型据此作答。这样答案来自你真实的数据,而不是模型的回忆。助手就是这样回答关于你的文档、你的政策、你的知识库的问题的 —— 准确而且是最新的。
- 问题
- 模型不了解你的数据,也不知道截止日期之后的事。
- 思路
- 找出文档中相关的部分,让模型据此作答。
- 例子
- 客服助手根据知识库里现行的那篇文章,回答退款政策问题。
- 代价
- 一整套检索系统:分块、索引、新鲜度、评测。
- 何时使用
- 知识量大、经常变化,或者因用户而异。
- 关联
为 grounding 而存在;建立在分块、embeddings 和向量检索之上。
Grounding —— 真正的收获
每句话都必须注明来源的记者,写出的捏造内容要比凭记忆写作的记者少得多。
RAG 重要的深层原因是 grounding(接地):因为答案取自检索到的文本,你可以要求引用,并检查每个论断是否真的有来源支撑。它不能完全消除幻觉,但能大幅减少,并让漏网的部分更容易被发现。能追溯到某份文档的答案,才是你可以信任 —— 也可以为之辩护的答案。
- 是什么
- 答案建立在检索到的文本上,而不是模型的记忆上。
- 原理
- 每个论断都能追溯到具体的某个片段,并可核对。
- 例子
- “退款需 14 天 [1]”,其中 [1] 是退款政策的某一段。
- 注意
- 它大幅减少幻觉,但不能降到零。
- 关联
- 通过仅依据上下文作答、引用和拒答来实现;用忠实度来衡量。
Retrieval-first —— 末端挂着一个模型的搜索系统
研究助理的水平取决于他查的那套归档系统 —— 给他一座好图书馆却配一个糟糕的索引,他照样会递给你错误的文件夹。
能帮你省下几个月的思维模型:RAG 主要是一个搜索问题,末端接一个语言模型来组织答案。模型是简单、基本已解决的那一部分。困难、决定质量的部分,是一切决定哪些文本能到达模型的环节 —— 这正是本课其余部分的内容。
别去问模型它知道什么。检索出相关事实,让它据此作答 —— 有依据、够新、可引用。
在检索之前,你要先把文档切成片段。怎么切,悄悄决定了检索的质量 —— 这是最不起眼的一步,却也是最重要的步骤之一。
Chunk —— 质量的基本单位
一本参考书只有切成可查找的条目才有用 —— 一卷巨大的、没有索引的长卷,或者一千张零碎的纸片,查起东西来都一样没用。
你检索的不是整篇文档,而是 chunk(片段) —— 几百个词长的段落。切出它们的过程叫分块(chunking)。这个 chunk 是搜索所看到的、也是模型所读到的单位,所以它的边界极其重要。好的 chunk 自成一体,只讲一个主题。分块做错了,再巧妙的检索、再聪明的模型都救不回来。
- 是什么
- 几百个词长的段落 —— 搜索与阅读的基本单位。
- 原理
- 文档预先切好;搜索返回 chunk,模型据此作答。
- 大小
- 太大会把答案埋掉,太小会丢掉上下文。这个数字要靠测量来找。
- 注意
- 糟糕的分块,搜索和模型都救不回来。
- 关联
用 structure-aware chunking 来切,用元数据来标记,再变成 embedding。
Chunk Size —— 太大会埋掉答案,太小会丢掉上下文
为了回答一行字的问题,递给别人整整一章,他得在噪音里趟水;只递给他一句没有前后文的话,他又看不出这是什么意思。
chunk 切得太大,每一块都把相关事实和好几段无关文字混在一起 —— 搜索变得模糊,模型的注意力也被稀释。切得太小,又会切断让这个事实有意义的上下文。最合适的大小,是装下一个完整的想法,并带着足够的周边内容、能独立成立。不存在通用的 chunk size;它取决于你的文档,要靠测量来调。
Structure-Aware Chunking —— 按含义切,而不是按字符数切
按字数数着切一本书,可能把一句话 —— 或者一道菜谱 —— 从中间劈开。按章节切,每一块都保持完整。
朴素的做法 —— fixed-size chunking(定长分块) —— 每 N 个字符切一刀,会切穿句子、表格和想法。更好的做法是按文档的天然结构来切 —— 标题、小节、段落 —— 让每个 chunk 都是一个完整的意思。相邻 chunk 之间留一点重叠(overlap),避免某个事实掉进两块之间的缝隙。尊重文档的形状,检索就会不费力地变容易。
- 问题
- 按字符数切分,会把句子和表格从中间劈开。
- 思路
- 按标题、小节和段落切分,并留一点重叠。
- 例子
- 整个“退款时限”小节成为一个 chunk。
- 代价
- 你得解析文档格式:Markdown、HTML、PDF。
- 关联
- 改善每一个 chunk 以及之后的一切。
Metadata —— 给每个 chunk 贴上标签
图书卡片记录的不只是文字 —— 还有作者、日期和章节,所以你在搜索之前就能先筛到恰当的那个书架。
存储每个 chunk 时带上元数据(metadata):来源文档、标题、日期、小节、权限。这让你可以在语义检索之前或同时做过滤 —— 只看这个产品的文档、只看现行政策、只看这个用户有权看的内容 —— 它还为引用提供了来源。元数据保存起来很便宜,却能把一堆扁平的文字变成可以精准定位的东西。
- 问题
- 一堆扁平的文字:没法缩小搜索范围,也没有可引用的来源。
- 思路
- 每个 chunk 都存上来源、标题、日期、小节和权限。
- 例子
- 只在这个用户有权看的现行政策里搜索。
- 代价
- 几乎为零 —— 每个 chunk 多几个字段。
- 关联
- 给向量检索提供过滤条件,给引用提供来源。
你检索的是 chunk,不是文档。按含义切,让每一块自成一体,并给它贴上标签 —— 分块质量决定了下游一切的上限。
要找到与问题匹配的 chunk,你得按含义搜索,而不是匹配字词。Embeddings 正是让“帮我找类似这样的东西”成为可能的那个窍门。
Embedding —— 含义变成坐标
一张地图,每个想法都有一个位置,含义相近的东西彼此靠得很近 —— “狗”挨着“小狗”,两者都离“纳税申报表”很远。
Embedding 是一串数字 —— 一个向量(vector) —— 它表示一段文本的含义,放在高维空间里,让含义相近的文本落在彼此附近。你把每个 chunk 只做一次 embedding,并存下这些向量。这样“含义”有了坐标,“找相关的文本”就变成了“找附近的点” —— 这是计算机能很快解决的问题。
- 是什么
- 一串数字,表示一段文本的含义。
- 原理
- embedding 模型输出坐标;含义相近就意味着点靠得近。
- 例子
- “狗”和“小狗”靠得近;两者都离“纳税申报表”很远。
- 关联
- 让向量检索成为可能;向量存放在向量数据库里。
Vector Search —— 按相似度找,而不是按关键词
一位按书的内容来找书的图书管理员 —— “类似这样的东西” —— 而不是只匹配你说的那个确切书名。
提问的时候,你用同样的方式给问题做 embedding,然后在库里找向量离它最近的 chunk。这就是向量检索(vector search),也叫语义检索(semantic search):即使用户问的是“把钱要回来”,它也能找到讲“退款政策”的 chunk,因为两者含义很近。关键词检索会漏掉这个;向量检索就是为此而生的。
- 是什么
- 找出向量离问题向量最近的那些 chunk。
- 原理
- 用同一个模型给问题做 embedding,然后找最近的点。
- 例子
- “把钱要回来”能找到“退款政策”小节。
- 注意
- 对确切的代码和名称表现不佳;“近”并不总是“有用”。
- 关联
- 运行在向量数据库上;由混合检索和重排序补全。
Vector Database —— 检索引擎
一座仓库,经过精心设计:给它任何一件物品,它都能立刻递给你最相似的一百件 —— 不是靠把每个货架看一遍,而是靠它的组织方式。
**向量数据库(vector database)**存放你的 embeddings,并在毫秒内回答“离这个最近的是什么”这类查询,即使面对几百万个 chunk 也一样,靠的是近似索引(ANN,近似最近邻),而不是全量扫描。它是 RAG 背后的检索引擎。你不需要自己造它 —— 但你得知道你的 chunk 就住在这里,以及它的检索有多快、多准。
- 是什么
- 存放向量、并能快速做最近邻搜索的库。
- 原理
- 用近似索引(ANN),而不是全量扫描。
- 例子
- 几百万个 chunk —— 毫秒内找到离问题最近的那些。
- 注意
- 你不用自己造它,但必须知道它的检索有多快、多准。
- 关联
- 存放 embeddings;向量检索运行在它上面。
Similar ≠ Relevant —— 相似不等于相关
两段文字可能主题相同,却回答不同的问题 —— “如何取消”和“人们为什么取消”挨得很近,但只有一个是被问到的。
向量检索返回的是语义上接近(相似)的内容,这通常是相关的,但并不总是。一个 chunk 可能讲的是正确的主题,却不包含答案。这个差距 —— 含义上接近与真正有用之间的差距 —— 就是为什么原始的向量检索是不错的第一轮,却不是最终结论,也是下一节存在的原因。
- 是什么
- 含义上接近的 chunk,不一定包含答案。
- 例子
- “如何取消”和“人们为什么取消”挨得很近;只有前者能回答问题。
- 注意
- 原始向量检索把“接近”误当成了“有用”。
- 关联
- 用重排序来修正;用检索评测来衡量。
Embeddings 给含义以坐标;向量检索按相似度找 chunk。它很强大 —— 但“含义上接近”并不完全等于“回答了问题”。
这一课能修好大多数出问题的 RAG 系统:答案不好时,原因通常在检索。把对的 chunk 送进去,一个像样的模型就能完成剩下的事。
Garbage In, Confident Garbage Out —— 垃圾进,自信的垃圾出
把错误的文件递给别人,让他做总结 —— 他会给你一份无可挑剔的总结,总结的却是完全错误的东西,而且听上去十分肯定。
RAG 的答案,只和交给它的 chunk 一样好。检索到了错误的段落,模型就会忠实地依据错误的上下文作答,带着它一贯的自信。这个 bug 看起来像是“模型错了”,但真正的失败发生在上游的检索。所以答案不好时,先检查检索到了什么,再去动提示词或模型。
Hybrid Search —— 把关键词和含义结合起来
一位搜索者清楚字词的含义,另一位能匹配确切的名称和代码 —— 两人合起来,能抓住任何一人单独会漏掉的东西。
向量检索懂含义,但可能在确切术语上出错 —— 产品代码、名称、罕见的行话。**关键词检索(keyword search)**能精确命中这些,却抓不到换种说法的表述。**混合检索(hybrid search)**把两者都跑一遍并合并结果,互相弥补盲区。对大多数真实语料来说,混合检索都优于任何单一方式,因为真实的问题把概念和具体名称混在一起。
- 问题
- 向量检索对确切的代码和名称出错;关键词检索抓不到换种说法的表述。
- 思路
- 两种搜索都跑,并合并结果。
- 例子
- “退货时报错 SKU-4471” —— 关键词检索找到代码,向量检索找到含义。
- 代价
- 两套索引,外加合并逻辑。
- 何时使用
- 面对真实语料,几乎总是该用。
- 关联
- 是重排序之前那一轮宽泛的初筛。
Reranking —— 给候选短名单重新排序
一场招聘:廉价的初筛先挑出五十份看似合适的简历,然后一位认真的审阅者仔细读过,排出真正的前五名。
第一轮检索又快又粗。**重排序器(reranker)**取前五十个候选,更仔细地逐个对照问题打分,把真正相关的 chunk 推到最前面。先广泛检索,再重排序,留下精准的少数几个。这种两阶段的形态 —— 宽泛廉价的召回,加上锐利的排序 —— 是对一个平庸的 RAG 系统来说杠杆最高的升级之一。
- 问题
- 第一轮又快又粗:对的 chunk 可能排在第 30 位。
- 思路
- 取前 50 个,仔细地逐个对照问题打分。
- 例子
- 从检索到的 50 个 chunk 里,重排序器留下最有用的 5 个。
- 代价
- 多一步 —— 每个问题都要多花一点延迟和费用。
- 何时使用
- RAG 表现平庸时 —— 最强的升级之一。
- 关联
- 修正 similar ≠ relevant;排在混合检索之后。
Precision & Recall —— 两者此消彼长
网眼大的网只能捞到大鱼,会漏掉很多;网眼细的网什么都能捞到,连水草也不放过。你根据需要的渔获来调整网眼。
检索的 chunk 太少,你可能漏掉带有答案的那个(低召回率 recall);检索得太多,答案又被淹没在无关文本里,稀释模型的注意力并浪费 token(低精确率 precision)。合适的 chunk 数量(常叫 k)能平衡两者,而且它取决于你的数据和问题类型。你不是猜出来的 —— 而是测出来的,这正是下一节的内容。
- 是什么
- 召回率 —— 对的 chunk 回来了没有;精确率 —— 同时带回了多少垃圾。
- 原理
- k 越大,召回率越高、精确率越低,反之亦然。
- 例子
- k = 2 会漏掉答案;k = 40 把它埋掉,还白烧 token。
- 注意
- 你猜不出合适的 k —— 要在自己的数据上测量。
- 关联
- 用检索评测来衡量;决定成本与延迟。
大多数糟糕的 RAG 答案,都是糟糕的检索。把关键词和语义结合起来,给短名单重排序,在怪模型之前先检查 chunk。
一旦对的 chunk 进入上下文,接下来的任务是让模型严格依据它们作答 —— 并证明它确实这样做了。这才把检索变成值得信赖的答案。
Context-Only Answering —— 只依据检索到的文本作答
一位被要求只陈述自己亲眼所见的证人 —— 不是他推测的、模糊记得的,或者听别人转述的。
指示模型只依据提供的 chunk 作答,答案不在其中时就说不知道。这是 grounding 的核心:检索到的文本是被允许的事实来源,模型自己的记忆则不在考虑之列。这不会完美 —— 模型仍可能跑偏 —— 但这条指令加上对的上下文,已经完成了大部分工作。
- 问题
- 模型把检索到的事实和自己的记忆混在一起。
- 思路
- 一条指令:只依据提供的 chunk 作答,否则就说“我不知道”。
- 例子
- “只依据下面的摘录作答。如果答案不在其中,就直说。”
- 代价
- 并不完美:模型仍可能跑偏。
- 关联
- grounding 的核心;由引用和忠实度来检查。
Citations —— 让论断可以被核对
带脚注的论文,让任何读者都能把一个论断追溯到它的来源并加以验证 —— 或者发现它站不住脚的地方。
让模型注明答案的每一部分来自哪个 chunk。**引用(citations)**有两个作用:让用户(和你)能对照来源验证论断;而且光是把每句话都建立在某段检索到的文字上,这个行为本身就会让模型不容易偏离事实。有可追溯来源的答案是你能审计的;没有来源的答案,只是一个自信的猜测。
- 问题
- 没有来源的答案无法核对 —— 它只是一个自信的猜测。
- 思路
- 模型说明每个论断来自哪个 chunk。
- 例子
- “退款需 14 天 [1]”,其中 [1] 是 refund-policy.md 的“时限”小节。
- 代价
- 每个 chunk 都需要带有来源的元数据。
- 关联
- 建立在元数据之上;让 grounding 可被核对。
Refusal —— 教它说“我不知道”
你最信任的专家,是那个会说“这个不在我手头的资料里”的人,而不是自信地用猜测去填补空白的人。
RAG 最危险的失败,是检索结果为空或偏题时仍然照答不误。所以要让拒答成为一种合法、被预期的输出:如果 chunk 里没有答案,模型就应该这样说,而不是凭记忆即兴发挥。一个承认空白的系统,远比一个把它遮掩过去的系统可信 —— 而且它还会暴露出你的检索哪里需要下功夫。
- 问题
- 检索结果偏题,模型却照样作答。
- 思路
- “这不在我的资料里”是一个正常的、被预期的回答。
- 例子
- 知识库之外的问题 → “文档里没有涉及这一点。”
- 代价
- 有时用户得不到答案 —— 但绝不会得到编造的答案。
- 关联
- 属于 grounding;拒答会暴露检索中的缺口。
Grounding 能减少幻觉 —— 但不能终结它
安全带能大幅降低死亡率,但你依然要小心驾驶。一道强力的保障,并不是不再看路的理由。
即使 chunk 完美,模型也可能读错、过度概括,或者把检索到的事实和自己的记忆混在一起。Grounding 大幅减少了幻觉,并让它可被发现;但它不会消除幻觉。所以你仍要验证 —— 用用户能核对的引用,以及衡量忠实度的评测。把 grounding 当作一种强有力的控制手段,而不是保证。
Grounding 意味着答案只来自检索到的文本,并用引用来证明 —— 而且当事实不在时,诚实地说一句“我不知道”。
RAG 有两个阶段,它们的失败方式不同,所以要分开衡量。把它们混在一起,你就会连着几周调错了那一半。(Evals 课程讲得更深;这里是 RAG 专属的形态。)
Two stages —— 把检索和生成分开衡量
一家餐厅出了一道坏菜,有两个可能的元凶 —— 送来的食材,或者厨师。你要先尝食材,否则会去培训错误的人。
RAG 的答案失败,可能是因为检索带回了错误的 chunk,也可能是因为生成阶段在对的 chunk 上答得不好。两者需要不同的修法,所以要分开衡量:对的 chunk 回来了吗?以及,给定这些 chunk,答案是否忠实且完整?大多数“没法改进自己 RAG”的团队,只给最终答案打分,然后猜该怪哪一半。
Retrieval Eval —— 对的 chunk 回来了吗?
在评判作文之前,先看看学生拿到的参考页对不对 —— 如果不对,他写的任何东西都不可能是对的。
单独评测检索 —— 这就是检索评测(retrieval eval):对一组已知相关文档的问题,搜索是否在靠前的结果里把它们返回了?这种命中所占的比例常被称为 recall@k。它能直接发现糟糕的分块、薄弱的检索和缺失的重排序 —— 也就是大多数糟糕答案的上游原因。先修检索,因为对提示词或模型做任何改进,都救不了建立在错误 chunk 之上的答案。
- 问题
- 从最终答案看不出是不是检索的错。
- 思路
- 拿已知正确文档的问题来测:它们回到前 k 名了吗?
- 例子
- 50 个真实问题里,有 41 个的正确文档在前 5 名。
- 能发现什么
- 糟糕的分块、薄弱的检索、缺失的重排序。
- 关联
- 衡量 precision & recall;要在忠实度之前先修好它。
Faithfulness —— 答案忠于 chunk 吗?
一位事实核查员对照引用的来源阅读答案,把来源其实并不支持的每一句都标出来。
检索一旦做好,就要评测答案的忠实度(faithfulness):每个论断是否都有检索到的 chunk 支撑,没有编造,也没有与之矛盾?还要检查它是否真的用上了检索到的内容,并回答了问题。这正是你抓住模型偏离坚实上下文的地方 —— 而且它是可以衡量的,常常由另一个模型当评分员(LLM-as-judge)。
- 是什么
- 答案中的每个论断都有检索到的 chunk 支撑。
- 原理
- 由评分员 —— 常常是另一个模型 —— 把句子与 chunk 逐一核对。
- 例子
- 两句有支撑,第三句没有:它被标记出来。
- 注意
- 忠于 chunk 的答案,仍然得回答问题。
- 关联
- 衡量 grounding;在做好检索评测之后才有意义。
Golden Set —— 用真实问题搭建评测
你用将要真正驶过大桥的卡车来测试它,而不是用你觉得方便的重量。
你的评测集 —— 常被称为 golden set —— 应该是用户真实会问的真实问题,包括杂乱的和超出范围的,每个问题都配上应当被检索到的 chunk,以及一个已知正确的答案。每次改动都跑一遍,这样你就能看出新的分块策略或重排序器是否真的有帮助。没有这个,你就是在凭轶事调 RAG —— 而轶事会骗人。
- 问题
- 凭轶事调优:“现在好像好些了。”
- 思路
- 真实问题 + 应该回来的 chunk + 已知正确的答案。
- 例子
一个杂乱的问题、一个换了说法的问题,以及一个超出范围、期望得到“我不知道”的问题。
- 代价
- 搭建和维护这套评测集要花时间。
- 关联
- 同时为检索评测和忠实度提供数据。
RAG 会在两个地方失败。把检索和生成分开衡量,先修检索,并用真实问题来搭建评测。
RAG 很强大,也常被滥用。真正的功夫在于:在它物有所值的时候才用,保持数据新鲜,并且不为一个更简单的办法本可以省掉的机制付费。
Paste First —— 能直接粘贴的,就别上 RAG
你不会为桌上的三本书建一套图书馆目录 —— 你只是把它们翻开。
如果相关的事实又少又固定 —— 几份文档、一段简短的政策 —— 就直接**放进提示词里。**RAG 只有在知识量大到上下文装不下、经常变化,或者必须按用户过滤时,才配得上它的复杂度。为三页纸搭一条检索管线,就像为一次调用写一个智能体循环那样,属于过度设计。数据逼你用的时候,再去用它。
- 问题
- 在根本不需要的地方搭了一条检索管线。
- 思路
- 小而稳定的事实直接放进提示词。
- 例子
- 一份两页的政策放进提示词,不用建索引。
- 何时用 RAG
- 知识放不进上下文、经常变化,或者要按用户过滤。
- 关联
- 阶梯的最底层一级;RAG 是下一级。
Index Freshness —— 过时的数据就是错误的数据
电话簿只有重新印刷才有用 —— 十年前的号码,是自信而又毫无用处的错误。
RAG 的承诺是最新的事实,这意味着你的索引必须保持最新。源文档变化时,chunk 和 embeddings 也必须更新 —— 即重建索引(reindexing) —— 否则模型会把答案建立在自信的过时文本之上。把重建索引当作系统的一部分来规划,而不是事后补救 —— 新鲜度是一项需要持续维护的功能,不是一次性得到的属性。
- 问题
- 文档变了,索引没变 —— 答案自信地过时了。
- 思路
- 按计划对变更的文档重新分块、重新做 embedding。
- 例子
- 政策更新了 —— 它的 chunk 当天就重建。
- 代价
- 一条需要你维护的重建索引管线。
- 关联
- 让 grounding 保持最新;涉及 chunk 和 embeddings。
Cost & Latency —— 盯着它们
管线里每多一步 —— 做 embedding、搜索、重排序、塞进上下文、生成 —— 都会给每一个问题增加一点时间、一点费用。
RAG 增加了若干阶段,每个阶段都要花延迟和 token。检索更多 chunk、重排序、更大的上下文 —— 都会在一定程度内提升质量,同时一路抬高账单。所以要调到能答好的最少 chunk 数,能缓存的地方就缓存,并记住:一个太慢或太贵的好答案,在生产环境里并不是好答案。
- 是什么
- RAG 的每个阶段,都会给每个问题增加时间和 token。
- 原理
更多 chunk、重排序、更大的上下文 —— 质量在一定程度内变好,成本则始终更高。
- 例子
- 重排序之后把 k 从 20 降到 5 —— 答案一样,账单更小。
- 注意
- 一个太慢或太贵的好答案,在生产环境里算不上好。
- 关联
- 与 precision & recall 和重排序相互拉扯。
RAG 只是一级台阶;模型仍然只是一个组件
好的厨房有储藏室,但储藏室不是厨师 —— 它只是给仍要亲手做出这道菜的人准备的、一份整理得当的输入。
RAG 在阶梯上位于普通提示词之上、工具和智能体之下:模型需要你的事实时就用它,并像对待任何依赖一样,把它放在干净的接口之后。检索是给模型喂料;它并不取代围绕模型的判断。纪律与到处一样 —— 用能行得通的最简单的那一级,并让模型可以替换。
这些概念如何连在一起
同一间厨房里的两个班次:夜里是备料 —— 把一切切好上架;白天是烹饪 —— 找出来、挑好、端上桌。
本课的一切都是分两个阶段的同一条链。离线(建索引):文档被切成带元数据的 chunk,变成 embeddings,存进向量数据库 —— 文档变化时再重建(index freshness)。查询时:混合检索找出候选,重排序留下最好的,精确率与召回率决定取多少个。然后是 grounding:模型只依据上下文作答,附上引用或诚实的拒答。另外,paste first:如果事实不多,你根本不需要这条链。而评测 —— 检索评测、忠实度、golden set —— 衡量每一个环节。
- 到底需不需要 RAG —— 还是事实又少又稳定,直接粘进提示词就行?
- 文档是怎么分块的 —— 按含义、自成一体、带元数据和一点重叠?
- 检索是混合并重排序的,还是一个你从没测量过的原始向量检索?
- 模型是否只依据检索到的文本作答、注明来源,并会说“我不知道”?
- 检索的评测是什么,与生成分开了吗?
- 索引如何保持新鲜,一次查询要花多少时间和 token?
- 答案自信地出错,而你从没看过检索到的那些 chunk。
- 只有原始向量检索 —— 没有关键词兜底,没有重排序。
- chunk 按字符数切分,切穿了句子和表格。
- 你在调提示词和模型,去修其实是检索遗漏的问题。
- 自源文档变化以来,索引一直没有重建过。
- chunk 语义完整、自成一体,带有用于过滤和引用的元数据标签。
- 检索是混合 + 重排序,调到能答好的最少 chunk 数。
- 答案有依据且有引用,事实没检索到时会诚实地拒答。
- 你把检索和生成分开衡量,并且先修了检索。
- 索引有新鲜度计划,RAG 位于一个你随时能替换的接口之后。
速查表:全部 22 个概念
基础
- Knowledge Cutoff训练截止日期
模型只知道截止某一天的训练数据 —— 不包括你的文档。
- RAGRetrieval-Augmented Generation
检索相关 chunk,放进上下文,据此作答。
- Grounding依据来源作答
答案建立在检索到的文本上,而且可以核对。
分块
- Chunk段落
几百个词长的段落 —— 搜索的单位;大小靠测量来调。
- Structure-Aware Chunking按结构切分
按标题和段落切分,并留一点重叠。
- Metadatachunk 标签
来源、日期、小节、权限 —— 用于过滤和引用。
Embeddings 与检索
- Embedding向量
一个向量 —— 文本含义的坐标。
- Vector Search语义检索
找出含义上离问题最近的 chunk。
- Vector DatabaseANN index
存放向量,并在毫秒内找到最近的那些。
- Similar ≠ Relevant相似度 vs 相关性
含义上接近的 chunk,不一定包含答案。
检索质量
- Hybrid Searchkeyword + vector
同时按字词和含义搜索,再合并结果。
- Rerankingtwo-stage retrieval
先广泛收集候选,再仔细挑出最好的几个。
- Precision & Recalltop-k
chunk 太少 —— 漏掉答案;太多 —— 答案被淹没。要测量 k。
Grounding
- Context-Only Answering依据上下文作答
只依据检索到的 chunk 作答,绝不依据模型的记忆。
- Citations来源标注
每个论断都指向它的 chunk,并且可以核对。
- Refusal“我不知道”
chunk 里没有答案 —— 诚实地说出来,而不是编造。
评测
- Retrieval Evalrecall@k
对的 chunk 回到前 k 名了吗?先修这个。
- Faithfulnessgroundedness
答案中的每个论断都有 chunk 支撑。
- Golden Seteval set
带期望 chunk 和答案的真实问题 —— 每次改动都跑一遍。
把它做好
- Paste Firstcontext stuffing
几条稳定的事实 —— 用提示词,不用 RAG。
- Index Freshness重建索引
文档变了 —— 重建索引,否则答案就过时了。
- Cost & Latency时间与 token
每个阶段都花时间和 token;取能答好的最小 k。
RAG 是末端挂着一个模型的搜索系统。把 chunk 做对,答案自然随之而来 —— 模型很少是问题所在。