第 6 周 · 检索系统 + RAG 生成与引用
从基础向量检索到生产级混合检索,让知识系统具备可靠回答与可验证引用
本周产出:三路混合召回 + Reranker、Context Packing、引用绑定、基本回归测试集 · 预计投入:15 到 20 小时 · 对应原 24 周编号:第 8、9 周
分档说明
四层评测方法论、消融实验、统计显著性在程序员进阶版附录 C,本周只要求基本固定测试集回归。
学前自测
1. 向量检索在什么情况下会输给 BM25?
精确关键词匹配的场景,比如查产品型号 SKU-8823、错误码 E1204、人名地名。向量检索擅长语义相似,但对这类没有语义只有字面的查询很弱。这就是为什么生产系统几乎都用混合检索,而不是纯向量。
2. RRF(Reciprocal Rank Fusion)解决什么问题?
多路召回的分数不可比。Dense 返回余弦相似度 0 到 1,BM25 返回的分数没有上界,直接加权求和是错的。RRF 只用排名不用分数,公式是对每一路的排名取倒数后相加,绕开了归一化难题。工程上简单可靠,是默认选择。
3. Reranker 和 Embedding 模型的区别是什么?为什么不能只用一个?
Embedding 是双塔结构,query 和 document 分别编码后算距离,可以预先索引所以快,但精度有限。Reranker 是交叉编码,把 query 和 document 拼在一起过一遍模型,精度高但必须实时算所以慢。生产做法是 Embedding 粗召回 100 条,Reranker 精排出 5 条。
4. 权限过滤放在召回前还是召回后?为什么?
必须在召回前(pre-filter)。放在召回后会导致两个问题:一是召回 10 条过滤掉 8 条只剩 2 条,结果质量塌方;二是更严重的,攻击者可以通过观察结果数量的变化推断出有哪些他看不到的文档存在。这是一类真实的信息泄漏。
学习目标
实现从基础向量检索到生产级混合检索,并让知识系统具备可靠回答。
这一周的关键词是可验证。一个说不出证据来源的 RAG 系统在企业里是不能上线的,因为出了错没人能定责。
课程内容
检索系统
- Embedding、Cosine / Dot Product、pgvector
- Metadata Filter、BM25、Elasticsearch
- Hybrid Search、Reciprocal Rank Fusion
- Query Rewrite、Multi-query、HyDE
- Reranker、Parent Document Retrieval
- Context Deduplication
- 框架无关 Retriever Contract
- Query / Result Provenance 与权限后过滤风险
RAG 生成与引用
- Context Packing、Citation Binding、Source URL
- 无答案检测、Groundedness、Faithfulness
- Answer Relevance、Citation Accuracy
- Retrieval Recall@K、MRR、nDCG(基本认知,不要求完整方法论)
- RAG Dataset、基本 Error Taxonomy
检索链路
实施任务
实现三路召回(Dense / BM25 / Metadata),合并后使用 RRF 和 Reranker。实现 Context Packing、Citation Binding 与无答案检测。建立一份基本固定测试集(不要求 100 条完整评测集与四层方法论)。
动手挑战
给你的 RAG 系统设计五道它必须答不出来的题。
这个练习反直觉但极其重要。准备五个问题,答案确定不在你的知识库里,比如「这份文档的作者今年多大」。然后观察系统的行为:
- 它是老实说不知道,还是编了一个听起来合理的答案?
- 如果编了,它给的引用指向哪里?引用和答案对得上吗?
- 你的无答案检测阈值定在多少?调高会怎样,调低会怎样?
能稳定说不知道的 RAG 系统比能答对更多问题的系统更有商业价值,因为前者可以被信任。这个实验的结果直接写进作品集。
Agent OS 里程碑
完成框架无关 Retriever Registry 与 RAG Playground。
验收标准
核心档(程序员基础版毕业线)
- 可选择检索策略,返回可解释分数
- Recall@K 有基线,Rerank 前后有对比
- 检索延迟 P95 有记录
- 权限过滤在召回前执行,并有跨租户泄漏测试
- 每个回答包含引用,无证据时不猜测
- 基本固定测试集在 CI 中执行回归
进阶档验收见程序员进阶版附录 B 与 C。
学后自测
1. 加了 Reranker 之后,你的 Recall@5 提升了多少?P95 延迟涨了多少?
两个数字都要能报。典型情况是准确率提升 10 到 20 个百分点,延迟增加 100 到 300 毫秒。能说清这个取舍,才叫做过工程决策而不是照抄教程。
2. 引用绑定怎么保证模型给的引用是真的,而不是它编的?
不能让模型自由生成引用文本。正确做法是给每个 Chunk 一个 ID,要求模型只输出 ID,然后由代码把 ID 映射回真实来源。模型能编造的只有 ID 编号,而无效 ID 可以直接被校验拦住。
3. 检索质量下降了,你怎么定位是召回问题还是生成问题?
分开测。先看标准答案所在的 Chunk 有没有被召回(Recall),如果没召回就是检索层的锅;如果召回了但答案还是错的,就是生成层没利用好证据。不做这个拆分的调优基本是碰运气。
本周作业
packages/retriever/:三路召回 + RRF + Reranker,可配置策略packages/rag-answer/:Context Packing、Citation Binding、无答案检测- 基本固定测试集 + CI 回归
docs/rag-evaluation.md:Recall@K 基线、Rerank 前后对比、P95 延迟、五道无答案题的实测结果- 跨租户泄漏测试:证明租户 A 的查询不可能召回租户 B 的 Chunk
面试考点
这一周对应面试里的 RAG 深度考察,是 AI 应用岗位的必考区。
- 「RAG 效果不好怎么优化?」:这是最高频的开放题。按层次答:先定位是召回还是生成 → 召回问题查 Chunk 策略、混合检索、Query 改写、Reranker → 生成问题查 Context 排序、Prompt、无答案检测。切忌一上来就说换个更好的 Embedding 模型。
- 「为什么要用混合检索?」:答向量对精确关键词弱,举 SKU 型号的例子。能顺带讲清 RRF 为什么用排名不用分数,是很明显的加分点。
- 「怎么防止 RAG 胡编?」:答引用绑定用 ID 不用文本、无答案检测、Groundedness 评测三层。最好带上你那五道必须答不出来的题的实测结果。
- 「你们的 RAG 准确率是多少?」:这题的陷阱是没有拆解就报一个数字。正确答法是先问评的是什么(召回还是端到端),再报你的 Recall@K 和基线对比。能反问的候选人显得专业。
- 场景题:多租户知识库怎么保证不串数据。答召回前过滤,并说明召回后过滤会有信息泄漏。
复习与延伸
官方文档与论文
起手代码(测试即规格)
examples/week-06/ 是这一周的练习仓,24 条测试。
pnpm --filter @agent-os/example-week-06 test里面有一条测试专门验证召回器拿到的是已经过滤过的文档,不是先召回再过滤。另一条把 BM25 分数放大一万倍,验证 RRF 的结果顺序不变。
本仓库对应源码
packages/rag-kit/src/similarity.ts:余弦相似度实现packages/rag-kit/src/vector-store.ts:内存向量库,用来理解检索的最小形态packages/rag-kit/src/vector-store.test.ts:检索测试写法