代码语言

知识点思维导图

9 个知识节点

面试题(19) - 高频面试题:RAG

读完后,你应能:

  • 给定一个知识库问答项目,能画出离线建库与在线检索链路图,并用数据版本、Chunk ID 和引用回链证明答案可追溯。
  • 给定一组标注问题,能输出检索与生成评测表,并用 Recall@K、引用正确率、拒答准确率和 P95 延迟说明系统是否可上线。
  • 给定越权与注入样本,能输出过滤记录,用 Trace 证明受限内容未进入上下文。

核心知识清单

  • 原始数据清洗
  • 聊天记录入库
  • 向量数据库选型
  • Embedding 向量维度
  • RAG 性能指标
  • 多问题与多意图处理

一、与进阶篇的分工

本篇保留为 RAG 面试速记。准备项目追问时,请结合 58-62、78-81、91,把“基础流程”升级成“工程链路、评测链路和权限证据链”的回答。

二、怎么用这一篇

RAG 面试的核心不是背定义,是证明你真把知识库问答从原理做到了落地。多讲引用、拒答、评测、权限,少讲玄乎的"智能"。


2.1 RAG 原理与基础链路

Q1:RAG 的完整流程是什么?

一句话答:离线把文档切块入库,在线检索相关块拼进 prompt 让模型基于资料回答。

展开:离线——解析文档 → 切 chunk → 生成 embedding → 存向量库(带来源元数据)。在线——问题向量化 → 检索 topK → 可选 rerank → 拼进 prompt → 模型基于资料生成 → 返回引用来源。

Q2:RAG 和微调怎么选?

一句话答:知识会变、要引用、要快速更新用 RAG;要改风格/格式/固有能力用微调。

展开:RAG 把知识放外部,改文档即可更新,天然支持引用和权限,成本低。微调把知识/风格压进权重,适合稳定的领域语气和输出格式,但更新慢、要重训、无引用。实际常是 RAG 为主,必要时叠加轻量微调。

Q3:chunk 切太大或太小分别有什么问题?

一句话答:太大答案被无关内容淹没还浪费上下文;太小语义被切断、命中了也信息不全。

展开:切太大,关键句被稀释,模型抓不住重点,还挤占上下文窗口。切太小,一句话被拆碎丢了上下文,检索到的片段不足以支撑回答。实践上按语义/段落切,加 overlap 保留跨块上下文。

Q4:embedding 为什么能做语义检索?

一句话答:把文本映射成向量,语义相近的向量距离也近,于是用向量相似度找相关内容。

展开:embedding 模型把文本编码成定长向量,训练目标让语义相近的文本在向量空间靠近。检索时把问题也编码成向量,算它和库里各 chunk 的余弦相似度,取最近的几个。比关键词匹配强在能命中"同义不同词"。

Q5:向量数据库的作用是什么?不用行不行?

一句话答:高效存储检索海量向量。数据小可暴力算相似度,量大必须用向量库做近似检索。

展开:向量库(FAISS/Milvus/pgvector)用 ANN 近似最近邻索引,把检索从 O(n) 降到接近 O(log n),支撑百万级向量毫秒检索,还提供元数据过滤和增删改。几千条以内确实可以内存暴力算。

2.2 检索质量、安全与排障

Q6:rerank 是干什么的?什么时候需要?

一句话答:用更强的模型对初步检索结果重新打分排序,把最相关的提到最前。

展开:向量检索快但粗,topK 里常混入相关性一般的。rerank 用 cross-encoder 对(问题, chunk)逐对精算相关性重新排序。先粗检召回、再精排提质是常见两阶段。召回够但答案质量不稳时加 rerank 收益明显。

Q7:怎么保证回答有引用、不编造?

一句话答:chunk 保留来源元数据,引用从实际命中的 chunk 生成,检索为空就拒答。

展开:每个 chunk 带 source/section。生成时 prompt 明确要求只基于给定资料,把命中 chunk 的来源作为 citation 返回。最关键是 if not hits: 拒答——检索不到就明说没依据,绝不让模型自由发挥。

Q8:RAG 答错了,怎么定位哪一环出问题?

一句话答:先看检索命中对不对——没命中是检索问题,命中了还答错是生成/prompt 问题。

展开:第一层看检索,把命中的 chunk 打出来,相关 chunk 没召回就调切分/embedding/topK 或加混合检索。第二层看生成,相关 chunk 召回了却答错,就是 prompt 约束不够或上下文太长被忽略,调 prompt、压上下文、强化引用约束。

Q9:RAG 怎么做评测?只靠人工看吗?

