1. RAG 面试为什么成了技术岗的“必考题”
这两年只要简历上写了“大模型应用”“知识库问答”“智能客服”这类关键词,面试官几乎一定会往 RAG 上引。原因不复杂:微调成本高、周期长,而 RAG 能在不改模型权重的前提下,把私有知识、实时数据、领域术语接进生成流程,工程上落地快,业务上见效直接。所以面试官问 RAG,不是想听你背定义,而是想确认三件事——你懂不懂检索链路的瓶颈在哪、你能不能定位生成质量差的根因、你有没有真正调过参数而不是只会调 API。
我面过也被人面过,RAG 的提问基本逃不出六个方向:原理链路、切分策略、向量检索、召回优化、重排与生成、评估与迭代。这六问层层递进,从“是什么”问到“怎么优化”,从“能跑通”问到“跑得稳”。下面我按这六条线拆开讲,每一问都给出面试官真正想听的回答逻辑,以及我踩过的坑和实测有效的调参经验。不管你是准备面试,还是正在搭自己的知识库系统,这套内容都能直接拿去用。
2. 第一问:RAG 的完整链路到底是什么
2.1 别只背“检索+生成”,要讲清数据流
很多人回答 RAG 就是“先检索文档,再让模型生成”,这句话没错但太浅。面试官想听的是离线索引和在线查询两条链路的分工。离线阶段负责把原始文档变成可检索的向量:文档解析、清洗、切分、向量化、入库。在线阶段负责把用户问题变成答案:查询改写、向量化、召回、重排、拼装上下文、生成、后处理。这两条链路是解耦的,离线做得好,在线才稳;离线偷懒,在线怎么调都救不回来。
我习惯用一个类比:离线索引像图书馆编目,在线查询像读者找书。编目做得粗,书放错架,读者再聪明也找不到。所以面试时我会先画这条数据流,再强调“检索质量的上限由离线索引决定,生成质量的下限由上下文拼装决定”。这句话一说,面试官就知道你分得清主次。
2.2 每一环的输入输出要能说清楚
面试官常追问“切分完的 chunk 长什么样”。你要能答出:每个 chunk 通常包含文本内容、元数据(来源、页码、标题层级)、向量、唯一 ID。元数据不是装饰,它决定了后面能不能做过滤、能不能溯源、能不能按来源加权。我见过有人只存文本和向量,结果线上要按部门过滤时只能全量召回再筛,性能直接崩。
在线链路里,查询改写是容易被忽略的一环。用户问“上季度华东区退货率”,直接拿这句去检索,向量可能匹配不到“退货率统计表”这种标题。所以要先做查询扩展或改写,把口语问题转成更接近文档表述的形式。这一步做不做,召回率能差 20% 以上,我在实际项目里反复验证过。
注意:面试时如果被问“RAG 和微调怎么选”,别答“RAG 更好”。正确逻辑是——知识频繁更新、需要溯源、数据敏感不能进训练,选 RAG;要改变模型风格、语气、推理格式,选微调;两者可以叠加,RAG 管知识,微调管表达。
3. 第二问:文档切分为什么是 RAG 的第一道生死线
3.1 切分粒度直接决定召回精度
切分是 RAG 里最不起眼但最致命的环节。切太大,一个 chunk 里混了好几个主题,向量被平均掉,检索时“什么都沾一点,什么都不准”;切太小,语义不完整,模型拿到半句话没法回答。我实测下来,中文技术文档按 300 到 500 字切分,配合 10% 到 15% 的重叠,是比较稳的起点。重叠的作用是防止关键句被切断,比如一个定义跨了两个 chunk,重叠能让它至少完整出现在其中一个里。
但固定长度切分是懒人做法。更好的策略是按语义边界切:优先在段落、标题、列表项处断开。Markdown 文档可以按标题层级切,代码文档按函数切,合同按条款切。我做过一个对比,同一份产品手册,固定长度切分的召回准确率大概 68%,按标题层级切分能到 82%。差距就在“语义完整性”这四个字上。
3.2 元数据补全比切分本身更容易被忽视
切分完别忘了给每个 chunk 补元数据。我通常至少补这几项:来源文件名、章节标题、页码或位置、文档类型、更新时间。这些字段在检索时能做过滤,在生成时能做引用,在排查时能做定位。有一次线上回答引用了过期文档,就是靠“更新时间”字段做过滤才修好的。
还有个技巧:给每个 chunk 前面拼一句上下文摘要,比如“本文档是 XX 产品的退货政策,以下内容属于第三章”。这句话会一起被向量化,能显著提升检索时的语义匹配度。这个做法在长文档场景下特别有效,相当于给每个片段加了个“自我介绍”。
| 切分策略 | 适用场景 | 召回准确率(实测参考) | 主要风险 |
|---|---|---|---|
| 固定长度 300-500 字 | 通用文本、新闻 | 65%-70% | 语义被切断 |
| 按段落切分 | 结构清晰的文档 | 72%-78% | 段落过长时仍会混主题 |
| 按标题层级切分 | 手册、规范、技术文档 | 80%-85% | 依赖文档结构质量 |
| 按语义聚类切分 | 长文、论文 | 82%-88% | 计算成本高、实现复杂 |
实操心得:切分参数没有万能值,必须拿真实问题集去测。我一般准备 50 到 100 条真实用户问题,跑一遍召回,看 Top5 里有多少包含正确答案,这个指标比任何理论都靠谱。
4. 第三问:向量检索的原理和选型怎么答
4.1 向量化的本质是语义压缩
面试官问“向量检索原理”,你可以从嵌入模型把文本映射到高维空间讲起:语义相近的文本,向量距离近;语义远的,距离远。检索就是算查询向量和文档向量的相似度,通常用余弦相似度。这里要强调一点:向量维度不是越高越好。768 维和 1536 维在多数中文场景下差距不大,但存储和计算成本差一倍。我一般先用 768 维跑基线,效果不够再升维。
嵌入模型的选择要看语言和领域。中文场景优先选中文语料训练充分的模型,通用模型在专业术语上往往表现一般。如果领域术语特别多,比如医疗、法律,可以考虑用领域数据做轻量微调,或者用混合检索来补——向量管语义,关键词管精确匹配,两者结合比单用向量稳得多。
4.2 相似度计算和索引结构要能说清
相似度计算常见三种:余弦相似度、点积、欧氏距离。归一化之后,余弦和点积等价,所以很多系统直接做归一化再用点积,省一次计算。索引结构方面,小数据量用暴力检索就行,几万条以内延迟可以接受;上百万条就得上近似最近邻索引,比如基于图的 HNSW 或基于量化的 IVF。HNSW 召回高但内存吃得多,IVF 省内存但需要调 nprobe 参数平衡速度和精度。
我踩过的一个坑:索引参数和召回率强相关,但很多人上线后从不调。HNSW 的 efSearch 参数调大,召回率上升、延迟增加;调小则相反。线上要根据 QPS 和延迟要求动态权衡。我一般先在测试集上画出“召回率-延迟”曲线,选一个拐点作为线上配置,而不是拍脑袋定值。
5. 第四问:召回效果差怎么优化
5.1 先定位是“没召回”还是“召回错”
召回优化最忌讳上来就换模型。正确做法是先做归因分析:拿一批 bad case,看正确答案到底在不在召回结果里。如果不在,是“没召回”,问题出在切分、向量化或查询改写;如果在但排得靠后,是“召回错”,问题出在排序或相似度计算。这两类问题的解法完全不同,混在一起调就是瞎调。
没召回的情况,我通常按这个顺序排查:查询改写有没有做、切分粒度是否合适、嵌入模型是否匹配领域、索引参数是否过严。召回错的情况,重点看重排和加权。我做过一个项目,正确答案 90% 都在 Top20 里,但不在 Top5,加了一个轻量重排模型后,Top5 命中率从 55% 提到 78%。所以先保证召回池够大,再用重排提精度,这个思路比死磕向量模型有效得多。
5.2 混合检索和查询扩展是两把利器
混合检索就是把向量检索和关键词检索的结果融合。关键词检索用 BM25 这类算法,对专有名词、编号、代码特别敏感,正好补上向量的短板。融合方式有加权求和和倒数排名融合,我一般用后者,因为它不依赖分数归一化,更鲁棒。实测在技术文档场景,混合检索比纯向量检索的 Top5 命中率高 15 到 20 个百分点。
查询扩展则是从问题侧下手。常见做法有同义词扩展、假设文档生成、多查询生成。假设文档生成是先让模型根据问题编一个“理想答案”,再拿这个答案去检索,因为答案和文档的表述风格更接近。这个方法在问答场景效果明显,但会增加一次模型调用,延迟敏感的场景要权衡。
注意:优化召回时一定要有评估集。没有评估集的优化就是盲调,今天调好了明天可能又坏了。评估集不用大,100 条真实问题加标准答案就够,关键是持续维护。
6. 第五问:重排和上下文拼装怎么做才不浪费 token
6.1 重排是精度和成本的平衡术
重排模型比嵌入模型重,但比生成模型轻。它的作用是拿查询和每个候选 chunk 做精细打分,把最相关的排到前面。常见的有基于交叉编码器的重排,精度高但慢;也有基于轻量模型的,快但精度一般。我的经验是:召回池 20 到 50 条时,加重排收益最大;召回池只有 5 条,重排意义不大;召回池上百条,重排延迟会拖垮整体响应。
重排之后要截断,只把 Top3 到 Top5 塞进上下文。塞太多不是好事:一是 token 成本上升,二是无关内容会干扰生成,三是模型对长上下文的注意力会稀释。我实测过,同样的问题,塞 3 条相关 chunk 和塞 10 条(含无关),答案质量前者反而更高。所以宁缺毋滥是上下文拼装的第一原则。
6.2 上下文拼装要讲顺序和格式
拼装顺序有讲究。我一般把最相关的放最前面,次相关的放最后,因为模型对开头和结尾的注意力更强,中间容易忽略。每条 chunk 之间加清晰的分隔符和来源标注,方便模型区分,也方便后面做引用。格式上,我会用类似“来源:XX文档 第X节”这样的前缀,生成时模型就能自然地带上出处。
还有一个细节:上下文里要保留必要的元信息,但不要塞无关字段。比如页码有用,文件大小没用;章节标题有用,创建人没用。拼装前做一次字段裁剪,能省不少 token。我见过有人把整个 JSON 元数据塞进去,token 直接翻倍,纯属浪费。
| 拼装策略 | Token 消耗 | 答案质量(实测) | 适用场景 |
|---|---|---|---|
| Top3 相关 chunk | 低 | 高 | 大多数问答场景 |
| Top5 相关 chunk | 中 | 高 | 复杂问题、多跳推理 |
| Top10 含无关 chunk | 高 | 中低 | 不推荐 |
| 全量召回拼接 | 极高 | 低 | 禁止 |
7. 第六问:RAG 系统怎么评估和持续迭代
7.1 评估要分模块,不能只看最终答案
RAG 评估最大的误区是只看生成答案好不好。答案差,可能是检索没召回,也可能是生成没用好上下文。所以要分模块评估:检索侧看召回率、命中率、MRR;生成侧看忠实度、相关性、完整性。检索侧有标准答案可对比,相对客观;生成侧需要人工或模型打分,成本高但必要。
我常用的做法是建一个分层评估集:简单事实题、多跳推理题、否定题、时效题各占一部分。简单题看基础能力,多跳题看检索深度,否定题看模型会不会胡编,时效题看更新机制。每类题单独统计,才能定位到具体环节。只用一个总分,出了问题根本不知道从哪修。
7.2 迭代要有节奏,别频繁大改
RAG 系统上线后,迭代节奏很重要。我的经验是小步快跑,一次只改一个变量。今天调切分,明天调重排,后天换模型,最后效果变好了也不知道是谁的功劳,变差了也找不到原因。正确做法是每次只改一个环节,用评估集验证,有效再保留,无效就回滚。这样积累下来,每个参数的最优值都有据可查。
另外要建立bad case 回流机制。线上用户反馈的差答案,定期收集起来,人工标注后加入评估集。这样评估集会越来越贴近真实场景,优化方向也不会跑偏。我维护的一个评估集,从最初 80 条涨到 500 多条,覆盖了各种边界情况,后面每次改动都能快速验证,效率比盲调高太多。
实操心得:RAG 没有“调完”的一天。文档在变、用户在变、问题在变,系统必须持续迭代。把评估和回流做成常规流程,比一次性调优重要得多。
8. 面试现场的几个真实应对技巧
面试官问 RAG,很多时候不是要标准答案,而是想看你的思考过程。遇到不会的,别硬编,可以说“这块我实际项目里没深入调过,但我的思路是……”。面试官更在意你有没有排查问题的框架,而不是背了多少名词。
还有一点:准备一两个自己踩过的坑。比如“我遇到过召回率突然下降,最后发现是文档更新后没重建索引”,这种真实案例比任何理论都有说服力。它证明你真正跑过系统,而不是只看过文章。我每次面试都会准备两三个这样的故事,讲到细节时面试官往往会顺着追问,节奏就掌握在自己手里了。
最后,RAG 的六个问题其实是连在一起的:原理链路是骨架,切分和检索是入口,召回和重排是精度,评估和迭代是保障。把这六块串成一条线讲,比零散回答每个问题更有整体感。面试官听完会觉得你不仅懂点,还懂面,这才是真正拉开差距的地方。