1. 为什么RAG成了面试官手里的"筛子"
这两年但凡跟大模型沾边的岗位,RAG几乎成了必考题。我参与过几次团队招聘,也帮朋友做过模拟面试,发现一个很明显的现象:简历上写"熟悉RAG"的人一抓一大把,但真正能扛住连续追问的,十个里挑不出两个。很多人对RAG的理解停留在"把文档切块、向量化、检索、拼进Prompt"这条流水线上,一旦问到"切块策略怎么定""召回不准怎么排查""幻觉到底该从哪一层治",就开始含糊其辞。
这就是所谓的"RAG面试6连问"的由来——它不是真的只问6个问题,而是面试官会沿着一条逻辑链,从原理一路问到优化,层层递进,直到把你的知识边界探出来。能答到第三层的人算及格,能答到第五层的人基本可以进核心团队。这篇文章我想把这条追问链完整拆开,把每一层面试官真正想听的东西、以及我踩过的坑和总结的答法都讲清楚。不管你是准备面试,还是正在项目里落地RAG,这些内容都能直接拿去用。
先说清楚RAG到底解决什么问题。大模型的参数里冻结的是训练截止那一刻的知识,它不知道你公司内部的文档、不知道昨天的新闻、更不知道你私有的业务数据。微调能注入知识,但成本高、更新慢、还容易灾难性遗忘。RAG的思路很直接:不改模型,把外部知识放在一个可检索的库里,用户提问时先检索出相关片段,再连同问题一起喂给模型,让模型"看着材料答题"。这个思路听起来简单,但工程上每一个环节都有讲究,而面试官问的就是这些讲究。
我见过太多候选人把RAG讲成一个线性流程就结束了,这恰恰是最大的问题。真实的RAG系统是一个有反馈、有取舍、有大量工程细节的系统,面试官想确认的是你有没有真正在生产环境里跑过、调过、被坑过。下面我按面试官最可能的追问顺序,一层一层往下拆。
2. 第一层追问:RAG的基本链路和它到底在治什么病
2.1 把链路讲清楚只是及格线
面试官第一个问题通常是"讲讲你对RAG的理解"。这个问题看似送分,其实是在筛人。流水账式的回答——"文档切块、embedding、存向量库、检索top-k、拼prompt、生成"——只能说明你看过教程。真正加分的答法是:先点明RAG的本质是"用检索增强生成,把参数化知识换成非参数化知识",然后指出这条链路里有两个独立的失败点:检索没召回对,或者召回了但模型没用对。
我一般会这样组织回答:RAG的核心矛盾是"知识的外部化"和"上下文窗口的有限性"之间的张力。外部知识库可以无限大,但能塞进Prompt的上下文有限,所以整个系统的设计目标就是——在有限的上下文预算里,塞进最相关、最不冗余、最能让模型答对的那部分内容。检索负责"找得全",重排负责"排得准",生成负责"用得对",三者缺一不可。
这个回答的好处是,它把RAG从"一条流水线"升级成了"一个有明确优化目标的系统",面试官立刻能感觉到你不是背概念,而是理解设计意图。
2.2 检索增强和微调不是二选一
紧接着的高频追问是"RAG和微调有什么区别,什么时候用哪个"。很多人会背"RAG管知识、微调管风格",这个说法对但不完整。我的答法是分三个维度看:
| 维度 | RAG | 微调 |
|---|---|---|
| 知识更新 | 改库即可,实时 | 需重新训练,滞后 |
| 成本 | 推理时增加检索开销 | 训练成本高,推理便宜 |
| 能力改变 | 只改"知道什么" | 可改"怎么表达、怎么推理" |
| 可解释性 | 能溯源到原文片段 | 黑盒,难溯源 |
| 数据需求 | 只需文档 | 需要高质量标注对 |
关键结论是:如果需求是"让模型知道最新/私有的事实",优先RAG;如果是"让模型学会某种输出格式、语气、或特定推理模式",优先微调;两者可以叠加,先用微调对齐风格,再用RAG补知识。我实际项目里最常见的是纯RAG,因为业务知识更新太频繁,微调根本追不上。
2.3 一个容易被忽略的点:RAG治不了所有幻觉
面试官很爱在这里挖坑:"有了RAG是不是就没有幻觉了?"如果你答"是",基本就凉了。正确答案是:RAG能显著降低"事实性幻觉",但治不了"忠实性幻觉"。也就是说,即使你把正确材料喂给模型,它仍可能编造材料里没有的内容,或者错误地拼接多个片段。
原因在于模型的生成是概率性的,它倾向于生成"流畅"而非"忠于原文"的内容。所以RAG之后还需要一层"忠实性约束",比如在Prompt里明确要求"只依据给定材料回答,材料没有就说不知道",或者用后置的校验模型去核对答案和原文的一致性。这一点能答出来,面试官会认为你真正跑过线上系统。
3. 第二层追问:切块、向量化和检索的工程细节
3.1 切块策略:为什么固定长度是个陷阱
"你的文档怎么切块?"这是第二层的开场。新手答"按500字切",老手会告诉你固定长度切块是最容易埋雷的做法。原因很简单:固定长度会把一个完整的语义单元拦腰截断,导致检索到的片段"半截话",模型拿到残缺信息自然答不准。
我实际用的策略是分层切块:先按文档的自然结构(标题、段落、列表)切,保证每个块是一个语义完整的单元;如果某个块太长超过阈值,再按句子边界二次切分,并保留一定的重叠(overlap)。重叠的作用是防止关键信息正好落在切缝上。重叠比例一般取块大小的10%到20%,太小没效果,太大则冗余严重、浪费上下文预算。
还有一个细节是元数据的保留。每个块除了文本本身,还要带上来源、标题路径、页码等信息。这些元数据在检索时可以参与过滤,在生成时可以做引用溯源。我见过不少项目切块时把元数据丢了,后面想做"按章节过滤检索"就抓瞎。
3.2 向量化的坑:模型选型和归一化
"用什么embedding模型?"这个问题背后考的是你对向量空间的理解。不同模型产出的向量维度、语义侧重都不同,选型要看你的语料语言和领域。通用中文场景下,一些开源的中文优化模型表现就不错;如果是专业领域(比如法律、医疗),通用模型可能力不从心,需要考虑领域微调过的embedding。
一个特别容易被忽略的点是向量归一化。如果你用余弦相似度检索,向量必须归一化,否则内积和余弦会不一致,导致排序错乱。很多向量库默认帮你做了归一化,但如果你自己算相似度,一定要确认这一点。我踩过一次坑:换了向量库之后召回质量突然下降,排查半天发现是新库没自动归一化,而我的向量是未归一化的,内积计算把长向量排到了前面。
3.3 检索:top-k不是越大越好
"检索几个片段?"很多人答"top-5"或"top-10",但说不出为什么。top-k的本质是在"召回率"和"上下文预算"之间做权衡。k太小,可能漏掉关键信息;k太大,噪声变多,还会挤占上下文、增加推理成本,甚至让模型被无关内容带偏。
我的经验是:先用一个较大的k(比如20)做粗召回,再用重排模型精排,最后取top-3到top-5喂给生成模型。这样既保证了召回,又控制了噪声。另外,k的取值要结合块的大小——块小就多取几个,块大就少取几个,核心是控制总token数在模型上下文窗口的合理比例内,一般不超过窗口的1/3,给问题和回答留足空间。
4. 第三层追问:召回不准,你怎么一步步排查
4.1 先分清是"没召回"还是"没排对"
这是我认为最能区分候选人的一层。面试官问"召回不准怎么办",如果你直接答"换更好的embedding模型",说明你没有系统排查的思路。正确的第一步是定位问题:是相关文档根本没被检索出来(召回失败),还是检索出来了但排在后面(排序失败)?
定位方法很朴素但有效:拿一批有标准答案的query,人工标注每个query对应的正确文档块,然后看这些块在检索结果里的排名分布。如果正确块压根不在top-20里,那是召回问题;如果在top-20里但不在top-5,那是排序问题。这两类问题的解法完全不同,混在一起调就是瞎调。
4.2 召回失败的常见根因
召回失败我总结下来主要有四类原因。第一类是query和文档的语义鸿沟,用户问的是口语化问题,文档是书面语,embedding没对齐。解法是query改写或扩展,比如用模型把用户问题改写成多个不同表述再分别检索。第二类是切块把关键信息切碎了,正确信息分散在多个块里,单个块都不够相关。解法是调整切块策略或引入父块检索(检索小块,返回它所属的大块)。第三类是embedding模型不适合你的领域。第四类是向量库的索引参数设置不当,比如近似最近邻的搜索精度太低。
我特别想强调query改写这一招。实际业务里用户的提问方式千奇百怪,直接拿原始query去检索效果往往一般。我通常会让模型先把query扩展成3到5个语义相近但表述不同的版本,分别检索后合并去重,召回率能明显提升。这个技巧成本低、见效快,面试时说出来很加分。
4.3 排序失败:重排模型是标配
如果正确块在候选里但排名靠后,那就上重排。重排模型(reranker)和embedding模型的区别在于:embedding是双塔结构,query和文档分别编码,快但精度有限;重排是交叉编码,query和文档一起过模型,慢但准。所以标准做法是"双塔粗召回+交叉重排精排"。
重排的另一个好处是它可以用更细粒度的相关性判断,把"字面相关但语义无关"的块压下去。我实测下来,加了重排之后top-3的命中率通常能提升十几个百分点,是性价比最高的一步优化。唯一要注意的是重排会增加延迟,如果对响应时间敏感,要控制粗召回的候选数量,别一次重排几百个。
5. 第四层追问:生成阶段怎么让模型"说人话且不瞎编"
5.1 Prompt模板的设计有讲究
检索做得好,生成拉胯,整个系统照样废。生成阶段的核心是Prompt设计。我见过太多项目把检索到的片段直接拼接丢给模型,结果模型要么忽略材料自由发挥,要么被无关片段干扰。一个好的RAG Prompt模板应该包含几个要素:明确的角色设定、严格的使用材料指令、材料的分隔标记、以及"材料不足时的兜底话术"。
具体来说,我会在Prompt里明确写"请仅依据下方材料回答问题,材料中没有的信息不要编造,如果材料不足以回答,请直接说明"。然后用清晰的分隔符把每段材料包起来,并标注来源编号,方便模型引用。最后要求模型在回答时标注引用的材料编号,这样既提升了忠实性,又方便后续做溯源展示。
5.2 上下文顺序会影响模型注意力
这是一个很反直觉但实测有效的点:检索到的多个片段,拼接顺序会影响模型的利用效果。大模型存在"中间遗忘"现象,也就是对上下文开头和结尾的信息利用得更好,中间部分容易被忽略。所以如果有一个片段是最相关的,应该把它放在开头或结尾,而不是夹在中间。
我的做法是把重排后得分最高的片段放在最前面,次高的放在最后,中间的按分数递减排列。这个细节很多教程不会讲,但在实际调优时能带来可感知的提升。面试时如果能主动提到这一点,面试官基本会认定你是真跑过系统的。
5.3 引用溯源:让答案可验证
生成阶段还有一个加分项是引用溯源。让模型在给出答案的同时,标注每个结论来自哪个材料片段。这不仅是产品体验问题,更是调试利器——当答案出错时,你能快速判断是检索错了还是生成错了。实现上可以在Prompt里要求模型输出结构化的引用标记,然后在后处理阶段把标记替换成可点击的来源链接。
我实际项目里,引用溯源功能上线后,用户对系统的信任度明显提升,因为他们可以自己核对答案依据。同时它也倒逼模型更谨慎,因为一旦编造,引用就对不上,很容易被发现。
6. 第五层追问:性能、成本和评估怎么平衡
6.1 延迟优化:每一毫秒都要抠
到了这一层,面试官开始关心工程落地。RAG的延迟主要来自三块:检索、重排、生成。生成通常是大头,但检索和重排也不能忽视。优化手段包括:向量检索用近似最近邻索引(如HNSW)替代暴力搜索;重排只对粗召回的前若干条做,不要全量重排;embedding和重排模型做批处理;对高频query做结果缓存。
我踩过的一个坑是:一开始为了追求召回质量,粗召回取了100条做重排,结果单次请求延迟飙到好几秒。后来把粗召回降到30条,重排后取top-5,质量几乎没降,延迟却降了一大半。这说明很多优化不是"越多越好",而是要找到性价比拐点。
6.2 成本控制:token就是钱
RAG的成本主要是token消耗,包括embedding的计算、重排的计算、以及生成时喂进去的上下文。控制成本的核心是"别把没用的东西塞进上下文"。具体做法:重排后严格取top-k,不要贪多;对材料做去重,避免相似片段重复占用预算;对超长材料做摘要压缩后再喂给模型。
还有一个容易被忽略的成本点是embedding的重复计算。如果文档库更新频繁,每次全量重新embedding非常浪费。正确做法是增量更新,只对新文档和修改过的文档重新计算,用文档ID做去重和版本管理。
6.3 评估:没有评估就没有优化
"你怎么知道你的RAG变好了?"这个问题能问倒一大片人。没有评估体系,所有优化都是拍脑袋。RAG的评估要分两层:检索层看召回率、命中率、MRR等指标;生成层看答案的忠实性、相关性、完整性。检索层可以用标注数据自动算,生成层则往往需要人工评估或用一个强模型做裁判。
我建议至少维护一个几十到上百条的评测集,覆盖典型问题和边界情况,每次改动后跑一遍,看指标是涨是跌。这个习惯能帮你避免"改了一个地方,修好了A却弄坏了B"的尴尬。评测集不用一开始就很大,但要持续积累,把线上发现的bad case不断加进去。
7. 第六层追问:那些让候选人翻车的开放题
7.1 多跳问题和多轮对话怎么处理
开放题往往从这里开始。"用户的问题需要综合多个文档才能回答,怎么办?"这就是多跳问题。单次检索可能只召回部分信息,解法是迭代检索:先检索一轮,让模型判断信息是否足够,不够就基于已有信息生成新的查询再检索一轮,如此往复。这本质上是把RAG和Agent的思路结合起来。
多轮对话的难点在于query改写。用户第二轮问"那它的价格呢",这个"它"指代的是上一轮的话题,直接拿这句话去检索肯定召回不到东西。所以需要先用对话历史把当前query改写成独立完整的查询,再去做检索。这一步不做,多轮场景的体验会非常差。
7.2 知识库冲突和时效性怎么处理
"如果检索到的两个片段互相矛盾怎么办?"这是个很现实的问题,尤其当知识库有多个来源或历史版本时。我的处理原则是:优先信任更新的、更权威的来源。实现上可以给每个片段打上时间戳和来源权重,在重排时把这些因素纳入打分。同时在Prompt里可以提示模型"如材料存在冲突,请指出并优先采用较新的信息"。
时效性还涉及一个策略问题:有些知识是"会过期的",比如价格、政策;有些是"稳定的",比如原理、定义。对会过期的知识,检索时要加时间过滤,避免召回陈旧信息。这个分类意识能体现你对业务的理解深度。
7.3 安全与权限:别让RAG泄露数据
最后一个高频开放题是权限控制。企业知识库往往有权限分级,不同用户能看的内容不同。如果RAG不做权限过滤,A用户可能通过提问检索到B用户才能看的文档,这是严重的安全事故。解法是在检索阶段就做权限过滤,把用户权限作为元数据过滤条件传给向量库,确保召回结果只包含该用户有权访问的片段。
这个点很多人会忽略,但在企业级RAG里是硬性要求。面试时主动提到权限过滤,会让面试官觉得你有生产环境的意识,而不是只做过demo。
8. 我踩过的坑和几条实在的建议
聊完这六层追问,我想再分享几个只有真正落地过才会知道的教训。第一个坑是"过度迷信embedding模型"。我早期遇到召回问题就想着换模型,后来发现大部分问题其实出在切块和query改写上,换模型带来的提升远不如把切块策略调对。所以排查顺序应该是:先看切块,再看query,再看检索参数,最后才考虑换模型。
第二个坑是"忽略bad case的积累"。上线初期我总觉得系统还行,直到把用户实际问的问题收集起来一看,才发现大量query的表述方式跟我测试时用的完全不一样。从那以后我养成了习惯:所有低分回答和用户点踩的case都记录下来,定期分析,这些真实数据比任何凭空设计的测试集都有价值。
第三个建议是"别追求一步到位"。RAG系统是可以渐进式优化的,先跑通基础链路,再加重排,再加query改写,再加评估体系。每一步都验证效果,别一次性堆一堆优化上去,否则出了问题根本不知道是哪个环节导致的。我见过团队一上来就上最复杂的架构,结果调不动、维护难,最后反而回退到简单方案。
最后一个体会是关于面试的:面试官问RAG,不是想听你把概念背一遍,而是想通过你的回答判断你有没有"系统思维"和"工程手感"。所以回答时多讲"为什么这么选""我当时遇到了什么问题""怎么定位和解决的",比罗列技术名词有用得多。哪怕你只做过一个小项目,只要能把里面的取舍和踩坑讲透,就比背了一堆论文但没动过手的人更有说服力。