跳到主要内容

面试题:RAG 检索增强生成:文档怎么切块、向量索引怎么建、混合检索怎么排、幻觉怎么治?

· 阅读需 9 分钟

这是「每日一题」专栏的第十三篇。每天一道面试题,后端 + AI 混合路线,从原理到代码一次讲清。上一篇讲了 Feed 流系统设计,今天按轮换回到 AI/LLM 方向,聊上一篇预告的题:RAG 检索增强生成。

题目​

AI 应用面试里和 Agent 并列的高频题:

设计一个 RAG 问答系统:文档怎么切块?向量索引怎么建?为什么纯向量检索不够、要混合检索?检索对了之后幻觉怎么治?

这道题考察四件事:懂不懂 RAG 的全链路、能不能说出切块和索引背后的 trade-off、知不知道混合检索为什么是标配、能不能把幻觉治理讲出层次。很多人能背出「embedding 进向量库、相似度检索」,但被追问「块切多大、为什么、索引选 HNSW 还是 IVF」就卡壳。

先给结论:RAG 的本质是把「模型的记忆外包给可检索的知识库」。回答这道题的正确姿势,是把整条链路讲成一条流水线,每个环节都说出取舍。

一、RAG 解决什么问题​

模型的知识有三个硬伤:会过时(训练截止时间之后的事不知道)、会幻觉(不知道就是编)、没有私有数据(公司文档、个人资料不在训练集里)。微调能解决一部分,但每次更新知识都要重新训练,成本高、周期长、还可能破坏已有能力。

RAG 的思路是不把知识塞进参数,而是把知识放在外面,用的时候检索出来拼进 prompt:

离线索引:文档 → 解析 → 切块 → Embedding → 向量库
在线问答:问题 → Embedding → 检索(召回)→ 重排 → 拼 Prompt → LLM 生成

对比微调(Fine-tuning),面试里这个对比是必答的:

维度RAG微调
知识更新换文档重索引即可,分钟级重新训练,小时到天级
成本低(推理时多一次检索)高(训练算力)
幻觉控制可引用溯源,可控性强无法控制模型「不知道」时的行为
能力改变不改变模型能力能改变风格、格式、专业能力
适用场景知识问答、私有资料库风格迁移、领域术语、指令遵循

一句话:RAG 管「知道什么」,微调管「怎么做事」。 两者不是互斥的,生产系统经常叠加使用。

二、切块:检索单元要对齐答案粒度​

切块是 RAG 里最容易被低估、实际上最影响效果的一步。目标是让「检索单元」和「答案粒度」对齐——答案通常是几句话到一段话,块太小,语义不完整;块太大,噪声多、向量被稀释。

主流切块策略:

策略做法优点缺点
固定长度按 token 数硬切(如 512 token)简单、快、可预测句子被腰斩,语义断裂
滑动窗口固定长度加重叠(overlap 50)保住上下文连续性存储冗余,检索可能重复命中
结构感知按 Markdown 标题/段落/代码块切语义完整,天然贴合文档依赖文档结构规范
语义切块用 embedding 相似度找语义断点边界最自然慢,且依赖 embedding 质量

工程上的经验值:从 256 到 512 token 起步,按文档类型调——技术文档用结构感知,聊天记录用滑动窗口,合同/法律条文用固定长度加元数据。

两个加分点:

父子分块(Parent-Child Chunking):检索用小子块(精确命中),但喂给 LLM 时带上父块(上下文完整)。解决「检索到的块太碎、拼不出完整答案」的问题,是生产 RAG 的标配。

元数据注入:把标题、章节路径、URL、更新时间存进向量库的 payload。好处有两个——检索时能做过滤(只搜某个文档、某个时间之后的),生成时能拿来做引用溯源(每个回答句子绑定来源 chunk)。

三、向量索引:从暴力搜索到 ANN​

向量库的核心问题是:百万甚至千万级向量,怎么快速找到最近的 k 个? 暴力计算所有距离在数据量大时延迟不可接受,所以必须用近似最近邻(ANN)。

主流方案三个,面试必须能说出区别:

方案核心思路特点
HNSW多层图:底层完整、上层稀疏,贪心从上层往下搜索召回高、延迟低,内存占用大
IVF聚类分桶(nlist),只搜最近的几个桶(nprobe)省内存、速度快,召回看桶质量
PQ乘积量化,把向量压缩成码本索引内存最省,精度损失大

HNSW 为什么是默认首选,一句话讲清原理:它受跳表启发——跳表用多层链表让「查找」跳过大量元素,HNSW 用多层图让「搜索」从稀疏的高层快速逼近目标区域,再逐层下探到完整底层做精细搜索。搜索时用参数 efSearch 控制候选集大小:efSearch 越大越准但越慢,这是召回率与延迟的直接旋钮。