一句话答:维护问题-答案/来源评测集,跑检索命中率和答案正确率,坏 case 单独标签跟踪。

展开:哪怕只有 20-50 条也要建。检索侧看命中率/召回率(正确 chunk 有没被检索到),生成侧看答案正确率(人工标或用更强模型当裁判)。每次改切分/检索参数都跑一遍对比。

Q10:知识库有权限(不同人看不同文档),RAG 怎么处理?

一句话答:在检索阶段就按用户权限过滤 chunk,绝不能检索到无权限内容再让模型"嘴下留情"。

展开:chunk 元数据存权限标签(部门/角色/密级)。检索时把用户权限作为过滤条件,只在有权访问的 chunk 里检索。权限过滤必须在检索层硬做,不能靠 prompt 让模型"别说",模型会被诱导泄露。

2.3 数据治理、向量选型与性能

Q11:原始数据进入 RAG 前可以做哪些清洗处理?

一句话答:原始数据清洗先修复解析错误和噪声,再做去重、规范化、脱敏与质量校验,同时保留来源、版本、结构和权限;目标是提高可检索性,不是改写事实。

展开:我会把清洗拆成六层:

  1. 格式与编码:统一 UTF-8、换行符、全半角和 Unicode 形式,识别乱码、空文件、加密文件与不支持格式。
  2. 解析与版面:去掉重复页眉页脚、页码水印和导航噪声;修复 PDF 双栏顺序、OCR 错字、断行连字符;表格保留表头、行列关系和页码,代码保留缩进。
  3. 内容规范化:规范多余空白和无意义重复标点,但保留数字、单位、否定词、故障码、条款号与标题层级,避免改变事实语义。
  4. 去重与版本:用来源 ID、文件哈希和段落指纹识别完全重复与近重复内容;同一文档保留有效版本和生效时间,而不是把新旧制度混在一起。
  5. 安全与权限:在索引前识别密钥、身份证、手机号等敏感字段,按策略删除、掩码或加密;同时写入 tenant_id、ACL、密级和可见范围。
  6. 质量门禁:统计解析成功率、空页率、乱码率、OCR 低置信页、表格保留率、重复率和待人工复核量;不合格文档进入隔离区,不能静默发布。

加分项:原始数据清洗必须保存内容哈希、解析器版本和来源坐标,并抽样对照原文件。原始数据清洗不能删除“不”、小数点或表头,否则会改变事实。

Q12:聊天记录如何处理后进入知识库?

一句话答:聊天记录入库不能整段直接向量化;先筛选可复用且已确认的知识,再按主题重建上下文、抽取事实、脱敏、绑定来源与权限,审核后才发布。

展开:首先区分三种数据:当前会话上下文属于短期记忆,用户偏好属于受控长期记忆,经过确认且可复用的业务结论才进入公共或企业知识库。入库链路通常是:

  1. conversation_id、消息时间和角色重建顺序,过滤心跳、按钮事件、失败重试、重复回答和无业务意义的寒暄。
  2. 按主题或任务阶段切分会话,保留必要的追问上下文;不要把整场长对话作为一个 Chunk。
  3. 从会话中抽取“问题—确认答案—证据”“事实—适用条件—有效期”或工单解决步骤。模型生成的摘要只是候选,不能自动成为事实。
  4. 对姓名、联系方式、账号、密钥和客户数据做脱敏,继承原会话的租户、参与者和可见范围。
  5. 写入稳定 ID、原消息引用、时间、负责人、置信度、审核状态和失效时间;与已有知识冲突时进入合并或人工复核,而不是覆盖。
  6. 审核通过后再分块、Embedding 和发布;原消息被删除或撤回时,派生知识也必须能按血缘关系删除或重建。

加分项:聊天记录入库只接收经过确认的可复用事实,原对话只是证据来源。聊天记录入库必须支持按来源撤回,否则错误会被 RAG 反复放大。

Q13:向量数据库怎么选,为什么?

一句话答:向量数据库选型要根据数据规模、过滤与一致性、更新频率、混合检索、运维能力和成本做基准测试,再选满足 SLO 的最简单方案。

展开:我会先列硬约束,再用真实向量和过滤条件压测候选:

场景 更常见的起点 主要原因
已使用 PostgreSQL、数据量中小、事务和 Metadata 过滤重要 pgvector 复用数据库、备份、权限和事务体系,架构简单
百万到十亿级向量、高吞吐、需要独立分片和扩缩容 Milvus 专用向量检索与分布式能力更完整,但运维成本更高
已使用 Elasticsearch,强依赖 BM25、过滤和全文检索 Elasticsearch 向量检索 稀疏与稠密检索在同一检索体系中,减少双写
单机实验、离线检索或数据很小 FAISS / 内存检索 部署简单,但权限、持久化和在线运维能力需要自己补

