Interview AiBoxInterview AiBox 实时 AI 助手,让你自信应答每一场面试
面试场景下,我们的 RAG 方案:从知识库构建到 Query 路由
很多人做 RAG,只会讲检索和模型,却讲不清离线解析、切分、Query 理解、元数据和多轮追问支撑。本文用更贴近真实技术面的方式,拆解 Interview AiBox 的面试级 RAG 方案。
- sellTechnical Deep Dive
- sell产品更新
之前我见过一个很典型的场景。
有个候选人面大厂 NLP 岗,简历里写着一句很常见的话:
“搭建了基于 RAG 的企业知识问答系统。”
面试官往下追问:
- 知识库里有多少文档?
- 都是什么格式?
- PDF 多栏排版怎么处理?
- 扫描件里的表格和代码怎么保结构?
- 你们 chunk 是固定切,还是会保语义边界?
- 如果一段完整流程被切断,检索怎么保证还能召回完整信息?
很多人就是在这里开始失速。
因为他们平时 90% 的精力都花在“在线检索”“Rerank”“模型选型”这些上层能力,却没有把离线解析和知识库构建讲明白。
而真相是:
知识库质量,决定了 RAG 效果的上限。
后面的检索再精准、模型再强,如果喂进去的是解析错乱、结构丢失、切分破碎的内容,结果也只会是经典的 Garbage in, Garbage out。
所以这篇文章,我不准备只讲“我们的 RAG 是多路召回 + 重排 + 生成”这种标准答案,而是按真实技术面的逻辑,重新拆一遍:
- 面试官真正关心你讲清楚什么
- 我们为什么把离线解析当成第一层胜负手
- 面试场景下,知识库怎么建才真的有用
- 为什么不是所有 query 都该直接去检索
- 如果被问“你们自己的 RAG 怎么做”,可以怎么答
先看全链路:Interview AiBox 的面试级 RAG 是怎么串起来的
一、面试官真正想听的,不只是“你用了 RAG”
在技术面里,“我们做了 RAG”本身几乎没有信息量。
面试官真正想判断的是:
- 你是不是理解知识从哪来
- 你有没有处理脏文档和复杂格式的经验
- 你知不知道 chunking 会直接影响召回上限
- 你能不能把离线质量和在线效果串起来讲
- 你是否真的做过一条完整链路,而不是只调过检索接口
这也是为什么在面试场景里,我们更愿意把 RAG 拆成两层去讲:
- 知识底座怎么建
- 在线问答怎么命中
如果第一层讲不清,第二层通常也立不住。
二、为什么我们把离线解析当成第一层胜负手
很多人对“离线解析”的理解还停留在“把文档转成文本”。这只说对了一小部分。
在我们看,完整的知识库构建至少包含这些步骤:
- 多格式文档解析
- 内容清洗与规范化
- 结构感知的文本分块
- 层级标签和来源元数据补齐
- 为后续召回做索引和检索辅助准备
这里每一步出问题,都会在后面的链路里被放大。
比如:
- PDF 多栏排版解析错了,语义顺序就会乱
- OCR 把表格打平了,字段关系就没了
- chunk 把一段完整流程切断了,召回命中率就会掉
- 元数据没标,在线阶段就做不了时间、来源、类型过滤
所以我们不把离线阶段看成“预处理杂活”,而是把它当成整条 RAG 链路的地基。
三、面试场景下,我们怎么构建这套知识底座
如果只做一个通用问答机器人,粗粒度切一下、能搜到大概意思,很多时候也能凑合用。
但面试场景不一样。用户不是要“知识点摘要”,而是要:
- 回答像自己
- 项目细节能撑住追问
- 多轮说法别互相打架
- 延迟别高到影响临场发挥
所以我们的知识底座会更强调下面几件事。
多格式资料先按类型拆开处理
知识库不是一个“附件桶”,不同类型的资料不能一股脑走同一套处理。
我们更接近下面这种思路:
- 结构化简历 / JSON:保留项目、时间线、职责、结果等字段
- Markdown / 项目复盘:保留标题层级、段落边界、列表和代码块
- QA 文档:保留问答对边界,因为这类内容天然适合回答组织
- 扫描件 / 图片型材料:先做版面分析,再走 OCR
- PPT / 含图说明材料:不仅提文本框,也会考虑图片中的文字信息
目标不是“先把文本抠出来”,而是尽量保住后续还能回答的语义单元。
版面分析比“直接抽文本”重要得多
真实项目里,最容易出问题的是 PDF。
尤其是双栏排版、带表格、带页眉页脚的文档,如果你只是简单按文本流去抽,很容易把左栏和右栏拼在一起,把表头和正文混在一起。
结果就是表面上“抽到了很多字”,实际上语义已经坏了。
所以在这类材料里,我们会优先考虑:
- 先识别物理区域
- 再按逻辑阅读顺序提取
- 表格、列表、代码块尽量单独保结构
- 页眉页脚、重复水印、无效噪声先清理
对面试来说,这一步的价值特别直接,因为一旦原文结构坏了,后面用户被追问“某个流程具体怎么走”“某张对比表里差异是什么”时,召回层就很难再把正确语义救回来。
chunking 不是切长度,而是切“可回答单元”
这是很多 RAG 项目最容易说空的一点。
很多人上来就说:
“我们按 512 token 切分,重叠 50 token。”
这不是不能说,但如果只停在这里,面试官通常会继续追:
- 为什么是这个长度?
- 语义边界怎么保?
- 表格和代码会不会被截断?
- 跨页段落怎么处理?
在面试场景里,我们更关注的是:一个 chunk 能不能成为一个相对自包含、可被直接引用的回答单元。
所以思路更接近三层:
- 先按结构切 用标题、段落、列表、表格边界、问答对边界做第一层切分。
- 再按语义修 如果某一段太短、上下文明显未完结,或者跨页内容本质属于同一主题,就做合并或调整。
- 最后做长度平衡 在不破坏语义完整性的前提下,把过长内容再按次级节点拆开,把过短内容与相邻块补齐。
另外,chunk overlap 不是形式主义。它真正解决的是块与块之间的连续性,避免硬切分后上下文突然断掉。
层级标签和元数据,往往是隐藏的效果放大器
很多人做完分块就直接算向量、建索引,然后进入在线召回。
但如果你在离线阶段丢掉了层级结构,很多检索信号也一起丢了。
我们会特别重视几类元数据:
- 层级路径:比如“报销政策 > 差旅报销 > 住宿标准”
- 内容类型:普通文本、表格、代码块、流程说明、QA
- 来源信息:文档名、页码、幻灯片页、更新时间
- 主题标签:项目名、岗位方向、技术栈、业务域
- 结果信号:是否有量化指标、是否包含 trade-off、是否是追问素材
它们的价值不只是方便回溯,更重要的是能在在线阶段参与过滤和重排。
比如用户问:
“昨天调整过的报销制度和之前有什么不同?”
如果离线阶段已经把更新时间、文档类型、主题路径标清楚,召回就能明显更聚焦;反过来,如果什么都没标,在线阶段就只能拿纯语义相似度硬扛。
我们希望知识库里保留“像人说话”的材料
面试场景的一个特别点是,用户不只是要事实,还要表达。
所以除了结构化项目材料,我们也会重视:
- 自我介绍草稿
- 项目复盘里的口述版总结
- 常见追问的 QA
- 面后补充的“这题我上次答崩了,正确应该怎么说”
因为这类内容能帮助系统做的不只是“知道答案”,而是更像用户本人地把答案组织出来。
四、离线质量怎么影响整条在线链路
很多人把离线解析和在线检索当成两个独立模块,这在工程上很常见,但在效果上非常危险。
因为离线阶段的每个决定,都会在在线阶段形成连锁反应。
chunk 大小会直接影响上下文利用率
块太大,一次只能塞进少量片段,覆盖面很窄。
块太小,虽然表面上更精准,但信息又会变碎,回答时需要拼更多片段,反而更容易让生成层发散。
所以 chunk 的好坏,不是看它“切得整不整齐”,而是看它:
- 能不能支撑召回完整信息
- 能不能塞进当前回答的有效上下文窗口
- 会不会让多轮追问时必须频繁跨块拼接
元数据质量决定在线过滤能力
如果离线阶段没有把来源、时间、类型、层级打出来,在线阶段很多本来可以做的过滤就没法做。
比如:
- 只看最新版本项目复盘
- 只看当前岗位定制简历
- 只拉系统设计类内容
- 只拉包含量化结果的项目证据
这些能力,本质上都不是在线“灵机一动”生成的,而是离线阶段先埋好了钩子。
解析质量会直接污染后续检索和生成
如果 OCR 输出本身就是乱码,后面无论是关键词检索、向量召回,还是重排模型,处理的都只是“乱码的另一种表示”。
这也是为什么我们在判断一条 RAG 链路是否稳时,不会只看最终答案,而会往前倒着看:
- 原始资料干净吗
- 结构保住了吗
- chunk 合理吗
- 标签够用吗
- 再谈召回和生成有没有意义
五、不是所有 query 都该直接去向量库里搜
很多人讲在线链路的时候,会下意识把问题简化成:
query 进来 -> 向量检索 -> 把文档和问题一起交给 LLM
这在 demo 里能跑,在真实系统里却很容易被一追问就问穿。
因为不是所有 query 都是“知识检索题”。
举几个非常典型的例子:
- 事实型查询:
A 款保险的保障范围是什么? - 计算型查询:
我投保了 50 万,免赔额 5000,这次理赔能拿多少? - 数据库查询:
上个月理赔审批平均用了多少天? - 带时间约束的查询:
最新的车险理赔流程是什么? - 越界闲聊 / 无关问题:
今天天气怎么样?
如果你把它们都一股脑丢进检索链路,系统就会出现两类非常典型的错误:
- 该算的不算,只返回几段相关条款
- 该过滤的不过滤,把旧版本、错来源、错时间的内容一起召回
所以对我们来说,在线阶段的第一步不是“搜什么”,而是先判断这到底是不是一个该搜的问题。
Query 理解,先回答“走什么路”
这一步的目标不是生成答案,而是做调度。
系统需要先判断:
- 这是知识问答、计算、数据库查询,还是闲聊
- 是否带有时间、来源、产品名、指标口径这些隐藏约束
- 应该走默认检索、计算模块、结构化查询,还是直接拒答/转人工
换句话说,Query 理解模块更像整条链路的“调度员”。
意图识别,我们更倾向于分层兜底
如果只靠一套方法把所有 query 全包掉,通常不是太慢,就是不够稳。
更现实的方案往往是分层:
- 规则优先 对明显的“算一下”“平均值”“最新版本”这类 query,用规则先吃掉一批高确定性场景。
- 轻量分类器兜底 规则覆盖不到的,交给轻量模型判断语义意图。
- 低置信度再交给 LLM 只有在规则没命中、分类器也不够确定时,才让大模型做最终判定。
这样做的好处是,速度、成本和鲁棒性相对更平衡。
只识别意图还不够,还要抽取约束实体
很多 query 真正关键的信息,不在主语义里,而在隐藏约束里。
比如:
“昨天的那个理赔案例进展怎样了?”
这里至少有几个需要被抽出来的条件:
昨天:时间约束理赔案例:业务对象进展:查询目标
再比如:
“帮我算一下 A 款保险这次大概能赔多少?”
系统除了知道这是“计算型 query”,通常还得继续找:
- 产品名
- 保额 / 免赔额 / 赔付比例
- 是否存在上下文中已给出的输入参数
如果这些条件不先抽出来,后续不是检索会偏,就是计算会缺参数。
路由的关键,不是“复杂”,而是“别走错”
Query 理解后,系统才进入真正的路由决策:
- 知识问答:走检索链路,必要时加时间、来源、类型过滤
- 计算求解:直接走计算模块,而不是先去搜知识库
- 结构化数据查询:走数据库 / NL2SQL 链路
- 闲聊或越界问题:不进业务型 RAG,直接拒答或转通用对话
一个非常重要的原则是:
宁可保守默认,也不要把 query 自信地送错链路。
因为对用户体验来说,“该搜的问题被送去计算”通常比“先按默认检索兜底”更糟糕。
路由也需要回退机制
真实系统里,路由不是一次判完就结束。
比如:
- 计算模块发现参数缺失
- 结构化查询执行失败
- 时间过滤后候选为空
这时候系统不应该直接把错误抛给用户,而应该有机会:
- 回退到默认检索
- 追加澄清问题
- 或切换到更保守的回答策略
这也是为什么 Query 理解不是“锦上添花的前处理”,而是整条在线链路的稳定器。
六、回到面试场景,我们的在线链路怎么工作
当知识底座更可靠后,在线链路才有真正优化空间。
在面试产品里,我们更接近下面这条路径:
先做 Query 理解,再判断当前问题属于什么场景
不是所有问题都该用一套检索策略,也不是所有问题都该先检索。
我们会先判断它更像:
- 项目追问
- 行为面
- 系统设计
- 自我介绍 / 总结表达
- 高频基础题
同时也会判断它是否还带有:
- 时间约束
- 来源限制
- 当前岗位限定
- 需要先算、先查、还是先搜
这些信号一旦明确,后面的召回范围和处理链路就能明显收窄。
真正进入检索后,再做多路候选召回
一个面试问题,往往同时需要几类素材:
- 简历里的项目事实
- QA 里的现成表达
- 技术文档里的细节补充
- 最近几轮问答的上下文连续性
所以我们更倾向于多路候选并行,再做重排,而不是只依赖单一相似度。
重排不只是“谁更像”,还是“谁更该被讲出来”
在面试里,最怕的是命中很多内容,但全都不够适合当前问题。
所以重排时我们更看重:
- 是否贴近当前问题意图
- 是否来自更新鲜、结构更完整的资料
- 是否和当前岗位更相关
- 是否能支撑追问,而不是只能回答第一句
最后只拼“够用”的上下文
面试不是论文生成,长上下文不等于更好。
如果把一堆无关内容都塞进回答层,结果通常会变成:
- 更啰嗦
- 更模板化
- 更不像用户本人
所以我们的目标不是“把知识库尽量塞满”,而是把当前最应该说的那部分,尽量准确地拼出来。
七、如果面试官继续追问,你可以把这几个坑讲出来
下面这些点,通常最能区分“真的做过”还是“只是听过”。
坑 1:PDF 多栏排版导致语义顺序错乱
如果只按文本流抽取,多栏文档非常容易把左右两栏拼在一起,导致句子看起来有字,但已经没有可检索的语义。
坑 2:OCR 把表格和代码打平
扫描件、图片型 PDF、PPT 截图里的关键信息,往往不是“识别不到”,而是“识别出来后结构全坏了”。
对表格和代码,这种结构损失几乎是致命的。
坑 3:固定长度切分把完整流程切断
你以为自己做的是标准 chunking,面试官看到的却是:
- 一段完整流程被截成两半
- 标题和正文拆开了
- 结论在一个 chunk,理由在另一个 chunk
一旦这样,召回再努力,也很难还原完整答案。
坑 4:没有层级标签,导致在线阶段无法精准过滤
很多系统不是“检索不出来”,而是候选太杂,找不到该优先谁。
层级路径、来源信息、更新时间、内容类型这些标签,看起来不起眼,实际上决定了在线链路有没有可控性。
坑 5:所有 query 都走同一条检索链路
这是另一种非常常见、但也非常容易被面试官追着问穿的问题。
如果用户问的是计算题、结构化统计、时间受限查询、或者干脆是无关闲聊,你却统一送去向量检索,那就说明系统根本没有 Query 理解与路由层。
这类系统看起来“链路很短”,实际上鲁棒性很差。
八、如果面试官问“你们自己的 RAG 是怎么做的”,可以这样答
如果你想讲得既像做过工程,又不至于讲得太散,可以用这版结构:
我们没有把它当成一个通用企业知识库来做,而是按面试场景重构了一条 RAG 链路。对我们来说,真正关键的不只是在线召回,而是知识库底座怎么建,以及 query 进来以后系统先不先读懂它。离线阶段我们会把简历、项目 Markdown、QA 文档、扫描件这几类资料分开处理,重点解决多格式解析、版面结构保留、语义分块和层级标签问题,尽量让每个 chunk 都是一个可回答单元。在线阶段则先做 Query 理解,判断当前问题是项目追问、行为面、系统设计,还是需要计算、过滤、结构化查询;再进入多路候选召回和重排;最后只把当前问题真正需要的上下文送进回答层,避免长上下文把答案污染掉。我们内部更关注项目完整率、追问命中率、冲突率和端到端延迟,而不只是检索分数本身。
这段话的好处是,它同时把四件事讲清楚了:
- 你理解离线解析和知识库构建
- 你知道 Query 理解和路由为什么必要
- 你知道 chunking 和元数据为什么重要
- 你能把离线和在线联动起来讲
- 你知道面试场景和通用知识问答的差别
总结
很多人一聊 RAG,就急着讲模型、讲向量检索、讲 Rerank。
但在真实项目里,最容易决定上限的,往往是更底层的几个问题:
- 文档有没有被正确解析
- 结构有没有保住
- chunk 有没有切成可回答单元
- query 进来以后有没有先被正确理解和分流
- 元数据有没有补齐
- 在线阶段有没有按场景路由和按需拼上下文
面试场景下,我们想做的从来不是一个“会搜索的文档系统”。
我们更想做的是:
一套能把用户资料真正组织成面试回答,并且能撑住追问的 RAG 方案。
相关阅读:
Interview AiBoxInterview AiBox — 面试搭档
不只是准备,更是实时陪练
Interview AiBox 在面试过程中提供实时屏幕提示、AI 模拟面试和智能复盘,让你每一次回答都更有信心。
AI 助读
一键发送到常用 AI
智能总结
深度解读
考点定位
思路启发
分享文章
复制链接,或一键分享到常用平台