面试追问「IVF 和 HNSW 怎么选」:数据量千万级以下、内存不紧张的在线服务,默认 HNSW;数据量大到内存放不下、追求低内存,用 IVF-PQ 或磁盘索引(如 DiskANN 类方案)。

还有个常被问的细节:Embedding 模型选型。同样一段文字,不同 embedding 模型的语义表达差异很大,主流选择(如 bge、text-embedding 系列)按 MTEB 榜单和实际场景评测选,向量维度影响存储和检索速度,不是越大越好。

四、混合检索:为什么纯向量不够​

纯向量检索有个致命短板:对精确匹配不敏感。产品型号(iPhone 15 Pro Max)、人名、编号、缩写——这些词的语义近邻往往和字面完全无关,向量距离算出来「很像」,实际不是用户要的。反过来,BM25 这类稀疏检索擅长精确词匹配,但理解不了同义表达。

所以生产环境标配是混合检索:BM25 和向量检索各跑一遍,再用 RRF(Reciprocal Rank Fusion,倒数排名融合)合并结果:

RRF 分数 = Σ 1 / (k + rank) 每个检索结果按排名计分
k 取经验值 60,rank 是该文档在某个检索器里的名次

RRF 妙在只用排名、不用原始分数——不同检索器的分数分布(向量余弦相似度、BM25 词频)完全不可比,但排名是统一的,直接相加即可,不需要归一化。

召回之后还有一步重排(Rerank):召回阶段用双塔模型(bi-encoder)快速筛出 top 50 到 100,重排阶段用 cross-encoder 把「问题+文档」拼在一起过一遍模型,输出精确相关度,取 top 5 到 10 进 prompt。为什么重排必须用 cross-encoder?因为双塔模型的问题和文档是分开编码的,看不到 token 级交互;cross-encoder 拼接后过 attention,能捕捉「这个关键词到底指谁」这种交互信息,精度高一个档次,代价是慢,所以只能在小候选集上用。

加分项:查询改写(Query Rewrite)——用户问题太口语化时,先让 LLM 把问题改写成适合检索的形式再查;HyDE——先让 LLM 基于问题生成一段假答案,用假答案去检索,因为假答案和文档的语言风格更接近,能提升召回。这两招在面试里说出来就是亮点。

五、幻觉治理:分三层讲​

幻觉是 RAG 的终极大考。RAG 不是天然没幻觉——检索不到、检索到但被模型忽略、上下文太长被淹没(lost in the middle),都会导致模型自由发挥。治理要分三层:

第一层:检索侧(防)

  • 切块质量:块对齐答案粒度,父子分块保上下文
  • 混合检索 + 重排:提高召回相关度,从源头保证「有料」
  • 查询改写:把模糊问题转成精确查询
  • 路由(Routing):简单问题走直答,复杂问题才走 RAG,避免不必要的检索噪声

第二层:生成侧(约束)

  • Prompt 硬约束:「只能基于检索内容回答;检索内容不含相关信息时,明确回答不知道」
  • 引用溯源:每个回答句子绑定来源 chunk 的引用,回答可验证
  • 低 temperature 降低随机性;必要时用小模型先过滤一遍答案

第三层:评估侧(验证)

  • 用 RAGAS 这类框架做自动化评估,核心指标两个:忠实度(Faithfulness)——回答的每个事实是否被检索上下文支持;上下文相关性(Context Relevance)——检索到的内容对回答问题有没有用
  • 线上人工标注 + 离线回归,检索和生成两个环节分别打分,出了问题能定位到环节

面试金句:幻觉不是模型的错,是「检索没给够」或「生成没对齐」——治理幻觉的本质,是让模型只能「照着材料说」,材料没有的,宁可说不知道。

六、面试回答模板​

按这个顺序答,逻辑闭环:

  1. 先给全链路:离线索引(解析 → 切块 → Embedding → 向量库)+ 在线问答(查询 Embedding → 混合检索 → RRF 融合 → cross-encoder 重排 → 拼 Prompt → 生成),并说清 RAG 和微调的分工。
  2. 再讲切块:检索单元对齐答案粒度,256 到 512 token 起步,父子分块 + 元数据注入是生产标配。
  3. 索引与检索:HNSW 默认首选(多层图、efSearch 旋钮),混合检索 BM25 + 向量 + RRF 因为纯向量对精确匹配不敏感,cross-encoder 重排因为能看到 token 级交互。
  4. 幻觉治理:检索侧防(切块、重排、改写)、生成侧约束(只答检索内容、引用溯源)、评估侧验证(忠实度指标)。
  5. 收尾金句:RAG 的本质是把模型的记忆外包给可检索的知识库——幻觉治理的本质,是让模型只能「照着材料说」。

明日预告:后端/分布式方向 ——「接口幂等:重复支付、消息重投、请求重试,怎么保证同一操作只生效一次?」