最终比较维度包括:目标向量数量和增长率、Embedding 维度、P95/P99 延迟与 QPS、Recall@K、HNSW/IVF 参数、标量过滤性能、增量更新与删除、索引重建和回滚、备份恢复、多租户隔离、SDK/社区成熟度、机器与人力成本。先用精确 KNN 生成小规模真值,再画 ANN 的召回—延迟曲线。

加分项:向量数据库选型不能替代权威数据存储,向量索引只是可重建投影。向量数据库选型涉及双写时,必须同时设计稳定 Chunk ID、版本状态和对账。

Q14:项目用了多少维向量,为什么?不同维度有什么区别?

一句话答:Embedding 向量维度首先由模型决定,不能为了省空间随意截断;项目应比较质量、延迟和容量,维度越高不代表一定越准。

展开:面试时应按真实项目回答,例如:“项目使用模型原生的 1024 维向量,因为它在中文业务 Query—Chunk 集上的 Recall@10 达标,并且单机批处理吞吐和索引内存满足预算。”这里的 1024 只是回答模板,必须替换成项目真实模型、版本和数据。

维度主要影响四件事:

  • 语义容量:同一模型家族中,更高维度可能保留更多信息,但检索质量还取决于训练数据、损失函数和领域匹配,不能跨模型只比维度。
  • 存储与内存:float32 原始向量约为 向量数 × 维度 × 4 字节。100 万条 768 维约 2.86 GiB,1024 维约 3.81 GiB,1536 维约 5.72 GiB,尚未包含 ANN 图、Metadata、副本和构建临时空间。
  • 计算与网络:维度越高,Embedding 输出传输、距离计算、索引构建和缓存压力通常越大,P95 延迟需要实测。
  • 索引契约:Collection 的维度必须与模型输出一致;模型或维度升级要新建索引、双写或影子验证后切换,不能把不同空间的向量混在一起。

若模型官方支持 Matryoshka 等可变维度或经过训练的降维,才可以比较 256/512/1024 等候选;普通向量直接截断或用未经评测的 PCA 都可能损失召回。

加分项:Embedding 向量维度必须与距离度量、归一化和索引 Schema 配套。Embedding 向量维度即使相同,不同模型的向量空间也不可直接比较。

Q15:统计过哪些性能指标,如何定位各模块耗时?

一句话答:RAG 性能指标要用同一 Trace 拆出改写、Embedding、召回、融合、Rerank、首 Token、生成和校验耗时,并同时看 P50/P95/P99、最大值、样本量和超时率。

展开:我会按请求记录下列指标,并带上模型、Prompt、Embedding、索引版本、租户和是否降级等标签:

层次 关键指标 用途
端到端 平均值、P50、P95、P99、最大耗时、QPS、并发数 判断整体 SLO 与长尾
检索 Query Rewrite、Embedding、BM25、向量检索、融合、Rerank 各自耗时 定位召回链路瓶颈
生成 首 Token 时间 TTFT、生成总耗时、输出 Token、tokens/s 区分等待模型和持续生成
可靠性 错误率、超时率、重试率、限流率、降级率、拒答率 判断慢请求是否伴随故障
质量与成本 Recall@K、nDCG/MRR、引用覆盖、忠实度、每问 Token 与费用 防止只提速却损失答案质量

平均响应时间会掩盖少量很慢的请求;最大值又容易被单个异常放大,因此必须和 P95/P99、样本量、时间窗口一起看。每个阶段用 Span 记录开始、结束、状态和输入规模,例如候选数、Top K、Chunk Token 数。BM25 与向量检索并行时,端到端检索耗时接近两者较慢者再加融合耗时,不能把并行 Span 简单相加。

面试中最好给出真实监控截图或一段经过脱敏的数据,例如“过去 7 天共多少请求,端到端 P95、检索 P95、Rerank P95、TTFT P95 分别是多少,最慢请求由哪个 Trace 定位到什么根因”。没有真实数据时应说明采集方案,不要编造漂亮数字。

加分项:RAG 性能指标必须有优化前后对照和质量护栏。RAG 性能指标变快后仍要回归 Recall@K 和答案正确率,避免以质量换延迟。

2.4 多问题与多意图路由

Q16:用户一句话包含多个问题或多个意图时,如何处理?

一句话答:多问题与多意图处理要保留原问题,再解析成带实体、约束和依赖的子任务;独立任务并行,依赖任务按 DAG 执行,歧义或高风险请求先追问。

