hello 我是逆境
阿杰入职第一周,主管给了他一个听起来很简单的任务:
“把公司的产品手册、售后规则和内部 FAQ 喂给大模型,做个知识助手。”
阿杰心想,这有什么难的?把问题发给模型不就行了。
半小时后,演示开始。主管问:“星河 Pro 路由器保修几年?”
模型回答:“提供三年全国联保。”
语气很稳,措辞很专业,唯一的问题是公司规定明明写着一年。会议室安静了几秒,主管问:“这三年是从哪儿来的?”
模型当然说不出来。它只是根据语言规律,拼出了一个听上去最像答案的句子。
这正是 RAG 登场的地方。
本文不把 RAG 拆成几十个孤零零的名词。我们会跟着阿杰,从第一次错误回答开始,经历文档解析、切块、向量检索、混合检索、重排、评测、权限隔离和线上故障。故事中的每一个坑,都是面试官爱问的一道题。
每个重点后面都有一段“面试时可以这样答”。理解故事之后再背这几句话,会轻松很多。
先看地图:RAG 到底在忙什么
在动手之前,先记住两条流水线。
第一条发生在用户提问之前,负责整理资料:
原始文档 ↓ 解析与清洗 ↓ 切成小块 Chunk ↓ 生成 Embedding ↓ 写入搜索索引或向量数据库第二条发生在用户提问之后,负责寻找证据并组织答案:
用户问题 ↓ 查询理解与改写 ↓ 关键词检索 + 向量检索 ↓ 融合与重排 ↓ 选出少量证据 ↓ 交给大模型生成带引用的回答前一条通常叫索引链路、摄取链路或离线链路,后一条叫查询链路、推理链路或在线链路。
面试里不少问题看似花哨,其实只是在问:这一步为什么放在这里?它解决了哪一种错误?
第一幕:模型会说话,但它不知道公司的事
1. 什么是 RAG?
RAG 的全称是 Retrieval-Augmented Generation,中文叫检索增强生成。
名字有点长,做的事倒很朴素。模型回答之前,系统先去指定的知识库里找资料,再把资料和问题一起交给模型。模型不再只靠训练时记住的内容,而是拿着一份“开卷材料”回答。
还是刚才的保修问题。没有 RAG 时,模型只能猜;有了 RAG,输入会变成这样:
用户问题:星河 Pro 路由器保修几年? 参考资料: 《星河 Pro 售后政策 2026-04 版》第 3 条: 整机自购买之日起享受一年有限保修。 请仅根据参考资料回答,并给出出处。这时模型更容易给出“一年保修”,还能告诉用户依据在哪。
面试时可以这样答:RAG 是先从外部知识库检索与问题相关的内容,再把检索结果作为上下文交给大模型生成答案。它适合补充私有知识和频繁更新的知识,也方便提供引用。RAG 能降低幻觉,但效果取决于文档质量、检索质量和生成约束。
2. 一套完整的 RAG 有哪些环节?
阿杰最初只说了三个词:“向量化、检索、生成。”
面试官如果继续问“文档怎么更新”“答案怎么评测”“不同部门的权限怎么办”,这三个词就不够用了。
一套能上线的 RAG,大致包含这些环节:
离线: 数据采集 → 文档解析 → 清洗去重 → 切块 → 元数据补充 → Embedding → 建立索引 → 增量更新 在线: 问题理解 → 查询改写/拆分 → 多路检索 → 结果融合 → Rerank → 上下文组装 → LLM 生成 → 引用与事实检查 保障: 离线评测 → 线上监控 → 用户反馈 → 回归测试 → 发布与回滚不用把所有步骤塞进一次回答。先讲离线和在线两条链路,面试官追问哪里,再往哪里展开。
面试时可以这样答:RAG 分为离线索引和在线问答两条链路。离线负责文档解析、切块、向量化和建索引;在线负责查询理解、召回、融合、重排、上下文构造和答案生成。生产系统还要补上增量更新、权限过滤、评测、监控和降级。
3. RAG 为什么能减少幻觉,却不能消灭幻觉?
第二次演示时,知识助手不再乱编保修期了,但它又出了一个新问题。
知识库里同时存在 2024 年和 2026 年的售后政策。检索器把旧版本排在前面,模型老老实实引用了旧规定。它没有凭空编造,答案还是错了。
RAG 只是给模型加了证据,不会自动保证:
- 证据本身正确;
- 正确证据一定被召回;
- 召回结果没有过期或冲突;
- 模型一定忠实使用证据。
幻觉治理要沿着整条链路排查。有时错在模型,有时根本轮不到模型背锅。
面试时可以这样答:RAG 通过外部证据约束生成,因此能减少知识缺失导致的幻觉,但不能彻底消除。错误仍可能来自脏数据、错误切块、漏召回、错误排序、上下文冲突和模型误读。治理时要分别评估检索与生成,不能只靠 Prompt 写一句“不要幻觉”。
4. RAG 和微调有什么区别?
主管问:“既然模型不知道售后规则,为什么不拿公司文档微调一次?”
因为“知道什么”和“怎么做事”不是同一个问题。
RAG 更像给员工一本随时更新的手册;微调更像培训员工形成某种工作习惯。今天售后政策改了,替换知识库文档就行。如果把政策写进模型参数,每次更新都重新训练,成本高,也很难确认模型到底记住了哪个版本。
| 对比项 | RAG | 微调 |
|---|---|---|
| 主要解决 | 缺少外部知识 | 行为、风格或特定任务能力不足 |
| 更新知识 | 更新索引即可 | 通常需要重新准备数据和训练 |
| 引用来源 | 容易实现 | 很难追溯参数里的知识来源 |
| 常见用途 | 企业问答、资料检索 | 分类、格式遵循、领域表达 |
两者可以一起用。例如,用微调后的模型负责稳定输出格式,再用 RAG 提供公司知识。
面试时可以这样答:RAG 主要解决知识注入和知识更新问题,微调主要改变模型的行为模式或特定任务能力。频繁变化、需要引用的事实更适合 RAG;稳定的输出风格、分类规则和领域任务可以考虑微调。实际项目可以组合使用。
5. 模型上下文已经很长了,为什么还需要 RAG?
有人会说:“现在模型能读几十万 Token,把资料全塞进去不就行了?”
如果只是临时总结三份合同,这么做很省事。可公司的资料有几十万份,还在不断变化。每次都把全部文档发给模型,费用和等待时间都很难接受,权限也不好控制。
更麻烦的是,模型并不会均匀注意上下文中的每一句话。关键证据埋在长文本中间时,可能被忽略,这就是常说的 Lost in the Middle。
比较现实的方案是先检索,把资料缩到少量相关片段,再让长上下文负责综合和推理。
面试时可以这样答:长上下文适合文档少、单次输入边界明确的任务;RAG 适合大规模、频繁更新且需要权限过滤的知识库。长上下文仍有 Token 成本、延迟和中间信息被忽略的问题。工程上通常先检索缩小范围,再利用长上下文完成推理。
第二幕:先把公司的资料整理成一座图书馆
模型愿意查资料了,下一步是让资料“查得到”。
阿杰把产品手册直接按整篇文档写进向量库。结果用户问一个端口参数,检索器返回了整本 180 页的说明书。相似是相似,没法用。
6. Embedding 是什么?
计算机不能直接拿两段中文比较“意思像不像”。Embedding 模型会把文本转换成一串数字,也就是高维向量。语义相近的文本,向量通常也更接近。
例如:
“如何办理退款” “退货后货款怎么退”它们用词不同,向量距离却可能很近。
RAG 建库时会计算文档块的向量;用户提问时再计算问题向量,然后寻找附近的文档块。
面试时可以这样答:Embedding 是把文本映射到高维向量空间的语义表示方法。RAG 会预先计算文档块向量,查询时计算问题向量,再通过相似度搜索召回相关内容。Embedding 负责表示和匹配语义,不负责生成答案。
7. 余弦相似度、点积和欧氏距离有什么区别?
三种方式都能衡量向量之间的接近程度,只是观察角度不同。
余弦相似度看方向是否一致:
[
\cos(\theta)=\frac{A\cdot B}{|A||B|}
]
点积同时受方向和向量长度影响。欧氏距离看空间中的直线距离。很多 Embedding 模型会对向量做归一化;归一化以后,余弦相似度和点积的排序往往一致。
面试时别凭喜好选择距离函数。应先看 Embedding 模型的说明,再看向量库是否按同样的度量建索引。
面试时可以这样答:余弦相似度比较向量方向,点积还受模长影响,欧氏距离比较几何距离。若向量已经归一化,余弦和点积常得到相同排序。实际选择要与 Embedding 模型训练方式及索引配置一致。
8. 为什么要切块?
一份手册可能同时包含安装、联网、保修和故障排查。整篇文档只生成一个向量,相当于用一个坐标概括所有主题,表达会很模糊。
切成小块后,每个块只表达一个相对集中的意思。查询“红灯闪烁怎么办”时,系统可以直接命中故障排查中的那一段,而不是把整本手册搬过来。
切块也能节省大模型的上下文窗口。不过切块不是越碎越好。
面试时可以这样答:切块是为了提高检索粒度,让每个向量表达相对集中的语义,同时减少传给模型的无关内容和 Token 消耗。切块过大会稀释主题,过小会丢失上下文,所以需要结合文档结构和问题粒度调优。
9. Chunk 应该多大?
网上常见“500 字符加 50 字符重叠”之类的经验值。可以拿来做基线,但别把它背成标准答案。
想象两个知识库:
- 产品参数表里,一行就是一个完整事实;
- 法律合同里,一个条款要结合前后定义才能读懂。
它们显然不该使用相同的 Chunk 大小。
Chunk 太小时,检索很准,但证据残缺;太大时,上下文完整,噪声也跟着进来。合理做法是准备真实问题,尝试几种切法,比较 Recall@K、答案正确率、延迟和 Token 成本。
面试时可以这样答:Chunk 大小没有通用最优值。小块提高定位精度,但可能割裂语义;大块保留上下文,却会引入噪声并增加 Token。应根据文档结构、用户问题粒度和模型限制设置基线,再通过评测集确定。
10. Chunk overlap 有什么用?
假设一句话刚好跨过切分边界:
块 A:星河 Pro 自购买之日起…… 块 B:……享受一年有限保修。两个块单独看都不完整。Overlap 会让相邻块重复一小段内容,降低关键信息被一刀切断的概率。
代价也很直接:索引变大,重复结果变多,上下文里可能出现同一句话好几遍。按标题和段落做结构化切分时,往往不需要很大的重叠。
面试时可以这样答:Overlap 用于保留切块边界附近的上下文,避免完整语义被截断。重叠过大会增加索引体积、重复召回和 Token 消耗。它应与文档结构配合设置,而不是固定套用某个比例。
11. 常见的切块策略有哪些?
阿杰先用固定长度切块,很快发现标题被切到上一块,正文被切到下一块。检索结果只剩一句“适用范围如下”,但“如下”究竟是什么,没人知道。
常见策略大概有这些:
- 固定字符或 Token:实现最简单,适合作为基线。
- 递归切分:优先按标题、段落、句子切,超过长度再继续拆。
- 语义切分:检测语义变化的位置,主题切换时再切。
- 文档结构切分:按 Markdown 标题、合同条款、代码函数或表格行处理。
- 父子块切分:小块用于检索,大块用于提供完整上下文。
切块时要把标题路径带进内容或元数据。只保存正文,容易丢失“这一段属于哪个产品、哪个章节”。
面试时可以这样答:常见切块方式有固定长度、递归切分、语义切分和基于文档结构的切分。生产中应尽量保留标题、段落和表格等天然边界,并保存标题层级、页码和来源等元数据。不同类型文档可以使用不同策略。
12. 什么是 Parent-Child Retrieval?
售后手册中的一句话很容易命中用户问题,但单独拿出来又解释不清。阿杰于是保存了两套粒度:
子块:短,负责检索命中 父块:长,负责给模型完整上下文检索时先找到子块,再沿着parent_id取回对应的完整段落或章节。这也叫 Small-to-Big Retrieval。
它解决的是“找得准”和“看得全”之间的矛盾,但父块不能无限大,否则又回到整篇文档塞进 Prompt 的老问题。
面试时可以这样答:Parent-Child Retrieval 用较小的子块建立索引,以提高召回精度;命中后返回对应的较大父块,为生成保留完整上下文。可以概括为小块负责找得准,大块负责答得全。
13. 元数据有什么用?
一个 Chunk 不能只有正文和向量。阿杰还保存了这些信息:
{"document_id":"after-sales-policy","version":"2026-04","product":"星河 Pro","department":"售后部","page":7,"updated_at":"2026-04-12","acl":["sales","support"]}元数据可以用来过滤产品、部门和时间,也能生成准确引用。权限控制更离不开它。
向量相似度只回答“语义上像不像”,不会自动判断文档是否过期,也不知道提问者有没有查看权限。
面试时可以这样答:元数据用于过滤、排序、权限校验、版本管理和引用追踪。常见字段有文档 ID、标题路径、页码、更新时间、版本、租户和 ACL。语义检索解决相关性问题,业务约束通常由元数据过滤补充。
14. PDF、扫描件和表格为什么难处理?
阿杰收到一份双栏 PDF。解析器先读完左栏第一行,又跳到右栏第一行,然后回来读左栏第二行。最终文本像把两本书的句子交叉洗牌,Embedding 再好也救不了。
真实文档经常有这些问题:
- 扫描件只有图片,需要 OCR;
- 页眉、页脚和水印反复混入正文;
- 多栏排版导致阅读顺序错乱;
- 表格被拆成一堆失去行列关系的文字;
- 图片、公式和流程图没有文本描述。
表格可以转成保留表头的 Markdown、结构化 JSON,或者直接放进适合查询的数据库。复杂页面还可能需要版面分析或多模态模型。
面试时可以这样答:PDF 保存的常是视觉布局,不等于干净文本。RAG 摄取阶段要处理 OCR、多栏阅读顺序、页眉页脚、表格结构和图片信息。解析质量会直接决定检索上限,很多效果问题并不是向量模型造成的。
15. 文档更新后,向量索引怎么同步?
售后部更新了一份政策。阿杰直接把新版本写进向量库,却忘了删旧版本。第二天,同一个问题召回了两种答案。
稳妥的更新链路通常是:
检测文件变化 ↓ 根据内容哈希判断是否真的修改 ↓ 解析并生成新版本 Chunk ↓ 写入临时索引或新版本 ↓ 校验数量与质量 ↓ 切换生效,删除或归档旧版本系统还要处理文档删除、任务失败、重复消费和断点重试。每个 Chunk 最好能从稳定的文档 ID 和版本推导出来,这样更新才不会越写越乱。
面试时可以这样答:文档更新需要稳定 ID、版本号、更新时间和内容哈希。系统检测变更后,应删除或失效旧 Chunk,重新解析和向量化变更内容,再以幂等方式写入新版本。生产中还要监控索引新鲜度、失败重试和重复数据。
16. 什么是向量数据库?一定要专门的向量数据库吗?
向量数据库负责保存向量,并高效执行相似度搜索。它通常还提供元数据过滤、索引管理和分布式扩展。
但“做 RAG 必须上某个专用向量数据库”并不成立。数据量不大时,带向量扩展的关系数据库可能已经够用;已有搜索系统时,也可以在同一个引擎里做关键词和向量混合检索。
选择时看数据规模、延迟、过滤能力、混合检索、运维成本和团队已有技术栈。产品名字反而是最后考虑的事。
面试时可以这样答:向量数据库用于存储向量并执行近似最近邻搜索,通常也支持元数据过滤。RAG 不一定需要独立的专用向量库,关系数据库扩展或搜索引擎也能承担这项工作。选型要看规模、检索能力、过滤需求和运维成本。
17. HNSW 是什么?
如果每次查询都和库里的每个向量比较,数据一多就慢。HNSW 会把向量组织成多层近邻图:上层连接稀疏,适合快速跳到大致区域;下层连接更细,用来找到附近结果。
可以把它想成找一家店。先通过高速公路到城区,再走主干道,最后进入小巷,而不是从家门口开始挨家挨户比较。
常见参数有:
M:每个节点保留多少邻居,越大通常召回更好,也更占内存;efConstruction:建图时搜索多大范围,影响建库时间和索引质量;efSearch:查询时搜索多大范围,越大通常更准,也更慢。
面试时可以这样答:HNSW 是基于多层近邻图的近似最近邻算法。它通过上层快速导航、下层精细搜索,在召回率和查询速度之间取得平衡。M、efConstruction 和 efSearch 分别影响内存、建索引成本、查询召回与延迟。
第三幕:图书馆有了,检索器却总拿错书
用户输入:“设备报 E17 怎么办?”
向量检索返回了一篇《17 类常见网络故障》,因为它在语义上很像“错误处理”。真正写着 E17 的维修手册却排在后面。阿杰第一次意识到,语义检索也有明显短板。
18. BM25 和向量检索有什么区别?
BM25 关心词有没有出现、出现得多不多、这个词在全库里是否少见。错误码E17、订单号、型号和人名都很适合关键词检索。
向量检索关心语义是否相近。用户说“钱什么时候退回来”,文档写“退款到账周期”,没有完全相同的词,向量检索也可能把它们找出来。
简单记:
BM25:擅长字面精确匹配 向量检索:擅长语义近似匹配它们不是竞争关系。线上系统常常两种都要。
面试时可以这样答:BM25 是稀疏检索,根据词频、逆文档频率和文档长度计算相关性,适合专有名词和精确关键词。向量检索使用稠密语义表示,适合同义表达和自然语言问题。两者优势互补,因此常组合成混合检索。
19. 什么是混合检索?
阿杰让关键词检索和向量检索同时工作:
用户问题 ├── BM25 检索 Top-N └── 向量检索 Top-N ↓ 结果融合 ↓ Rerank ↓ 最终证据 Top-K这样既能命中E17,又能处理“连不上网”和“网络连接失败”这样的同义表达。
混合检索不是简单把两份结果首尾拼起来。两套检索分数的范围和含义不同,直接相加很容易失真,需要做归一化、加权融合或排名融合。
面试时可以这样答:混合检索并行执行关键词检索和向量检索,再融合两边候选结果。它兼顾精确词匹配与语义召回,通常比单一路径更稳定。融合可以使用归一化加权,也可以使用 RRF 这类基于排名的方法。
20. RRF 是什么?
RRF 的全称是 Reciprocal Rank Fusion,倒数排名融合。它不纠结两套系统的原始分数能不能比较,只看文档分别排第几。
[
score(d)=\sum_i \frac{1}{k+rank_i(d)}
]
如果某份文档在 BM25 和向量结果里都排得靠前,它的融合分数就会更高。只在某一路出现的文档也有机会保留。
RRF 的好处是简单、稳定,不需要先把 BM25 分数和余弦相似度强行拉到同一个尺度。缺点是它主要利用排名,没有充分使用原始分数差距。
面试时可以这样答:RRF 是一种基于名次的多路结果融合算法。它为文档在每个结果列表中的排名计算倒数分数,再求和得到最终排序。由于不直接比较不同检索器的原始分数,RRF 很适合融合 BM25 与向量检索结果。
21. Top-K 应该设多大?
阿杰把 Top-K 从 5 调到 50,召回率上去了,答案反而变差。原因不神秘:模型一次看到了十几段相似但不完全相关的说明,还有两个旧版本,真正的答案被挤在中间。
Top-K 太小会漏证据;太大会引入噪声、增加 Token 和延迟。常见做法是第一阶段多召回一些,比如 20 到 50 个候选,再经过重排压到 3 到 10 个。数字只是起点,不是行业标准。
面试时可以这样答:Top-K 需要在召回率、精度、延迟和上下文成本之间取舍。K 太小容易漏掉正确证据,太大会引入噪声。通常第一阶段宽召回,随后重排和截断,最终参数通过评测集与线上指标确定。
22. 什么是 Rerank?为什么检索后还要重排?
第一阶段检索面对几十万甚至上百万个 Chunk,首要任务是快。它用向量距离或 BM25 分数粗略筛选,不会把问题和每个文档做很深的比较。
Reranker 只处理几十个候选,可以更仔细地判断“这段话是否真的回答了这个问题”。
快速召回 Top-50 ↓ Reranker 精排 ↓ 保留 Top-5 给大模型重排通常能提高前几名的质量,但会增加一次模型调用。线上要给它单独设置超时;服务不可用时,可以降级使用原始检索顺序。
面试时可以这样答:第一阶段检索追求高效和高召回,初始排序不一定准确。Rerank 使用更强的相关性模型对少量候选做二次排序,再把前几个结果交给生成模型。它能提高精度,但要付出额外延迟和计算成本。
23. Bi-Encoder 和 Cross-Encoder 有什么区别?
向量检索常使用 Bi-Encoder。问题和文档分别编码:
问题 → 向量 A 文档 → 向量 B 比较 A 和 B文档向量可以提前算好,查询很快。代价是问题与文档在编码阶段没有直接“见面”。
Cross-Encoder 会把问题和候选文档一起送入模型,让每个词充分交互,相关性判断通常更细。它没法低成本扫描整个知识库,却很适合给几十个候选重排。
面试时可以这样答:Bi-Encoder 独立编码问题和文档,文档向量可预计算,适合大规模召回。Cross-Encoder 联合编码问题和文档,交互更充分、排序通常更准,但计算成本高。因此常见方案是 Bi-Encoder 召回,再用 Cross-Encoder 重排。
24. Query Rewrite 是什么?
用户在多轮对话中说:“那它支持七天无理由吗?”
检索器只看到这一句,根本不知道“它”是哪款产品。Query Rewrite 会结合聊天历史,把问题改成:
星河 Pro 路由器是否支持七天无理由退货?查询改写还可以补全缩写、统一术语、纠正明显错别字。但模型改写得太积极,也可能改变用户原意。比较稳妥的做法是保存原问题,必要时让原问题和改写问题一起参与检索。
面试时可以这样答:Query Rewrite 是把原始问题改写成更适合检索的独立查询,常用于消除多轮对话中的指代、补全上下文和统一术语。它能改善召回,也可能引入语义漂移,所以应保留原查询并用评测验证。
25. Multi-Query 和 Query Decomposition 有什么区别?
用户问:“比较星河 Pro 和云舟 X2 的价格、保修期以及对小户型的适用性。”
Multi-Query 会为同一个意图生成几种说法,目的是从不同表达角度多捞一些资料。
Query Decomposition 则把复杂问题拆成真正不同的子问题:
星河 Pro 的价格是多少? 云舟 X2 的价格是多少? 两款产品各自保修多久? 哪一款更适合小户型?前者主要解决表达差异,后者主要解决复杂问题。两种方法都会增加调用次数,还要处理重复结果和子问题之间的依赖。
面试时可以这样答:Multi-Query 为同一问题生成多个语义近似查询,提高表达层面的召回;Query Decomposition 把复杂问题拆成多个子问题,分别检索后再汇总。前者应对措辞差异,后者应对多条件或多跳问题。
26. HyDE 是什么?
用户只输入“E17”,信息少得可怜。HyDE 会先让模型生成一段假设性文档,例如“E17 表示设备认证失败,可检查账户绑定状态”,再用这段较完整的文本生成向量去检索。
为什么可能有效?知识库里存的是说明文,不是两个字的查询。假设性答案在语言形式上更像目标文档。
问题也在“假设”二字上。如果模型先猜错了方向,检索会跟着跑偏。因此 HyDE 更像一种可评测的召回技巧,不是默认必开的开关。
面试时可以这样答:HyDE 先根据问题生成假设性答案或文档,再对这段文本做 Embedding 并检索。它能缓解短查询与文档表达形式不一致的问题,但假设内容可能带来查询漂移,需要与原查询结合并通过评测决定是否使用。
27. 元数据过滤应该放在检索前还是检索后?
用户只想查“星河 Pro”,知识库里却有十几个产品。先查全库再把别的产品过滤掉,可能出现一种尴尬情况:Top-10 全是其他产品,过滤完一个结果都不剩。
如果向量库支持,应尽量把产品、租户、部门和权限条件放进检索过程,让搜索只在合法范围内进行。某些复杂规则无法下推时,才在召回后补充过滤,并适当扩大候选集。
权限过滤尤其不能只在答案生成后处理。敏感文本只要进入 Prompt 或日志,泄露就已经发生了。
面试时可以这样答:能下推到检索引擎的元数据和权限条件,应尽量在召回阶段过滤,避免无关结果占满 Top-K。无法下推的业务规则可以后过滤,但要扩大候选集并重新排序。安全权限不能只靠生成后脱敏。
第四幕:拿到证据不等于答对,还得建立一套判分方法
系统看起来已经能用了。可主管问了一个很现实的问题:“你说优化之后效果更好,好了多少?”
阿杰答不上来。他一直在凭感觉测试:随手问几个问题,觉得回答顺眼,就宣布版本通过。
这种方式很容易被几个漂亮案例骗过去。
28. 怎样让模型尽量只根据知识库回答?
先把规则写清楚:
只能依据给定资料回答。 资料不足时明确说明无法确认。 每个事实标注来源。 遇到冲突时展示冲突,不得自行猜测。但 Prompt 不是安全锁。真正稳妥的系统还会检查检索分数、验证引用是否支持答案、识别无证据主张,并给高风险问题设置人工审核。
如果模型根本没拿到正确资料,再严厉的 Prompt 也只能让它更礼貌地答错。
面试时可以这样答:可以通过限定回答范围、要求证据不足时拒答、强制引用和生成后事实检查来约束模型。同时要设置检索相关性门槛,验证答案主张是否得到上下文支持。Prompt 只是其中一层,不能替代检索质量和程序校验。
29. RAG 应该评估哪些指标?
不要只看“最终答案准确率”。先分清是检索没找到,还是模型拿到了证据却没用好。
检索层常看:
- Recall@K:标准证据有没有出现在前 K 个结果里;
- Precision@K:前 K 个结果里有多少真正相关;
- MRR:第一个正确结果排得有多靠前;
- NDCG:整体排序是否把高相关结果放在前面。
生成层常看:
- Faithfulness:答案中的主张能否由检索上下文支持;
- Answer Relevance:答案有没有正面回应问题;
- Answer Correctness:答案与事实或参考答案是否一致;
- 引用正确率和拒答准确率。
线上还要看用户反馈、任务完成率、延迟和成本。一个离线分数很高但每次等十五秒的客服,仍然不好用。
面试时可以这样答:RAG 要分层评估。检索侧可使用 Recall@K、Precision@K、MRR 和 NDCG;生成侧关注 Faithfulness、答案相关性、正确性、引用与拒答表现。生产中还要结合延迟、成本和用户反馈,避免只优化单一指标。
30. Faithfulness 和 Answer Correctness 有什么区别?
知识库中有一份错误旧文档,写着“保修三年”。模型严格照着它回答三年。
这个答案很忠实,因为每句话都有上下文支持,所以 Faithfulness 可能很高。但它与当前真实政策不符,Answer Correctness 很低。
反过来,模型也可能靠训练记忆碰巧答对“一年”,可检索上下文里没有任何依据。正确性看似不错,忠实度却差,这种答案很难让企业放心。
面试时可以这样答:Faithfulness 衡量答案是否得到检索上下文支持,Answer Correctness 衡量答案是否符合真实事实或参考答案。上下文本身过期时,答案可以忠实但不正确;模型脱离上下文碰巧答对时,也可能正确但不忠实。
31. 如何构建 RAG 评测集?
一条有用的评测样本通常不只是“问题 + 答案”,还要知道正确证据在哪:
{"question":"星河 Pro 的保修期是多久?","reference_answer":"自购买之日起一年有限保修。","reference_documents":["after-sales-policy-2026-04#section-3"],"answerable":true,"category":"售后政策"}样本要来自真实业务:客服工单、站内搜索、用户反馈和领域专家编写。除了常见问题,还应包含无答案、错别字、专有名词、多跳问题、过期版本、冲突文档和权限问题。
训练或调参用过的样本不要全部拿来汇报最终成绩。否则系统只是在熟悉的试卷上考得好。
面试时可以这样答:评测集至少包含问题、参考答案和标准证据,并标注是否可回答及问题类型。数据应覆盖真实高频问题、长尾问题、无答案、多跳、版本冲突和权限场景。调参集与最终测试集要分开,并持续吸收线上失败样本。
32. 检索结果正确,模型还是答错,怎么排查?
先别继续调 Embedding。正确证据已经召回,问题多半在召回之后。
阿杰按下面的顺序检查:
- 正确 Chunk 是否真的被放进最终 Prompt;
- 是否在截断和上下文压缩时被删掉;
- 是否有旧版本或冲突资料干扰;
- 关键证据是不是埋在很长上下文中间;
- Prompt 有没有明确回答边界;
- 模型是否能完成所需的比较、计算或多跳推理。
把每一步的输入输出记录下来,比对着最终答案猜原因有效得多。
面试时可以这样答:若正确证据已进入 Top-K,应继续检查重排、截断、去重和 Prompt 组装,确认最终模型上下文里是否仍有证据。然后排查冲突文档、上下文位置、指令约束和模型推理能力。不要把所有答案错误都归因于召回。
33. 完全检索不到结果,怎么排查?
零召回不只意味着“知识库没有答案”。也可能是索引任务失败、过滤条件过严、用户使用了缩写,或者文档解析后根本没保留那段内容。
可以沿着这条链路查:
原文里有答案吗? → 解析结果里还有吗? → 对应 Chunk 已写入索引吗? → 元数据过滤是否把它排除了? → BM25 和向量检索各自能找到吗? → Query Rewrite 是否改变了原意?如果知识库确实没有答案,系统应该拒答或转人工,不要降低阈值直到随便捞出一段不相干的文字。
面试时可以这样答:零召回要依次检查知识源、解析结果、切块、索引写入、过滤条件和查询改写,再分别测试关键词与向量检索。如果知识库确实没有证据,应明确拒答或走兜底,而不是无条件降低相关性阈值。
34. 如何处理互相冲突或已经过期的文档?
知识库不是“有文档就行”,还要有版本秩序。
阿杰给文档增加了生效时间、失效时间、版本号和权威级别。默认检索只看当前有效版本;如果两个当前来源仍然冲突,答案会同时展示两种说法和出处,并提示需要确认。
涉及价格、库存、账户余额等强一致信息时,不应该相信几天前导入的静态文档。此时应查询业务数据库或 API。
面试时可以这样答:应通过版本号、生效时间、来源权威性和失效标记管理文档,检索时优先过滤到当前有效版本。无法自动解决的冲突要连同引用一起呈现,不应让模型自行选择。强一致数据应查询实时业务系统。
35. 引用是怎么做的?模型写个“来源 1”就够了吗?
当然不够。模型可能给一段没有真正支持答案的文字贴上引用,看起来煞有介事。
建库时应保留文档 ID、版本、页码、标题路径和原文偏移。生成答案后,再把答案中的事实主张与引用 Chunk 对齐,检查引用是否真的包含支持信息。
引用质量至少有两层:
相关性:这段资料是否讨论了同一主题? 支持性:这段资料是否真的能推出答案中的主张?前者容易,后者才是难点。
面试时可以这样答:引用需要依赖摄取阶段保存的来源、版本、页码和片段位置。生成时让模型标注证据,生成后再验证每个主张是否被对应片段支持。引用存在不等于引用正确,还要区分主题相关与事实支持。
第五幕:演示能跑不算结束,线上会用另一套方式考你
知识助手在测试环境里表现不错。上线第一天午休时间,流量突然上涨。查询改写调用一次模型,重排调用一次,最终回答又调用一次。用户等了十几秒,页面还没动静。
主管的下一句话很熟悉:“效果先不说,怎么这么慢,还这么贵?”
36. 如何降低 RAG 延迟?
先把端到端耗时拆开,不要凭感觉优化:
查询改写 120 ms Embedding 80 ms 混合检索 60 ms Rerank 350 ms LLM 首 Token 900 ms 完整生成 2.8 s知道时间花在哪,才能对症下药。常见办法有:
- BM25 与向量检索并行;
- 缓存热门查询、Embedding 和稳定结果;
- 减少改写次数与重排候选数;
- 用小模型完成改写、路由和压缩;
- 设置超时,Reranker 超时就退回原排序;
- 流式返回,让用户尽早看到首字。
流式输出只改善体感,不会自动缩短完整生成时间,这一点面试官很爱追问。
面试时可以这样答:先按查询改写、Embedding、检索、重排、首 Token 和完整生成拆分延迟,再优化主要瓶颈。可并行多路检索、缓存稳定结果、缩小重排候选、使用轻量模型并设置超时降级。流式输出降低感知等待,不等于降低总耗时。
37. 如何降低 RAG 成本?
RAG 的账单不只来自最后一次生成。一次看似普通的问题,背后可能有查询分类、改写、多路查询、重排、上下文压缩和事实检查。
阿杰先记录每个阶段的输入 Token、输出 Token、调用次数和重试次数,然后做了几件很实际的事:
- 简单问题不做多查询拆分;
- 重复 Chunk 去重后再进 Prompt;
- 路由和改写使用较小模型;
- 对稳定 FAQ 做缓存;
- 设置单请求 Token 和调用次数预算。
压缩上下文不能只追求短。删掉关键限定词后,Token 是省了,答案也可能错得更干脆。
面试时可以这样答:RAG 成本要统计整条调用链,包括改写、重排、重试和最终生成。可以通过模型路由、缓存、结果去重、控制 Top-K、压缩上下文和减少不必要的多查询来优化。所有降本措施都应同时观察答案质量。
38. RAG 怎样做权限控制?
财务部上传了一份薪酬制度。普通员工问“部门工资范围”,向量检索很可能认为这份文档高度相关。
如果系统先检索全文,再让模型“不要泄露”,已经太晚了。敏感内容可能进入 Prompt、Trace、缓存,甚至被模型转述。
正确思路是把用户身份转换为检索过滤条件:
tenant_id = 当前租户 department in 用户所属部门 acl contains 当前用户或角色 document_status = active这些条件应在召回阶段执行。缓存键也要包含租户和权限范围,避免 A 用户命中的结果被 B 用户复用。
面试时可以这样答:权限控制应在检索阶段完成。索引中保存 tenant、user、role、department 和 ACL 等字段,查询时按当前身份过滤,确保未授权内容不会进入候选集、Prompt、日志和缓存。生成后的脱敏只能作为补充。
39. 线上应该监控哪些指标?
阿杰给每次请求分配一个 Trace ID,把改写后的查询、召回文档、重排分数、最终 Prompt、模型响应、Token 和耗时串起来。某个用户投诉时,他终于可以重放当时发生了什么。
监控通常分几类:
| 层面 | 例子 |
|---|---|
| 系统运行 | QPS、错误率、P95/P99、超时率 |
| 检索 | 零召回率、Recall@K、过滤后候选数 |
| 生成 | 拒答率、引用支持率、用户差评 |
| 成本 | Token、模型调用次数、缓存命中率 |
| 数据 | 解析失败率、索引延迟、过期文档数量 |
Trace 中可能含有用户问题和企业资料,必须脱敏、采样并设置保留期限。为了排查问题而制造新的数据泄露,得不偿失。
面试时可以这样答:线上要同时监控系统、检索、生成、成本和数据新鲜度。通过 Trace ID 关联查询改写、召回、重排、Prompt 与模型响应,才能定位问题。日志和 Trace 要进行脱敏、访问控制、采样和生命周期管理。
40. Reranker 或模型服务挂了,怎么降级?
生产系统不要假设每个外部服务永远可用。
例如:
Reranker 超时 → 使用混合检索原始顺序 大模型超时 → 切换备用模型或返回检索摘要 向量服务异常 → 退化为 BM25 知识库不可用 → 明确提示暂时无法查询,转人工降级结果可以变简单,但不能跨过权限边界,也不能伪装成完整答案。主备模型的输出格式还要保持兼容,否则切换成功了,解析器又报错。
面试时可以这样答:应为查询改写、向量检索、重排和生成分别设置超时、熔断与备用路径。降级方案可以牺牲部分质量,但必须守住权限和事实下限,并向用户透明说明。主备模型还要验证输出契约兼容。
41. 什么是 GraphRAG?
有些问题不是找一段话,而是沿着关系一步步查。
例如:“与供应商甲合作的产品中,哪些使用了受影响芯片?”答案可能分散在供应商合同、产品清单和芯片公告里。普通向量检索能找到局部相似片段,却不一定能稳定串起“供应商—产品—芯片”这条关系。
GraphRAG 会抽取实体和关系,形成知识图谱,再结合图遍历、社区摘要和原文检索回答问题。
它适合多跳关系和全局归纳,但构图、实体消歧、版本更新都很费功夫。普通 FAQ 上来就用 GraphRAG,往往是把简单问题做复杂了。
面试时可以这样答:GraphRAG 将实体、关系和原始文档组织成图结构,通过图检索与文本检索支持多跳推理和全局总结。它适合关系密集、证据分散的问题,但构图、消歧和增量更新成本较高,不应替代所有普通 RAG。
42. 什么是 Agentic RAG?
传统 RAG 像一条固定流水线:每次都改写一次、检索一次、生成一次。
Agentic RAG 更像一个会自己决定查资料步骤的研究助理。它可以判断:
- 这个问题是否需要检索;
- 应该查产品库、订单库还是售后库;
- 是否需要拆成多个子问题;
- 现有证据够不够,要不要继续查;
- 应该查文档,还是调用实时业务 API。
灵活性上去了,可控性也变差了。Agent 可能重复检索、选错数据源或者迟迟不肯停止,所以要限制轮数、工具权限、Token 预算和总超时。
面试时可以这样答:Agentic RAG 由模型动态规划检索步骤,可选择数据源、拆分问题、循环补充证据并调用工具。它适合复杂、多源和多跳任务,但会增加延迟、成本和不确定性,需要限制循环、权限、预算并做好轨迹评测。
43. 如何系统优化一个效果很差的 RAG?
这是很常见的综合题。最忌讳的回答是:“我会换一个更好的大模型,再调一下 Prompt。”
阿杰会先拿一批失败样本,把错误分到四层:
数据层:原文缺失、解析错乱、版本过期、Chunk 不合理 检索层:召回失败、过滤错误、查询漂移、专有名词匹配差 排序层:正确证据排名低、重复结果多、旧版本靠前 生成层:证据被截断、上下文冲突、引用不支持、模型推理失败如果标准证据根本没进 Top-K,就先修数据与检索;如果已经召回但排得低,再调融合与 Rerank;如果最终 Prompt 里证据完整,答案仍错,才轮到生成模型和 Prompt。
每次只改一个主要变量,用同一套评测集比较。否则同时换 Embedding、Chunk 和大模型,分数涨了也不知道是谁起的作用。
面试时可以这样答:我会先建立带标准证据的评测集,把问题拆成数据、召回、排序和生成四层。先检查标准证据是否进入 Top-K,再检查重排后是否进入最终上下文,最后判断模型是否忠实使用。每次控制变量,并同时观察质量、延迟和成本。
面试前最后十分钟:把整套 RAG 压成一条回答
如果面试官只问一句“介绍一下你理解的 RAG”,可以按下面的顺序说。别一口气背完,讲到对方感兴趣的地方停下来等追问。
RAG 是先检索外部知识,再把证据交给大模型生成答案。离线链路负责文档解析、切块、Embedding、元数据和索引更新;在线链路负责查询理解、关键词与向量混合召回、结果融合、Rerank、上下文组装和生成。
它的难点不只是调用向量库。切块决定知识能否被完整表达,混合检索解决专有名词与语义查询的互补问题,Rerank 提高前几名精度,引用与拒答控制幻觉。评测时要把检索和生成分开,看 Recall@K、Faithfulness、正确性和引用支持率。
上线后还要处理增量更新、版本冲突、权限过滤、缓存、延迟、成本、Trace 和服务降级。复杂的多源问题可以使用 GraphRAG 或 Agentic RAG,但是否采用要看评测收益,不能只因为概念新。
这段话里埋了十几个追问入口。你真正理解以后,面试官从任何一个词切进去,都能接着讲。
一张故障速查表
| 现象 | 先查哪里 | 常见原因 |
|---|---|---|
| 完全找不到答案 | 数据与索引 | 原文没有、解析丢失、索引失败、过滤过严 |
| 找到了相似内容,却不是答案 | 检索 | Chunk 太大、只用向量、查询表达不完整 |
| 正确文档排在后面 | 融合与排序 | Top-K 太小、RRF 权重不合适、缺少 Rerank |
| 正确证据已召回,回答仍错 | 上下文与生成 | 截断、冲突、Lost in the Middle、模型误读 |
| 引用存在但不支持答案 | 引用校验 | 只检查相关性,没有检查事实支持 |
| 同一问题一会儿答旧政策,一会儿答新政策 | 数据治理 | 旧版本未失效、缺少生效时间过滤 |
| 效果不错但又慢又贵 | 调用链 | 多次改写、候选过多、大模型承担简单任务 |
| 普通用户看到了敏感内容 | 权限 | 只在生成后脱敏,缓存没有隔离 |
容易被追问的五组对比
RAG 与微调
RAG:给模型资料,解决“知道什么” 微调:改变模型行为,解决“怎样做”BM25 与向量检索
BM25:看字面,擅长型号、编号、专有名词 向量:看语义,擅长同义改写和自然语言Bi-Encoder 与 Cross-Encoder
Bi-Encoder:分开编码,快,适合海量召回 Cross-Encoder:联合编码,准,适合少量重排Recall 与 Precision
Recall:该找的证据有没有漏掉 Precision:找回来的内容有多少真有用Faithfulness 与 Correctness
Faithfulness:答案有没有忠实使用给定证据 Correctness:答案是否符合真实事实真正值得背的,不是产品名
向量数据库会换,Embedding 模型会换,框架的 API 也会换。面试官真正想确认的是,你能不能沿着一条请求,把每一步为什么存在说清楚。
用户问了一句话。系统怎样理解它?去哪找?为什么相信这几段资料?旧版本怎么处理?模型凭什么拒答?答案错了怎样判断是检索问题还是生成问题?高峰期服务挂了一半,还能不能给出安全的结果?
能回答这些问题,RAG 就不再是一串术语。
阿杰最后一次演示时,主管又问了那句:“星河 Pro 保修几年?”
知识助手回答:
根据《星河 Pro 售后政策》2026 年 4 月版第 3 条,整机自购买之日起享受一年有限保修。[查看原文,第 7 页]
这次主管没有马上问下一个问题。他先点开了引用。
对于一套企业 RAG 来说,这个动作比一句“回答正确”更重要。用户终于知道,系统为什么这么说。
延伸阅读
- Microsoft:高级 RAG 系统的摄取、推理与评估
- Azure AI Search:RAG 与混合检索概览
- Azure AI Search:RRF 排名融合原理
- Elastic:Hybrid Search
- Ragas:RAG 评测指标