展开:不能只按“和、然后、另外”机械切句,因为这些词也可能连接同一个条件。生产链路通常分为六步:

  1. 识别是否需要拆解:单一事实查询直接检索;出现多个动作、对象、时间范围或数据源时进入多意图分析,同时保留原始 Query 作为召回和回放依据。
  2. 结构化拆解:输出 sub_questionintent、实体、时间范围、约束、目标数据源和 depends_on。使用 JSON Schema 校验,缺字段或置信度低时回退原问题或请求澄清。
  3. 判断任务关系:相互独立的问题可以并行;后一个问题依赖前一个结果时构建 DAG;共享同一实体的子问题可复用检索结果;互相冲突或指代不明时先让用户确认。
  4. 分别路由与鉴权:制度问答进入 RAG,订单金额进入 SQL/API Tool,实时状态进入业务接口。每个子任务都单独执行租户、ACL 和工具权限校验,不能因为整句话已鉴权就放行所有分支。
  5. 检索与执行:每个子问题可同时使用原问题和改写问题召回,保留子任务 ID、候选、耗时和引用。设置最大子任务数、并发数、总超时、Token 与费用预算,防止一句话触发无限拆解。
  6. 合并答案:按用户原始顺序逐项回答,标明未完成、拒答或需要补充的信息;引用必须绑定对应子答案。多个来源结论冲突时展示差异和时间版本,不能让汇总模型擅自选一个。

例如用户问“退款规则是什么,顺便查一下订单 A 是否满足退款条件并计算可退金额”,应拆成“检索退款制度”“读取订单状态”“根据制度和订单计算金额”三个任务。后两步依赖前置证据与订单数据,不能把整句话只送进向量库,也不能让模型凭文档猜订单金额。

验收指标:至少统计多意图识别准确率、子问题拆解完整率、路由准确率、子问题答案覆盖率、引用正确率、澄清率、端到端 P95、并发节省时间和单请求成本。评测集要包含独立问题、依赖问题、共享实体、否定条件、指代、省略、冲突意图和不应拆解的单意图长句。

加分项:多问题与多意图处理不是拆得越多越好,过度拆解会增加延迟、成本和语义漂移。多问题与多意图处理遇到高风险或低置信度路由时应追问或转人工。


三、动手实践:16 道高频 RAG 面试题 —— 抽题自测

脚本直接从本篇正文提取 16 道题,避免题目和答案维护成两份。先用 --all 通读,再每天随机抽题并口述答案。

python3 quiz.py          # 随机抽 5 题,逐题自测(回车看答案,Ctrl+C 退出)
python3 quiz.py -n 3     # 随机抽 3 题
python3 quiz.py --all    # 通读全部 16 题和答案,不交互

脚本为 Python 3.10+ 标准库实现。卡壳时回到对应小节,先说清“一句话答”,再补展开、指标和风险边界。

四、总结

  • RAG 必须分别验证解析、召回、排序、生成、引用和权限,检索不到可靠证据时应拒答。
  • 原始数据清洗要保留来源、版本、结构和 ACL;聊天记录经事实确认、脱敏和审核后才能成为知识。
  • 向量库按规模、过滤、一致性、性能和运维成本选型,Embedding 维度由模型契约和业务评测共同决定。
  • Trace 要记录端到端与各模块 Span,延迟同时观察 P50/P95/P99、最大值、样本量和超时率。
  • 多问题请求先结构化拆解和判断依赖,再分别路由、鉴权和绑定引用;歧义或高风险请求先澄清。
  • 任何提速或参数调整都要同时回归 Recall、答案正确率、引用忠实度和单问成本。

4.1 实现源码与运行边界

quiz.py

学完自测

选择所有正确答案;提交后逐项核对判断依据。

1在“高频面试题:RAG”中,需要同时满足“原始数据清洗”与“聊天记录入库”。给定正文约束“原始数据清洗必须保存内容哈希、解析器版本和来源坐标,并抽样对照原文件。”,哪些判断保持了原有处理机制?多选
2“高频面试题:RAG”出现偏差:“在“高频面试题:RAG / 向量数据库选型”中,即使不满足“向量数据库选型不能替代权威数据存储,向量索引只是可重建投影”,结果与副作用仍会保持不变。”已成为实际行为。围绕“向量数据库选型”与“Embedding 向量维度”,哪些判断能定位被改变的职责或边界?多选
3评审“高频面试题:RAG”方案时,验收条件包含“RAG 性能指标必须有优化前后对照和质量护栏。”。关于“RAG 性能指标”与“多问题与多意图处理”的哪些决策符合正文机制?多选