Agent 面试通关 / 09
RAG 与检索系统:从 chunk 设计到多路召回
RAG 是 Agent 系统的“外部知识接口”。面试官考 RAG 时不想听“向量数据库”四个字——他想知道的是离线怎么切片、在线怎么召回、召回后怎么排序,以及面对复杂查询时怎么做改写和意图识别。
检索基础与原理
Q:多维度的查询改写是什么?改写遇到需要用户补充信息时怎么设计?
来源:抖音基础架构 Agent 一面【淘天一面追问:改写为何提升精准度的底层原理】【美团 Agent 开发一面追问:短 Query 与长 Chunk 的非对称召回】【阿里巴巴(淘天)- 大模型算法岗(搜推方向)追问:淘宝搜索中如何用大模型做 Query 理解和改写?】【美团 - Agent 开发岗(场景设计方向)追问:RAG 召回不相关时 Query Rewrite 优化举例?】;本轮追问:如果让你优化小红书搜索的Query理解,你会用大模型做什么?(小红书多模态秋招二面);本轮追问:能否举例说明改写逻辑,以及改写前后的问题分别是什么?例如用户问“知识库里有哪些知识”,或者结合项目中的电商场景说明。 / 问题改写和子问题拆分,是在一次模型推理中完成,还是需要多次调用模型?(字节 Agent 秋招二面);0924恒生电子|AI 应用开发工程师 |AI面
新手答:“用大模型把用户的查询扩展一下。”
高手答:
多维度查询改写是指同时从多个角度对原始 query 做变换,提升召回的全面性:
原始 query:"北京周末带娃去哪玩"
维度1-意图展开:亲子活动 / 儿童乐园 / 博物馆 / 户外游
维度2-实体补全:北京市 → 朝阳区/海淀区/...
维度3-同义改写:"带娃" → "亲子" / "儿童" / "适合小朋友"
维度4-约束提取:时间=周末,地点=北京,人群=有孩子的家庭
需要用户补充信息时,用槽位填充 + 主动澄清机制:
- 意图识别后,检查必要槽位是否完整(比如“订酒店”需要日期、城市、人数)
- 缺失槽位时,不是笼统地问“你能说得更清楚吗”,而是生成具体的选择题:“你想去哪个城市?”或“入住日期是什么时候?”
- 多个槽位都缺时,按优先级排序,先问最关键的
技术实现上,查询改写用模型生成 + 规则约束混合:模型负责语义理解和改写,规则负责实体标准化和格式校验。槽位检测用一个轻量分类器判断缺失情况,避免每次都调大模型。
优化小红书搜索的 Query 理解,可让大模型识别内容意图、主题实体、地点时间、人群和风格等约束,处理口语、省略词及中英文混杂,并结合用户上下文生成结构化 Query。对美妆、旅行等场景还可抽取图片或笔记中的视觉属性,随后用规则校验、召回与精排结果及人工标注集评估改写是否引入意图漂移。
改写可先输出结构化意图、实体和约束,再生成多条检索 Query。例如“知识库里有哪些知识”可改为“知识库主题分类有哪些”“各主题下有哪些文档”,电商中“适合夏天的女装”可补成季节、性别、品类等条件。实现上可一次模型调用同时完成改写与拆分;若需澄清槽位、校验结果或根据召回反馈迭代,则采用多次调用,并设置次数与长度上限。
追问补充:对明确指向旧知识的 Query,应先识别时间、版本、发布日期等锚点,并将其作为不可改写约束;按知识版本或生效时间路由、过滤候选,禁止改写结果覆盖原始时间条件。召回后用原 Query 与改写 Query 交叉校验,离线重点评估旧知识命中率和时间漂移率。
差距在哪:新手的“扩展一下”是单维度思考。高手的多维度改写覆盖了意图、实体、同义、约束四个角度,且有用户交互的槽位填充机制。面试官考的是你对查询理解链路的完整认知。
追问:Query 改写为什么能提升召回精准度?底层原理是什么?
改写不是“让 query 变长”,而是解决 query 和文档之间的三类鸿沟:
| 鸿沟类型 | 问题 | 改写如何解决 | 示例 |
|---|---|---|---|
| 词汇鸿沟 | 用户用词 ≠ 文档用词 | 同义扩展弥合词汇差异 | “手机卡” → “SIM 卡 / 流量卡 / 电话卡” |
| 意图鸿沟 | 短 query 意图模糊 | 意图展开消除歧义 | “苹果” → “Apple 公司 / 苹果水果”(结合上下文选择) |
| 粒度鸿沟 | query 太宽泛或太细碎 | 拆分/合并调整检索粒度 | “怎么部署” → “Docker 部署 + K8s 部署 + 物理机部署” |
为什么多维度改写比单次改写效果好:单次改写只能沿一个方向扩展,可能强化了某个意图但遗漏了其他。多维度改写用多条路径并行检索再合并,Recall 提升显著(实测 +15~25%),但 Precision 可能下降——所以改写后必须接 Rerank 精排过滤噪声。
追问:Query 只有几个字,Chunk 却很长,直接比较 Embedding 会有什么问题?
长度差异本身不是判错条件,真正的问题是信息粒度不对称:短 Query 意图不完整,长 Chunk 又可能混有多个主题,单个向量会把局部相关信号平均掉。先按线上 Query 长度、意图完整度和 Chunk 主题数切片评测,确认失败来自歧义、词汇鸿沟还是向量稀释,不能看到短 Query 就无条件扩写。
治理可以分三层:查询侧结合会话补全实体与约束,生成多条受控改写;文档侧用父子索引或多向量表示,让标题、摘要、子段分别参与召回;检索侧并行 BM25、稠密向量和 metadata filter,再用原始 Query 对候选精排。评测同时看短 Query 分桶的 Recall@K、最终答案正确率和改写引入的误召回,避免只把 Query 变长却改变用户意图。
Q:RAG 的检索如何实现?
来源:阿里 AI Agent 开发一面;钉钉一面;本轮追问:你的父子切割具体是如何实现的?(本轮追问);本轮追问:保留了向量检索或混合检索接口,具体怎么实现?(小红书 Product Engineer(AI与全栈方向)-社区工程 一面面经);27秋招-恒生电子AI面试-AI应用开发岗-26.9.23;多益网络面试;度小满 - AI 全栈研发 - 一面;乐堡AI应用开发岗四面面经,面试官非常nice!
新手答:“用向量数据库做相似度搜索。”
高手答:
RAG 检索分离线和在线两部分。
离线侧负责文档清洗、切片、去重、embedding 计算和向量入库。在线侧的流程是:
- 用 query 编码成向量,去向量库做召回
- 结合 BM25 或关键词检索做混合召回
- 用 rerank 模型重排
- 把最相关的证据拼接给大模型生成答案
# 简化版 RAG 检索流程
query_vec = embed(query)
candidates = vector_db.search(query_vec)
bm25_docs = bm25.search(query)
merged = merge_and_dedup(candidates, bm25_docs)
reranked = reranker.rank(query, merged)
context = "\n".join(doc.text for doc in reranked[:top_k])
answer = llm.generate(query, context)
切片策略直接影响效果:块太大召回不准,块太小上下文断裂。通常用滑窗切割 + overlap,对长文档还会给每个 chunk 带上标题、章节路径、来源元信息,提升召回相关性。
工程上可抽象统一检索接口,输入 query、过滤条件和 top_k,输出带分数及来源的文档;向量库与 BM25 分别实现适配器。混合召回可用加权归一化或 RRF 融合,随后去重、按权限和元数据过滤,并对任一检索源超时设置降级与日志,验证各路召回量、融合结果和延迟。
差距在哪:新手只说了“向量数据库”——这是一个组件,不是方案。高手的回答覆盖了离线和在线两条链路,且点出了 chunk 设计这个影响效果的关键因素。面试官考的是你对 RAG 工程的完整认知。
Q:讲一下项目里召回的流程
来源:抖音基础架构 Agent 一面;本轮来源;本轮来源;本轮来源;本轮追问:讲一下完整的 RAG 流程。(小红书 Product Engineer(AI与全栈方向)-社区工程 一面面经);美团一面全栈开发日常实习面经
新手答:“用向量搜索召回相关文档。”
高手答:
召回是一个多路召回 → 合并去重 → 精排的三阶段流程:
第一阶段:多路召回
┌→ 向量召回(语义相似度,覆盖同义表达)
改写后 query ──┼→ 关键词召回(BM25,覆盖精确匹配)
├→ 标签召回(实体/品类标签匹配)
└→ 图召回(知识图谱关联路径)
每路召回各取 top-K,各有优势:向量召回抓语义,关键词召回抓精确词,标签召回抓结构化属性,图召回抓实体关系。
第二阶段:合并去重
多路结果合并,同一文档被多路召回的加分。去重用文档 ID 做精确去重 + 内容指纹做近重复去重。
第三阶段:精排
用 Cross-Encoder 或精排模型对候选集做细粒度相关性打分。精排模型能看到 query 和文档的交互特征,精度远高于召回阶段的双塔模型。关键工程细节:每路召回的 K 值怎么定——K 太小漏结果,K 太大精排压力大,通常根据各路历史准确率动态调整。
完整 RAG 还包括离线知识入库与在线问答:先对文档解析、切分、清洗,生成向量并写入向量库,同时保留元数据;请求到达后做意图识别、改写和权限过滤,再执行多路召回、重排与上下文拼接,交给大模型生成答案,并返回引用来源。需通过召回率、答案准确性、引用正确性和延迟评估闭环。
差距在哪:新手只知道向量检索一路。高手的多路召回 + 精排是搜索系统的标准范式,面试官考的是你对召回-精排两阶段架构的完整理解。
Q:并行化意图识别是什么?为什么要并行化?如何实现的?
来源:抖音基础架构 Agent 一面;9.14字节推荐架构一面
新手答:“用多线程跑意图分类。”
高手答:
并行化意图识别是指同时执行多个意图维度的判断,而不是串行地先判大类再判小类。
串行方案的问题是链路长、延迟高。比如先判“是不是搜索意图” → 再判“搜索什么品类” → 再判“有没有比较意图”,三级串行加起来可能 300ms+。而且前一级判断错了,后面全错——错误级联放大。
并行化把多个维度同时发出去:
┌→ 意图大类分类器(搜索/导航/交易)
user query ──┼→ 品类识别器(美食/旅游/购物/...)
├→ 行为意图检测器(比较/推荐/查询/...)
└→ 情感倾向检测器(正面/负面/中性)
每个分类器独立运行,结果汇总后做融合决策。实现关键点:
- 各分类器用异步并发执行(
asyncio.gather或线程池),总延迟 = 最慢的那个 - 每个分类器可以用不同规模的模型——简单维度用小模型,复杂维度用大模型
- 设置超时兜底:某个分类器超时不影响其他维度,用默认值填充
差距在哪:新手的“多线程”只答了实现手段,没答为什么要并行化。高手先解释了串行方案的问题(延迟高 + 错误级联),再给出并行化的架构和融合策略。面试官考的是性能优化思维。
Q:如果 RAG 召回了很多相互矛盾的文档,Agent 应该怎么处理,而不是直接让模型自己总结?
来源:腾讯大模型应用开发二面
新手答:“让模型自己综合判断。”
高手答:
不能直接把矛盾文档一股脑丢给模型让它自己“综合”,那样很容易生成一个看起来圆滑但实际上没有依据的答案。
更合理的做法是先做证据归一化和冲突检测:
- 分组:按来源、时间、可信度对召回文档分组
- 冲突检测:抽取同一字段的不同取值,判断冲突类型——是时间差异导致的,还是来源本身互相打架
- 冲突消解:
- 时间敏感信息 → 新版本优先
- 来源权威性不同 → 官方文档优先
- 无法判断 → 明确告诉用户存在冲突,说明目前最可信的依据
Agent 在这里更像证据调解器,而不是万能总结器。核心是在模型生成前就把冲突处理好,而不是让模型在矛盾信息中自己编一个“看起来合理”的答案。
差距在哪:新手直接把矛盾丢给模型——这会生成看似合理但无依据的答案。高手在模型生成前加了冲突检测和消解层,按时间、权威性、可判断性三个维度做处理。面试官考的是你有没有意识到 RAG 不只是“召回 + 生成”,中间还需要证据治理。
检索算法与微调
Q:RAG 中如何提高文档召回率?
来源:蚂蚁集团智能体与大模型应用一面;本轮追问:如果 RAG 检索时文档内明明存在目标内容但召回失败,你会怎么一步步排查定位问题?(本轮追问);阳光电源 AI应用开发工程师 一面;字节跳动Agent开发1面凉经;本轮追问:RAG 可以使用哪些召回方式? / 如何保证 RAG 召回结果的准确度? / 如何通过 Query Rewrite、调整 TopK、替换模型等方式优化召回?(字节 aime 一面 9.10);九方智投 一面凉经;小红书 Product Engineer(AI与全栈方向)-社区工程 一面面经;本轮追问:最初测召回时,20条召回结果里会漏掉正确的文档片段,当时你们是怎么一步步排查定位出漏召的根本原因的?(27秋招-恒生电子AI面试-AI应用开发岗-26.9.23);本轮追问:RAG 的召回率一般从哪些角度提升?父子文档索引解决什么问题?(字节 AI Agent 开发 一面(抖音电商 · 一面掉池子里面了));度小满 - AI 全栈研发 - 三面;美团一面全栈开发日常实习面经
新手答:“换更好的 Embedding 模型。”
高手答:
召回率低意味着正确文档没有进入候选集——模型连看到正确答案的机会都没有。提升召回率要从离线和在线两端同时入手:
离线端——提升文档的“可被检索性”:
- Chunk 策略优化:
- 块太大 → 一个 chunk 混了多个主题,语义被平均化,精准匹配变弱
- 块太小 → 上下文断裂,语义不完整
- 最佳实践:语义分块(按段落/标题/逻辑边界切割)+ overlap(相邻 chunk 重叠 10-20%)
- 文档增强:给每个 chunk 附加元信息——标题、所属章节、关键词标签、生成摘要。检索时不只匹配 chunk 正文,还匹配元信息
- Embedding 模型适配:通用模型在专业领域(医疗/法律/代码)的表现可能大幅下降。用业务数据微调 Embedding 模型,Recall 通常能提升 10-20%
在线端——提升查询的“被理解度”:
- 查询改写:用大模型对用户 query 做多维度改写(同义替换、意图展开、实体补全),从不同角度匹配文档
- 混合召回:不只用向量检索,同时用 BM25 关键词检索 + 标签检索,多路结果合并。向量路抓语义,关键词路抓精确匹配,互补覆盖
- HyDE(Hypothetical Document Embeddings):让模型先生成一个“假设性答案”,用这个答案的 embedding 去检索——因为答案和文档的语义更接近,比直接用 query 检索效果好
flowchart TB
Q["用户 Query"] --> QR["查询改写\n(多维度)"]
Q --> HY["HyDE\n生成假设答案"]
QR --> VR["向量召回"]
QR --> KR["关键词召回"]
QR --> TR["标签召回"]
HY --> VR2["向量召回"]
VR --> M["合并去重"]
KR --> M
TR --> M
VR2 --> M
M --> RR["ReRank 精排"]
RR --> TOP["Top-K 结果"]
效果最大的三板斧:根据实践经验,混合召回 > chunk 优化 > Embedding 微调。很多团队一上来就微调模型,其实先加一路 BM25 召回就能显著提升 Recall。
TopK 不能只凭经验设置,应在标注评估集上做 K 值消融,观察 Recall、答案准确率、延迟和上下文成本;召回后用 Rerank 按 query 与 chunk 的细粒度相关性重排,并结合阈值过滤。若仍失败,再对比不同 Embedding 模型及领域数据微调效果。
排查时先用标注集确认漏召,再逐层检查文档是否入库、切片边界、Embedding、索引、权限过滤、Query 改写和 TopK,并用关键词检索与向量检索对照定位。父子索引让小子块负责精准召回、父块补充完整上下文,兼顾命中率与可读性。
追问补充:针对数据坍缩,应做近重复检测、去重和多样性约束,避免 TopK 被同一文档或模板占满;噪声问题则通过来源质量过滤、元数据权限过滤、相关性阈值与 Rerank 截断处理。用标注集分别评估 Recall、噪声率和结果多样性,定位是索引污染还是排序偏置。
差距在哪:新手只想到换模型。高手从离线端(chunk/文档增强/Embedding 微调)和在线端(查询改写/混合召回/HyDE)六个方向给出了完整方案,且点出了优先级排序。面试官考的不是你知不知道某个技术,而是你能不能系统性地优化一条 RAG 管线。
Q:RAG 为什么需要向量检索?和传统关键词检索有什么本质区别?
来源:蚂蚁集团智能体与大模型应用一面【拼多多 复活赛 一面追问:关键词 / 倒排这种方式有明显局限,比如“苹果”和“apple”可能匹配不上,你们怎么看?】【百度Agent一面追问:BM25 和向量检索分别解决什么类型的问题?】;字节全栈一面;本轮追问:简历里写了多种检索方式,分别是什么,为什么需要这么多种?(字节Agent开发后端 日常实习一面凉面)
新手答:“向量检索更准。”
高手答:
不是“更准”——是解决了不同的问题。传统检索和向量检索的核心差异在于匹配方式:
| 维度 | 传统关键词检索(BM25) | 向量检索(Embedding) |
|---|---|---|
| 匹配方式 | 词级精确匹配 | 语义级相似度匹配 |
| 核心算法 | TF-IDF / BM25 | ANN(近似最近邻) |
| 能处理同义词 | ❌ “退货”搜不到“退款” | ✅ 语义相近就能匹配 |
| 能处理精确术语 | ✅ 搜“order_id=123”直接命中 | ❌ 向量化后精确性丢失 |
| 计算成本 | 低(倒排索引,O(1)级) | 高(向量距离计算 + ANN 索引) |
| 索引存储 | 小(倒排表) | 大(每条文档一个高维向量) |
| 对新词/专业术语 | 好(只要文档里有就能匹配) | 差(模型没见过的词 embedding 质量低) |
RAG 为什么需要向量检索:
用户提问的方式和文档的表述方式几乎不可能完全一样。用户问“服务器老是挂”,文档里写的是“服务可用性异常”——没有一个共同关键词,但语义完全匹配。传统检索在这种场景下召回率为零,向量检索能轻松解决。
但向量检索不能完全替代关键词检索:
查具体的错误码(ERR_CONNECTION_REFUSED)、精确的文件路径、特定的 API 名称——这些场景关键词检索比向量检索更快更准。向量化反而会把精确信息“模糊化”。
生产环境的最佳实践是混合检索:
向量检索(语义匹配)─┐
├→ 合并去重 → ReRank 精排 → Top-K
关键词检索(精确匹配)─┘
两路互补:向量路保证语义覆盖,关键词路保证精确命中。合并后用 ReRank 统一排序。
差距在哪:新手用“更准”一词概括——其实向量检索在精确匹配上反而不如关键词检索。高手明确了两者的优劣势互补关系,且指出生产环境用混合检索。面试官考的是你对检索系统的工程认知——不是“哪个更好”,而是“什么场景用什么”。
Q:RAG 系统检索到的文档很多但回答质量差,怎么排查?
来源:携程 Agent 开发实习一面;本轮追问:如何权衡上下文召回率和答案正确率的?(顺丰线下面(成都)ai开发工程师);本轮追问:如何判断问题出在切片、召回、重排还是生成阶段?(字节 aime 一面 9.10);本轮追问:如果企业内部有大量存在表述差异但高度相关的文档,比如不同部门对同一业务流程的不同口径记录,传统检索加生成会出现什么核心问题?(27秋招-恒生电子AI面试-AI应用开发岗-26.9.23);秋招-字节跳动-抖音电商-Agent开发一/二/三面
新手答:“可能是模型不够好,换个更强的模型。”
高手答:
“检索多但回答差”说明问题大概率不在模型,而在检索质量和上下文组装。排查按链路从前到后逐段定位:
1. 检索相关性差(召回了但不准):
- 症状:返回的文档和用户问题表面相关但实际不对口
- 排查:抽样看 top-K 文档和 query 的匹配度,计算 Recall@K / Precision@K
- 常见原因 + 解法:
- Embedding 模型领域适配差 → 用业务数据微调 Embedding
- Chunk 切分不合理(太大导致噪声多,太小导致上下文断裂)→ 调整 chunk size 和 overlap
- 缺少多路召回 → 加 BM25 关键词路补充精确匹配
2. 排序失效(相关文档排在后面):
- 症状:相关文档确实被召回了,但排在第 8、9 位,top-3 都是噪声
- 排查:对比有无 ReRank 时的排序效果
- 解法:加 Cross-Encoder ReRank 模型做精排;或微调 ReRank 模型
3. 上下文组装问题(给模型的信息太杂):
- 症状:top-K 文档质量还行,但模型回答仍然差
- 排查:直接看拼给模型的 context,是不是信息太多、互相矛盾、或关键信息被淹没
- 解法:减少 top-K(从 10 降到 3-5);对召回文档做摘要提取再喂给模型;加冲突检测
4. Prompt 模板问题:
- 症状:换了更好的检索结果,回答质量还是没提升
- 排查:检查 Prompt 是否清晰指示模型“基于以下资料回答,如果资料不足请说明”
- 解法:优化 Prompt 模板,加引用约束
权衡时建立带标准答案或证据标注的离线样本,同时看 Recall@K、答案正确性和引用一致性;逐步调整 K、重排阈值及上下文预算。召回不足优先扩大覆盖,噪声过多则收紧过滤或精排,不能只追求单一指标。
多部门文档口径不一致时,核心问题不是召回不足,而是证据冲突与权威性不明:系统可能混合不同生效时间、适用范围和流程版本,生成模型难以判断应采信哪份,容易拼接出看似完整但实际错误的答案。应保留部门、版本、生效时间等元数据,按权限和时效过滤,并在冲突时返回差异、要求澄清或升级人工确认。
追问补充:切分后通常按“查询改写→混合召回→重排→去重与上下文组装→生成→引用校验”形成答案。生成阶段只允许依据检索证据作答,证据不足时明确拒答;同时保留 chunk 的来源和页码,便于核验答案是否被证据支持。
差距在哪:新手第一反应是“换模型”——这是最贵且通常无效的做法。高手按 RAG 链路逐段排查(检索 → 排序 → 组装 → Prompt),每段都有具体的症状、排查方法和解法。面试官考的是你排查问题时的系统性思维。
Q:什么是余弦相似度?在 RAG 系统中用来做什么?
来源:携程 Agent 开发实习一面【9.4 某小厂 AI Agent hr+技术面追问:在向量检索召回阶段,度量 Query 与文档向量相似度的常用算法是什么?】;美团AI全栈一面,AICoding把我整不会了
新手答:“衡量两个向量的相似程度。”
高手答:
余弦相似度衡量的是两个向量方向的接近程度,不关心长度,只关心角度:
cos(A, B) = (A · B) / (|A| × |B|)
值域:[-1, 1]
1 = 方向完全一致(语义最相似)
0 = 正交(语义无关)
-1 = 方向完全相反(语义相反)
为什么用余弦而不是欧氏距离:
Embedding 模型输出的向量,不同文本的向量长度(模)可能差异很大。如果用欧氏距离,一段长文本和一段短文本即使语义相同,距离也可能很远(因为向量模不同)。余弦相似度归一化了长度,只比较方向——语义相同的文本,无论长短,余弦相似度都接近 1。
在 RAG 系统中的用途:
- 检索阶段:用户 query 向量和文档库中所有文档向量计算余弦相似度,取 top-K 作为候选
- 去重阶段:两个 chunk 的余弦相似度 > 0.95,判定为近重复,去掉一个
- 阈值过滤:相似度低于阈值(如 0.6)的文档直接丢弃,不进入精排——避免把完全不相关的文档喂给模型
补充:实际向量数据库(Milvus / Qdrant)在 ANN 检索时用的是近似最近邻算法(HNSW / IVF),不是暴力遍历所有向量。精确的余弦计算只在小规模候选集上做。
差距在哪:新手只背了定义。高手从公式、为什么选余弦而非欧氏、在 RAG 中的三个具体用途(检索/去重/过滤)做了完整解释,且补充了工程实现细节。面试官考的是你理解了这个指标的设计动机,而不只是会算。
Q:什么是嵌入(Embedding)?为什么 RAG 系统需要将文本转为向量?
来源:携程 Agent 开发实习一面;本轮追问:为什么 RAG 既要 embedding 又要 rerank?(中兴未来领军计划AI算法一面);本轮追问:向量化具体是怎么做的?(字节全栈一面);合肥某头部企业软件开发实习生面试问题汇总(时长1个小时)
新手答:“把文本变成数字,方便计算。”
高手答:
嵌入(Embedding)是把文本映射到一个高维向量空间中的过程——每段文本变成一个固定长度的数字数组(如 768 维或 1536 维),这个数组就叫这段文本的“向量表示”。
关键特性:语义相近的文本,在向量空间中的位置也相近。
"北京今天天气很好" → [0.12, -0.45, 0.78, ...] ─┐
"今日北京晴朗" → [0.11, -0.43, 0.76, ...] ─┘ 向量接近
"明天股市走势如何" → [-0.67, 0.23, -0.11, ...] ← 向量远离
为什么 RAG 需要向量化:
传统检索靠关键词匹配——用户搜“怎么退货”,系统只能找到包含“退货”两个字的文档。但用户可能问的是“买错了怎么办”“商品不满意能换吗”——意思一样,但没有一个共同关键词。
向量化解决的是语义匹配问题——“怎么退货”和“商品不满意能换吗”的 Embedding 向量很接近,即使没有共同关键词也能检索到。
Embedding 模型的选型考量:
- 通用模型:OpenAI text-embedding-3、BGE、E5、GTE——开箱即用,适合大部分场景
- 领域微调:如果业务术语多(医疗、法律、金融),通用模型可能把业务术语和日常用语混淆,需要用业务数据做微调
- 维度和性能的权衡:维度越高表达力越强,但存储和计算成本也越高。768 维是常见平衡点
Embedding 通常按文档清洗、分块、生成向量、写入向量库完成;查询时对问题向量召回候选。Rerank 再用更精细的交叉编码器结合问题与候选全文重排:前者覆盖面和速度好,后者精度高但成本大,因此常先多召回、再重排少量结果。
差距在哪:新手的“变成数字”没有解释为什么要这么做。高手从语义匹配的角度解释了向量化的动机——解决关键词匹配的语义鸿沟问题,且覆盖了模型选型的实际考量。面试官考的是你理不理解 Embedding 在 RAG 管线中的核心作用。
追问:Embedding 的本质是什么?向量的每个维度代表什么含义?
来源:小红书 AI应用开发
Embedding 的本质是将离散符号映射到连续向量空间,使语义关系可以用几何距离衡量。但很多人会追问:向量的每个维度到底是什么意思?
每个维度不是一个可解释的特征——这是 Embedding 和传统特征工程的根本区别:
| 对比 | 传统特征向量 | Embedding 向量 |
|---|---|---|
| 每个维度 | 有明确含义(年龄、价格、频率) | 无单一可解释含义 |
| 表示方式 | 人工设计的特征 | 模型自动学到的潜在特征 |
| 信息分布 | 每维独立编码一种信息 | 一种语义分布在多个维度上 |
| 术语 | 特征工程 | 分布式表示(Distributed Representation) |
什么是分布式表示:一个语义概念(如“食物”)不是由某一个维度单独表达,而是由多个维度的组合模式来表达。反过来,一个维度也参与了多个语义概念的编码。这就是为什么单看某一维的数值没有意义,但整体向量之间的距离能反映语义相似性。
维度数量的工程权衡:
低维(256-384):存储小、速度快,但语义区分度有限,适合简单场景
中维(768): 最常见的平衡点,大多数场景够用
高维(1024-3072):区分度更高,能捕获更细粒度的语义差异,但存储和计算成本线性增长
面试加分点:如果面试官继续追问“能不能让每个维度可解释”,可以提到 Sparse Embedding(如 SPLADE)——它在词表维度上做稀疏编码,每个维度对应一个 token,可解释性强但维度极高(30000+)。这也是为什么实际系统常用 Dense + Sparse 混合检索——Dense 捕获语义,Sparse 保留精确匹配能力。
Q:Embedding 和 ReRank 模型具体怎么做的微调?
来源:腾讯 AI 应用开发 【腾讯AI应用开发一面追问:重排序完整实现流程】;本轮追问:直接使用预训练 Cross-Encoder,训练目标和你的业务场景并不一致,如何保证效果?(字节Agent开发后端 日常实习一面凉面)
新手答:“用自己的数据训练一下。”
高手答:
Embedding 模型微调:
目标是让模型在业务领域里,把语义相近的 query 和文档映射到向量空间中的相近位置。
训练数据格式:(query, positive_doc, negative_doc) 三元组。hard negative 越难越好——随机采样的 negative 太简单,模型学不到有区分度的表示。用 BM25 或当前模型 top-K 中的非相关文档做 hard negative。
常用 loss:
- MultipleNegativesRankingLoss(sentence-transformers 最常用):batch 内其他 query 的 positive 自动作为 negative,不需显式构造
- InfoNCE / Contrastive Loss:拉近 positive pair,推远 negative pair
- Triplet Loss:
max(0, d(q, pos) - d(q, neg) + margin)
框架:sentence-transformers 最成熟,支持 BGE、E5、GTE 等预训练模型的微调。
ReRank 模型微调:
ReRank 是 Cross-Encoder——输入是 (query, doc) 拼接后一起过模型,输出相关性分数。比 Embedding 双塔精度高,但计算量大,只用于精排。
训练数据:(query, doc, label),label 是相关性分数或 0/1 标签。Loss 用 BCE 或 MSE。
微调关键细节:
- Hard Negative Mining:negative 质量决定微调效果
- 评估指标:用 Recall@K、MRR、NDCG 在验证集上评估,不是看 loss 降了就行
- 防止过拟合:微调轮数不宜过多(1-3 epoch),否则通用检索能力退化
不能假设预训练 Cross-Encoder 的通用分数等于业务相关性。应从线上点击、人工标注和失败检索中构造业务正负样本,补充同主题 hard negative,按业务标签做校准或排序微调,并用时间切分和关键查询集比较 NDCG、MRR 及下游命中率;上线先灰度,监控分布漂移和误杀。
差距在哪:新手只说了“用数据训”。高手覆盖了完整链路——数据构造(三元组 + hard negative)、loss 选择、框架、评估、防过拟合。面试官考的是你有没有真正微调过检索模型。
Q:如何用通俗易懂的方式向非技术人员解释 RAG?有没有好的类比?
来源:携程 Agent 开发实习一面;本轮追问:讲下 LangChain 和 RAG(腾讯元宝 风控实习一面);字节跳动Agent开发1面凉经
新手答:“就是让模型先搜索再回答。”
高手答:
给非技术同事解释 RAG,我会这么说:
一句话版本:RAG 就是让 AI 在回答问题之前,先去翻资料,而不是纯靠记忆回答。
图书馆类比(最直观):
flowchart LR
subgraph no_rag["❌ 没有 RAG"]
direction LR
Q1["你提问"] --> E1["专家凭记忆回答"]
E1 --> R1["知识可能过时\n细节可能记错\n还可能自信地编答案"]
end
subgraph with_rag["✅ 有 RAG"]
direction LR
Q2["你提问"] --> S["检索员去书架\n找最相关的资料"]
S --> E2["专家翻阅资料后回答"]
E2 --> R2["答案有据可查\n知识随时可更新"]
end
核心价值(三点):
- 知识实时性:模型训练数据有截止日期,但外部知识库可以随时更新——今天新上线的产品文档,明天就能被检索到
- 可追溯性:回答附带引用来源,用户可以点击查看原文,建立信任
- 降低幻觉:有资料做依据,模型不容易“编”答案
主要应用场景:企业知识库问答(内部文档/FAQ)、客服系统(产品手册检索)、法律/医疗等需要精确引用的领域、代码文档助手。
LangChain 是编排这条链路的开发框架:可把提示词、模型、检索器、文档切分与引用输出串成可替换组件,并支持多步链或 Agent;RAG 则是其中的应用模式,先检索外部知识,再把证据交给模型生成答案。
差距在哪:新手的解释太技术化,非技术人员听不懂。高手用图书馆类比把 RAG 的三个角色(用户 → 检索员 → 专家)讲清楚了,再用三点核心价值说明“为什么需要”。面试官考的不只是你懂不懂 RAG,还考你能不能把复杂概念讲给不同背景的人听——这是工程师的沟通能力。
Q:双路召回的 TopK,K 是如何确定的?有没有试过一个多召回点、一个少召回点?
来源:腾讯 AI 应用开发
新手答:“K 就取 10 或 20。”
高手答:
K 值要根据召回路的特性和下游精排的承载能力来定。
BM25 关键词召回:K = 10~20(精确匹配路,召回量不需要太大)
Embedding 向量召回:K = 20~50(语义路,覆盖面要大一些)
ReRank 精排后最终 TopK:K = 3~5(给模型的上下文不宜太多)
K 值调优方法:Grid Search 在评估集上搜索最优组合——固定一路 K,遍历另一路(5、10、20、30、50),合并去重后精排,用 Recall@K 和最终生成质量评判。
一多一少的策略:实际中确实会对不同路设不同 K:
- 向量路 K 大、BM25 路 K 小:向量覆盖面广但精度稍低,多召回交给 ReRank 筛;BM25 精确率高,少量就够
- 反过来也有场景:精确查询(订单号、型号)时 BM25 路 K 调大
关键权衡:K 越大覆盖率越高但噪声也多(ReRank 负担重、延迟增加);K 越小精度高但可能漏掉相关文档。生产环境通常还有延迟约束(“总检索时间不超过 200ms”),K 值要在 Recall 和延迟之间找平衡。
差距在哪:新手随便定一个 K。高手有系统的调优方法论——Grid Search + 不同路不同 K + 延迟约束。面试官考的是你调 RAG 参数时有没有数据驱动的方法。
Q:如何快速上手一个没接触过的技术(如向量数据库)?
来源:携程 Agent 开发实习一面
新手答:“看官方文档,跑个 Demo。”
高手答:
快速上手一个新技术,我的方法论是“倒金字塔学习法”——从应用场景倒推,不从底层原理开始:
第一步:搞清楚“它解决什么问题”(30 分钟)
不是先看原理,而是先理解:传统方案的痛点是什么?向量数据库比传统数据库多解决了什么?答案是——传统数据库只能精确匹配,而向量数据库能做语义相似度检索。这一步决定了你后面学的所有东西有没有方向感。
第二步:跑通一个最小可用的 Demo(2-3 小时)
选一个主流方案(如 Milvus / Qdrant / Chroma),跑通“文本 → Embedding → 入库 → 查询 → 返回结果”的最短路径。不要一开始就研究分布式部署、索引类型选择这些细节。
# 最小 Demo:Chroma
import chromadb
client = chromadb.Client()
collection = client.create_collection("demo")
collection.add(documents=["北京今天晴天", "上海明天下雨"], ids=["1", "2"])
results = collection.query(query_texts=["天气怎么样"], n_results=1)
第三步:对标项目需求,补齐关键知识点(1-2 天)
Demo 跑通后,对照项目需求列一个清单:需要什么索引类型(HNSW / IVF)?数据量级多大?需不需要过滤?需不需要持久化?然后按需深入,不铺开学。
第四步:踩坑 → 查 Issue → 形成经验(持续)
真正的理解来自踩坑。遇到问题先查 GitHub Issue 和社区讨论,很多坑别人已经踩过了。
差距在哪:新手的“看文档跑 Demo”没有方法论,容易在原理细节里迷失方向。高手的倒金字塔方法有明确的四步节奏——先理解价值、再跑通最短路径、再按需深入、最后靠实践沉淀。面试官考的是你的学习效率和自驱能力。
Q:如果用全量生产文档做关联性检索,用户每个问题要交互多少轮?有没有更高效的方案?
来源:蚂蚁集团智能体与大模型应用二面
新手答:“文档多了就慢一点,多检索几次。”
高手答:
全量文档场景的核心挑战是文档量级和查询效率的矛盾——几万甚至几十万份文档,用户一个问题不可能遍历所有文档找关联。
传统 RAG 的局限:
标准 RAG 是 query → embedding → top-K 召回。但当文档量大且内容跨领域时,单次召回很难覆盖所有相关信息。用户可能需要多轮追问才能拿到完整答案——每轮交互本质上是在“逐步缩小检索范围”。
更高效的方案:
1. 文档预处理——建立关联索引:
不等用户查询时才找关联,离线阶段就把文档间的关联性预计算好:
- 文档聚类:按主题对文档自动分组,查询时先定位到相关组,缩小搜索范围
- 知识图谱:从文档中抽取实体和关系,建立文档间的语义关联图。查询时沿着图谱做多跳检索,找到间接关联的文档
- 摘要索引:每份文档生成摘要,先用摘要做粗筛,再用原文做精排——两级检索比全量检索快很多
2. Multi-hop RAG——一次查询找到链式关联:
flowchart LR
Q["用户提问:\n这个服务为什么延迟高?"]
Q --> R1["第一跳:找到\n服务架构文档"]
R1 --> R2["第二跳:从架构文档\n发现依赖 Redis"]
R2 --> R3["第三跳:找到\nRedis 配置变更记录"]
R3 --> A["综合三份文档回答"]
Multi-hop RAG 让 Agent 自动做多轮检索,每一跳基于上一跳的结果生成新的子查询,沿关联链逐步深入。用户只问一次,Agent 内部自动完成多轮检索。
3. GraphRAG——结构化关联检索:
微软提出的 GraphRAG 方案:先从全量文档构建知识图谱和社区摘要,查询时在图上检索而非在文档上检索。优势是能找到文档间的隐式关联——两份文档没有共同关键词,但通过实体关系链接在一起。
差距在哪:新手认为全量文档只能“多搜几次”。高手给出了三种更高效的方案——预计算关联索引、Multi-hop RAG 自动多跳检索、GraphRAG 结构化关联。面试官考的是你对 RAG 架构演进方向的认知——从单次检索到多跳检索到图检索,是检索系统面对大规模文档的自然演化路径。
RAG 在 Agent 中的角色
Q:在渐进式披露的架构下,还需要 RAG 吗?RAG 的角色会怎么变?
来源:蚂蚁集团 Agent 开发二面;本轮追问:你怎么看 RAG?针对现在很多人所说的“RAG 不能用了”,请多方面分析一下,以及 LLM Wiki?(迅雷 Agent一面)
新手答:“模型上下文窗口越来越大,RAG 可能不需要了。”
高手答:
RAG 不会消失,但角色会发生本质变化——从“弥补模型知识不足”变成“渐进式披露架构的信息供给层”。
为什么上下文窗口变大不能替代 RAG:
即使窗口有 100 万 token,也不能把所有文档都塞进去:
- 成本问题:塞 100 万 token 的成本是塞 1 万 token 的 100 倍
- 精度问题:信息越多,模型在噪声中迷失的概率越大(Lost in the Middle)
- 实时性问题:长上下文解决不了“信息需要实时更新”的问题
所以不是“要不要 RAG”,而是“RAG 在新架构里扮演什么角色”。
RAG 在渐进式披露架构中的新角色:
传统 RAG:用户提问 → 检索文档 → 塞进上下文 → 生成回答(一次性、静态)
新角色 RAG:Agent 执行到某阶段 → 按需检索该阶段需要的知识 → 精确注入 → 继续执行(多次、动态)
| 维度 | 传统 RAG | 渐进式架构下的 RAG |
|---|---|---|
| 触发时机 | 用户提问时一次性触发 | Agent 执行过程中多次按需触发 |
| 检索粒度 | 和用户 query 匹配 | 和当前执行阶段的子目标匹配 |
| 结果用途 | 直接喂给模型生成答案 | 作为当前阶段的决策依据 |
| 生命周期 | 检索一次用到结束 | 阶段切换后可能需要重新检索 |
具体变化:
- 从“回答前检索”到“执行中检索”:RAG 不只在开头检索一次,而是 Agent 在规划、执行、验证各阶段都可能触发检索,每次检索的 query 不同
- 从“通用检索”到“阶段感知检索”:同一个用户问题,规划阶段需要检索的是“方法论文档”,执行阶段需要的是“API 文档”,验证阶段需要的是“规范标准”——检索策略随阶段变化
- 从“替代模型知识”到“精确注入运行时上下文”:RAG 的价值从“给模型不知道的知识”转变为“在正确的时机给出正确的精确信息”
“RAG 不能用”通常是检索、切分、评测或知识时效治理不到位,而非范式失效;应按场景比较关键词、向量、混合检索与长上下文,并用召回率、答案正确性和引用可追溯性验证。LLM Wiki 更适合作为结构化、可维护的知识源,仍需权限、版本和更新校验。
差距在哪:新手用“窗口大了不需要 RAG”的线性思维。高手看到了 RAG 在新架构下的角色转变——从一次性的知识注入变成多阶段的动态信息供给。面试官考的是你对 RAG 技术演进方向的理解,以及能不能把 RAG 放到更大的架构图景中思考。
Q:如果 RAG 返回了看似可信但实际过时的信息,你会怎么降低 Agent 被误导的概率?
来源:Agent 开发面试 30 题;虾皮agent开发一面;0924恒生电子|AI 应用开发工程师 |AI面
新手答:“定期更新知识库。”
高手答:
定期更新是必要的,但更新和检索之间一定有时间差——今天更新的文档可能要到明天才入库,而在这个窗口期内返回的就是过时信息。更根本的问题是:很多文档没有明确的“过期时间”,系统不知道它过时了。
需要多层防线:
第一层:离线端——给文档打时间标签和可信度标签
- 每个 chunk 存储文档创建时间、最后更新时间、来源权威等级
- 有明确时效性的内容(价格、政策、版本号)标记为“时效敏感”
- 建立文档更新监控——源文档变更后自动触发重新入库
第二层:检索端——时间感知的检索和排序
- 检索时对结果按时间新鲜度加权——同等相关性下,新文档排在前面
- 对“时效敏感”标签的 chunk,如果超过 TTL(如 30 天)直接降权或过滤
- 返回结果时附带时间元信息,让 Agent 知道证据的时效性
第三层:Agent 端——生成前做时效性判断
在 Prompt 中明确要求模型:
注意:以下检索结果附带了文档日期。如果信息可能已过时(如价格、政策、版本号),
请在回答中标注"此信息来源于 YYYY-MM-DD 的文档,建议确认是否仍然有效"。
模型看到日期后会主动判断时效性,并在回答中加上免责提示。
第四层:用户端——可追溯的引用
回答中附带引用来源和日期,让用户自行判断信息是否过时。这是最后一道防线——即使系统没发现过时,用户看到“来源:2024 年 3 月的文档”也会自己注意。
追问补充:若知识库无法治理,应采用“受限证据问答”而非强行选一条答案:先按来源权威性、时间和相互矛盾度筛选;冲突未解或证据过期时明确告知不确定性、展示冲突依据并拒答关键结论。允许外部工具时再做实时核验,否则要求用户提供新资料或转人工确认。
差距在哪:新手只想到“更新知识库”——这是必要但不充分的。高手从离线(时间标签)、检索(时间加权)、Agent(时效性判断)、用户(可追溯引用)四层构建了防过时信息的完整体系。面试官考的是你对 RAG 系统“证据可靠性”这个核心问题的工程化思考。
Q:如果检索结果很多但质量参差不齐,你会把控制点放在召回、重排,还是 Agent 规划层?
来源:Agent 开发面试 30 题;顺丰线下面(成都)ai开发工程师
新手答:“加 ReRank 重排就行。”
高手答:
三个控制点都需要,但投入产出比不同:
召回层——控制“进来什么”:
问题:召回 50 条,30 条不相关
解法:① 优化 query(多维度改写)② 收紧召回阈值 ③ 加关键词路补充精确匹配
效果:减少噪声进入下游,降低精排压力
召回层的控制是成本最低、效果最直接的——垃圾在入口就拦住,比在后面处理便宜得多。
重排层——控制“排在前面的是什么”:
问题:相关文档被召回了,但排在第 8 位,top-3 都是噪声
解法:用 Cross-Encoder 精排,把真正相关的推到前面
效果:精度提升显著,但增加延迟和计算成本
重排层解决的是顺序问题,前提是相关文档已经被召回了。如果召回阶段就漏了,重排也救不了。
Agent 规划层——控制“怎么用检索结果”:
问题:top-3 文档质量还行,但信息分散,模型拼出了错误答案
解法:Agent 在使用检索结果前做质量判断——
"这些证据是否足够回答问题?是否有矛盾?需不需要再查一次?"
效果:提升最终回答质量,但增加一轮模型调用
规划层是最后一道防线,也是唯一能做“再查一次”决策的地方。
优先级排序:
投入优先级:召回优化(成本低效果大)> ReRank(精度提升明显)> 规划层判断(兜底)
先把召回质量做好,再加精排提升排序,最后在 Agent 层做质量兜底。很多团队跳过前两步直接在 Agent 层“让模型自己判断”,这是最贵且最不可靠的做法。
差距在哪:新手只想到 ReRank 一个点。高手从召回、重排、规划三层分别分析了控制方法和投入产出比,且给出了明确的优先级排序。面试官考的是你对 RAG 质量控制的全链路思维。
Q:RAG 在 Agent 体系里应该被看成工具、记忆,还是推理前置步骤?
来源:Agent 开发面试 30 题
新手答:“RAG 就是个工具,需要的时候调一下。”
高手答:
RAG 在 Agent 体系里的定位取决于使用方式,三种定位都成立,适用场景不同:
当工具用——按需调用:
Agent 在执行过程中判断“我需要查资料”,主动调用 RAG 检索。这时 RAG 和其他工具(搜索、计算器)是同级的。
适用场景:开放性任务,Agent 不一定每次都需要检索。比如用户问“1+1 等于几”不需要 RAG,问“公司休假制度”才需要。
当记忆用——上下文扩展:
每次对话开始时,自动检索和当前话题相关的历史文档注入上下文。RAG 充当的是“长期记忆的检索接口”。
适用场景:垂直领域问答,几乎每次都需要外部知识。比如客服机器人,每个问题都要查产品文档。
当推理前置步骤——先检索再思考:
RAG 不是可选步骤,而是必经环节——先检索证据,再基于证据推理。模型不允许在没有证据的情况下直接回答。
适用场景:高准确性要求的场景(法律、医疗),必须有据可依。
| 定位 | 触发方式 | 适用场景 | 典型架构 |
|---|---|---|---|
| 工具 | Agent 主动调用 | 开放性任务 | ReAct + RAG Tool |
| 记忆 | 每轮自动注入 | 垂直领域问答 | RAG-augmented Chat |
| 前置步骤 | 强制先检索 | 高准确性要求 | Retrieve-then-Read |
实际生产中这三种往往混合使用:基础知识自动注入(记忆模式),需要深入查找时主动调用(工具模式),关键结论必须有证据支撑(前置步骤模式)。
差距在哪:新手把 RAG 固定为“工具”一种定位。高手看到了 RAG 在 Agent 体系中的三种不同角色,且说清了各自的适用场景和触发方式。面试官考的是你对 RAG 和 Agent 系统集成方式的灵活理解。
Q:Agent 场景下,什么时候该做一次检索、多次使用;什么时候该边执行边检索?
来源:Agent 开发面试 30 题
新手答:“复杂问题多查几次。”
高手答:
判断标准是信息需求在任务开始时是否完全可知:
一次检索、多次使用(Retrieve-once):
适用条件:
- 任务开始时就能确定需要什么信息
- 信息需求不会随执行过程变化
- 检索结果在整个任务周期内有效
典型场景:
- 客服问答:用户问"退货政策是什么"→ 一次检索产品文档,回答完整问题
- 报告生成:给定主题,一次性检索所有相关数据,然后生成报告
- FAQ 类问答:一问一答,信息需求明确
优势是延迟低、成本低,只调用一次检索管线。
边执行边检索(Iterative Retrieval):
适用条件:
- 下一步需要查什么取决于上一步的结果
- 任务目标可能在过程中细化或变化
- 单次检索无法覆盖所有需要的信息
典型场景:
- 故障排查:"服务挂了"→ 查架构文档 → 发现依赖 Redis → 查 Redis 变更记录 → 定位根因
- 竞品分析:查到竞品 A 的信息后,发现需要对比的维度,再查竞品 B
- 多跳推理:答案分布在多个文档中,需要逐步追溯
优势是信息覆盖全,但延迟和成本成倍增加。
工程上的混合策略:
先做一次广泛的初始检索,如果 Agent 判断信息不足再触发增量检索。设一个检索预算上限(如最多 3 次),避免无限检索。
第一次:广泛检索,覆盖主要信息需求
执行中判断:信息够 → 继续执行。信息不够 → 生成更精确的子查询,再检索一次
最多追加 2 次,超过后用已有信息给出最优答案
差距在哪:新手用“复杂度”判断。高手用“信息需求是否可预知”做精确判断,且给出了一次检索和迭代检索的各自适用场景,以及“初始广泛 + 按需增量”的混合策略。面试官考的是你在 RAG 和 Agent 结合时的架构设计能力。
召回与排序优化
Q:为什么在检索阶段引入BM25?它和向量检索怎样组合?
来源:快手 AI Agent 开发一面 【字节二面同题:多路检索 + 向量/关键词各解决什么】【淘天Agent开发同题:为什么加 BM25 + 具体解决了什么 bad case】【钉学科技 FDE 实习一面追问:双路短板、融合与分类 bad case 验证】【9.4 某小厂 AI Agent hr+技术面追问:在混合检索中,除了向量语义检索,常结合的基于关键词词频与文档相关性的检索算法是什么?】【虾皮Agent一面追问:BM25 检索结果和向量检索结果,两套数据如何做结果融合?】;字节 aime 一面 9.10;字节Agent开发后端 日常实习一面凉面;本轮追问:为什么这个场景更适合关键词检索?(小红书 Product Engineer(AI与全栈方向)-社区工程 一面面经);本轮追问:用户提供了一个非常明确的错误,用向量检索反而可能查不到,你觉得是为什么?然后怎么改进?(淘天供应链ai应用研发一面);经纬恒润ai应用开发一面面经;多益网络面试;合肥某头部企业软件开发实习生面试问题汇总(时长1个小时);shopee ai基础设施一面;高斯信息技术,ai开发工程师,一面;10.8 pdd秋招 agent 一面
新手答:“BM25 是传统检索方法,加上它可以互补。”
高手答:
为什么引入 BM25:向量检索擅长语义匹配,但在三类场景下表现很差:
- 精确术语:错误码
ERR_OOM_KILL、API 名称getUserProfile——向量化后精确信息被稀释 - 低频专业词:Embedding 模型对训练数据中低频的词 embedding 质量差
- 新词/缩写:近期出现的产品名、术语,Embedding 模型没见过
BM25 基于词频和逆文档频率做精确匹配,恰好弥补这三个短板;但它对同义词、改写和没有词面重合的语义查询较弱。两路是互补关系,不应预设固定增益,是否有效必须由本业务评测集证明。
组合方式:主流有两种融合策略:
方案一:分数融合(Score Fusion)
final_score = α × normalize(vector_score) + (1-α) × normalize(bm25_score)
需要先对两路分数做归一化(min-max 或 z-score),否则量纲不同无法直接加权
方案二:倒数排名融合(Reciprocal Rank Fusion, RRF)
RRF_score(d) = Σ 1/(k + rank_i(d))
只看排名不看分数,对分数分布差异免疫,k 通常取 60
比例怎么设:不是拍脑袋定的。初始值用 0.7 向量 + 0.3 BM25,然后在评估集上做 grid search:
遍历 α = [0.5, 0.6, 0.7, 0.8, 0.9]
对每个 α,计算 Recall@10 和最终回答质量
选最优 α。不同业务场景最优值不同:
技术文档 → BM25 权重可以更高(精确术语多)
日常对话 → 向量权重更高(同义表达多)
完整检索流程(从 query 到最终上下文):
flowchart LR
Q["用户 Query"] --> QR["Query 预处理\n改写/扩展/意图识别"]
QR --> V["向量检索\nTop-K₁"]
QR --> B["BM25 检索\nTop-K₂"]
V --> M["合并去重\n分数融合"]
B --> M
M --> RR["Rerank 精排\nCross-Encoder"]
RR --> TK["Top-K 截断\n3~5 块"]
TK --> CTX["上下文组装\n拼接 Prompt"]
CTX --> LLM["LLM 生成回答"]
- Query 预处理:意图识别、查询改写、关键词提取
- 双路并行召回:向量路取 Top-20~50,BM25 路取 Top-10~20,并行执行
- 合并去重:按文档 ID 去重,同一文档被多路命中的加分
- Rerank 精排:用 Cross-Encoder(如 bge-reranker-v2、Cohere rerank)对 query-doc pair 做精细打分
- Top-K 截断:取精排后 Top-3~5 作为最终上下文
- Prompt 组装:把检索结果按相关度排序拼入 Prompt,交给 LLM 生成回答
评估不能只看一个聚合 Recall。要把 bad case 按查询类型分桶,例如:产品编码、版本号、错误码等精确词面查询;同义词、口语改写和近义表达等语义查询;同时包含精确约束与自然语言描述的混合查询。分别检查 BM25 单路、向量单路、合并后的候选集和 rerank 后结果,才能发现“总体指标上涨,但产品编码类反而退化”这类问题,并把失败样本持续沉淀为分类回归集。
更广义的多路检索策略:
BM25 + 向量检索只是多路检索的起点。生产级 RAG 系统的多路检索可以更丰富:
| 检索路径 | 原理 | 擅长 | 不擅长 |
|---|---|---|---|
| 向量检索 | 语义相似度 | 同义改写、模糊表述 | 精确关键词、专有名词 |
| BM25 | 词频-逆文档频率 | 精确关键词、专有名词 | 同义词、语义理解 |
| 元数据过滤 | 结构化字段匹配 | 时间范围、类别筛选 | 语义理解 |
| 知识图谱 | 实体关系遍历 | 多跳推理、关联查询 | 模糊意图 |
融合策略:
多路召回后需要融合排序,主流方案:
- RRF(Reciprocal Rank Fusion):
score = Σ 1/(k + rank_i),不需要归一化,简单有效 - 加权分数融合:
score = α × vector_score + β × bm25_score,需要分数归一化到同一量纲 - 级联融合:第一路做粗召回(高召回率),第二路在结果集上做精排(高精确率)
实际生产中,RRF 是默认首选——不需要调权重,对不同分布的分数天然鲁棒。
追问补充:一种可验证的流程是:BM25 与向量检索分别召回,按文档或片段 ID 去重,用 RRF 融合名次,再由 Cross-Encoder 精排;候选仍高度同质时用 MMR 平衡相关性与多样性。MMR 与精排的顺序是工程选择,需用固定评测集验证,不能把某一顺序当协议要求。
追问补充:BM25按词频、逆文档频率和文档长度归一化计算词面相关性,常由 Lucene、Elasticsearch 或 OpenSearch 实现。余弦相似度先除以向量范数,内积直接做点积;向量已归一化时二者排序等价,否则内积会受向量长度影响。
差距在哪:新手只说了“互补”两个字。高手说清了 BM25 解决的三类具体问题、两种融合方案的差异、比例调优方法论,以及完整的端到端检索流程。面试官考的是你对混合检索的工程化认知——不只是“加了 BM25”,而是知道怎么组合、怎么调参、怎么评估。
追问:RRF 融合中 K 参数一般取值多少?大一点、小一点对结果有什么影响?
RRF 公式:score(d) = Σ 1/(K + rank_i(d)),K 是一个平滑常数,决定了排名差异的敏感度。
| K 值 | 效果 | 适用场景 |
|---|---|---|
| K 很小(如 1~10) | Top-1 和 Top-2 的分数差异极大,“赢家通吃” | 某一路检索质量明显优于其他路,希望它主导结果 |
| K=60(默认值) | 排名差异被适度平滑,各路贡献相对均衡 | 多路检索质量相当,需要综合各路信号 |
| K 很大(如 200+) | 排名差异几乎被抹平,趋近于“被多少路命中”的计数 | 更看重文档被多路召回的次数,而非在单路的排名 |
实际调参方法:
1. 默认 K=60,大多数场景不需要调
2. 如果发现某一路检索远强于其他路 → 减小 K,让强路主导
3. 如果各路检索互补性强(向量找语义、BM25 找关键词) → 保持或增大 K
4. 在评测集上做 grid search:K ∈ {10, 30, 60, 100},看 Recall@K 和 MRR 变化
RRF 相比加权分数融合的核心优势:不需要归一化。不同检索路径的分数量纲和分布可能差异巨大(向量余弦 0~1,BM25 可能 0~50),RRF 只看排名不看分数,天然免疫分布差异。
追问:长尾或语义模糊的查询,怎么提升召回准确率?
长尾查询的核心问题是信息量不足——query 太短、太模糊、或用了非标准表述,导致检索系统无法精准匹配。
分层应对策略:
flowchart TB
Q[“长尾/模糊 Query”] --> D{“诊断 Query 类型”}
D -->|”太短(1-2词)”| E1[“Query 扩展\nLLM 生成多个子查询”]
D -->|”非标准表述”| E2[“同义改写\n术语标准化”]
D -->|”意图不明”| E3[“多意图并行检索\n各意图独立召回再合并”]
D -->|”领域专业词”| E4[“领域词典匹配\n+BM25 精确检索”]
E1 --> R[“合并多路结果\nRRF 融合”]
E2 --> R
E3 --> R
E4 --> R
R --> RK[“Rerank 精排\n过滤噪声”]
| 策略 | 原理 | 适用场景 |
|---|---|---|
| HyDE(假设性文档嵌入) | 让 LLM 先“编”一篇假想答案,用假想答案的 embedding 去检索 | query 极短但意图明确 |
| Query 扩展 | 一条 query 变 3~5 条子 query,多路召回合并 | query 模糊、可能有多种理解 |
| 领域词典 + BM25 | 对专业术语做标准化映射,用 BM25 精确匹配 | 医疗、法律、金融等术语密集领域 |
| 伪相关反馈(PRF) | 第一轮检索的 Top-K 结果作为反馈,扩展 query 做第二轮检索 | 初始召回有部分相关结果但不够 |
| 渐进式放宽 | 初始用严格条件检索,无结果则逐步放宽约束 | 用户需求精确但知识库覆盖不足 |
实测中,HyDE 对短 query 提升最大(Recall +20~30%),但会增加一次 LLM 调用的延迟。Query 扩展是性价比最高的通用方案。
追问:基于 Milvus,BM25 与向量检索的分数归一化具体怎么做?
来源:阿里淘天 AI应用开发一面
两路检索的分数量纲完全不同——BM25 分数是无界的(取决于文档长度和词频),向量余弦相似度在 [-1, 1] 区间。不归一化直接加权会导致一路完全压过另一路。
三种归一化方案:
| 方案 | 做法 | 优点 | 缺点 |
|---|---|---|---|
| Min-Max 归一化 | 每路取当前 batch 的 min/max 映射到 [0,1] | 简单直观 | 不同 query 的 min/max 波动大,不稳定 |
| Z-Score 归一化 | 减均值除标准差 | 统计稳定 | 需要维护全局统计量 |
| RRF(Reciprocal Rank Fusion) | 不看分数只看排名:score = Σ 1/(K+rank_i) | 无需归一化,对异常值鲁棒 | K 参数需调优 |
Milvus 实战:Milvus 2.4+ 原生支持 hybrid search,内置 RRF 和 WeightedRanker 两种融合策略。推荐先用 RRF(K=60 是常用起点),如果对精排效果不满意再切 WeightedRanker 手动调权重。
Q:如何系统性提升 RAG 的检索相关度与生成效果?
来源:快手 AI Agent 开发一面【抖音电商Agent全栈开发工程师一面追问:底层检索做了哪些提升?】;本轮来源;本轮来源;本轮追问:RAG 怎么做的?针对 RAG 做了哪些优化?如果继续改进还有哪些措施?(cvte应用软件开发一面);本轮追问:检索后的重排是怎么做的?(字节 Agent 秋招二面);本轮追问:如果最初的检索方向走偏了,系统有哪些机制能把它拉回来?(9.20 汇川技术 数字化全栈工程师 一面)
新手答:“换更好的 Embedding 模型。”
高手答:
优化要分检索阶段和生成阶段,两者瓶颈不同、手段不同:
检索阶段优化(提升相关度):
| 优化方向 | 具体手段 | 预期效果 |
|---|---|---|
| Query 侧 | 查询改写、意图识别、HyDE | 提升 query 和文档的匹配度 |
| 索引侧 | 父子索引、语义分块、元信息增强 | 提升文档的可检索性 |
| 模型侧 | Embedding 微调、ReRank 微调 | 提升语义匹配精度 |
| 召回策略 | 混合检索(BM25 + 向量)、多路召回 | 提升覆盖率 |
生成阶段优化(提升回答效果):
| 优化方向 | 具体手段 | 预期效果 |
|---|---|---|
| 上下文质量 | 精排后截断、去除低分块、冲突检测 | 减少噪声干扰 |
| Prompt 工程 | 引用约束、格式要求、拒答指令 | 提升回答的忠实度和格式规范 |
| 模型选择 | 复杂问题用强模型、简单问题用轻量模型 | 平衡质量和成本 |
| 后处理 | 答案事实性校验、引用来源标注 | 降低幻觉风险 |
优先级排序(投入产出比从高到低):
① 混合检索(加 BM25 路,成本几乎为零,Recall 提升 10-15%)
② Chunk 策略优化(父子索引、语义分块,一次性投入,长期受益)
③ 查询改写(显著提升长尾 query 的召回率)
④ ReRank 引入/微调(精排对最终质量影响大)
⑤ Embedding 微调(效果好但需要标注数据,成本较高)
⑥ Prompt 优化(持续迭代,每次小幅提升)
如何验证优化是否有效:
离线评估:
检索指标:Recall@K、MRR、NDCG
生成指标:Faithfulness、Answer Relevancy、Completeness
工具:RAGAS 框架自动化评估
在线验证:
A/B 测试:新旧方案同时上线,对比用户满意度和任务完成率
灰度发布:先 10% 流量验证,确认无回退再全量
关键原则:每次只改一个变量,否则无法归因
重排通常将 Query 与每个候选 Chunk 成对输入 Cross-Encoder 或重排模型,输出相关性分数后排序,并结合阈值、去重和多样性截断上下文。若初始方向偏了,可并行保留 BM25、向量、原始 Query 和改写 Query 多路候选,用关键词或元数据过滤兜底;若候选仍为空,触发澄清、放宽过滤或降级到关键词检索,并记录 bad case 验证恢复效果。
差距在哪:新手只想到换模型——这是最贵且不一定有效的做法。高手把优化拆成检索和生成两阶段,每个阶段有明确的手段和优先级排序,且有离线+在线的验证体系。面试官考的是你优化 RAG 系统时有没有系统性的方法论和效果验证闭环。
追问:实际项目中召回不准,你做过哪些改进?效果如何?
这种问题考的是实战排查方法论,而不是罗列技术。回答结构应该是“定位 → 归因 → 方案 → 效果”:
典型排查流程:
1. 定位:抽 100 条 bad case,标注失败原因
→ 发现 60% 是"召回了但排名靠后",30% 是"根本没召回",10% 是"召回正确但生成忽略"
2. 归因:
"召回了但排名靠后" → Rerank 模型对当前领域的区分度不够
"根本没召回" → query 用词和文档差异大(词汇鸿沟)
"召回正确但生成忽略" → 上下文中噪声 chunk 干扰了模型
3. 方案(按投入产出比排序):
① 加 BM25 路 → 解决词汇鸿沟问题,0.5 天
② Query 改写 → 用 LLM 做同义扩展,1 天
③ Rerank 模型换成 bge-reranker-v2 → 精排能力提升,0.5 天
④ 上下文截断策略从 Top-5 改为"分数阈值 + Top-3 兜底" → 减少噪声,0.5 天
4. 效果:Recall@10 从 72% → 85%,端到端回答准确率从 68% → 81%
关键认知:优化不是“把所有方法都堆上去”,而是先做归因分析,找到占比最大的失败模式,针对性解决。每次改一个变量,用评测集验证,确认有效后再上线。
Q:Rerank 后一般返回几个块?TopK 截断策略怎么设计?
来源:快手 AI Agent 开发一面 【字节二面追问:Re-rank 的作用 + 为什么有了向量相似度还需要它】【淘天Agent开发追问:低分阈值提前过滤策略】;本轮追问:为什么需要 Rerank?(字节 aime 一面 9.10);本轮追问:重召回是以 TopK 还是 TopP 返回的?(迅雷 Agent一面);本轮追问:为什么不能全部 rerank?(中兴未来领军计划AI算法一面);10.8 pdd秋招 agent 一面
新手答:“返回 5 个左右。”
高手答:
通常返回 3~5 个块,这个范围是多个因素权衡的结果:
太少(1-2 个):信息可能不完整,复杂问题需要多个证据源佐证
太多(8-10 个):
① 噪声增加——低相关度的块干扰模型判断
② Lost in the Middle——模型对中间位置的信息关注度下降
③ Token 成本线性增长
④ 生成延迟增加
验证方法:在评估集上做消融实验:
固定其他参数,遍历 K = [1, 2, 3, 5, 8, 10]
对每个 K 计算:
- 回答准确率(人工评判或 LLM-as-Judge)
- Faithfulness(回答是否忠于检索结果)
- Token 消耗和延迟
通常 K=3~5 是准确率和成本的甜点区间
TopK 截断策略:
不建议用固定 K 一刀切。更好的做法是分数阈值 + 上限 K + 断崖检测三条件组合:
def adaptive_topk(reranked, max_k=5, min_score=0.6, score_drop=0.3):
selected = []
for i, result in enumerate(reranked[:max_k]):
if result.score < min_score:
break
if i > 0 and (selected[-1].score - result.score) > score_drop:
break
selected.append(result)
return selected if selected else [reranked[0]]
三个截断条件:
- 硬上限:最多取 max_k 个,防止上下文过长
- 绝对阈值:低于 min_score 的块直接丢弃——质量太差的证据不如没有
- 分数断崖检测:相邻块分数骤降超过阈值时截断——说明后面的块相关度显著下降
上下文过长/过短的处理:
| 情况 | 处理策略 |
|---|---|
| 上下文过长 | ① 对每个块提取关键句而非全文 ② 截断低分块 ③ 只保留和 query 最相关的段落 |
| 上下文过短 | ① 增大召回 K 值,降低召回阈值 ② 启用父 chunk 扩展上下文 ③ 查询改写后重新检索 ④ 兜底:告知用户“知识库中未找到足够信息” |
Rerank 的作用是对初召回候选进行更细粒度的 query-doc 相关性判断,修正向量相似度受词面、主题泛相关影响的排序错误;它不能弥补初召回完全漏掉的文档,因此应先保证召回池覆盖,再用 Rerank 做精排和截断。
重召回通常用固定 TopK(必要时按查询类型动态调整),而不是 TopP:向量或混合检索分数未必可校准,TopP 会导致候选数和成本波动。不能把所有候选都 rerank,因为逐对判断计算昂贵、延迟线性增加,还会引入边缘噪声;应先用廉价召回缩小候选池,再在预算内精排。
差距在哪:新手随便说了个数。高手用消融实验确定 K 值,用三条件自适应截断代替固定 K,且对上下文过长/过短都有处理方案。面试官考的是你调参时有没有数据支撑的方法论,以及面对边界情况的工程化处理。
Q:RAG 中为什么引入父子索引?
来源:快手 AI Agent 开发一面;本轮追问:你的父子切割 RAG 是如何实现的?为什么要使用父子切割?父块和子块分别设置多大,为什么这样设置?(飞书深诺(全栈AI应用开发方向))
新手答:“为了更精确地检索。”
高手答:
父子索引解决的是 chunk 粒度的两难问题——检索精度和生成质量对 chunk 大小的需求是矛盾的。
小 chunk(100-200 字):
✅ Embedding 语义集中,检索精度高
❌ 上下文断裂,模型拿到的信息不完整
大 chunk(500-1000 字):
✅ 上下文完整,模型能理解前因后果
❌ Embedding 被多个主题稀释,检索精度下降
父子索引的设计思路是解耦检索粒度和上下文粒度:
flowchart TB
D["原始文档"] --> P1["父 chunk 1(500字,完整段落)"]
D --> P2["父 chunk 2(500字)"]
P1 --> C1["子 chunk 1a(150字)"]
P1 --> C2["子 chunk 1b(150字)"]
P1 --> C3["子 chunk 1c(150字)"]
P2 --> C4["子 chunk 2a(150字)"]
P2 --> C5["子 chunk 2b(150字)"]
检索时用子 chunk(小粒度,精度高),返回时取父 chunk(大粒度,上下文完整)。这样同时拿到了检索精度和生成上下文质量。
实现方式:
- 离线阶段把文档切成大块(父 chunk),再把每个父 chunk 切成若干小块(子 chunk),子 chunk 记录
parent_id - 对子 chunk 做 embedding 入向量库
- 检索时用 query 匹配子 chunk,拿到结果后通过
parent_id取出对应的父 chunk - 父 chunk 去重后送入 rerank 和 LLM
进阶:还可以做多级索引——文档摘要作为最顶层,段落作为中间层,句子作为最底层。先粗筛文档,再定位段落,最后精确到句子,逐层缩小范围。
差距在哪:新手只说了“更精确”但不知道为什么需要两层。高手点出了核心矛盾——检索需要小 chunk 精度、生成需要大 chunk 上下文——父子索引用“小粒度检索、大粒度返回”同时满足两个需求。面试官考的是你对 chunk 策略的深入理解。
Q:RAG 系统的端到端性能如何优化?
来源:快手 AI Agent 开发一面;本轮追问:数据量多的时候如何优化检索速度?(滴滴一些面经合集(算法))
新手答:“用更快的向量数据库。”
高手答:
RAG 的端到端延迟 = 检索延迟 + 排序延迟 + LLM 生成延迟。优化从三个层面切入:
检索层优化:
① ANN 索引调优:HNSW 的 ef_construction 和 M 参数影响召回率和速度的平衡
② 预过滤:先用元数据(时间范围、文档类别)缩小候选集,再做向量检索
③ 并行召回:BM25 和向量检索并行执行,总延迟 = max(两路) 而非 sum(两路)
④ Embedding 缓存:高频 query 的 embedding 结果缓存,避免重复计算
模型层优化:
① 流式输出(Streaming):用户不用等完整回答生成完才看到内容
② 模型路由:简单问题用小模型快速回答,复杂问题用大模型保证质量
③ 上下文压缩:减少送入 LLM 的 token 数——token 越少生成越快、成本越低
④ KV Cache 复用:相同 system prompt 部分的 KV cache 可以跨请求复用
架构层优化:
flowchart LR
Q["用户 Query"] --> C{"语义缓存\n命中?"}
C -->|"命中"| R["直接返回缓存结果"]
C -->|"未命中"| P["并行检索"]
P --> RR["Rerank"]
RR --> LLM["LLM 生成"]
LLM --> W["写入缓存"]
W --> R2["返回结果"]
① 语义缓存:用 embedding 相似度判断——"RAG 是什么"和"什么是 RAG"命中同一缓存
命中率高的场景能减少 40-60% 的 LLM 调用
② 异步预处理:文档入库时预计算 embedding、预生成摘要,查询时直接用
③ 请求合并:短时间内相同/相似 query 合并为一次检索
④ 分级 SLA:核心业务走低延迟链路,非核心走高质量链路
各优化手段的延迟收益估算:
| 优化手段 | 典型延迟收益 | 实现成本 |
|---|---|---|
| 并行召回 | -30~50ms | 低 |
| 语义缓存 | 命中时 -500ms+ | 中 |
| 流式输出 | 首 token 提前 200-500ms | 低 |
| Embedding 缓存 | -20~50ms | 低 |
| 模型路由 | 简单问题 -300ms+ | 中 |
| 上下文压缩 | -100~300ms | 中 |
差距在哪:新手只想到“换更快的数据库”——这只是检索层的一个点。高手从检索、模型、架构三层拆解了完整的性能优化方案,且给出了每个手段的延迟收益估算。面试官考的是你对 RAG 系统全链路延迟的分析和优化能力。
知识库与索引工程
Q:分块策略怎么设计?不同策略的优缺点?
来源:高德 AI 应用开发实习一面【腾讯AI应用开发二面追问:chunk 边界修正 + 表格跨块修复】【字节AI一面追问:领域文档语义感知切片】【Shopee 一面追问:为什么不能只按固定 Token 数切分】【字节数据平台 Agent 一面追问:跨物理页 Chunk 与页码引用】;钉钉一面【虾皮Agent一面追问:文档分块具体采用什么分块策略?;除递归字符切分外,还有哪些文档分块方案?】【百度Agent一面追问:Chunk 太大或太小有什么影响?Chunk 大小怎么确定?】;本轮来源;本轮来源;本轮追问:切分文档时,切片策略是什么?比如说 chunk size 为什么这么取,决策依据什么?有什么指标能判断你的决策?(腾讯元宝 风控实习一面);本轮追问:什么是结构化切片、固定长度切片和语义切片?(字节 aime 一面 9.10);本轮追问:RAG切片大小的依据是什么? / 为什么设计切片重叠?(浙江未讯科技);本轮追问:分块大小、聚合时的 chunk size 分别设置为多少?(字节 Agent 秋招二面);本轮追问:针对跨章节、逻辑强关联的超长文档,如何设计分块策略避免语义割裂? / 固定长度切分在投研、财报这类专业文档场景下,会出现哪些典型失效问题、割裂哪些业务逻辑? / 语义感知加层级多粒度分块,对比传统固定长度分块,会给检索召回环节带来哪些全新挑战? / 语义感知层级多粒度分块的具体方案是什么?如何识别专业文档的逻辑边界?不同粒度的分块如何做关联绑定?(27秋招-恒生电子AI面试-AI应用开发岗-26.9.23);本轮追问:Chunk 切得太细和太粗分别有什么问题?(小红书 Product Engineer(AI与全栈方向)-社区工程 一面面经);合肥某头部企业软件开发实习生面试问题汇总(时长1个小时);10.8 pdd秋招 agent 一面;秋招-字节跳动-抖音电商-Agent开发一/二/三面
新手答:“按 500 字切一段。”
高手答:
分块(Chunking)是 RAG 中影响效果最大的单一设计决策——切得不好,后面的检索和生成再怎么优化都救不回来。
五种主流分块策略对比:
| 策略 | 原理 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| 固定长度分块 | 按 token 数切分 | 实现简单、大小可控 | 可能切断语义 | 结构不清晰的纯文本 |
| 语义分块 | 按段落/章节/标题切分 | 保持语义完整 | 块大小不均匀 | 有清晰结构的文档 |
| 递归分块 | 先尝试大单元分割,不满足再细分 | 平衡语义和大小 | 实现复杂 | 通用场景首选 |
| Sliding Window | 固定大小 + 重叠区域 | 防止边界信息丢失 | 存储冗余 | 精度要求高的场景 |
| Agentic Chunking | 用 LLM 判断分块边界 | 最智能 | 成本高、速度慢 | 高价值文档 |
关键参数设计:
Chunk Size(块大小):256 ~ 1024 tokens
太小(< 200 tokens)→ 语义不完整,一个 chunk 可能只有半句话
太大(> 1500 tokens)→ 噪声多,embedding 被多个主题稀释,召回精度低
Overlap(重叠区域):chunk size 的 10 ~ 20%
作用:防止切断句子或段落,保证边界处的信息在相邻 chunk 中都有
Metadata(元信息):每个 chunk 保留——
source:来源文档标识
page:所在页码
section_title:所属章节标题
parent_doc_id:父文档 ID(用于父子索引)
父子索引策略——同时解决检索精度和上下文完整性:
flowchart TB
DOC["原始文档"] --> PARENT["父 chunk(500-1000 tokens)\n完整段落,上下文丰富"]
PARENT --> CHILD1["子 chunk A(150-300 tokens)\n精确语义,检索用"]
PARENT --> CHILD2["子 chunk B(150-300 tokens)"]
PARENT --> CHILD3["子 chunk C(150-300 tokens)"]
Q["用户 Query"] --> SEARCH["用 Query 匹配子 chunk\n(小粒度,精度高)"]
SEARCH --> RETURN["返回对应的父 chunk\n(大粒度,上下文完整)"]
用小 chunk 做检索(精度高),返回大 chunk 给 LLM(上下文完整)——两全其美。
递归分块的实现逻辑:
分割优先级:
1. 先按 "\n\n"(段落)分割
2. 段落仍然太大 → 按 "\n"(换行)分割
3. 还是太大 → 按 "。"(句号)分割
4. 再不行 → 按空格或字符数强制切分
每一级都尽可能保持语义完整,只有上一级切不够小时才降到下一级。
实践建议:从递归分块(LangChain 的 RecursiveCharacterTextSplitter)作为 baseline 开始,然后根据文档类型和评估结果调整。不同类型的文档用不同策略——技术文档用语义分块(按标题切),日志文件用固定长度分块,合同文档用 Agentic Chunking。
结构化切片是按标题、章节、列表、表格等文档结构切分;固定长度按字符或 token 上限切分;语义切片依据段落主题或相邻句向量相似度确定边界。chunk size 应用离线标注集做对比,观察召回率、MRR、Recall@k、答案正确率、上下文噪声和成本,按结果而非固定经验确定。
追问补充:进入 RAG 前切分,是为了把可检索语义单元控制在 embedding 和上下文窗口可承受的范围内,减少主题混杂与无效 token。512 tokens 只能作为 baseline,应在固定数据集上对比不同大小,结合 Recall@k、MRR、答案正确率、边界完整性和成本选择,而不是视为通用最优值。
差距在哪:新手用固定长度一刀切,不考虑语义。高手对比了五种策略的优劣势,理解 chunk size 和语义完整性的 tradeoff,用父子索引同时满足检索精度和上下文质量,并且知道分块策略必须根据文档类型和评估结果来调整——不存在“万能的分块方案”。面试官考的是你对 RAG 管线中最关键的预处理环节有没有深入的工程理解。
追问:chunk 切分的边界修正怎么做?比如表格被切成了两半怎么处理?
来源:腾讯 AI 应用开发二面
边界修正是分块策略中最容易被忽视的工程细节。切错边界比不切更糟——一个被拦腰截断的表格,检索到任何一半都无法提供完整信息。
主流边界修正策略:
- 结构感知切分:先用文档解析器识别出结构元素(标题、段落、表格、代码块、列表),以完整结构元素为最小切分单位,绝不从结构内部切断
- Overlap(重叠窗口):相邻 chunk 之间保留 10-20% 的重叠区域。即使切断了,下一个 chunk 的开头会包含上一个的结尾,信息不会完全丢失
- 表格特殊处理:表格作为独立 chunk,不参与常规切分。如果表格超长,按行切分但每个子 chunk 都保留表头(表头是理解表格的关键)
表格被切成两半的检测和修复:
检测:解析文档时标记所有表格的起止位置 → 切分后检查是否有 chunk 边界
落在表格内部 → 有则标记为”边界异常”
修复:把跨越表格的两个 chunk 合并,或者把表格提取为独立 chunk
实际工程中,最稳的做法是先提取后切分:先用文档解析器把表格、图片、代码块等结构化元素单独提取出来,剩余的纯文本再做常规分块。这样结构化元素天然不会被切断。
追问:领域文档(法律/医疗)的语义单元跨 chunk 被切散,怎么办?
来源:字节 AI 一面(法律 RAG 项目深挖)
法律文档中,“第三条第二款”和“第三条之二”是完全不同的法律概念——前者是第三条下的第二个分款,后者是独立的第三条之二。如果切片把这类语义单元切散,模型会混淆引用关系,直接导致回答错误。
领域感知切片的四层方案:
| 层级 | 做什么 | 具体实现 |
|---|---|---|
| 结构解析 | 用领域规则识别语义边界 | 法律:条/款/项层级正则;医疗:诊断-处方-医嘱分段 |
| 边界保护 | 语义单元不可被切断 | 将“第X条”到“第X+1条”之间的内容视为原子块 |
| 层级 metadata | 每个 chunk 携带完整的上下文链 | {law: "民法典", chapter: "第三编", article: "第三条", clause: "第二款"} |
| 交叉引用 | 法条互相引用时双向关联 | “依据第五条”→ 在 chunk metadata 中标记依赖关系 |
核心原则:通用切片策略(按 token 数、按段落)是 baseline,领域文档必须叠加领域感知的边界规则。切片粒度不是工程参数,是业务决策——需要和领域专家一起定义“什么是不可切断的最小语义单元”。
追问:句子或表格跨物理页时,Chunk 要不要跨页?怎么保证引用仍能定位?
物理页是展示边界,不一定是语义边界。解析阶段先保存每个文本/表格单元的 page_no + bbox/span,再按段落、标题和表格结构拼语义单元;跨页句子可以合并,跨页表格要保留表头、续表关系和每一行的页码。Chunk metadata 不能只存一个 page,而应保存来源跨度,例如 page_start/page_end 和更细的证据 span。
检索返回 Chunk 后,引用层根据实际支持结论的 span 生成页码,而不是把整个跨页 Chunk 都标成同一页。验收要覆盖跨页句子、续表、脚注、页眉页脚和 OCR 错位,并检查“召回正确、引用页码也正确”两个指标。是否跨页最终由语义完整性决定,但证据定位必须保留到原始页面坐标。
Q:知识库整体怎么设计?
来源:高德 AI 应用开发实习一面【字节二面同题:RAG 完整流程从文档切块到生成】【阿里 Agent Infra 一面题库同题】;百度 Agent 二面【拼多多 复活赛 一面追问:聊聊你们知识库是怎么设计的?怎么检索的?】【虾皮Agent一面追问:讲下项目里 RAG 的整体实现流程。】;阿里云 ai应用开发 一面;字节 aime 一面 9.10;本轮追问:你的RAG项目的整个流程是什么样子?(美团ai全栈一面);九方智投 一面凉经;本轮追问:知识社区平台实现了哪些功能?整体架构是什么?(字节剪映AI应用开发一面);中科曙光 AI Agent 一面;高斯信息技术,ai开发工程师,一面
新手答:“把文档存到向量数据库。”
高手答:
知识库不是“把文档扔进向量数据库”——它是一个完整的系统,涵盖文档处理、存储索引、检索召回、质量保障和运维五个层面。
整体架构:
flowchart TB
subgraph offline["离线处理"]
direction TB
RAW["原始文档\nPDF / Word / HTML / Markdown"] --> PRE["预处理\n格式转换、清洗、去噪"]
PRE --> CHK["分块\n递归分块 / 语义分块"]
CHK --> EMB["Embedding 计算"]
CHK --> META["元数据提取\n来源、日期、类别"]
EMB --> VDB["向量数据库\nMilvus / Qdrant"]
META --> MDB["元数据库\nElasticsearch / PostgreSQL"]
CHK --> INV["倒排索引\nElasticsearch"]
end
subgraph online["在线检索"]
direction TB
Q["用户 Query"] --> QR["查询改写"]
QR --> MR["多路检索\n向量 + BM25 + 元数据过滤"]
MR --> RR["Rerank 精排"]
RR --> CA["上下文组装"]
CA --> LLM["LLM 生成回答"]
end
五层设计:
1. 文档处理层——把非结构化文档变成可检索的结构化数据:
- 格式解析:PDF / Word / HTML → 纯文本。不同格式的解析难度差异很大——PDF 的表格和多栏排版是重灾区
- 清洗去噪:去掉页眉页脚、广告、导航栏等无关内容
- 元数据提取:来源、创建日期、类别、作者——这些元信息在检索时用于过滤和排序
2. 索引层——三种索引各司其职:
- 向量索引(FAISS / Milvus):语义检索,处理同义改写和模糊表述
- 倒排索引(Elasticsearch):关键词检索,处理精确术语和专有名词
- 元数据索引(过滤字段):结构化筛选,处理时间范围、文档类别等约束
为什么需要三种?因为不同类型的查询需要不同的索引——“退货政策”需要语义检索,“ERR_OOM_KILL”需要关键词检索,“最近一周的变更记录”需要元数据过滤。
3. 检索层——查询理解 + 多路召回 + 精排:
- 查询改写(多维度扩展用户意图)
- 多路召回(向量 + BM25 + 元数据过滤并行)
- Rerank 精排(Cross-Encoder 细粒度打分)
- 上下文组装(Top-K 截断、信息去冗余)
4. 质量保障层——知识库不是建完就不管了:
- 文档去重:内容指纹检测近重复文档
- 新鲜度追踪:过期文档标记或降权
- 冲突检测:同一主题的矛盾信息标记提醒
- 覆盖分析:哪些主题的文档充足,哪些有缺口
5. 运维层——保证知识库持续可用:
- 增量更新管线:新文档自动入库,变更文档自动重新索引
- 版本管理:文档变更可追溯
- 访问控制:不同用户看到不同范围的文档
- 监控:检索命中率、用户反馈、知识库健康度
关键设计决策:
| 决策点 | 选项 | 权衡 |
|---|---|---|
| Chunk 大小 | 256 / 512 / 1024 tokens | 粒度越小检索越精确,但上下文越不完整 |
| 单索引 vs 多索引 | 只用向量 vs 向量 + BM25 + 元数据 | 多索引召回率高,但系统复杂度增加 |
| 实时更新 vs 批量更新 | 文档变更立即入库 vs 每天定时批量处理 | 实时性 vs 系统稳定性和计算成本 |
知识社区平台可在此基础上提供内容发布、分类标签、评论问答、全文与语义搜索、收藏反馈、审核和权限管理。架构上由前端、API/业务服务、关系库与对象存储承载内容,搜索与向量服务负责检索,消息队列驱动解析和索引更新,并配套鉴权、审计与监控。
差距在哪:新手认为知识库就是向量数据库。高手设计了五层系统——文档处理、索引、检索、质量保障、运维——覆盖了从数据入库到持续运维的完整生命周期。面试官考的是你对知识库的认知是“一个组件”还是“一套系统”。
Q:GraphRAG 在处理 Agent 复杂关联查询时的优势在哪里?
来源:淘天 AI Agent 一面 【蚂蚁AI应用开发二面同题:GraphRAG 理解与应用】【字节二面追问:多跳推理/复杂逻辑查询场景下 RAG 架构优化】
新手答:“用知识图谱检索,比向量搜索更准。”
高手答:
先说清一个常见误解:GraphRAG ≠ 知识图谱检索。传统知识图谱检索是在预构建的三元组上做 SPARQL 查询,而 GraphRAG 是微软提出的一套完整架构——从文档自动构建知识图谱 + 社区摘要 + 本地/全局双搜索。
传统 RAG 的瓶颈:
传统 RAG 的检索单元是“文本块”(chunk),本质是扁平的。当用户的问题涉及多跳推理(A 和 B 的关系 → B 和 C 的关系 → 推导 A 和 C 的关系)或跨文档关联(信息分散在多个文档中)时,靠向量相似度只能找到局部相关的片段,无法把分散的信息串联起来。
传统 RAG 的困境:
用户问:”项目 A 的技术负责人和项目 B 的技术负责人之间有什么合作关系?”
文档1 提到:张三是项目 A 的技术负责人
文档2 提到:李四是项目 B 的技术负责人
文档3 提到:张三和李四共同发表了论文 X
→ 向量检索可能只召回文档1和文档2,漏掉关键的文档3
→ 即使三个都召回了,模型也需要自己做推理串联
GraphRAG 的架构与流程:
flowchart TB
D[“源文档集合”] --> EE[“实体与关系抽取\n(LLM 逐段提取)”]
EE --> G[“构建知识图谱\n(实体节点 + 关系边)”]
G --> CD[“社区检测\n(Leiden 算法)”]
CD --> CS[“社区摘要生成\n(LLM 为每个社区\n生成主题摘要)”]
Q[“用户查询”] --> R{“查询路由”}
R -->|”具体实体/关系查询”| LS[“本地搜索\nLocal Search”]
R -->|”全局性/主题性查询”| GS[“全局搜索\nGlobal Search”]
LS --> G
LS --> D
LS -->|”从目标实体出发\n沿关系边遍历\n收集关联实体和原文”| A1[“聚合上下文”]
GS --> CS
GS -->|”遍历社区摘要\n提取相关主题\n逐层汇总”| A2[“Map-Reduce 聚合”]
A1 --> LLM[“LLM 生成最终回答”]
A2 --> LLM
GraphRAG 的三大核心优势:
1. 多跳推理能力
知识图谱天然支持关系链遍历。上面那个例子,在图中就是:项目A → 技术负责人 → 张三 → 合作论文 → 李四 → 技术负责人 → 项目B。沿着关系边走两三跳就能拿到完整的关联信息,不需要模型自己推理。
2. 全局理解能力
这是 GraphRAG 最大的创新——社区摘要。通过社区检测算法把图中紧密关联的实体聚成社区,再用 LLM 为每个社区生成主题摘要。当用户问“这个领域的整体趋势是什么”这类全局性问题时,传统 RAG 只能拼凑零散的片段,GraphRAG 可以直接基于社区摘要回答。
3. 结构化实体消歧
同一个实体在不同文档中可能有不同的名称(“OpenAI”、“openai”、“Open AI”),图构建过程中会做实体合并和消歧,保证检索的一致性。
不同查询类型下的对比:
| 查询类型 | 传统 RAG | GraphRAG |
|---|---|---|
| 单跳事实题(“X 是什么”) | 效果好,向量检索足够 | 效果好,但构建成本更高 |
| 多跳关系题(“A 和 C 什么关系”) | 容易漏召回,依赖模型推理 | 图遍历直接获取关系链 |
| 全局摘要题(“整体趋势是什么”) | 只能拼凑片段,质量差 | 社区摘要直接回答,质量显著更好 |
| 对比分析题(“X 和 Y 的异同”) | 需要分别检索再交叉,效果不稳定 | 两个实体的关联属性在图中直接可比 |
| 时序关系题(“先发生什么后发生什么”) | 缺乏时序建模 | 可在关系边上标注时间属性 |
什么时候该用 GraphRAG:
适合 GraphRAG 的场景:
✓ 文档集中有大量实体间的关系信息
✓ 用户经常问多跳推理或全局摘要类问题
✓ 实体消歧是痛点(同一实体多种写法)
✓ 需要可解释的推理路径
不适合 GraphRAG 的场景:
✗ 文档量小(<100篇),图太稀疏没有意义
✗ 查询以单跳事实题为主,传统 RAG 就够了
✗ 对实时性要求极高——图构建和社区摘要是离线批处理,延迟高
✗ 预算有限——图构建需要大量 LLM 调用(实体抽取 + 社区摘要)
成本方面,GraphRAG 的图构建阶段需要对每个文档段落调用 LLM 提取实体和关系,再对每个社区调用 LLM 生成摘要。对于 10 万篇文档的知识库,图构建的 LLM 调用成本可能是传统 RAG embedding 计算的 10-50 倍。但构建完成后,查询阶段的成本差异不大。
差距在哪:新手把 GraphRAG 等同于“知识图谱检索”——这忽略了 GraphRAG 最核心的创新:社区摘要和本地/全局双搜索架构。高手的回答从传统 RAG 的瓶颈讲起,解释了 GraphRAG 的完整管线(实体抽取 → 图构建 → 社区检测 → 摘要生成 → 双路搜索),并用对比表格说清了不同查询类型下的效果差异和适用边界。面试官考的不是“你知不知道 GraphRAG”,而是“你能不能说清楚它比传统 RAG 好在哪、什么时候该用、什么时候不该用”。
追问:GraphRAG 召回海量关联信息后,生成阶段如何用 Self-Reflection 或 CoT 策略过滤检索噪声?
来源:蚂蚁 AI应用开发 二面
GraphRAG 的 Community Summary + 三元组召回会返回大量关联信息,其中不少是“图上相关但问题无关”的噪声。生成阶段的过滤策略:
CoT 策略(生成前过滤):在生成 Prompt 中要求模型先做一步“证据筛选”——逐条判断每个召回片段与当前问题的相关性,只保留高相关的片段再生成回答。这相当于在生成阶段内置了一个轻量 Rerank。
Self-Reflection 策略(生成后校验):先基于全部召回信息生成初版回答,然后用反思 Prompt 检查:“回答中是否引用了与问题无关的信息?是否遗漏了关键关联?” 发现问题后定向修正。
两者结合:CoT 做前置过滤降低噪声,Self-Reflection 做后置校验捕获遗漏。前者减少“答非所问”,后者减少“漏答关键点”。
追问:GraphRAG 的三元组是用 LLM 抽取的吗?怎么保证不幻觉?
来源:腾讯 AI 应用开发二面
是的,三元组(实体-关系-实体)通常由 LLM 抽取,但不能无条件信任 LLM 的抽取结果。
抽取流程:
文档段落 → LLM 提取实体 + 关系 → 结构化三元组 → 合并去重 → 入图
幻觉控制的四层防线:
- Prompt 约束:在抽取 Prompt 中明确要求“只提取文本中明确提到的实体和关系,不推断”。给出具体的输出格式和 Few-shot 示例,减少模型自由发挥的空间
- Schema 约束:预定义允许的实体类型和关系类型(如医学领域只允许“疾病-症状-药物-基因”四类实体)。LLM 抽出的实体必须属于预定义类型,否则丢弃
- 多轮验证:同一段文本让 LLM 抽取两次,只保留两次结果一致的三元组(投票机制)。或者用一个 Critic 模型检查抽取结果是否有文本依据
- 溯源校验:每个三元组保留源文本引用。后续使用时可以回查原文验证
实体抽取错误的排查方法:
- 随机抽样检查:从抽取结果中随机抽 100 条三元组,人工校验准确率
- 高频实体审查:按实体出现频次排序,高频实体更值得校验(一个错误的高频实体会污染大量关系)
- 孤立节点检查:只有一条边的实体往往是噪声
追问:Community Summary 的设计思路是什么?
来源:腾讯 AI 应用开发二面
Community Summary 是 GraphRAG 最核心的创新——把知识图谱从“查询时遍历”变成“预计算摘要”。
设计思路:
- 社区检测:用 Leiden 算法对知识图谱做社区划分,把紧密关联的实体聚成社区(类似“话题簇”)
- 层次化摘要:对每个社区调用 LLM 生成一段自然语言摘要,描述“这个社区里的实体之间有什么关系、核心主题是什么”
- 多层级:社区可以递归聚合——小社区合成大社区,大社区有更宏观的摘要。查询时根据问题的抽象程度选择合适的层级
为什么这样设计:传统知识图谱回答全局性问题(“这个领域的整体趋势是什么”)需要遍历大量节点,成本高且容易遗漏。Community Summary 把全局知识预压缩成摘要,查询时直接检索摘要即可——用离线计算换在线效率。
追问:GraphRAG 的叶子节点在智能客服中如何触发?
来源:币安 AI大模型实习一面
GraphRAG 的图结构是分层的:根节点(全局摘要)→ 社区节点(主题簇摘要)→ 实体节点 → 叶子节点(原始文档 chunk / 三元组细节)。不同粒度的问题触达不同层级。
触发机制——Global Search vs Local Search:
| 用户问题类型 | 搜索模式 | 是否触达叶子节点 | 示例 |
|---|---|---|---|
| 全局性/概览性 | Global Search | 否,社区摘要足够 | “你们有什么售后服务” |
| 具体实体细节 | Local Search | 是,需要原始文档细节 | “iPhone 15 能不能 7 天无理由退” |
| 需要外部数据 | Local + API 调用 | 是,且需调用外部系统 | “我的订单 123456 什么时候到” |
叶子节点的触发流程:
flowchart LR
Q[“用户 query”] --> NER[“实体识别\n提取产品名/订单号/功能名”]
NER --> LOC[“图定位\n在知识图谱中找到目标实体节点”]
LOC --> TRAV[“关系遍历\n沿实体的关系边向下到叶子节点”]
TRAV --> AGG[“上下文聚合\n叶子内容 + 关系链 + 社区摘要”]
AGG --> LLM[“LLM 生成回答”]
工程实现要点:用意图分类器判断问题粒度——粗粒度走 Global(快但粗),细粒度走 Local 到叶子节点(慢但准)。两者可以级联:先 Global 判断主题范围确认实体所属社区,再 Local 深入到叶子节点获取具体细节。
智能客服中的典型场景:用户问“我买的 XX 产品能退吗” → 实体识别提取产品名 → 图中定位到该产品节点 → 沿“退货政策”关系边遍历到叶子节点(具体退货条件、时间限制、操作步骤)→ 聚合上下文生成精确回答。
Q:RAG 召回数据层应如何设计文档、Chunk、Embedding、版本和权限 Schema?
来源:Newegg AI 软件工程实习一面【拼多多 复活赛 一面追问:如果文档都做倒排或索引,怎么同时解决切分和权限问题?】;本轮追问:整条链路的原始输入数据有哪些?会产出哪些重要的中间数据?例如“快充快退”应如何从数据层面定义和识别?(本轮追问);本轮追问:权限控制是表级、字段级还是行级?(本轮追问);本轮追问:项目中大约有多少份文档和多少条 chunk?(本轮追问);本轮追问:TOKEN 和权限是怎么关联的?数据库层面如何设计?(本轮追问);迅雷 Agent一面;10.8 pdd秋招 agent 一面
新手答:“建一张表存文档和向量,再加标题、内容、更新时间几个字段。”
高手答:
不要把逻辑文档、某次解析结果、Chunk 和 Embedding 塞进一张宽表。至少拆成五类实体:
document 业务文档身份、数据源、owner、当前有效版本
document_ver 内容哈希、原始对象 URI、解析状态、创建时间、父版本
chunk 稳定 chunk_id、version_id、正文、章节路径、page/span、content_hash
embedding chunk_id、model_id、维度、向量/向量库 point_id、构建状态
acl_binding resource_id、subject/role/tenant、policy_version、有效期
离线任务另存 ingestion_run,记录解析器、Chunk 策略、Embedding 模型、输入/输出数量、失败项和幂等键。document_id 表示业务对象,version_id 表示不可变快照;回答绑定具体版本和 Chunk,不能只记“来自某文档”。Embedding 模型升级时新增 embedding 记录和索引版本,不覆盖旧向量;切流完成后再按保留策略回收。
关键不变量包括:Chunk 必须属于一个不可变文档版本;向量必须能反查原文 span;删除/权限撤销能沿数据血缘找到索引、缓存和派生摘要;同一 content_hash + pipeline_version 重跑幂等。关系库保存权威元数据和状态,原始大文件进对象存储,向量库负责近邻检索;三者通过稳定 ID 关联,不让向量库成为唯一事实源。
差距在哪:新手只有“内容加向量”,高手把版本、血缘、权限、模型迁移和可删除性落实成数据模型与不变量。
Q:向量数据库怎么选型?不同规模下该用什么方案?
来源:阿里国际 AI 应用研发二面 【淘天Agent开发追问:为什么选 pgvector 而不是其他向量数据库】;中兴软开一面;钉钉一面;本轮追问:对于百万级、千万级更大规模的知识库,这类检索方案你有什么了解?(本轮追问);本轮追问:Qdrant向量数据库特点及选型理由?(本轮追问);本轮追问:Embedding 模型和向量数据库是如何选择的?(本轮追问);本轮追问:为什么用 Milvus 向量数据库?(cherrystudio面试);本轮追问:现在 Milvus 里有一千亿个向量,你怎么设计索引?(奇怪の字节二面面经(大概率凉经))
新手答:“用 Milvus 就行。”
高手答:
向量数据库的选型不是“挑一个最有名的”,而是按数据规模分层选择,再根据业务需求做筛选。
按数据规模分层推荐:
小规模(< 10 万条向量):pgvector / SQLite-VSS
直接在现有关系型数据库上加向量扩展。运维成本几乎为零,不需要额外部署服务。对于早期项目和 PoC 阶段完全够用。
中等规模(10 万 - 1000 万条向量):Milvus Lite / Qdrant / Weaviate
需要专用的向量数据库。这个量级对索引类型(HNSW / IVF)、过滤能力、持久化都有要求。这三个都支持元数据过滤,且社区活跃、文档完善。
大规模(1000 万条以上):Milvus 集群 / Pinecone / Zilliz Cloud
需要分布式架构和水平扩展能力。Milvus 集群支持多副本和分片;Pinecone 和 Zilliz Cloud 是全托管服务,运维成本低但按量计费。
选型维度对比:
| 选型维度 | 关键问题 | 影响选择 |
|---|---|---|
| 数据规模 | 当前多少条?预期增长到多少? | 决定单机 vs 分布式 |
| 过滤需求 | 是否需要 metadata 过滤(按时间、类别筛选)? | 排除不支持过滤的纯 ANN 方案 |
| 延迟要求 | P99 延迟要求多少 ms? | 影响索引类型和部署架构 |
| 运维复杂度 | 团队有没有专人运维? | 决定自建 vs 托管服务 |
| 成本 | 预算约束是什么? | 开源自建 vs 商业托管 |
| 混合检索 | 是否需要向量 + 关键词混合搜索? | 部分方案原生支持(Qdrant、Weaviate),部分需要外接 ES |
关键考量:大多数真实 Agent 场景都需要元数据过滤——比如“只检索最近 30 天的文档”“只查某个品类下的内容”。这个需求会直接淘汰一些纯 ANN 方案(如裸用 FAISS),因为它们不支持带条件的向量检索。
生产建议:先简单后迁移。项目初期用 pgvector 快速验证效果,等数据量或性能真正成为瓶颈时再迁移到专用向量数据库。过早引入分布式向量数据库是典型的过度工程——你花两周部署 Milvus 集群,结果数据才 5 万条,pgvector 10ms 就能搞定。
选择 Milvus 的理由应结合实际约束:数据规模较大时需要分布式扩展、向量索引、元数据过滤和持久化能力,同时其生态与运维方案较成熟。最终仍应以数据规模、延迟、成本和压测结果验证,不应只因品牌选择。
一千亿规模不能单机建一个索引:先按租户或业务分片并按主键或哈希分布,分片内用 IVF_PQ 或 DiskANN 等压缩索引,按冷热数据分层,副本承担读请求。查询先路由候选分片,再并行检索、合并重排;通过召回率、P99、内存和扩缩容压测确定 nlist、nprobe、压缩率,并采用增量构建与后台重平衡。
差距在哪:新手只给一个品牌名。高手按数据规模分层推荐,且给出了选型维度和“先简单后迁移”的工程建议。面试官考的是你对向量检索基础设施的全面认知。
Q:Embedding 模型怎么选?选型时考虑哪些因素?
来源:高德 AI 应用开发实习一面;本轮追问:Chunksize怎么选,Embedding模型怎么选?(本轮追问);本轮来源;本轮来源
新手答:“用 OpenAI 的就行。”
高手答:
Embedding 模型选型不是“哪个最有名用哪个”,而是要从六个维度系统评估:
| 维度 | 考虑因素 | 说明 |
|---|---|---|
| 语言支持 | 中文/英文/多语言 | 中文场景优先选中文优化模型 |
| 向量维度 | 768/1024/1536 | 维度越高精度越好但存储和检索成本越大 |
| 检索精度 | MTEB/C-MTEB 排名 | 用公开基准评估基础能力 |
| 推理速度 | tokens/sec | 影响索引构建和在线检索延迟 |
| 部署成本 | 模型大小、GPU 需求 | 小模型可 CPU 部署 |
| 最大长度 | 512/8192 tokens | 影响 chunk 大小设计 |
主流模型对比:
| 模型 | 来源 | 特点 |
|---|---|---|
| BGE 系列 | BAAI(智源) | 中文效果好,开源,多尺寸可选 |
| M3E | Moka | 中文优化,轻量 |
| text-embedding-3 | OpenAI | 效果好但需 API 调用,成本高 |
| jina-embeddings-v3 | Jina AI | 多语言,支持长文本 |
| GTE | Alibaba | 中英文均衡 |
实际选型决策流程:
flowchart TB
S["开始选型"] --> L["确定语言需求"]
L -->|"中文为主"| CN["优先 BGE / M3E / GTE"]
L -->|"英文为主"| EN["优先 E5 / GTE / OpenAI"]
L -->|"多语言"| ML["优先 jina-embeddings-v3"]
CN --> EV["在自己的数据上做评估"]
EN --> EV
ML --> EV
EV --> COST["对比部署成本"]
COST --> FT{"是否需要微调?"}
FT -->|"领域术语多"| YES["选开源模型\n用业务数据微调"]
FT -->|"通用场景"| NO["直接部署\n定期评估效果"]
- 先确定语言需求:中文场景优先选中文优化模型,不要盲目选英文模型
- 跑 domain-specific evaluation:不只看 MTEB/C-MTEB 排名,必须在自己的数据上评估。公开 benchmark 上排名第一的模型,在你的业务数据上可能排第五
- 对比部署成本:API 调用模型(如 OpenAI)按量计费,自部署模型有 GPU 成本。数据量大时自部署更划算
- 考虑是否需要微调:领域术语多的场景(医疗、法律、金融),通用模型的 embedding 质量会明显下降,这时选开源模型做微调是更好的路径
关键认知:公开 benchmark 排名不等于你的场景效果。必须在自己的数据上做 A/B 评测——构建几百条 (query, relevant_doc) 的评估集,跑 Recall@K 和 MRR,用数据说话。
差距在哪:新手直接选最有名的模型。高手从六个维度系统评估,坚持在业务数据上做 domain-specific evaluation,而不是盲目跟 benchmark 排名。面试官考的是你选型时有没有工程化的方法论,以及对“通用模型 vs 领域适配”这个 tradeoff 的理解。
Q:为什么 Claude Code 不用 RAG 检索代码,而是直接用 grep?
来源:字节 Agent 开发实习一面;小红书 Product Engineer(AI与全栈方向)-社区工程 一面面经
新手答:“可能是还没来得及实现 RAG。”
高手答:
这道题非常好,它直接挑战了“RAG 万能论”的假设。答案是:对于代码检索场景,grep 在多个维度上优于 RAG,这是一个深思熟虑的架构选择,而不是技术局限。
grep 胜过 RAG 的五个原因:
| 维度 | grep | RAG |
|---|---|---|
| 精确性 | grep "functionName" 精确匹配,100% 准确率 |
向量检索返回“语义相似”的结果,可能漏掉目标函数 |
| 实时性 | 直接操作当前文件系统,永远是最新的 | 需要索引,代码一改索引就可能过时(开发时代码频繁变动) |
| 成本 | 纯 CPU 计算,免费,耗时 <100ms | 需要 Embedding 计算、向量数据库,索引需随代码变更重建 |
| 可解释性 | 结果确定且可追溯——匹配到哪个文件第几行一清二楚 | 结果取决于 Embedding 质量,无法解释“为什么返回这个结果” |
| 代码结构利用 | 代码高度结构化(函数、类、import 有固定模式),grep + 正则能精准利用这种结构 | Embedding 会丢失代码的结构信息,把代码当成普通文本处理 |
什么时候 RAG 比 grep 更好:
grep 不是万能的,以下场景 RAG 占优:
自然语言查询:"认证逻辑在哪里?"
→ grep 无法处理,因为代码中没有"认证逻辑"这个字符串
→ RAG 的语义检索能找到 auth_middleware.py、login_handler.py
概念级搜索:"找到类似的实现"
→ grep 只能匹配精确字符串
→ 向量检索能找到语义相似的代码片段
跨模块依赖分析:"哪些模块依赖了这个服务?"
→ grep 能做简单的 import 搜索,但知识图谱 / RAG 能发现间接依赖
Claude Code 的实际策略——渐进式披露(Progressive Disclosure):
flowchart TB
Q["需要查找代码信息"] --> C1{"精确符号查找?"}
C1 -->|"是"| G["grep / find\n(免费、精确、实时)"]
C1 -->|"否"| C2{"需要目录结构?"}
C2 -->|"是"| LS["ls / directory listing\n(零成本)"]
C2 -->|"否"| C3{"需要语义理解?"}
C3 -->|"是"| R["Read 文件内容\n(按需加载)"]
C3 -->|"否"| G
核心原则是从最廉价、最精确的工具开始,按需逐步升级到更昂贵的工具。grep 和 find 是第一层(零成本、高精度),读文件是第二层(中等成本),只有在前两层无法满足需求时才考虑更重的检索手段。
这道题的 meta 启示:
最佳检索方法取决于查询类型。不要默认使用 RAG——有时候更简单的工具反而更好。这个原则不仅适用于代码检索,也适用于所有 Agent 的工具选择:先用廉价精确的工具,只在必要时才升级到昂贵复杂的工具。这就是渐进式披露在工具选择层面的体现。
差距在哪:新手假设 RAG 是万能的,认为不用 RAG 是技术缺陷。高手理解 grep 在精确性、实时性、成本、可解释性和代码结构利用五个维度上的优势,并且看到了 Claude Code 的渐进式披露策略是一个深思熟虑的架构选择——从廉价精确工具开始,按需升级。面试官考的是你能不能跳出“RAG 万能论”的思维定式,根据场景选择最合适的检索方案。
Q:Coding Agent 应从代码反向理解领域知识,还是维护独立知识库/规则库?
来源:国际业务 Agent 二面;本轮追问:能否让专门的领域 SubAgent 读取算法细节,只向外抽象出诊断规则,再由外层 Agent 使用这些规则?(本轮追问);本轮追问:你说你构建了静态规则库,怎么做的,原理讲一下?(Agent 开发面经)
新手答:“把代码全部向量化放进知识库,Agent 检索到相关代码就能理解业务。”
高手答:
代码和知识库不是二选一,它们回答不同问题。代码、类型、接口和可执行测试是“系统现在怎么运行”的证据;产品规则、术语、流程、合规约束和设计决策解释“为什么这样运行、允许改成什么”。只读代码会把历史兼容逻辑误当业务规则,只读文档又可能使用已经过期的设计。
构建上下文时分层检索:先用符号搜索、依赖图和测试定位当前实现,再按模块、领域实体和版本检索规范/决策记录。每条外部知识保留 owner、适用服务、代码版本范围、更新时间和来源;代码索引绑定 commit,知识索引绑定文档版本。两者冲突时不让模型自行“取一个更合理的”,而是按权威策略处理:运行事实以当前代码/测试为准,目标行为以已批准 Spec 为准,无法判定则生成差异报告并请求 owner 澄清。
变更后同时验证代码和知识:接口/领域事件变化触发受影响文档检查,规范变更触发实现和测试差异检查。最终提交应说明用了哪些代码证据、哪些业务规则以及尚未解决的冲突,避免 Agent 把推断写成事实。
静态规则库可从代码、配置、Spec和测试中抽取条件—结论—动作,人工审核后统一成带适用范围、优先级、版本和证据位置的规则。执行时由规则引擎先匹配,Agent只负责解释和补充;规则变更需回放样例、单测并保留版本,冲突按优先级或转人工。
差距在哪:新手把领域知识等同于代码 Embedding,高手区分运行事实与规范意图,并用版本、权威层级和双向变更检查处理冲突。
Q:升级 Embedding 模型后,怎么保证索引和检索向量的逻辑一致性?
来源:阿里国际 AI 应用研发二面;本轮追问:向量怎么存储的?(本轮追问)
新手答:“重新跑一遍索引就行了。”
高手答:
核心问题:旧文档用 Model_v1 编码入库,新查询用 Model_v2 编码检索——两个模型的向量空间不对齐,导致检索质量断崖式下降。即使两个模型都很强,它们学到的向量空间是不同的,v1 空间里的“近邻”在 v2 空间里可能完全不是近邻。
“全量重建索引”是正确的方向,但对于百万级文档,全量重建需要数小时甚至数天,在此期间系统要么不可用,要么用旧模型继续服务(效果变差)。所以真正的挑战不是“能不能重建”,而是“怎么平滑过渡”。
三种升级策略:
策略一:双索引并行
在旧索引继续服务的同时,后台用新模型构建新索引。
新索引构建完成后,做一次原子切换——流量瞬间从旧索引切到新索引。
优点:切换瞬间完成,用户无感知。缺点:过渡期需要双倍存储成本,且切换前无法验证新索引的线上效果。
策略二:渐进式迁移
给每个文档向量打上 embedding_model_version 标签。
过渡期内,查询同时用 v1 和 v2 两个模型编码,分别检索对应版本的分区,合并结果。
后台逐步将旧文档用新模型重新编码,完成后删除旧分区。
优点:平滑过渡,任何时刻系统都可用。缺点:过渡期查询要编码两次、搜索两次,延迟翻倍。
策略三:版本化索引 + 灰度切换
新索引构建完成后,不立即全量切换,而是先导流 5-10% 到新索引。
对比新旧索引的线上指标(召回率、相关性、用户点击率)。
指标达标 → 逐步扩大流量比例直到全量切换。
指标异常 → 立即回滚到旧索引。
优点:风险最低,有数据验证。缺点:验证周期长,需要流量分配基础设施。
完整的双索引过渡流程:
flowchart TB
START["触发模型升级"] --> BUILD["后台构建新索引\n(Model_v2 编码全量文档)"]
BUILD --> OLD["旧索引继续服务\n(Model_v1)"]
BUILD --> DONE{"新索引\n构建完成?"}
DONE -->|"否"| OLD
DONE -->|"是"| CANARY["灰度切换\n5% 流量到新索引"]
CANARY --> CHECK{"质量指标\n达标?"}
CHECK -->|"是"| SCALE["逐步扩大流量\n10% → 50% → 100%"]
CHECK -->|"否"| ROLLBACK["回滚到旧索引\n排查问题"]
SCALE --> FULL["全量切换完成"]
FULL --> CLEAN["清理旧索引\n释放存储"]
工程保障措施:
- 始终存储原始文本:向量可以重算,原始文本不能丢。每个 chunk 必须保留原始文本,这样任何时候都能用新模型重新编码
- 版本标记每个向量:
embedding_model_version字段必须持久化到向量记录中,方便区分哪些文档已迁移、哪些还没有 - 自动化质量回归测试:维护一组
(query, expected_relevant_docs)的黄金测试集,每次模型升级后自动跑 Recall@K 和 MRR,低于阈值则阻断上线
差距在哪:新手只想到“重建”——这是正确的第一步但忽略了过渡期的可用性。高手给出了双索引并行、渐进式迁移、灰度切换三种策略,且强调了版本标记和自动化质量回归测试。面试官考的是你对向量检索系统升级的工程化思维——不是“能不能升级”,而是“怎么平滑升级”。
进阶检索架构
Q:RAG 架构与模型微调(Fine-tuning)相比,各自的适用场景和优缺点是什么?
来源:字节后端 Agent 开发二面 【淘天转正实习一面追问:预训练语料已包含相关知识为什么还要RAG】【字节二面(Trae)追问:RAG 主要用来做什么?】;本轮追问:你做过多模态大模型微调,什么场景下需要做模型微调?微调可以解决什么问题?(本轮追问);滴滴一些面经合集(算法);帆软终面-人生最烂的面试体验;本轮追问:rag是什么,具体场景有哪些,如何分片(赛诺贝斯 面经 一面过 笔试过 hc无);美团agent一面;本轮追问:RAG、传统检索+生成、微调三种方案的本质区别是什么?分别在什么场景下选用?(27秋招-恒生电子AI面试-AI应用开发岗-26.9.23);0924恒生电子|AI 应用开发工程师 |AI面
新手答:“RAG 不需要训练,Fine-tuning 效果更好。”
高手答:
这两种方案不是互斥的,而是解决不同类型知识注入问题的工具。核心判断框架:
RAG 本质是「外挂知识」——检索时注入
| 维度 | RAG |
|---|---|
| 知识更新 | 改文档即生效,无需重新训练 |
| 可追溯性 | 每个回答都能追溯到来源文档 |
| 成本 | 无训练成本,主要是检索基础设施 |
| 知识容量 | 理论上无上限,取决于文档库规模 |
| 适用场景 | 知识频繁更新、需要引用来源、企业知识库 |
Fine-tuning 本质是「内化知识」——训练时注入
| 维度 | Fine-tuning |
|---|---|
| 知识更新 | 需重新训练和部署 |
| 可追溯性 | 无法追溯到具体来源 |
| 成本 | 训练 + 数据标注 + GPU 资源 |
| 知识容量 | 受模型参数量限制 |
| 适用场景 | 固化领域风格/格式、提升特定任务能力、降低推理成本 |
关键决策点:
flowchart TD
A["知识会频繁变化吗?"] -->|"是"| B["RAG"]
A -->|"否"| C["需要引用来源吗?"]
C -->|"是"| B
C -->|"否"| D["是格式/风格问题\n还是知识问题?"]
D -->|"格式/风格"| E["Fine-tuning"]
D -->|"知识"| F["数据量够吗?"]
F -->|"充足"| G["Fine-tuning + RAG 混合"]
F -->|"不足"| B
最优解往往是混合方案:用 Fine-tuning 让模型学会领域的「语言」和「格式」(怎么说),用 RAG 注入具体的「事实」和「知识」(说什么)。例如医疗场景——微调让模型学会医学术语和问诊风格,RAG 提供最新的诊疗指南和药品信息。
典型流程是“文档解析→清洗→分片→向量化→召回→重排→拼接上下文”。分片可按标题、段落和语义边界切分,控制块大小并设置适度重叠,避免上下文断裂;同时保留文档、页码、章节等元数据。应通过召回率、命中片段完整性和端到端答案评测调整策略。
传统检索+生成通常指用关键词、规则或数据库检索结果拼接提示词再生成,RAG是更广义的知识增强范式,可包含稠密、混合检索、重排和引用约束;两者有重叠。稳定事实和固定输出格式适合微调,动态、可追溯知识适合RAG,简单场景可用传统检索,复杂语义检索再采用完整RAG。
差距在哪:新手把 RAG 和 Fine-tuning 当成二选一。高手理解两者解决不同问题——RAG 解决「知道什么」,Fine-tuning 解决「怎么表达」——且给出了决策框架和混合方案。面试官考的是你对知识注入手段的全局认知。
Q:PDF 解析用什么工具?Layout-aware Parsing 是怎么做的?
来源:腾讯 AI 应用开发二面;本轮追问:PDF转写从31分钟优化到2.5分钟,怎么做的?(本轮追问);本轮追问:你的 Agent 在实现文件解析方面做了哪些优化,图表解析有什么优化思路?(本轮追问);本轮追问:目前你的 RAG 项目可以读取哪些文件?可以读取 PDF 和 PPT 吗?(本轮追问);阳光电源 AI应用开发工程师 一面;本轮追问:RAG中PDF从上传到最终召回经历哪些阶段?(字节全栈一面);本轮追问:怎么解决文档解析出错的问题?(拼多多 agent 一面凉经);经纬恒润ai应用开发一面面经;合肥某头部企业软件开发实习生面试问题汇总(时长1个小时)
新手答:“用 PyPDF 读文本就行。”
高手答:
PyPDF 只能提取纯文本流,完全丢失版面布局信息——表格变成散乱的文字、双栏论文的左右栏被混在一起、图片标注和正文混淆。RAG 的质量上限取决于解析质量,解析错了后面全链路都救不回来。
主流 PDF 解析工具对比:
| 工具 | 原理 | 优势 | 劣势 | 适合场景 |
|---|---|---|---|---|
| PyPDF / pdfplumber | 文本流提取 | 快、零依赖 | 丢失布局,表格乱 | 纯文本 PDF |
| Unstructured | 规则 + ML 混合 | 支持多格式,社区活跃 | 表格准确率一般 | 通用文档 |
| Marker | 视觉模型 | 版面还原度高 | 速度慢 | 学术论文 |
| MinerU (PDF-Extract-Kit) | 版面检测 + OCR | 表格还原强,开源 | 资源消耗大 | 复杂排版 PDF |
| 商业方案(Azure Document Intelligence) | 云端 ML | 准确率最高 | 收费、数据出境 | 企业级生产 |
Layout-aware Parsing 的核心思路:
flowchart LR
A[“PDF 页面图像”] --> B[“版面检测\n(识别文本/表格/图片区域)”]
B --> C[“区域分类\n(标题/正文/表格/脚注)”]
C --> D[“分区提取\n(文本用OCR,表格用专门解析器)”]
D --> E[“阅读顺序重建\n(双栏→单栏序列)”]
E --> F[“结构化输出\n(带标签的文本块)”]
关键是先“看”再“读”——不是直接提取文本流,而是先用视觉模型识别页面上每个区域的类型和位置,然后按阅读顺序依次提取。
选型建议:学术论文用 Marker 或 MinerU(版面复杂但格式相对规范),企业文档用 Unstructured + 自定义后处理,对准确率要求极高的场景用商业方案。没有万能工具,必须横向对比——用同一批标注好的文档测试不同工具的准确率,选最适合自己文档类型的。
完整链路通常是上传校验与存储、解析/OCR、版面重建、清洗切块、写入元数据、向量化建索引,查询时再召回、重排并组装上下文。解析出错应保留页码和坐标,结合置信度、规则校验和人工抽检定位问题;对扫描件或低置信区域切换 OCR/备用解析器,并用样本文档回归测试。
追问补充:可接收 PDF、Word、PPT、Excel、HTML、TXT 和图片等格式,先按 MIME 与文件特征校验,再走对应解析器并统一成带页码、坐标、表格结构的中间格式。原生 PDF 通常直接读取文本层并校验阅读顺序;缺少可靠文本层的扫描 PDF 需逐页 OCR,并依据置信度触发重试或人工抽检。
差距在哪:新手用 PyPDF 读文本,遇到表格和复杂排版就束手无策。高手理解 Layout-aware Parsing 的核心是“先视觉理解版面结构,再分区提取内容”,并能对比不同工具的适用场景做选型。面试官考的是你对 RAG 管线最上游(文档解析)的工程理解——这一步的质量决定了后续所有环节的上限。
Q:向量数据库中 IVF_FLAT 和 HNSW 索引的区别是什么?各自适合什么场景?
来源:快手AI应用开发一面【阿里巴巴(淘天)- 大模型算法岗(搜推方向)追问:向量检索中 IVF 与 HNSW 的选型依据是什么?】【全栈实习一面,20分钟居然问这么细😂追问:你的 RAG 向量数据库用的索引是什么?】;本轮追问:如果分完桶之后,有一个桶里面只有 10000 个向量,为什么会出现这样只有 10000 个向量的桶?这些向量是怎么组织的,怎么分层的?(奇怪の字节二面面经(大概率凉经));华为AI开发一面;字节 260907 一面面经;虾皮秋招 研发工程师
新手答:“都是加速向量搜索的索引,HNSW 更快。”
高手答:
IVF_FLAT 和 HNSW 是两种完全不同的索引范式——一个基于分区量化,一个基于图遍历,适用场景差异很大:
| 维度 | IVF_FLAT | HNSW |
|---|---|---|
| 核心思想 | 先聚类分桶,查询时只搜少数桶 | 构建多层跳表图,贪心遍历近邻 |
| 构建时间 | 快(kmeans 聚类) | 慢(逐点插入建图) |
| 内存占用 | 低(只存聚类中心 + 原始向量) | 高(每个节点存多层邻居指针) |
| 查询速度 | 中等(受 nprobe 参数控制) | 极快(图遍历,路径短) |
| 召回率 | nprobe 小时召回低,大时接近精确 | 高(ef_search 调大后接近 100%) |
| 增量更新 | 容易(新向量分配到最近的桶) | 较难(插入需更新多层图结构) |
| 数据规模 | 适合千万级以上(配合 PQ 压缩) | 适合百万到千万级 |
IVF_FLAT 工作原理:
建索引:对所有向量做 K-means 聚类 → 得到 nlist 个聚类中心
查询时:计算 query 与所有聚类中心的距离 → 选最近的 nprobe 个桶 → 在这些桶内暴力搜索
HNSW 工作原理:
建索引:逐个插入向量,每个向量随机分配层级 → 在每层中与最近邻建立边
查询时:从顶层入口点开始 → 在每层贪心跳到最近邻 → 逐层下降直到底层 → 底层精搜 Top-K
选型决策:
| 场景 | 推荐索引 | 原因 |
|---|---|---|
| 数据量大(>1000w)、内存有限 | IVF_PQ(IVF + 量化压缩) | HNSW 内存扛不住 |
| 数据量中等、要求低延迟 | HNSW | 查询速度最快,延迟稳定 |
| 数据频繁更新(实时写入) | IVF_FLAT | 增量更新成本低 |
| 离线批量检索、对延迟不敏感 | IVF_FLAT(大 nprobe) | 召回率高且节省内存 |
| RAG 在线服务 | HNSW | 用户感知延迟要低,内存可以加机器解决 |
桶大小不是固定值。K-means 按向量到聚类中心的最近距离分配,若数据分布不均、中心数较大或存在密集与离群区域,各桶自然会大小不同;10000 只是该中心吸引到的向量数。桶内通常保存向量及主键等数据,查询先选最近的 nprobe 个中心,再在对应桶内扫描;IVF 本身没有像 HNSW 那样的多层邻接结构。
追问补充:还可选Flat暴力检索、IVF_SQ、IVF_PQ、DiskANN等:小规模或极高召回优先Flat,内存受限可用SQ/PQ,超大规模且数据主要在磁盘可评估DiskANN。HNSW适合内存充足、低延迟和较稳定更新的在线场景;若写入频繁、内存紧张或可接受更高延迟,应优先比较IVF或磁盘索引,并用召回率、延迟、内存和更新成本压测决定。
差距在哪:新手只知道“HNSW 更快”——这是结论不是理解。高手从数据结构原理(分桶 vs 图遍历)出发,推导出各自的性能特征和适用场景,且能给出具体的选型建议。面试官考的是你对向量检索底层机制的理解深度——不是会用 API,而是知道为什么这个参数要这样调。
Q:图检索、向量检索、混合检索有什么区别?怎么选?
来源:腾讯 AI 应用开发二面;字节 AI 应用开发二面【百度Agent一面追问:为什么选择混合召回?】【作业帮秋招一面追问:RAG 是多路检索吗,单路检索能不能做、能不能解决业务问题?】;本轮追问:为什么设计三层管线,先使用 LLM 转化,再使用 Neo4j,最后使用 Milvus 兜底?设计原理是什么?(飞书深诺(全栈AI应用开发方向));10.8 pdd秋招 agent 一面;高斯信息技术,ai开发工程师,一面
新手答:“向量检索最常用,图检索更准。”
高手答:
三种检索方式解决的是不同类型的查询问题,不存在“哪个更准”:
| 维度 | 向量检索 | 混合检索 | 图检索(GraphRAG) |
|---|---|---|---|
| 检索原理 | 语义相似度匹配 | 语义 + 关键词双路 | 实体关系遍历 + 社区摘要 |
| 擅长的查询 | “XX 是什么”“如何做 XX” | 既需要语义又需要精确匹配 | “XX 和 YY 有什么关系”“整体趋势” |
| 不擅长的查询 | 多跳推理、关系型问题 | 全局性总结类问题 | 简单事实问答 |
| 索引构建成本 | 低(只需 Embedding) | 中(Embedding + 倒排索引) | 高(LLM 抽取实体 + 图构建) |
| 查询延迟 | 毫秒级 | 毫秒级 | 秒级(需图遍历) |
| 维护成本 | 低(增量更新简单) | 中 | 高(实体变更需重建子图) |
选型决策树:
查询类型主要是什么?
├── 事实问答(”XX 的创始人是谁”)→ 混合检索(关键词精确 + 语义兜底)
├── 概念解释(”什么是 RAG”)→ 向量检索(语义匹配足够)
├── 关系推理(”A 和 B 有什么关联”)→ 图检索
├── 全局总结(”这个领域的趋势”)→ 图检索(Community Summary)
└── 混合场景 → 多路检索 + ReRank 融合
生产系统的常见做法:不选一种,而是多路并行、统一精排。向量检索和关键词检索作为基础双路,图检索作为补充路(只在检测到关系型查询时启用)。最后用 ReRank 模型统一排序,取 Top-K 送给生成模型。
“为什么没用 Knowledge Graph”也要用证据回答:先按线上 Query 标注事实查找、精确术语、多跳关系和全局总结的占比,再用同一评测集比较向量/混合检索与图检索在目标切片上的增量。如果问题主要是单跳事实、实体关系数据不完整、知识更新频繁,图的抽取、消歧、冲突合并和增量维护成本可能高于收益,此时不使用 KG 是合理决策;只有关系型切片的端到端正确率、证据质量或可解释路径显著提升,且延迟与维护成本可接受,才逐步启用图检索。不能用“GraphRAG 更先进”或“项目没时间”代替量化取舍。
三层管线是按成本与确定性逐级兜底:先由 LLM 将自然语言转成实体、关系或结构化查询,便于 Neo4j 做精确关系遍历;图查询失败、实体缺失或不适合关系推理时,再用 Milvus 做语义召回,避免因图谱不完整直接无结果。各层应记录命中率、延迟和答案正确率,用评测数据验证是否值得保留。
差距在哪:新手把三种检索当成“好/更好/最好”的关系。高手理解它们解决的是不同类型的查询问题——向量检索擅长语义匹配,混合检索兼顾精确和语义,图检索擅长关系推理和全局总结。选型依据不是“哪个更先进”,而是“你的查询类型分布是什么”。面试官考的是你对多种检索范式的系统性理解和选型能力。
Q:如何处理 RAG 过程中的权限隔离和时效性问题?
来源:字节后端 Agent 开发二面【阿里千问 AI 应用研发一面追问:文档/Chunk ACL、缓存与引用泄露】【拼多多 复活赛 一面追问:你们把内部文档给 Agent 用,有没有考虑过泄露问题?】;本轮追问:你们定义的 RWBNCT 这 6 类权限 scope 分别代表什么,实际落地了哪几个?(本轮追问);本轮追问:有没有用过 RAG?(本轮追问)
新手答:“给每个用户建一个单独的知识库。”
高手答:
权限隔离和时效性是 RAG 上生产环境后最先暴露的两个安全问题。单独建库的方案在用户量大时不可行——需要系统性的工程方案:
一、权限隔离:检索前过滤,而非物理隔离
用户请求 → 鉴权(提取用户权限标签)
→ 在向量检索时注入 metadata filter
→ 只召回用户有权访问的文档
实现方式:
| 方案 | 实现 | 适用场景 |
|---|---|---|
| 元数据过滤 | 每个文档 chunk 存储权限标签(部门、角色、项目),检索时通过 pre-filter 过滤 | 权限维度明确、变更不频繁 |
| 多租户索引 | 按租户分索引(物理隔离),查询时路由到对应索引 | 租户间数据完全隔离(如 SaaS 多客户) |
| 行级安全 | 在关系型数据库层面做权限控制,向量检索结果再和权限表 join | 权限规则复杂、需要动态变更 |
关键工程细节:pre-filter(检索前过滤)vs post-filter(检索后过滤)的选择。pre-filter 在向量数据库层面直接过滤,效率高但可能影响召回质量(候选集变小);post-filter 先全量召回再权限过滤,召回质量高但有信息泄露风险(模型可能已经「看到」了无权限内容的 embedding 相似度信号)。生产中推荐 pre-filter。
ACL 必须从文档继承到 Chunk、派生摘要、图片描述和索引点,所有向量/BM25/GraphRAG/补充检索路径使用同一授权条件。向量库的 metadata filter 只是执行能力,例如 Qdrant 官方过滤文档支持 payload 条件;授权策略仍由可信身份系统决定。关系元数据可使用类似 PostgreSQL Row-Level Security的默认拒绝策略,并审计高权限账号和策略绕过边界。
缓存键还要包含租户、权限摘要和策略版本;权限撤销后使相关缓存失效。Rerank、上下文组装和最终引用再次校验资源权限,避免无权 Chunk 通过缓存、日志或引用反查泄露。回归集覆盖跨租户、共享文档、权限撤销、ACL 继承和缓存串读。
二、时效性:文档生命周期管理
| 策略 | 做法 |
|---|---|
| 时间戳标记 | 每个 chunk 存储文档创建/更新时间,检索时做时间衰减加权 |
| 增量更新 | 文档变更时只重新嵌入受影响的 chunk,不重建全量索引 |
| 版本管理 | 同一文档的多个版本共存,检索时优先返回最新版本 |
| TTL 机制 | 设置文档过期时间,过期后自动降权或剔除 |
时效性的隐藏陷阱:用户问「最新的政策是什么」,如果召回了旧版本文档,模型会很自信地给出过时的答案——这比「不知道」更危险。防御方案:在生成阶段注入时间上下文(「以下文档更新于 2024-03-01,请注意时效性」),让模型自己判断是否需要提示用户信息可能过时。
差距在哪:新手只想到物理隔离(按用户建库)。高手给出了三层权限方案(元数据过滤、多租户索引、行级安全)和四种时效性策略,且点出了 pre-filter vs post-filter 的安全 trade-off。面试官考的是你对 RAG 工程化落地中安全问题的实战认知。
Q:Deep Research 在代码层面是怎么实现的?和普通 RAG 有什么区别?
来源:bilibili AI研发实习一面【字节火山引擎 Managed Agent 一面追问:如何用 Agent 做 Auto Research】;斑头雁(Agent实习生面试一面);10.10 无锡赫玛科技
新手答:“就是多搜几次,然后总结一下。”
高手答:
Deep Research 不是“多搜几次”——它是一种Agent 驱动的迭代检索-合成架构,核心区别在于检索策略是动态的、由 Agent 在运行时根据已有信息决定下一步查什么。
和普通 RAG 的本质区别:
| 维度 | 普通 RAG | Deep Research |
|---|---|---|
| 检索次数 | 一次(query → 检索 → 生成) | 多次迭代(每轮检索结果影响下一轮查询) |
| 查询生成 | 用户原始 query 或简单改写 | Agent 根据已有信息动态生成子查询 |
| 知识综合 | 拼接检索结果给模型 | 逐步构建结构化的知识图,跨文档关联 |
| 覆盖判断 | 无——检索一次就结束 | Agent 评估“信息是否足够”,不够则继续检索 |
| 输出 | 短回答 | 长篇结构化报告 |
代码层面的核心实现:
用 LangGraph 实现 Deep Research 的典型架构:
flowchart TB
Q["用户研究问题"] --> PLAN["规划节点\n生成研究大纲 + 子问题列表"]
PLAN --> SEARCH["检索节点\n对当前子问题做多源检索"]
SEARCH --> ANALYZE["分析节点\n提取关键信息 + 评估覆盖率"]
ANALYZE --> CHECK{"覆盖率\n足够?"}
CHECK -->|"否:发现知识缺口"| REFINE["改写节点\n生成新的子查询"]
REFINE --> SEARCH
CHECK -->|"是"| SYNTH["综合节点\n跨文档知识整合"]
SYNTH --> REPORT["报告生成节点\n结构化输出 + 引用标注"]
关键实现细节:
1. 规划节点——把大问题拆成可检索的子问题
def plan_node(state):
prompt = f"""将以下研究问题拆解成 3-5 个具体的子问题,
每个子问题应该能通过一次文献检索回答:
研究问题:{state["research_question"]}
"""
sub_questions = llm.invoke(prompt)
return {"sub_questions": sub_questions, "current_index": 0}
2. 检索节点——对每个子问题做多源并行检索
async def search_node(state):
query = state["sub_questions"][state["current_index"]]
results = await asyncio.gather(
search_semantic_scholar(query),
search_arxiv(query),
search_web(query),
)
merged = deduplicate(flatten(results))
return {"search_results": merged}
和普通 RAG 只查一个向量库不同,Deep Research 通常并行查询多个数据源(学术数据库、网页、专利库),然后合并去重。
3. 分析节点——提取信息并评估覆盖率
这一步是 Deep Research 的核心——Agent 不只是检索,还要评估检索结果的充分性。如果发现知识缺口(某个子问题还没有足够的证据支撑),生成新的查询再检索。
def analyze_node(state):
extracted = llm.invoke(f"""从以下检索结果中提取关键信息:
{state["search_results"]}
已有知识:{state.get("accumulated_knowledge", "")}
当前子问题:{state["sub_questions"][state["current_index"]]}
输出:1. 关键发现 2. 置信度评估 3. 知识缺口
""")
return {
"accumulated_knowledge": state.get("accumulated_knowledge", "") + extracted.findings,
"gaps": extracted.gaps,
"coverage_sufficient": extracted.confidence > 0.8
}
4. 迭代控制——防止无限检索
def should_continue(state):
if state["coverage_sufficient"]:
return "synthesize"
if state["iteration_count"] >= MAX_ITERATIONS: # 通常 3-5 轮
return "synthesize"
return "refine_query"
必须设置最大迭代次数,否则 Agent 可能陷入“总觉得信息不够”的无限循环。
5. 综合节点——跨文档知识整合
普通 RAG 直接把检索结果拼给模型生成答案。Deep Research 需要先做跨文档的知识整合——对比不同来源的观点、识别共识和争议、构建时间线和因果关系——然后基于整合后的结构化知识生成报告。
工程上的核心难点:
| 难点 | 解决方案 |
|---|---|
| 迭代多轮导致上下文膨胀 | 每轮只保留结构化摘要,原始检索结果不进入下一轮上下文 |
| 多源检索结果质量参差不齐 | 来源权威性评分 + ReRank 精排 |
| 幻觉引用风险高 | 所有事实必须关联到具体检索结果的 ID,生成后做引用校验 |
| 检索成本高 | 设最大迭代次数 + 子问题优先级排序(先查最关键的) |
追问补充:在 ReAct 循环中,工具应按职责拆分为检索、日志查询、指标查询、代码或配置读取,并用结构化 schema 限制参数和权限;提示词要求每轮输出“观察、判断、下一步工具调用及停止条件”,对超时、空结果和冲突证据设重试、改写或人工确认分支,避免无效循环。
差距在哪:新手把 Deep Research 理解为“多搜几次加总结”。高手在代码层面展示了完整的迭代检索-分析-改写循环,核心是 Agent 驱动的动态查询生成和覆盖率评估——每轮检索的 query 不是预设的,而是根据已有信息实时生成的。面试官考的是你能不能把 Deep Research 从产品概念转化为可实现的 Agent 管线。
Q:RAG 知识库的噪声剔除和文档去重怎么做?
来源:腾讯 AI 应用开发二面 【淘天Agent开发追问:防止 AI 批量生成虚假数据投毒】;经纬恒润ai应用开发一面面经;秋招-字节跳动-抖音电商-Agent开发一/二/三面
新手答:“看着删。”
高手答:
知识库的质量直接决定 RAG 的效果上限。垃圾进,垃圾出——再好的检索和生成也无法弥补知识库本身的噪声。
噪声剔除分三层:
| 层次 | 噪声类型 | 剔除方法 |
|---|---|---|
| 文档级 | 空文档、格式损坏、非目标语言 | 规则过滤(长度/编码/语种检测) |
| 段落级 | 页眉页脚、版权声明、目录、广告 | 正则匹配 + 分类器(训练一个轻量模型区分正文和噪声) |
| 语义级 | 无信息量的废话、过时信息 | 信息密度评分(困惑度过低的段落往往是套话) |
文档去重的三种策略:
- 精确去重(URL / 文件哈希):对文档的 URL 或内容 MD5 去重,处理完全相同的文档。最快,但无法处理“内容相同但格式不同”的情况
- 近似去重(MinHash / SimHash):计算文档的指纹,相似度超过阈值(如 0.9)的文档只保留一篇。适合处理“同一篇文章的不同版本”
- 语义去重(Embedding 聚类):对所有文档做 Embedding,用 DBSCAN 聚类,同一簇内保留质量最高的一篇。计算成本高,但能处理“不同表述的相同内容”
重复片段识别:
多篇文章中出现的重复段落(如“免责声明”“公司简介”)比整篇重复更隐蔽。处理方法:
1. 对所有 chunk 计算 SimHash 指纹
2. 按指纹分桶,同桶内的 chunk 两两比较文本相似度
3. 相似度 > 0.85 的标记为重复片段
4. 保留出现次数最多的那一份,其余删除或标记为”低优先级”
追问补充:入库前增加内容审核闸门:校验来源可信度、时效性、完整性和敏感信息,识别恶意指令、虚假内容及与主题无关的文档;高风险或低置信内容进入隔离区。按版本记录审核人、时间和处理结果,定期抽样复核并用检索命中率、引用正确性反馈清洗规则。
追问补充:相似名称只能用于召回候选,不能直接判重。先规范化名称,再核对唯一编号、适用范围、发布机构、生效时间及正文关键义务;字段和语义均一致才合并,否则保留独立版本,并由来源或人工复核确认。
差距在哪:新手要么不做清洗(让噪声进入检索),要么靠人工逐条检查(不可扩展)。高手从文档级/段落级/语义级三层做噪声剔除,用精确/近似/语义三种策略做去重,形成了可自动化、可扩展的知识库清洗管线。面试官考的是你对 RAG 数据质量的工程化管控能力。
Q:RAG 检索到的 Chunk 不足以回答问题,后续怎么处理?
来源:字节春招大模型测开一面;本轮追问:使用全文索引检索,如果遇到召回不到的问题怎么处理?(淘天AI应用开发二面);本轮追问:是否先按照标题结构划分模块,再将模块拆成小 chunk?检索时召回小 chunk,再补充对应的父模块吗?(字节 Agent 秋招二面)
新手答:“让模型直接用自己的知识回答,或者告诉用户找不到。”
高手答:
这是 RAG 系统最常见的退化场景之一。“Chunk 不足”有两种含义——检索到了但信息不够完整,或者根本没检索到相关内容。处理策略完全不同:
第一层:判断“不足”的程度
在生成前先做一步充分性评估(Sufficiency Check):用 LLM 判断当前检索结果能否支撑回答。评估维度:
- 关键实体是否存在(问“A 和 B 的区别”,至少要有 A 和 B 的描述)
- 时间/数值是否覆盖(问“2024年营收”,2023年的数据不算充分)
- 逻辑链是否完整(问“为什么 X 导致 Y”,需要因果链条,不能只有结论)
第二层:补充检索策略
如果判定不足,触发 Agentic RAG 的补充检索:
flowchart TD
A[“初次检索结果”] --> B{“充分性评估”}
B -->|”充分”| C[“直接生成回答”]
B -->|”不充分”| D[“策略切换”]
D --> E[“查询改写\n换角度/拆子问题”]
D --> F[“扩大召回\n放宽阈值/切换索引”]
D --> G[“跨库检索\n换知识源/调外部API”]
E & F & G --> H{“二次充分性评估”}
H -->|”充分”| C
H -->|”仍不足”| I[“诚实告知+给出部分答案+标注不确定性”]
关键策略:
- 查询改写 — 原始 query 可能太笼统或措辞偏离文档表达。拆成子问题、换同义词、补充上下文后重新检索
- 扩大召回范围 — 降低相似度阈值、增加 Top-K、切换到 BM25 关键词匹配(语义检索漏掉的关键词匹配可能命中)
- 跨库检索 — 如果本地知识库确实没有,可以调用外部搜索引擎、数据库查询、或调用其他系统的 API
第三层:生成策略
如果补充检索后仍不足:
- 部分回答 + 标注 — “根据现有信息,X 部分的答案是…,但关于 Y 的具体数据暂未找到”
- 不编造 — 绝对不能让模型用自身参数知识补充事实性信息(这是幻觉的主要来源)
- 引导用户 — “您可以提供更具体的文档/关键词吗?”或“建议查阅 XX 系统获取最新数据”
全文索引召回不到时先用已知文档做可检索性验证,检查分词器、同义词、字段权重、大小写及停用词配置,并确认文档已入索引且过滤条件未排除。再用关键词拆分、同义词扩展、拼写纠错或放宽过滤重试,结合 explain 和命中样本定位是索引还是查询问题。
差距在哪:新手的处理是二元的——“有就答,没有就说不知道”。高手有一套分级应对策略:先评估不足程度,再用查询改写/扩大召回/跨库检索做补充,最后仍不足时给出部分答案并标注不确定性。面试官考的是你对 RAG 系统边界情况的处理能力——生产环境中“检索不足”比“检索精准”出现得更频繁。
Q:Agentic RAG 是什么?和传统 RAG 的核心区别?
来源:美团Keeta Agent开发一面;本轮追问:RAG 项目使用的基座模型是什么?(本轮追问)
新手答:「就是把 RAG 和 Agent 结合起来吧。」
高手答:
传统 RAG 是单轮管线:query → 检索 → 生成,一次检索定胜负。Agentic RAG 的本质变化是把 Agent 的推理循环引入检索过程——检索不再是单次操作,而是 Agent 的一个可反复调用的工具。
两者的核心架构差异:
flowchart LR
subgraph trad[“传统 RAG”]
Q1[“Query”] --> R1[“检索”] --> G1[“生成”]
end
subgraph agentic[“Agentic RAG”]
Q2[“Query”] --> A[“Agent 推理”]
A -->|”判断需要什么信息”| R2[“检索工具”]
R2 -->|”结果不够/不对”| A
A -->|”需要补充”| R3[“二次检索/换策略”]
R3 --> A
A -->|”信息充足”| G2[“生成”]
end
| 维度 | 传统 RAG | Agentic RAG |
|---|---|---|
| 检索决策 | 固定管线,query 进来就检索 | Agent 判断是否需要检索、检索什么 |
| 检索次数 | 单次 | 多次迭代,根据结果质量决定是否继续 |
| Query 改写 | 预定义规则改写 | Agent 根据上下文动态改写,甚至拆分子问题 |
| 结果评估 | 无(检索到什么就用什么) | Agent 评估检索质量,不满意则换策略重检 |
| 工具组合 | 只有向量检索 | 可组合多种检索工具(向量、图谱、SQL、API) |
| 适用场景 | 简单事实问答 | 复杂多跳推理、需要整合多源信息的任务 |
Agentic RAG 的三个关键能力:
- 自主判断检索时机:不是每个 query 都需要检索——Agent 先评估自身知识是否足够,不足时才触发检索。避免了传统 RAG 对所有请求都检索的资源浪费
- 检索结果自我评估:检索完成后,Agent 判断结果是否能回答问题。如果召回的文档不相关或信息不完整,主动改写 query 或切换检索策略进行二次检索
- 多源检索编排:复杂问题拆成多个子问题,分别用不同的检索工具(向量库查概念、知识图谱查关系、SQL 查数据),最后综合推理
工程落地的权衡:
Agentic RAG 的能力更强,但延迟和成本也更高——多次检索意味着多次 LLM 推理。生产中通常采用分级策略:简单 query 走传统 RAG 快速响应,复杂 query 才进入 Agentic RAG 循环。
差距在哪:新手把 Agentic RAG 简单理解为「RAG + Agent」的拼凑。高手理解核心区别在于检索从固定管线变成了 Agent 的可迭代工具——Agent 能自主决定是否检索、检索什么、结果够不够、要不要换策略。面试官考的是你对 RAG 范式演进的认知——从被动管线到主动推理。
Q:补充检索是如何评估数据质量并触发的?怎么保证二次检索能搜到之前没搜到的内容?
来源:淘天 Agent 开发;本轮追问:如果检索不到相关内容,是视频中本来没有答案、解析阶段丢失了信息,还是检索策略有问题?(本轮追问);腾讯 260824 一面面经
新手答:“检索结果不好就再搜一次。”
高手答:
「再搜一次」如果用同样的策略,结果不会有本质变化。补充检索的关键是先评估质量,再换策略重搜:
一、什么时候触发补充检索?
需要一个质量评估门控,而不是每次都二次检索:
| 评估维度 | 检测方法 | 触发条件 |
|---|---|---|
| 召回数量 | 候选文档数 < 阈值 | top-K 返回不足 3 条 |
| 相关性得分 | Rerank 后最高分低于阈值 | 最高分 < 0.5(模型和数据相关) |
| 覆盖度 | query 中的关键实体/概念是否被召回文档覆盖 | 核心实体零命中 |
| 自洽性 | 让模型判断「基于这些文档能否回答问题」 | 模型输出「信息不足」信号 |
最实用的方案是相关性得分 + 模型自判组合:Rerank 分数兜底硬指标,模型自判捕捉语义层面的不足。
二、怎么保证二次检索搜到不同的内容?
核心是换检索策略,而不是重复同一策略:
flowchart LR
A["首次检索失败"] --> B["策略切换"]
B --> C["查询改写\n同义扩展/拆分子问题"]
B --> D["换检索路\n向量→BM25\n或反过来"]
B --> E["放宽约束\n扩大时间范围\n降低阈值"]
B --> F["升级索引\n从chunk级→文档级\n或引入父子索引"]
C --> G["二次检索"]
D --> G
E --> G
F --> G
| 策略 | 做法 | 为什么能搜到新内容 |
|---|---|---|
| 查询改写 | 用 LLM 将原 query 改写为 2-3 个不同表述 | 弥补词汇鸿沟,触达不同文档 |
| 切换检索路 | 首次向量召回不好 → 换 BM25 精确匹配 | 两种检索的盲区不同 |
| 放宽约束 | 去掉时间/来源等过滤条件 | 扩大候选集 |
| 拆分子问题 | 复杂 query 拆成多个简单子 query 分别检索 | 每个子 query 更精准 |
三、防止无限循环
补充检索必须设上限(最多 2-3 轮)。如果多轮检索后质量仍不达标,应该诚实告知用户信息不足,而不是用低质量结果硬凑答案。
追问补充:用户未搜到预期结果时,先记录原始问题、改写结果、过滤条件、召回与重排日志,区分“数据源不存在”“解析或切分丢失”“索引未更新”“查询表达或检索策略不匹配”。再用人工标注查询检查文档覆盖、关键词命中和向量召回,定位后分别补数据、修解析索引或调整检索策略。
差距在哪:新手的「再搜一次」没有质量评估也没有策略切换——大概率搜出同样的结果。高手先用质量门控判断是否需要补充检索,再用策略切换保证二次检索有实质性差异。面试官考的是你对 RAG 检索链路的精细化控制能力。
Q:向量数据库里两个同义词是什么关系?完全同义的词会在同一个点上吗?
来源:字节春招大模型测开一面
新手答:“同义词的向量应该一样,在同一个点上。”
高手答:
同义词在向量空间中非常接近但不会完全重合。这涉及 Embedding 模型的本质工作方式:
为什么不在同一个点上:
Embedding 模型编码的不仅是“词义”,还包括:
- 使用语境差异 — “开心”和“高兴”虽然同义,但“开心果”和“高兴果”不等价。模型会捕捉到这些细微的搭配差异
- 语域/正式度 — “逝世”和“死了”语义相同,但正式度不同,向量会有偏移
- 训练语料分布 — 两个词在训练数据中的上下文分布不完全相同,导致编码略有差异
具体的空间关系:
完全同义词(如 “AI” 和 “人工智能”):
→ 余弦相似度 > 0.95,几乎重合但有微小偏移
近义词(如 “开心” 和 “高兴”):
→ 余弦相似度 0.85-0.95,同一区域的邻近点
上下位关系(如 “狗” 和 “动物”):
→ 余弦相似度 0.6-0.8,有方向性偏移
反义词(如 “大” 和 “小”):
→ 余弦相似度可能 0.3-0.6(不一定对称分布在原点两侧)
对 RAG 的实际影响:
同义词接近但不重合意味着:
- 查询 “AI应用” 可以召回包含 “人工智能应用” 的文档(相似度高)
- 但精确匹配度略低于完全相同的表述 → 这就是为什么需要查询改写(把 “AI” 扩展为 “AI/人工智能”)
- 也是为什么混合检索(向量 + BM25)有效 — BM25 处理精确匹配,向量处理语义近似
差距在哪:新手认为同义词 = 同一个点。高手理解 Embedding 空间是连续的高维空间,同义词是“近邻”而非“重合”,且能解释为什么——因为模型编码的是上下文分布而非字典定义。面试官通过这个问题考察你对 Embedding 的理解是停留在“API 调用”还是真正理解其数学含义。
Q:多模态 Embedding 检索中,文本语义与图像视觉特征的权重怎么平衡?用户检索图纸参数却召回外观相似零件,根源是什么?
来源:阿里淘天 AI应用开发一面;本轮追问:向量检索在多模态场景怎么用?图片和文本怎么映射到同一空间?(小红书多模态秋招二面)
新手答:“把文本和图片都转成向量,拼一起搜。”
高手答:
多模态检索的核心矛盾是不同模态的语义空间天然不对齐——文本描述的是抽象概念(尺寸、材质、公差),图像编码的是视觉特征(颜色、形状、纹理)。“拼一起搜”忽略了这个根本问题。
两种融合方式:
| 融合方式 | 原理 | 优点 | 缺点 |
|---|---|---|---|
| Early Fusion(CLIP-style 联合空间) | 文本和图像在训练时就映射到同一个向量空间 | 端到端优化,跨模态匹配能力强 | 通用模型学到的是“外观相似性”,不理解工程参数 |
| Late Fusion(分别编码再加权) | 文本和图像各自编码,检索时加权合并分数 | 权重可灵活调整,各模态可独立优化 | 跨模态交互弱,依赖权重调参 |
权重平衡方案:
静态权重:final_score = α × text_sim + (1-α) × image_sim,α 是固定值(如 0.6)。简单但不灵活——参数查询和外观查询用同一个权重显然不合理。
动态权重(更优方案):根据 query 类型自动调整权重——
Query 类型判断:
"M8×1.25 螺栓 材质 304" → 参数查询 → α=0.9(几乎全靠文本)
"这个零件长什么样" → 外观查询 → α=0.2(主要靠图像)
"找类似这张图纸的零件" → 混合查询 → α=0.5(均衡)
实现方式:用一个轻量分类器(或规则引擎)先判断 query 类型,再动态设置 α。
图纸参数召回外观相似零件的根源分析:
问题不在检索算法,在 Embedding 模型。通用视觉模型(如 CLIP)在预训练时学到的是外观级别的相似性——颜色、形状、轮廓。它不理解工程图纸中的参数语义(尺寸标注、公差范围、材质标签)。所以当用户搜“M8×1.25 不锈钢螺栓”时,模型返回的是外观最像螺栓的图片,而不是参数匹配的零件。
三种解决方案对比:
| 方案 | 做法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| 通用视觉模型(CLIP) | 直接用预训练模型做多模态检索 | 开箱即用,零成本 | 不理解工程参数,召回靠外观 | PoC 阶段、外观检索 |
| 领域微调模型 | 用工程图纸 + 参数标注数据微调 Embedding | 理解领域语义,参数匹配准确 | 需要标注数据,训练成本高 | 参数检索精度要求高 |
| 混合检索方案 | 参数字段走精确匹配,外观走向量检索 | 各取所长,参数精确、外观覆盖 | 系统复杂度高,需维护两套索引 | 生产环境首选 |
推荐的生产方案——混合检索:
结构化参数(尺寸、材质、公差)→ 标量过滤(精确匹配 / 范围查询)
外观特征(形状、颜色) → 向量检索(视觉相似度)
两路结果取交集或加权合并
结构化参数不应该走向量检索——“M8×1.25”这种精确规格用 Embedding 编码后会丢失精确性,直接用结构化字段过滤才是正确做法。向量检索只负责外观维度的相似度匹配。
差距在哪:新手把多模态当成“拼向量”。高手理解多模态检索的核心矛盾——不同模态的语义空间不对齐,权重平衡不是调参数,是选架构。面试官考的是你能不能从一个检索失败案例反推出系统设计缺陷。
Q:向量数据库中需要限定时间范围检索时,标量条件过滤怎么高效实现?
来源:阿里淘天 AI应用开发一面
新手答:“先向量检索再过滤掉不符合时间的。”
高手答:
“先搜后滤”(Post-filter)是最直觉但最低效的方案——放大 K 倍检索再过滤,过滤率高时大量计算浪费,且可能凑不够 K 条结果。
三种策略对比:
| 策略 | 做法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| Pre-filter | 先用标量索引(B-tree / bitmap)筛出时间范围内的文档 ID 集合,再在该子集上做 ANN 搜索 | 结果精确,不浪费向量计算 | 时间范围内文档太少时 ANN 效果退化(候选集不够大) | 过滤条件选择性高(筛掉大部分数据) |
| Post-filter | 先做 ANN 搜索取 top-K×M(放大 K),再用标量条件过滤 | 实现简单,不影响 ANN 索引结构 | 过滤率高时计算浪费严重,可能凑不够 K 条结果 | 过滤条件选择性低(只筛掉少量数据) |
| Hybrid | 在 ANN 搜索过程中同时检查标量条件,边搜边滤 | 平衡精度和效率 | 实现复杂,需要索引层支持 | 通用场景 |
Pre-filter 的详细流程:
1. 用标量索引快速筛选:SELECT doc_id FROM docs WHERE timestamp > 1700000000
→ 得到候选 ID 集合(毫秒级,B-tree 范围查询)
2. 在候选 ID 子集上做 ANN 搜索:只在这些向量上计算距离
→ 得到 top-K 结果(精确且无浪费)
Milvus 具体实现:
Milvus 支持 boolean expression 做 pre-filter,底层在 segment 级做分区裁剪(partition pruning):
# Milvus pre-filter 示例
results = collection.search(
data=[query_vector],
anns_field="embedding",
param={"metric_type": "COSINE", "params": {"nprobe": 10}},
limit=10,
expr="timestamp > 1700000000 and timestamp < 1710000000" # 标量过滤
)
最佳实践:
- 时间维度做 partition key:按时间范围(如按月)对数据做分区,查询时直接跳过不相关的分区,连标量过滤都省了
- 高基数标量字段建 scalar index:对 timestamp、category 等字段建标量索引,加速过滤
- Pre-filter 优先:除非过滤条件非常宽松(只筛掉 <10% 数据),否则 pre-filter 几乎总是优于 post-filter
- 监控过滤率:如果 post-filter 丢弃了超过 50% 的 ANN 结果,说明应该切换到 pre-filter
flowchart TB
Q["用户 Query + 时间范围"] --> D{"过滤选择性?"}
D -->|"高(筛掉 >50% 数据)"| PRE["Pre-filter\n先标量筛选再 ANN"]
D -->|"低(筛掉 <10% 数据)"| POST["Post-filter\n先 ANN 再标量过滤"]
D -->|"中等"| HYB["Hybrid\n边搜边滤"]
PRE --> R["Top-K 结果"]
POST --> R
HYB --> R
差距在哪:新手用“先搜后滤”的暴力方案。高手对比了 pre/post/hybrid 三种策略,理解 Milvus partition pruning 机制。面试官考的是你对向量数据库工程实现的理解深度。
Q:RAG 过程中如何处理文件里的图片?
来源:字节暑期agent实习二面【PDD Agent三面追问:RAG如果存在图片类非文本内容,如何处理?】;本轮追问:采集结果中的图片和多媒体如何处理?(携程 AI 应用开发二面(已oc));本轮追问:跟我详细介绍一下图片和文字你们是怎么样进行存储的,然后怎么样写到一块的?(杭州微链词元 AI应用开发);小厂智能体凉经
新手答:“把图片转成文字再检索。”
高手答:
RAG 中图片处理是多模态 RAG 的核心问题,主流方案:
- 图片→文本描述(OCR + Caption):用 OCR 提取图中文字,用多模态模型(如 GPT-4V/Qwen-VL)生成图片描述,将描述文本一起做 Embedding 索引
- 多模态 Embedding 直接索引:用 CLIP 等模型直接将图片编码为向量,和文本向量放同一向量空间,支持跨模态检索
- 图文联合分块:在 chunk 切分时保持图片与其上下文段落的关联——图片属于哪个段落,chunk 就包含“段落文本 + 图片描述/图片引用”
- Layout-Aware 解析:用 PDF 解析工具(如 Unstructured、Marker)识别图片在文档中的位置和语义角色(图表?示意图?截图?),不同类型用不同处理策略
- 延迟处理:检索阶段只用文本索引,召回相关 chunk 后发现有关联图片时,再把图片和文本一起送多模态模型做最终回答
采集阶段应保留原始媒体、来源、时间戳和权限,并按类型分流:图片做 OCR、版面解析或视觉描述;音频做 ASR 和说话人/时间段标注;视频按时间或场景抽帧并结合音频转写。索引文本、时间戳和媒体引用,回答时按权限回取原文件或片段,避免只保留摘要导致证据丢失。
工程上可将原文件和图片存入对象存储,元数据表记录文档、页码、图片坐标、权限和对象地址;向量库的每个文本或图片向量携带同一 document_id、page_id、chunk_id,并在 chunk 内容中保存正文、OCR/描述和 image_ref。召回后按 image_ref 回取原图,与对应文字按 chunk_id 或页码拼接送入模型。
追问补充:PDF 中的数学公式不能只做普通 OCR:先用版面分析定位公式区域,采用公式识别模型转为 LaTeX 或 MathML,并保留原页码、坐标和渲染图片。检索时可同时建立公式文本和图像索引,回答前回取原公式渲染结果校验上下标、分数及符号,避免解析错误传播。
差距在哪:面试官关注你对“多模态信息如何融入检索链路”的工程思考——不是有 OCR 就够了,要考虑检索效果和成本的平衡。
Q:随着大模型上下文窗口持续扩容(100K→1M+),传统 RAG 技术是否会被完全替代?
来源:阿里淘天 AI Agent应用开发二面;本轮追问:为什么普通接口查询不能完全替代 Agent?(本轮追问);小红书多模态秋招二面
新手答:“窗口够大了就不需要 RAG 了,直接把所有文档塞进去就行。”
高手答:
短期内不会被完全替代,长期会深度融合而非简单替代。核心论点:
RAG 不会消失的四个理由:
- 成本问题:1M token 的推理成本远高于“检索 5 个 chunk + 8K 上下文”。对高 QPS 场景(如客服),全量塞入的经济性不可接受
- 注意力稀释:即使窗口能装下,模型对中间位置信息的关注度仍然不均匀(Lost in the Middle 问题未根本解决),检索后精选 Top-K 反而提高相关信息的权重
- 实时性与权限:知识库持续更新,不可能每次请求都重新拼装全量文档;且不同用户有不同的数据权限,RAG 的过滤层天然支持权限隔离
- 可审计性:RAG 能明确告诉你“这个回答基于哪个文档的哪个片段”,全量塞入后模型引用溯源变得极困难
窗口扩容确实改变了什么:
- RAG 的角色从“必须”变成“优化”:以前窗口不够必须检索,现在是为了提高质量和降本而检索
- chunk 策略变粗:以前切 512 token 的小块,现在可以检索整段甚至整篇文档
- 检索-生成边界模糊化:可以先粗检索一批大文档塞进长窗口,再让模型自己做“精排 + 生成”
- 简单场景不再需要 RAG:FAQ、单文档问答等简单场景,直接全文塞入更省事
未来的融合形态:
graph TD
A[用户 Query] --> B{复杂度判断}
B -->|简单/单文档| C[直接全文塞入长窗口]
B -->|复杂/多文档/高QPS| D[RAG 检索 + 精选注入]
B -->|实时数据/权限隔离| E[必须经 RAG 过滤层]
C --> F[生成回答]
D --> F
E --> F
差距在哪:这是开放观点题,面试官考的是技术判断力。新手非此即彼(要么 RAG 必须,要么窗口万能),高手能分场景讨论成本、注意力、实时性、可审计性四个维度,给出“不是替代而是融合”的结论,并能描述融合后的具体形态。
Q:如何避免模型回复过度依赖检索到的外部知识,导致回答生硬、缺乏共情能力和自然度?
来源:阿里淘天 AI Agent应用开发二面
新手答:“在 Prompt 里加一句‘请用自然语言回答,不要直接复制文档内容’就行了。”
高手答:
这个问题的本质是检索内容“绑架”了模型的生成自由度。模型把 RAG 返回的文档当成唯一信息源,逐句改写而非理解后重新组织,导致回答像“念文档”而非“对话”。
解法分三层:
1. 检索层——控制注入量和粒度
- 不是检索到的东西全塞进 Prompt,而是只注入与当前轮次直接相关的片段
- 设置相关性阈值:低于阈值的 chunk 不注入,让模型用自身知识补全
- 对长段落做摘要后注入,而不是原文照搬——摘要后模型有更大的表达空间
2. Prompt 层——分离“知识”和“表达风格”
- 系统 Prompt 中明确区分角色:你是一个友好的助手,参考资料只是辅助,回答要自然
- 使用“参考但不照抄”的约束:
以下资料供参考,请结合你的理解用口语化方式回答,不必逐条复述 - 给模型留“自由发挥区”:允许在事实准确的前提下加入过渡语、共情表达、追问
3. 生成层——后处理与反馈闭环
- 自然度评分:对生成结果用小模型打分(流畅性、重复率、文档复制比例),低分回退重生成
- A/B 测试:对比“全量注入 vs 摘要注入 vs 无 RAG 回退”三种策略的用户满意度
- 温度调节:对事实性回答用低温度保准确,对情感/共情类回答适当提高温度增加自然度
实际工程中常见的 Pattern:
- 双通道生成:先让模型不看 RAG 结果生成一版“自然回答”,再与 RAG 检索结果做事实校验合并
- 引用标记 + 自由组织:要求模型标注哪些内容来自文档、哪些是自己推理的,便于后续审计
差距在哪:面试官考的是你对“RAG 不只是拼 Prompt”的理解。检索是为了保证事实准确,但不能牺牲对话体验。高手会从注入策略、Prompt 设计、后处理三层分别控制“依赖度”,而不是只靠一句 Prompt 指令。
ES 切换向量检索的能力变化
Q:如果从 ElasticSearch 切换到向量检索,哪些能力会下降,哪些能力会提升?
来源:字节跳动 Agent开发实习生一面
新手答:“向量检索语义能力更强,ES 适合关键词。”
高手答:
这不是简单的“好 vs 坏”,而是两种检索范式的能力互补。切换时要清楚你会失去什么、得到什么、以及怎么补回来。
切换后提升的能力:
| 能力 | 原因 |
|---|---|
| 语义理解 | “如何降低延迟”能匹配“性能优化方案”,ES 做不到 |
| 同义/改写鲁棒性 | 用户换种说法不影响召回质量 |
| 跨语言检索 | 多语言 Embedding 天然支持中英混搜 |
| 模糊意图处理 | 用户表达不精确时,语义相似度比关键词匹配更有效 |
切换后下降的能力:
| 能力 | 原因 |
|---|---|
| 精确匹配 | 搜“错误码 E4012”,向量检索可能返回语义相关但不是这个编码的文档 |
| 结构化过滤 | ES 天然支持 range/term/bool 组合过滤,向量库需要额外的 metadata filter |
| 实时索引 | ES 近实时(1s),很多向量库批量索引有延迟 |
| 高亮/聚合 | ES 内建 highlight、aggregation,向量库通常没有 |
| 可解释性 | BM25 分数有明确含义(TF-IDF),向量相似度的 0.82 vs 0.79 难以解释 |
最佳实践——混合检索:
不要“切换”,而是“叠加”。用 ES 做精确匹配 + 结构化过滤,用向量库做语义召回,然后 RRF 或 Rerank 融合。把 ES 降级为精确匹配通道,而不是完全替换。
差距在哪:面试官考的是你对检索系统的完整理解。只说“向量比 ES 好”说明你没在生产环境用过 ES。能说出精确匹配下降、结构化过滤缺失、实时性差异,并给出混合方案,说明你做过检索系统的技术选型。
语义切分与文档聚类
Q:笔试题:多路召回结果合并去重 + 加权排序 + TopK
来源:数据智能查询平台面试(笔试)【作业帮秋招一面追问:两路检索得到的召回结果如何做结果融合?】;本轮追问:精排模型最终 rank 分怎么得到?是加权和还是 learned score?(本轮追问);本轮追问:除了图召回之外,你们的系统中是否还有其他召回路径?(本轮追问);本轮来源;字节Agent开发后端 日常实习一面凉面;虾皮agent开发一面;虾皮秋招 研发工程师
题目:给定多路召回结果,每条包含 docId、score 和来源(source)。要求合并去重,按加权分数排序,返回 TopK,保证同一文档只出现一次。
高手答:
from collections import defaultdict
from typing import List, Dict
def merge_recall_results(
recall_results: List[Dict], # [{"docId": "d1", "score": 0.8, "source": "vector"}, ...]
source_weights: Dict[str, float], # {"vector": 0.6, "bm25": 0.3, "graph": 0.1}
top_k: int = 10
) -> List[Dict]:
"""多路召回合并去重 + 加权排序"""
# 1. 按 docId 聚合,累加加权分数
doc_scores = defaultdict(float)
doc_sources = defaultdict(list)
for item in recall_results:
doc_id = item["docId"]
source = item["source"]
weight = source_weights.get(source, 0.0)
doc_scores[doc_id] += item["score"] * weight
doc_sources[doc_id].append(source)
# 2. 按加权总分降序排序
sorted_docs = sorted(
doc_scores.items(),
key=lambda x: x[1],
reverse=True
)
# 3. 取 TopK
results = []
for doc_id, final_score in sorted_docs[:top_k]:
results.append({
"docId": doc_id,
"score": round(final_score, 4),
"sources": doc_sources[doc_id]
})
return results
关键设计决策:
- 去重策略:同一 docId 被多路召回时,分数是累加而非取最大值——被多路命中本身就是强相关信号
- 权重设计:向量召回侧重语义相关,BM25 侧重关键词精准匹配,权重根据业务场景调——FAQ 场景 BM25 权重高,开放问答场景向量权重高
- 归一化:如果不同来源的 score 量纲不同(如向量余弦 0-1,BM25 可能 0-30+),需要先做 Min-Max 或 Z-Score 归一化再加权
- 时间复杂度:O(N log N),N 为总召回条数。如果 N 很大且只需 TopK,可用堆优化到 O(N log K)
面试沟通要点:先写出清晰正确的基础版本,再主动提出“归一化”和“堆优化”的扩展——展示工程思维的层次感。
追问补充:五路召回用于覆盖不同相关性信号和数据盲区:向量捕获语义,全文保证关键词精确匹配,图或规则补充结构与业务约束,其余路径可覆盖热度、历史或个性化。分数相同时使用固定次级键(如docId)排序,避免依赖不稳定的遍历顺序,保证结果可复现。
差距在哪:这道笔试题不难,面试官看的是代码风格(清晰度、命名)和对“为什么这样设计”的思考。只写出 sort 是及格,能说出累加 vs 取最大值的权衡、归一化的必要性、以及大规模场景的堆优化,才是加分项。
Q:父文档是怎么得到的?语义切分具体是怎么做的?聚类后怎么区分不同文档?
来源:同程Agent开发实习一面【百度Agent一面追问:为了保证连续语义,文本具体怎么切分?有什么算法?】;本轮追问:你的文档从哪儿来?(本轮追问);本轮追问:分块后与前面的内容进行聚合,具体是怎么实现的?相邻块之间是否会存在重合?(字节 Agent 秋招二面);本轮追问:按照标题切割时,有的文本块很大、有的很小,该怎么办?(九方智投 一面凉经);乐堡AI应用开发岗四面面经,面试官非常nice!
新手答:“按 512 token 切就行了,父文档就是原始文档。”
高手答:
父子文档索引的核心思路是:子文档用于精准召回,父文档用于提供完整上下文。语义切分是让子文档在语义上自洽的关键。
语义切分流程:
flowchart TD
A[原始文档] --> B[句子级分割]
B --> C[逐句 Embedding]
C --> D[相邻句子相似度计算]
D --> E{相似度低于阈值?}
E -->|是| F[标记为语义断点]
E -->|否| G[继续]
F --> H[按断点聚合为语义段落]
H --> I[检查 token 上限]
I -->|超限| J[段落内再按相似度二分]
I -->|合格| K[生成子文档 chunk]
K --> L["聚合同一来源的子文档 → 父文档"]
具体步骤:
- 句子级分割:用标点/换行将文档拆成句子序列
- 逐句 Embedding:每句生成向量
- 滑动窗口余弦相似度:计算相邻句子之间的语义相似度,相似度骤降的位置即为语义断点
- 按断点聚合:断点之间的句子合并为一个语义段落(即子 chunk)
- token 限制兜底:如果某个语义段超过 max_tokens(如 512),在段内再找次级断点拆分
父文档的生成方式:
- 最简单:父文档 = 原始文档(或原始文档的某一节)
- 进阶:多个相邻子 chunk 共享同一父文档,父文档 = 子 chunks 的上下文窗口扩展(向前向后各扩展 N 句)
聚类后如何区分不同来源:
- 每个 chunk 携带 metadata:
{doc_id, section_id, chunk_index, parent_id} - 检索命中子 chunk 后,通过
parent_id回溯父文档,返回更完整的上下文 - 不同文档通过
doc_id天然隔离,聚类只在单文档内部进行
聚合时为相邻子块维护顺序和 parent_id,可按固定句数或 token 窗口保留少量重叠,避免边界丢失上下文。标题切分后,过大的块递归按子标题、段落或语义断点拆分;过小的块与相邻块合并,同时保留标题路径和最小长度约束。
差距在哪:面试官深挖切分细节是为了验证“你的 RAG 到底做了多深”。只说“按 token 切”说明你用了默认方案没调优。能说出语义断点检测 + 相似度骤降 + 父子回溯,说明你真的做过切分实验并理解效果差异。
Q:手动干预切片是怎么做的?为什么需要这一步?
来源:视频面经汇总;本轮追问:动态重叠窗口切片相比固定长度切片解决了什么问题?(本轮追问);字节跳动Agent开发1面凉经
新手答:“人工检查切片结果,把切错的手动改一下。”
高手答:
为什么需要手动干预:自动切片算法(按 token 数 / 按段落 / 按语义)在 80% 的文档上表现不错,但以下场景必须人工介入:
- 表格跨页:PDF 中的表格被切成上下两半,上半截没有表头,下半截缺少上下文
- 图文混排:图片说明被切到和图片不同的 chunk,检索到说明但没有图
- 术语定义:专业术语在第一次出现时有定义,但后续 chunk 中使用时失去了定义上下文
- 层级结构:技术文档的标题-子标题层级被打断,子内容脱离了父标题
实现方式——三种粒度:
| 方式 | 适用场景 | 实现 |
|---|---|---|
| 标注切分规则 | 某类文档有固定结构 | 配置“遇到一级标题必须切分”等规则 |
| 手动标记断点 | 特殊文档(合同、法规) | 上传时人工在 UI 上标注分割点 |
| 切片后审核 | 线上 bad case 驱动 | 检索效果差的 query → 追溯到源 chunk → 人工修正 |
工程落地的关键设计:
- 切片结果存数据库时保留
source_type字段标记(auto / manual_split / manual_merge) - 人工修正后重新生成 embedding 并更新向量索引(增量更新,不重建全量)
- 建立“bad case → chunk 溯源 → 修正 → 效果验证”的闭环流程
差距在哪:面试官深挖切分细节是为了验证“你的 RAG 到底做了多深”。新手觉得切片是一次性的预处理工作。高手知道切片质量直接决定检索效果——自动切片解决大部分情况,但 bad case 驱动的人工干预是持续优化的关键环节。这体现了 RAG 系统的运营思维,而不是纯开发思维。
Q:Text2SQL 的 RAG 架构里,DDL 层和规则层分别解决什么问题?业务表频繁变更时怎么保持可用?
来源:数据智能查询平台面试;OPPO IT 开发一面;本轮追问:项目中引入了哪些外部知识召回手段(如 RAG、CodeGraph)?各自解决什么问题?(本轮追问)
新手答:“DDL 层存表结构,规则层存一些 SQL 模板。”
高手答:
Text2SQL 的 RAG 架构不是简单的“查文档生成答案”,而是一个分层知识注入系统——每层解决不同类型的错误:
flowchart TD
A[用户自然语言问题] --> B[意图识别 + 查询改写]
B --> C[DDL 层检索]
B --> D[规则层检索]
B --> E[示例层检索]
C --> F[Schema 上下文]
D --> G[业务规则约束]
E --> H[Few-shot 示例]
F --> I[LLM 生成 SQL]
G --> I
H --> I
I --> J[SQL 校验 + 执行]
DDL 层解决的问题——Schema 对齐:
- 存储表结构、字段含义、枚举值映射、表关联关系
- 解决“表不存在”“字段名错误”“join 关系写反”等结构性错误
- 关键设计:不是存原始 DDL 文本,而是存语义化描述(如
status: 订单状态,1=待付款 2=已付款 3=已取消)
规则层解决的问题——业务逻辑对齐:
- 沉淀内容:计算口径(“GMV = 实付金额,不含退款”)、过滤条件(“有效订单需排除测试账号”)、时间约定(“自然周从周一开始”)、特殊逻辑(“跨境订单金额需转为人民币”)
- 解决“SQL 能跑但结果不对”的语义性错误
业务“黑话”和同义词先进入受治理的术语表,例如把“成交额”“流水”“GMV”映射到明确的指标版本,而不是只靠 Query 改写。再往上一层可以建立本体/语义层:统一定义指标、实体、维度、实体关系与 Join,并把用户可见范围绑定到行列级权限。模型负责把自然语言解析成受约束的语义查询或候选计划;确定性编译器负责校验指标与关系、注入权限策略并生成目标数据源 SQL,最终 SQL 还要经过只读、成本和语法门禁。
Cube 语义层文档展示了一种实现边界:指标、实体、Join 和访问规则集中在共享数据模型中,查询经语义层校验并确定性应用访问策略后才到数据仓库。这不是说 Text-to-SQL 必须依赖 Cube,而是说明“模型理解问题”和“受治理地编译/执行 SQL”应分层。直接 Text-to-SQL 更灵活,适合 Schema 较小、探索性强的场景;语义层/本体方案前期建模成本更高,但更适合跨数据源、稳定业务口径和统一权限。两者可以组合:模型先选语义对象,语义层编译 SQL;无法覆盖的长尾查询再进入受限的直接生成路径。
业务表频繁变更时的保鲜机制:
| 策略 | 实现 | 适用场景 |
|---|---|---|
| Schema 变更监听 | 监听数据库 DDL 变更事件(如 MySQL 的 schema_change 事件),自动触发知识库更新 | 字段增删改 |
| 定时全量同步 | CronJob 每天对比 information_schema 与知识库的 diff,补充新增表/字段 | 兜底保障 |
| 业务方标注 | 提供 Web UI,业务方修改字段含义/计算口径后自动更新 Embedding | 语义变更 |
| 版本化管理 | DDL 知识按版本存储,查询时带上时间戳匹配对应版本 | 历史数据查询 |
规则层感知业务变化的方式:
- 被动:用户反馈“SQL 结果不对” → 追溯到规则缺失/过期 → 补充规则
- 主动:监控上游数据表血缘变更(如字段口径调整的 MR/PR),自动创建规则审核任务
- 定期:每季度组织业务方 review 规则库,清理过期规则
差距在哪:新手把 Text2SQL 简化成“查表结构+生成SQL”。高手看到的是一个三层知识注入系统——DDL 解决结构错误、规则解决语义错误、示例解决风格对齐。面试官深挖“变更怎么感知”是在考你有没有运营过这套系统,而不只是搭建过。
Q:RAG 项目里,MySQL 和 Elasticsearch 的数据一致性怎么保证?
来源:视频面经汇总;10.8号顺丰AI全栈一面
新手答:“写入 MySQL 后同步写 ES。”
高手答:
MySQL 和 ES 的数据一致性是经典的“双写一致性”问题,在 RAG 系统中尤为重要——MySQL 存文档元数据和权限,ES 存全文索引用于召回,两边不一致会导致“能搜到但无权限”或“有权限但搜不到”。
常见方案对比:
| 方案 | 一致性 | 延迟 | 复杂度 |
|---|---|---|---|
| 同步双写 | 强(但有失败风险) | 高 | 低 |
| 异步消息队列 | 最终一致 | 秒级 | 中 |
| CDC(binlog 监听) | 最终一致 | 秒级 | 高 |
| 定时全量同步 | 弱一致 | 分钟级 | 低 |
我们的实践(CDC + 补偿):
flowchart LR
A[应用写入 MySQL] --> B[binlog]
B --> C[Canal/Debezium 监听]
C --> D[消息队列 Kafka]
D --> E[ES 同步消费者]
E --> F[写入 ES 索引]
D --> G[向量库同步消费者]
G --> H[更新向量索引]
- 主路径:应用只写 MySQL,通过 Canal 监听 binlog 变更,推到 Kafka,下游消费者分别更新 ES 和向量库
- 补偿机制:定时 Job 对比 MySQL 和 ES 的文档 ID 集合,diff 出不一致的记录重新同步
- 幂等保证:ES 写入用文档 ID 作为
_id,重复消费不会产生重复数据 - 顺序保证:同一文档的变更按 partition key(doc_id)路由到同一 Kafka partition,保证顺序消费
追问补充:翻译质量由翻译 Agent 负责初检,规则校验、术语一致性和抽样人工复核共同兜底;不应把未验收译文直接写入 ES。应先将原文、译文、质量状态和版本写入 MySQL,验收通过后由 CDC 按版本同步到 ES,失败则进入修订或隔离队列。
差距在哪:新手的“同步双写”在生产中很脆弱——ES 写入失败怎么办?回滚 MySQL 吗?高手用 CDC 方案将写入解耦,配合补偿机制处理极端情况,这才是生产级的一致性方案。
Q:RAG 文档切分中遇到代码块、表格、标题等特殊内容怎么处理?
来源:最有料 AI 实习生面经【虾皮Agent一面追问:PDF 电子表格如果很长、超出 chunk 长度,切分时会从表格中间截断吗?截断后如何避免表格行数据残缺带来的问题?】【阿里边缘bu 秋招一面 (已过)追问:同一文档中的两个表格存在逻辑关联时,应该如何切分和维护这种关联?】;本轮追问:如果Markdown没有标题,你怎么切分?(美团AI全栈一面,AICoding把我整不会了);本轮追问:如果一段内容有 1,000 个 token,chunk size 为 400,最后剩余的 200 如何处理?是否会向前补充内容,凑成 400? / Markdown 中的图片、ul 等内容是如何处理的?(字节 Agent 秋招二面);本轮追问:切块除了按段落、标题,还有做其他优化吗?(小红书 Product Engineer(AI与全栈方向)-社区工程 一面面经);本轮追问:如果搭建财务知识库,里面有制度文档、Excel报表表格,不同文件怎么做Chunking切分?如何规避新旧版本制度冲突导致回答错误?(药明康德(AI数据方向-二面));小厂智能体凉经
新手答:“按固定长度切就行,遇到什么都一样处理。”
高手答:
通用的固定长度切分对纯文本效果还行,但遇到代码块、表格、标题这类结构化内容,会导致语义断裂和检索质量骤降。每种特殊内容需要专门的处理策略。
核心原则:结构化内容是不可切断的原子单元
flowchart TD
A["原始文档"] --> B["结构识别\n标记特殊内容边界"]
B --> C["分类处理"]
C --> D1["代码块 → 独立 chunk\n保持完整性"]
C --> D2["表格 → 独立 chunk\n保留表头"]
C --> D3["标题 → 作为 metadata\n注入子 chunk"]
C --> D4["纯文本 → 语义切分\n正常处理"]
D1 --> E["统一入库\n附带结构类型标签"]
D2 --> E
D3 --> E
D4 --> E
各类特殊内容的处理策略:
| 内容类型 | 问题 | 处理方案 | 关键细节 |
|---|---|---|---|
| 代码块 | 切断后语义完全丧失 | 整块作为独立 chunk | 附带前后文描述(“以下代码实现了XX功能”) |
| 表格 | 切断后失去表头,数据无意义 | 整表独立 chunk;超长表格按行切分但每段保留表头 | 额外生成表格的文字摘要用于语义检索 |
| 标题层级 | 切分后子内容脱离标题上下文 | 标题作为 metadata 注入所有子 chunk | 层级路径:“第三章 > 3.2 节 > 数据库设计” |
| 列表/枚举 | 列表项被拆到不同 chunk | 整个列表作为一个 chunk;超长列表按逻辑分组切 | 保留列表前的引导句 |
| 图片引用 | 图片说明和图片分离 | 图片说明 + 图片描述合成一个 chunk | 用多模态模型生成图片文字描述 |
代码块的详细处理:
处理流程:
1. 用正则/AST 识别代码块边界(```...``` 或缩进块)
2. 判断代码块长度:
- < 500 tokens → 整块作为独立 chunk
- 500-2000 tokens → 整块 + 压缩前后文描述
- > 2000 tokens → 按函数/类边界切分(需要语言感知)
3. 每个代码 chunk 附加 metadata:
- 语言类型(Python/JavaScript/...)
- 前文描述(代码块前的解释文字)
- 所属标题路径
4. 额外为代码生成自然语言摘要("这段代码实现了用户认证的 JWT 验证逻辑")
→ 用摘要做语义检索,命中后返回原始代码
表格的详细处理:
处理流程:
1. 识别表格边界(Markdown 表格语法 / HTML <table>)
2. 判断表格大小:
- 行数 < 20 → 整表独立 chunk
- 行数 > 20 → 按逻辑分组切分,每段保留表头
3. 为表格生成文字摘要:
"该表格对比了 5 种向量数据库的性能指标,包括 QPS、延迟、内存占用"
4. 索引时同时存储:原始表格文本 + 文字摘要
→ 摘要用于语义检索,原始表格用于返回给用户
标题层级的处理——上下文路径注入:
标题不应该单独成为 chunk(信息量太少),而应该作为 metadata 注入所有子内容:
原始文档结构:
# 第一章 系统架构
## 1.1 数据库设计
### 1.1.1 表结构
正文内容...
切分后的 chunk metadata:
{
"content": "正文内容...",
"title_path": "第一章 系统架构 > 1.1 数据库设计 > 1.1.1 表结构",
"level": 3,
"doc_id": "architecture.md"
}
检索时:title_path 参与 Embedding 计算和 BM25 索引
→ 用户搜"数据库表结构"时,即使正文中没有这几个字,
标题路径也能帮助召回
工程实现建议:
- 先识别后切分:不要先切分再处理特殊内容。正确顺序是先标记所有特殊内容的边界,再对剩余的纯文本做常规语义切分
- 类型标签:每个 chunk 存储
content_type字段(text/code/table/list),检索时可以按类型过滤 - 双索引:对代码和表格,同时索引原始内容和文字摘要——用摘要的语义 Embedding 做召回,用原始内容做返回
- 评测覆盖:评测集中必须包含针对代码/表格/标题层级的 query,验证特殊内容的召回率
没有标题时先按空行、列表、代码块和段落边界识别候选区块,再用语义相似度或主题变化合并;无法可靠推断层级时不伪造标题,而是生成稳定的段落序号、主题摘要和文档范围 metadata,并采用带重叠的语义切分。通过跨段检索问答集验证边界是否丢失上下文。
对于 1,000 token 内容按 400 切分,末尾 200 不应为凑满而盲目向前复制;可作为短尾块保留,或在不破坏语义且未超上下文预算时与相邻块合并。财务知识库应分别解析制度正文和 Excel 表格,保留表头、行列关系、期间及来源版本;检索前按生效状态、日期和版本过滤,冲突时优先最新有效版本,并在答案中返回版本证据。
差距在哪:新手用统一策略处理所有内容——结果是代码被切断无法理解、表格丢失表头、子内容脱离标题上下文。高手对每种结构化内容设计专门的保护策略,核心原则是“结构化内容是不可切断的原子单元”。面试官考的是你对 RAG 文档预处理的工程化深度——切分质量是 RAG 效果的上限。
Q:处理一万个长文档构建 RAG 知识库,工程上怎么做?
来源:阿里 Agent 面经(场景题);本轮追问:搭建这个财务知识库需要哪些硬件、技术条件?(药明康德(AI数据方向-二面));本轮追问:跟我详细讲解一下你在实习的时候,整个文档入库的全流程,对于不同文档是如何进行处理的?(杭州微链词元 AI应用开发);度小满 - AI 全栈研发 - 三面
新手答:“循环处理每个文档,切分后存到向量数据库。”
高手答:
一万个长文档(假设每个 5000-50000 字)的规模,单机串行处理可能需要数天。工程上需要从并行处理、管线设计、质量保障和增量更新四个维度系统设计。
整体处理管线:
flowchart LR
subgraph ingest["数据摄入层"]
A["文档源\n(S3/本地/API)"] --> B["格式解析\n(PDF/Word/HTML→文本)"]
end
subgraph process["并行处理层"]
B --> C["分片调度器\n(按文档分配 Worker)"]
C --> D1["Worker 1\n清洗→切分→Embed"]
C --> D2["Worker 2\n清洗→切分→Embed"]
C --> D3["Worker N\n清洗→切分→Embed"]
end
subgraph store["存储层"]
D1 --> E["向量数据库\n(批量写入)"]
D2 --> E
D3 --> E
D1 --> F["元数据库\n(文档状态)"]
D2 --> F
D3 --> F
end
subgraph qa["质量保障"]
E --> G["抽样检查\n切分质量/Embedding质量"]
F --> H["进度监控\n失败重试/告警"]
end
第一步:格式解析——最容易卡住的环节
一万个文档格式不会统一(PDF、Word、HTML、Markdown 混合),解析是最耗时且最容易出错的环节:
| 格式 | 解析工具 | 难点 |
|---|---|---|
| MinerU / Unstructured / 商业 API | 表格、双栏、扫描件 OCR | |
| Word | python-docx / Unstructured | 嵌入图片、复杂格式 |
| HTML | BeautifulSoup + 正则清洗 | 去除导航/广告/脚本 |
| Markdown | 原生解析 | 最友好,几乎无损 |
关键决策:对 PDF 等复杂格式,先用自动解析 + 后期抽样检查的方式,不要追求 100% 解析正确——80% 质量上线后再迭代优化 bad case。
第二步:并行处理——从小时级降到分钟级
规模估算:
10000 文档 × 平均 10000 字 = 1 亿字
切分后约 50 万 chunk
Embedding 计算:50 万 × 768 维 ≈ 1.5GB 向量数据
单机串行耗时:
解析:~2s/文档 × 10000 = 5.5 小时
切分:~0.5s/文档 = 1.4 小时
Embedding:~0.1s/chunk × 50 万 = 14 小时
总计:~21 小时
10 Worker 并行:
总计降到 ~2 小时
并行策略:
- 文档级并行:每个 Worker 处理一批文档(如每批 100 个),互不依赖
- Embedding 批处理:不逐条调 API,而是攒够 32/64 条后批量调用,减少 API 开销
- 异步管线:解析、切分、Embedding 三个阶段用生产者-消费者模式串联,不等全部解析完才开始切分
第三步:容错与状态管理
处理一万个文档必然有失败——某个 PDF 解析崩溃、Embedding API 超时、网络抖动。需要:
| 容错机制 | 实现 |
|---|---|
| Checkpoint | 每个文档处理完记录状态(pending/processing/done/failed) |
| 重试策略 | 失败的文档指数退避重试 3 次,仍然失败标记为 manual_review |
| 幂等设计 | 重复处理同一文档不产生重复 chunk(用 doc_id + chunk_index 做去重) |
| 进度可视化 | 实时显示总进度、成功/失败/进行中的数量 |
| 断点续跑 | 中断后从 checkpoint 恢复,不重头开始 |
第四步:入库策略——批量写入 vs 逐条写入
❌ 逐条写入向量数据库:
50 万次网络请求,延迟巨大,可能触发限流
✅ 批量写入:
每攒够 1000 条 chunk,批量 upsert 到向量数据库
Milvus/Qdrant 都支持批量 insert,吞吐高 10-50 倍
第五步:质量保障——不能只看“处理完了”
- 切分质量抽检:随机抽 100 个 chunk,人工检查是否语义完整、有无切断代码/表格
- Embedding 质量验证:构造 20 组已知相关的 (query, doc) pair,验证 Recall@10 是否达标
- 去重检查:对所有 chunk 做近似去重(SimHash),重复率超过 5% 说明切分策略有问题
- 覆盖度分析:统计各文档的 chunk 数量分布,异常值(某文档只有 1 个 chunk 或 1000 个 chunk)需要排查
第六步:增量更新——不是一次性工程
知识库建好后,文档会持续更新。增量更新策略:
文档新增 → 走完整处理管线 → 新 chunk 入库
文档修改 → 删除旧 chunk → 重新处理修改后的文档 → 新 chunk 入库
文档删除 → 按 doc_id 删除所有关联 chunk
触发方式:
- 文件系统监听(inotify / fswatch)
- 定时扫描 diff(每天一次)
- 手动触发(管理后台)
硬件与技术条件取决于瓶颈:解析和切分以 CPU、内存及本地临时盘为主;扫描 PDF 的 OCR 或本地 Embedding 可按吞吐配置 GPU,否则使用受控的外部 API。还需对象存储、任务队列、元数据数据库、向量库、网络带宽与 API 配额,并为大文件、超时和限流设置缓存、批处理和断点续跑。
差距在哪:新手的“循环处理”忽略了规模化场景下的并行处理、容错设计、质量保障和增量更新。高手设计了完整的工程管线——并行 Worker + 批量写入 + Checkpoint 容错 + 质量抽检 + 增量更新——这才是生产级知识库构建方案。面试官考的是你能不能把一个“看起来简单”的任务(处理文档)做成一个可靠的、可运维的工程系统。
Q:RAG 知识库更新怎么不停服?热更新方案怎么设计?
来源:腾讯AI应用开发(Agent后端)【抖音电商Agent全栈开发工程师一面追问:更新是每天全量跑一遍吗?】;本轮追问:怎么维护、迭代知识库,怎么感知新增文档,怎么设计迭代链路? / 文档新增之后是自动生效还是需要别的流程,怎么做人工审核?(淘天AI应用开发二面);本轮追问:产品迭代更新后知识库容易老旧,知识库如何保鲜、保证准确度?(美团AI Agent一面);本轮追问:知识库怎么更新?需要人工 review 吗?(淘天供应链ai应用研发一面);度小满 - AI 全栈研发 - 三面
新手答:“重新跑一遍 Embedding 流水线,更新完重启服务。”
高手答:
生产级 RAG 知识库的更新必须做到对用户无感知——不能停服、不能出现检索空窗期。
1. 双索引切换(Blue-Green):
- 维护两份向量索引:active(当前服务)和 standby(正在更新)
- 增量或全量更新只操作 standby 索引
- 更新+验证通过后,原子切换路由指向 → 零停服
- 切换后保留旧索引一段时间用于快速回滚
2. 增量更新(适合高频变更):
- 新文档实时切块 → Embedding → 写入向量库(append)
- 删除/修改的文档通过 doc_id 标记 soft delete → 检索时过滤
- 定期做 compaction 清理已标记删除的向量
3. 版本化管理:
- 每次更新带版本号,检索请求携带版本参数
- 支持灰度:10% 流量走新索引,90% 走旧索引
- A/B 对比新旧索引的检索质量指标(召回率、相关性分数)
4. 一致性保证:
- 文档元数据(MySQL/ES)和向量索引的同步用事件驱动(CDC + 消息队列)
- 写入向量库成功但元数据未同步 → 检索到但渲染不出来 → 需要双写确认机制
- 设置“数据新鲜度”指标:从文档更新到可被检索到的延迟 < 5min
更新链路可采用“采集/CDC→解析去重→切块向量化→离线评测→人工审核→灰度发布→监控回滚”。新增文档先进入待发布版本,不应自动影响线上;审核校验来源、时效、敏感信息和问答样例,产品变更触发旧文档标记过期并定期复评、清理。
差距在哪:新手的“重新跑一遍+重启”在生产环境是不可接受的——停服意味着用户体验中断。高手用双索引切换做零停服、增量更新做低延迟、版本化做灰度验证,三层组合保证知识库永远在线且可回滚。
Q:RRF(Reciprocal Rank Fusion)是什么?如何融合多路检索结果?
来源:滴滴一些面经合集(算法);字节Agent开发后端 日常实习一面凉面;本轮追问:RAG中向量、BM25、图谱多跳做IF融合,IF怎么计算?为什么不用分数直接加和做融合?79%-95%的评测指标是如何构建的?(药明康德(AI数据方向-二面));本轮追问:你们使用到的RRF融合,这个里面的k是你参与自己测试调试出来的吗,还是已经有的?你自己有尝试去调一下吗?(杭州微链词元 AI应用开发);虾皮秋招 研发工程师;高斯信息技术,ai开发工程师,一面;百度agent harness一面
新手答:“RRF 会根据各路检索结果的排名计算倒数得分,再把同一文档在多路结果中的分数相加并重新排序。”
高手答:
RRF(Reciprocal Rank Fusion)只依赖排名,不要求不同检索器的分数可比。对每一路结果中的文档按名次计算贡献,常见形式为 1/(常数+名次),再把同一文档在多路中的贡献求和,得分越高越靠前,因此适合融合 BM25、向量检索或不同查询改写的结果。工程实现要先统一文档 ID、去重并保留来源和原始名次;缺席某一路通常贡献为零。常数、各路权重和截断深度应通过离线标注集评估,并检查 Recall、MRR、NDCG 及延迟,而不是直接照搬默认值。还要处理重复切片、权限过滤和失效文档,否则融合可能把同一内容重复放大,甚至造成越权展示。
若 IF 指加权插值融合,应先分别归一化各路分数,再按权重求和;原始分数直接相加会因量纲、分布和分值范围不同而失真。评测集应由真实问题、相关文档标注和难负例组成,按 Recall、MRR、NDCG 对权重及 k 做网格或分桶对比,79%—95%必须注明指标、数据集和切分方式,不能只报单一数字。
追问补充:加权 RRF 可写为 score(d)=Σ wi/(k+ri(d)),缺席通道贡献为零;五路模块应统一 ID 后去重,记录来源,按标题加分并限制单文档配额,再交给 reranker,超时则回退融合排序。通过消融实验调 k、权重、截断数和精排参数,比较 Recall、MRR、NDCG、重复率、延迟及超时降级成功率。
差距在哪:浅层只需说“按排名倒数加权”;深入回答要明确公式、去重与文档 ID、权重和常数的选择,以及用检索评估和权限过滤验证融合是否有效。
Q:基于关键词的命令行代码搜索与基于 Embedding/RAG 的代码搜索,各有什么优缺点?
来源:某小厂FOSHO/AI应用开发二面;本轮追问:你的搜索引擎和直接使用云博客搜索有什么区别?(本轮追问);本轮追问:code agent 怎么根据 PRD 的描述定位到要修改的代码?(本轮追问);本轮追问:如何基于 AST 识别代码中的硬编码路径?(本轮追问);本轮追问:有什么办法能让 AI 看代码时看得更准?代码库规模较大时,怎么确认 AI 为什么找不准?(淘天供应链ai应用研发一面);虾皮agent开发一面
新手答:“关键词搜索快但不智能,RAG搜索智能但慢。”
高手答:
| 维度 | 关键词搜索(grep/ripgrep) | Embedding/RAG搜索 |
|---|---|---|
| 速度 | 极快(ms级,直接扫文本) | 较慢(需要embedding+向量检索) |
| 精确度 | 完全精确匹配(函数名、变量名) | 可能有语义偏移 |
| 语义理解 | 零(只看字符串) | 强(理解“授权”=“authentication”) |
| 索引成本 | 零/极低 | 需要预计算embedding,增量更新成本高 |
| 跨语言能力 | 无 | 有(理解不同语言的同一概念) |
| 代码更新 | 实时(直接搜文件) | 有延迟(需要重新embedding) |
| 最佳场景 | 找函数定义、变量引用、精确错误信息 | 找“做XX功能的代码在哪”、理解性搜索 |
为什么 Claude Code 选 grep 而非 RAG:
- 代码库变化频繁,embedding 索引维护成本高
- 开发者搜索多数是精确搜索(函数名、类名、错误信息)
- grep 结果确定性强——不会出现“检索到语义相似但不相关的代码”
- 可以用 AST 结构化搜索补充 grep 的语义不足
最佳实践:混合方案——先 grep 精确匹配,无结果时再 fallback 到语义搜索。
flowchart TB
Q["代码搜索需求"] --> D{"查询类型?"}
D -->|"精确符号/函数名/错误码"| G["grep/ripgrep\n(ms级,100%精确)"]
D -->|"概念级/功能描述"| R["Embedding/RAG\n(语义匹配)"]
D -->|"不确定"| F["先 grep → 无结果 → fallback RAG"]
G --> RES["结果"]
R --> RES
F --> RES
让 AI 看得准要结合符号索引、AST、调用关系和分层上下文,检索后按路径、类型与相关性重排,并附来源片段。大库查不准时记录查询、候选集、得分、最终采用片段和索引版本,分别排查术语不匹配、切片丢上下文、召回不足、重排错误及索引过期;用标注问题集评估召回和命中率。
差距在哪:面试官考的是对“搜索”本质的理解——不同场景下最优解不同,不是新技术一定比老技术好。能说出 Claude Code 选择 grep 的四个工程理由,说明你对代码搜索有深入的实践经验。
Q:混合检索到底在哪个环节比单独用效果好?
来源:淘天/AI Agent一面【百度Agent一面追问:有没有通过实验分析向量检索及混合检索带来的提升?】;本轮追问:混合检索是怎么实现的?(字节 Agent 秋招二面)
新手答:“混合检索综合了向量和关键词的优点,效果自然好。”
高手答:
混合检索不是“无条件好”——需要分场景分析:
向量检索强的环节:语义模糊/同义改写(“电脑卡顿” → “性能优化方案”)
BM25强的环节:精确术语/实体名/代码片段(“RuntimeError: CUDA out of memory”)
混合检索真正发挥优势的场景:
- 长尾查询:用户用口语化表达但目标文档是专业术语——向量桥接语义,BM25精确命中关键词
- 多意图查询:“Python的GIL锁对多线程性能的影响”——向量理解整体意图,BM25命中“GIL”这个精确关键词
- 短查询消歧:“苹果”——纯向量可能检索到手机和水果,BM25结合上下文关键词辅助消歧
混合反而变差的场景:
- 纯语义问答(“什么是幸福”)→ BM25引入噪声
- 纯关键词检索(错误码查询)→ 向量检索稀释精确结果
融合策略的关键:RRF(Reciprocal Rank Fusion)中的K参数决定了两路结果的权重平衡——需要根据实际查询分布调优。
flowchart TB
Q["用户 Query"] --> D{"查询类型判断"}
D -->|"语义模糊/同义改写"| V["向量检索主导"]
D -->|"精确术语/实体名"| B["BM25 主导"]
D -->|"长尾/多意图/消歧"| H["混合检索\nRRF 融合"]
V --> R["结果"]
B --> R
H --> R
实现时对同一 Query 并行执行 BM25 和向量召回,各自取候选集;可先做 metadata 过滤,再用 RRF 按两路排名融合,或对分数归一化后加权。融合后去重并保留来源、排名等特征,最后交给 Rerank 精排;权重、候选数量和过滤条件应在分桶评测中调优。
差距在哪:面试官考的不是“混合检索好不好”,而是“你知不知道它在什么条件下好”——要有反面案例。能说出混合反而变差的场景(纯语义问答、纯关键词检索),说明你对混合检索有深入的工程实践,而非人云亦云。
Q:知识图谱如何从文档构建、增量维护,并处理实体与关系冲突?
来源:阿里云暑期 Agent 面经(2026-05-03)【抖音电商Agent全栈开发工程师一面追问:知识构建与图谱抽取怎么做?;更新时实体抽取和关系关联怎么处理?】;本轮追问:知识图谱主要是干什么的?怎么来的?和单纯 RAG 比较有什么效果?(携程agent开发一面);虾皮agent开发一面;10.8号顺丰AI全栈一面
新手答:“用大模型从文档抽取实体和三元组,去重后写入 Neo4j;有新文档就继续追加。”
高手答:
文档知识图谱不是一次三元组抽取,而是一条带 Schema、溯源和变更语义的数据管线:文档解析与分块 → 实体/关系候选抽取 → 类型与关系 Schema 校验 → 实体规范化与消歧 → 证据绑定和置信度计算 → 合并入图 → 质量评测。每个实体、关系或属性都要保留来源文档、版本、原文区间、抽取器版本和时间,不能只留下一个失去证据的 (subject, predicate, object)。
实体合并至少结合规范化名称、别名词典、唯一业务标识、上下文和邻居结构。例如两个“苹果”不能因字符串相同直接合并;同一家公司的中英文名也不能因字符串不同就创建两个节点。低置信候选先进入待确认区,高价值实体可用人工标注集持续评估 precision、recall 和错误合并率。
增量维护应以文档版本差异驱动,而不是只追加:
- 新增文档只抽取受影响分块,并与现有实体做链接。
- 修改文档先撤销旧版本贡献的证据,再重算变更分块及其邻域。
- 删除文档删除的是证据边;只有当实体或关系不再有任何有效证据时才 tombstone,不能误删其他文档共同支持的知识。
- Schema、消歧模型或抽取 Prompt 变更要记录版本,并支持按受影响类型回放,而不是全图无条件重建。
冲突也不能简单“新值覆盖旧值”。先区分实体重复、抽取错误和来源观点冲突:实体重复进入 merge/split 流程;违反 Schema 或原文不支持的关系拒绝入图;两个可信来源给出不同结论时,把“声明”建模为带来源、有效时间、适用范围和置信度的独立记录并保留并存。查询时再按时间、权威度、业务域和用户意图选择或同时展示,关键冲突升级人工裁决,裁决过程可回滚。
知识图谱把分散文本中的实体、关系和属性组织成可追溯网络,适合多跳关系查询、实体消歧和关系推理。通常由文档解析、实体关系抽取、规范化消歧、合并及证据挂接得到。相比只检索文本片段的 RAG,图谱更擅长结构化、多跳和全局关联,但构建维护成本高、抽取错误会传播;RAG 更灵活且保留原文,二者可混合检索并回溯证据。
追问补充:查询时先用实体规范名、别名和业务标识做精确或倒排匹配,再以模糊、向量检索补充候选;结合实体类型、上下文、领域和时间消歧,确定实体 ID 后进行邻接或多跳查询,并返回对应证据与置信度。
追问补充:节点变更后先依据证据反向索引找出受影响的关系、属性和文档,再沿业务定义的依赖边做有界传播;对每个邻居比较旧新实体、关系、时间范围和置信度,只有影响其可查询结论或约束时入重算队列。记录影响路径,抽样回放并校验未受影响节点,避免全图重建。
差距在哪:新手停在“LLM 抽三元组 + 图数据库”。高手覆盖了 Schema、实体消歧、证据溯源、按文档版本撤销贡献和多来源冲突建模,回答的是知识图谱如何长期可信地演化。
Q:Reranker 的原理、效果上限与评估方法是什么?
新手答:“Reranker 会对召回的候选文档再次打分,把更相关的内容排到前面,通常能提升检索准确率。”
高手答:
Reranker 通常是 cross-encoder:把 query 与候选文档拼接后送入 Transformer,让双向注意力直接建模词句交互,输出相关性分数,再重排召回的 Top-K。它不能找回第一阶段没有召回的文档,因此上限受召回率、切片质量和上下文截断限制;候选数越大,延迟和成本通常越高。评估应拆成召回层 Recall@K 与重排层 MRR、nDCG、Precision@N,并做端到端答案正确率、延迟和成本评测。测试集要覆盖同义表达、长文档、难负例和无答案问题,避免训练测试泄漏;线上还应监控分数漂移、拒答和业务成功率。
追问补充:先从 query 抽取具体实体、型号和限定属性,将泛化类别词标为弱意图或过滤条件,重排时提高实体与属性的匹配权重,并按标签分组设配额或做多样性约束,避免同类泛化结果占满 Top-K。需用带标签的难负例比较分组前后的 nDCG、实体命中率和用户有效点击。
追问补充:reranker 不是通用必选组件:它依赖候选质量、query 与文档交互及延迟预算,结构化过滤、精确匹配或候选很少时可能收益有限;也不是所有 RAG 都必须使用,需用端到端正确率、延迟和成本的对照实验决定是否加入。
差距在哪:浅层回答只描述“重新排序并提升准确率”,深入回答还应说明 cross-encoder 的注意力机制、召回上限、延迟成本、难负例与分层评估。
Q:MMR 为什么还能提高效果?重排后为什么还要设置 MMR 截断?
来源:深势科技一面;合肥某头部企业软件开发实习生面试问题汇总(时长1个小时)
新手答:“MMR去重,避免重复内容。”
高手答:
MMR(Maximal Marginal Relevance)的核心公式:
MMR = argmax[λ × Sim(doc, query) - (1-λ) × max(Sim(doc, selected_docs))]
为什么能提高效果(不只是去重):
- 信息多样性:相关但不重复的文档比多篇高度相似的文档提供更多有效信息
- 减少上下文浪费:如果Top-5里3篇说同一件事,相当于浪费了2个slot——MMR确保每个slot贡献增量信息
- 缓解位置偏差:Rerank可能因为表面相似度把多篇近义文档排在前面,MMR打散后模型能看到更全面的信息
重排后还要MMR的原因:
Rerank模型(Cross-encoder)只看query-doc相关性,不看doc-doc相似度——它可能给出5篇“都相关但信息高度重叠”的结果。MMR在Rerank之后引入文档间多样性约束,是“相关性+多样性”的二次平衡。
MMR截断(λ阈值):当MMR分数低于阈值时停止取文档——宁可少给也不给低质量/低增量的内容。
flowchart LR
Q["用户 Query"] --> RR["Rerank 精排\n只看 query-doc 相关性"]
RR --> MMR["MMR 多样性筛选\n引入 doc-doc 相似度约束"]
MMR --> CUT["MMR 截断\n分数低于阈值时停止"]
CUT --> CTX["最终上下文\n每篇文档贡献增量信息"]
实际效果数据:Top-5中加MMR vs 不加MMR,生成答案的完整性提升约15-20%(因为覆盖了更多角度)。
差距在哪:面试官考的是对“检索后处理”环节的理解深度——不只是“去重”,而是信息论层面的最优信息子集选择。能说出Rerank和MMR各自解决什么问题(相关性 vs 多样性),说明你对检索管线有精细化的认知。
Q:知识库持续更新时,如何保证一次 RAG 回答读取同一逻辑快照?
来源:腾讯互娱全栈开发(AI)二面(2026-08-13);联宝科技秋招AI应用开发AI面面经
新手答:“更新索引时用蓝绿切换,查询总是读当前索引。”
高手答:请求开始时取得快照 ID,Query Rewrite、稀疏/向量召回、补充检索、文档读取和引用校验都携带该 ID。新版本先完整写入正文、向量和元数据,校验后原子发布快照指针;旧快照保留到在线请求、评测和审计结束。跨存储要用共同版本清单,不能让正文、ACL 和向量各读“最新”。
差距在哪:新手保证单次检索可用,高手保证整条回答链的一致读视图。
Q:RAG 如何防止引用漂移和跨版本证据拼接?
来源:腾讯互娱全栈开发(AI)二面(2026-08-13);本轮追问:Chunk 摘要直接作为最终答案的证据不行吗?(本轮追问)
新手答:“让模型输出引用编号,生成后检查编号存在。”
高手答:证据块携带稳定 citation ID、文档/版本、章节区间、内容哈希和 ACL;模型只能选择本次允许的 ID。合并相邻块前验证版本、连续位置和权限一致,生成后逐 claim 检查引用是否真正支持结论。无法映射的断言删除、降级为不确定或触发补检索,不能只验证“编号存在”。
差距在哪:新手验证格式,高手验证证据身份、连续性和语义支撑。
Q:RAG 前端如何展示长文档,并让引用稳定跳转到原文证据?
来源:商汤 AI Agent 开发面经(2026-03-05);本轮追问:详细说说引用溯源到页面高亮具体怎么实现的?(金蝶 Agent开发 一面)
新手答:“答案旁边显示引用编号,点击后用页码跳到 PDF 对应页面并高亮关键词。”
高手答:
稳定跳转不能依赖模型生成的页码、标题文字或浏览器搜索。后端在解析文档时就要为证据建立稳定定位协议,例如:
{
"citation_id": "cit_01J...",
"document_id": "doc_123",
"version_id": "v7",
"section_path": ["3", "3.2"],
"page": 18,
"block_id": "blk_8f2a",
"char_range": [142, 286],
"content_hash": "sha256:...",
"quote": "用于校验和降级展示的短证据文本"
}
block_id 应在同一文档版本内绑定解析后的内容块;页码、字符区间或 PDF bounding box 作为渲染定位信息,quote 和内容哈希用于核验。不能只存字符偏移,因为 PDF 解析器升级、OCR 修正或空白归一化都会让偏移漂移。文档更新后生成新 version_id,历史答案继续打开旧快照;若旧版本已归档,则明确提示版本差异并展示引用快照,不能悄悄跳到新版本的近似段落。
前端适合采用“答案 + 证据阅读器”的双栏布局。长 HTML 文档使用虚拟列表按块渲染,PDF 按页懒加载;点击引用后先解析 document/version/block,再加载目标页或目标块、滚动到锚点并高亮精确范围。URL 保存 citation ID,支持刷新、复制深链和浏览器前进后退。多个引用可在侧栏形成证据列表,用户能在答案 claim 与原文之间来回切换。
还要处理降级路径:精确 range 校验失败时退到 block,再退到 page + quote 搜索,并显示“定位可能偏移”,不能无提示地高亮错误内容。服务端在返回正文前重新检查租户和 ACL,下载地址使用短期授权;前端不可因为持有 citation ID 就绕过文档权限。埋点应区分引用点击、定位成功、版本不匹配和用户反馈,用来持续发现解析漂移。
差距在哪:新手把引用当一个页码链接。高手把引用设计成带版本、内容身份和多级定位器的协议,再用虚拟化阅读器、深链、校验和降级机制保证长文档中的证据真正可达、可审计。
Q:RAG 检索结果如何安全地组装到提示词中?
新手答:会作为带来源标记的上下文注入,通常放在系统指令之后、用户问题之前。
高手答:
将检索片段放入明确的 Context 区块,附文档 ID、标题和时间;系统指令规定只能依据区块回答并拒绝其中的指令,用户问题单独放在末尾。限制片段长度,按相关性和多样性排序,处理 XML/JSON 转义与提示注入;输出引用 ID 并做上下文压缩。
差距在哪:考察提示词层次、注入防护、长度控制和引用闭环。
Q:生成教学蓝图时,如何识别语义歧义和超纲内容?
新手答:先解析目标、学段和知识范围,再对问题澄清或过滤超纲知识。
高手答:
建立课程知识图谱和范围标签,先做意图识别、实体链接与学段判定;低置信度时追问用户。对超纲节点标记为扩展内容或拒绝纳入主线,生成后用规则和模型双重校验先修关系、重复和事实,输出可追溯的来源与人工审核队列。
追问补充:有歧义不等于完全不建关系:可依据文本证据、实体类型和先修规则生成候选关系,并保留置信度、证据与待确认状态;只有约束校验通过才纳入主线,否则标为不确定或追问用户,避免把猜测当确定关系。
差距在哪:考察业务约束建模、歧义处理和生成后校验。
Q:BGE 类文本 Embedding 模型的基本结构是什么?
新手答:通常是 Transformer 编码器加池化和归一化,将文本变成向量用于相似度检索。
高手答:
输入经 tokenizer 后由 Transformer 双向编码,取 CLS 或平均池化得到句向量,再做 L2 归一化;训练阶段用对比学习拉近正样本、拉远负样本,推理用余弦或点积。实际使用需关注模型语言版本、最大长度、指令前缀和向量维度,并用领域数据评估召回。
差距在哪:考察编码器、训练目标和检索工程参数,避免把 BGE 误说成生成模型。
Q:RAG 中如何解析文档引用并完成跨文档内容检索?
新手答:“先从文档中提取引用链接或文档标识,再定位并检索被引用文档的内容,最后结合原文回答并保留引用关系。”
高手答:
应把任务拆成“引用解析、文档定位、权限校验、内容获取、跨文档检索和证据生成”。先识别 URL、标题、编号、脚注或参考文献条目,统一解析为文档 ID;再通过目录、元数据服务或连接器获取目标文档,处理相对链接、重定向、版本和失效链接。检索时不能只把两份全文拼接,应保留 source_id、段落位置、版本和引用链,分别切分、索引,再进行多跳检索或查询改写。访问必须继承用户权限,避免通过索引泄露无权内容;抓取、解析和重复请求要有缓存、超时、重试及幂等设计。回答阶段要求模型引用可回溯证据,找不到目标文档时明确说明,不应猜测。验证可用带人工标注引用链的数据集评估解析准确率、召回率、证据支持率和权限隔离,同时覆盖链接失效、同名文档和循环引用等失败场景。
差距在哪:浅层回答停留在“提取链接后搜索”,深入考察引用解析、权限与版本治理、证据回溯、多跳检索及可量化评估。
Q:数据库检索与 RAG 检索有什么区别?什么场景下应优先选择数据库检索?
新手答:“数据库检索适合精确查询结构化数据,RAG 更适合从文档中进行语义检索并生成回答。”
高手答:
数据库检索以结构化字段、SQL 条件、索引和事务语义为核心,适合订单、库存、权限、账务等需要精确过滤、强一致、实时性和可审计的数据;RAG 通常先对文档切片、建立向量或混合索引,再召回相关片段交给模型生成答案,适合制度、手册、FAQ 等半结构化知识。若问题包含明确主键、范围、聚合、排序或权限约束,应优先数据库,避免模型把召回文本当成事实。RAG 的召回和生成都可能漏检、错配或产生幻觉,不能替代授权校验和事务写入。实践中可采用混合方案:数据库负责事实查询与权限,RAG 负责解释和背景;用命中率、答案可验证性、延迟、成本及数据变更后的新鲜度评估选型。
差距在哪:浅层只停留在“结构化对非结构化”的分类,深入回答要说明事务、权限、实时性、召回误差、幻觉和混合架构的取舍。
Q:粗排后为什么需要使用 Cross-Encoder 重排?两阶段检索如何分工?
新手答:“粗排用向量相似度快速筛选候选,Cross-Encoder 联合理解查询和文档后重新排序,因此通常更准确但更慢。”
高手答:
两阶段检索是效率与相关性的折中。粗排通常用双塔或其他可预计算表示,把查询与文档分别编码并通过向量索引快速召回,目标是尽量保住相关文档的召回率;Cross-Encoder 则把查询和候选文档拼接后共同输入模型,通过跨文本注意力直接判断匹配度,能识别词序、否定、条件和细粒度语义,因此往往比单纯向量相似度更有判别力。它需要对每个候选逐一推理,候选过多会带来延迟和成本。应在固定候选规模下评估 Recall、MRR或NDCG、延迟与成本,并检查长文截断、领域偏差、重复结果和恶意文本等失败模式。
追问补充:常见策略包括 pointwise 逐篇打分、pairwise 比较文档对、listwise 对候选列表整体排序;工程上也可将 Cross-Encoder 分数与向量相似度、BM25 或业务规则加权融合,并按延迟预算选择策略。
差距在哪:浅层回答只强调“一个快、一个准”,深入回答还应解释双塔与交叉编码的交互差异、候选规模约束,以及用召回率、排序质量和延迟共同验证。
Q:如何设计支持版本过滤和时间旅行查询的向量索引?
来源:腾讯互娱全栈开发(AI)二面(2026-08-13)
新手答:“向量记录加 version 字段,查询时过滤即可。”
高手答:记录文档 ID、逻辑版本、生效区间、租户、ACL 和删除标记;更新时关闭旧版本区间并插入新版本,不覆盖历史。过滤选择性高时应预过滤或按快照分区,避免 Top-K 被不可见版本占满。异步构建失败时旧版本继续服务,只有正文、向量、元数据和权限全部就绪才发布新快照。
差距在哪:新手只有字段,高手考虑 ANN 过滤性能、发布原子性和历史保留。
Q:图召回如何缓解热门内容被过度推荐的问题?
新手答:热门节点连接多,容易被召回更多,需要加入去偏和多样性策略。
高手答:
在召回阶段对节点度数做惩罚或采用逆流行度权重,限制同一热门簇的配额;融合长尾、内容相似和用户新颖性通道。排序时加入曝光校正和多样性约束,并按新老用户、岗位类别分层评估覆盖率、Gini 和点击质量,防止只优化 CTR。
差距在哪:考察图召回的流行度偏差、指标设计和多通道治理。
Q:RAG 组装上下文后,如何选择最终生成模型?
来源:腾讯AI全栈一面
新手答:根据任务复杂度、延迟和成本选择生成模型,并不是固定某一个模型。
高手答:
先用离线集比较候选模型在正确率、引用一致性、拒答率、延迟和成本上的表现;简单问答可路由小模型,复杂推理升级大模型。统一模型适配层、温度和输出 schema,保留版本与回滚;检索模型和生成模型可独立替换,避免把某个供应商写死。
差距在哪:考察模型选型是否基于指标和路由策略,而非背诵模型名称。
Q:视频没有语音时,如何保持检索效果?
新手答:依赖语音的检索会下降,但可用视觉、OCR 和元数据补足。
高手答:
根据音频是否存在动态选择模态:抽取关键帧、场景标签、字幕/OCR 和动作描述,生成视觉向量;查询侧同时编码文本和视觉概念,使用多路召回与后融合。对无语音样本单独评测 Recall@K、MRR 和延迟,必要时提示用户结果置信度下降。
差距在哪:考察多模态降级、融合策略和分场景评测。
Q:双塔模型与单塔模型的原理、差异和适用场景是什么?
来源:滴滴一些面经合集(算法)
新手答:“双塔模型分别编码查询和候选内容后计算相似度,适合大规模召回;单塔模型把二者一起输入并直接交互,效果通常更好但计算成本更高。”
高手答:
双塔模型由查询塔和候选塔组成,分别将问题、文档编码为向量,再用内积或余弦相似度检索,适合离线建库、近似最近邻召回和高并发场景;代价是两侧只能通过最终向量交互,细粒度词序、否定关系可能丢失。单塔模型把查询与候选拼接后联合编码,注意力可直接建模跨文本关系,通常更适合精排或复杂匹配,但候选数一多就需要重复推理,延迟和成本较高。工程上常用“双塔粗召回+单塔重排”,并关注向量版本、索引更新、负样本质量、截断和缓存。验证不能只看离线召回率或排序指标,还应按查询类型做分桶评估,并用线上延迟、吞吐、点击或任务成功率及人工抽检确认收益;同时检查数据泄漏、重复文档和权限过滤。
差距在哪:浅层回答只停留在“速度与效果”的二分,面试官还会考察向量交互限制、两阶段架构、索引与负样本工程,以及如何用离线和线上指标验证选型。
Q:如何从技术和工程维度选择两套 RAG 方案?
新手答:“我会从效果、速度、成本、稳定性和维护难度比较两套 RAG,并用统一测试集和线上指标验证后再决定。”
高手答:
应先统一业务目标、数据范围、模型版本、提示词和评测集,避免把不同实验条件下的结果直接比较。技术上分别检查切分与索引质量、召回率、排序、上下文去重、引用准确性、生成答案的完整性和拒答能力;同时覆盖无答案、冲突文档、时效性和权限隔离场景。工程上比较端到端延迟、吞吐、存储与模型成本、扩缩容、可观测性、失败降级、数据更新和回滚能力,并审查提示注入、越权检索和敏感信息泄露风险。可用离线分桶评测、人工盲测和小流量 A/B 验证,记录置信度与线上反馈。最终不一定选单项分数最高者,而应按业务权重选择总体风险和维护成本可接受的方案。
差距在哪:浅层回答停留在准确率、速度和成本,深入回答会建立可复现评测,并覆盖检索链路、数据权限、失败模式、上线治理与权衡。
Q:如何设计一个支持图文检索的多模态搜索 Agent?
来源:小红书多模态秋招二面
新手答:“可以用图像和文本编码器生成向量,在向量数据库中召回相似笔记,再用排序模型选出最相关结果。”
高手答:
将 Agent 设计为检索编排器,而不是让大模型直接“猜答案”:先识别用户是找视觉相似、主题相近还是图文综合匹配,并对图片做主体检测、OCR、标签和质量检查。离线为笔记图片、标题、正文、OCR 和结构化元数据建立索引;用共享空间的图文向量做粗召回,再融合关键词、标签、地理和时间过滤,最后用图文交叉编码器或轻量排序模型重排,并返回匹配证据。索引需支持增量更新、删除同步、权限过滤和多租户隔离,图片上传要限制大小、格式及恶意内容,避免泄露原图。用 Recall@K、NDCG、相似度人工评审和零结果率评估,分桶验证延迟、成本与点击;纯向量召回语义泛化好但可能忽视精确词,纯关键词可解释却难处理视觉近似,因此采用混合召回和可回退策略。
差距在哪:浅层回答只描述“向量库加排序”,深入回答会覆盖意图路由、多模态索引、权限与安全、证据返回、评估指标及召回质量与成本延迟的权衡。
Q:如何优化内容结构与元数据以提升大模型检索和引用效果?
新手答:“把内容写得清晰、结构化,并补充准确的标题、标签和摘要,能帮助模型更容易检索和引用。”
高手答:
核心不是堆关键词,而是让内容具备可检索、可理解、可归因的证据结构。正文应使用描述性标题、短段落、稳定术语和明确问答;在元数据中标注主题、实体、时间、版本、作者、适用范围与 canonical URL,并把结论、条件、例外和来源放在同一语义单元。工程上要避免重复、过期和互相矛盾的页面,处理权限、隐私、版权和敏感信息;这些是治理建议,不构成法律意见。可用真实查询集评估召回率、引用准确率、覆盖率、更新时间和人工可读性,比较分块、字段和重排策略。结构化程度与写作自然度、维护成本之间需要权衡。
差距在哪:浅层只会建议加关键词和标签,深入回答还应覆盖语义分块、来源归因、时效与权限治理,并说明如何用检索和引用指标验证。
Q:RAG 中如何进行查询分解与子问题拆分?
新手答:“查询分解就是把复杂问题拆成多个更具体的子问题,分别检索相关知识,再汇总结果生成答案。”
高手答:
查询分解的目标不只是“每次检索一个问题”,而是把多跳、并列或条件复杂的原问题改写成可独立检索、可验证的子任务。分解器可基于规则、查询分类器或大模型生成子问题,并保留实体、时间范围、过滤条件和原问题上下文;随后对子问题分别改写、召回、重排,最后按依赖关系合并证据。工程上要限制拆分数量和递归深度,避免检索放大、重复召回与成本失控;并处理子问题之间的依赖,不能把必须先回答的结果静态并行化。验证应检查召回覆盖率、证据与子问题的对应关系、最终答案的引用一致性,以及无须拆分问题上的收益和延迟。主要权衡是更高的召回与可解释性,换来更多请求、延迟和错误传播风险。
差距在哪:浅层只描述“拆成多个问题分别检索”,深层还应说明拆分策略、依赖与数量约束、证据合并、评估指标及成本和错误传播权衡,考查的是端到端 RAG 编排能力。
Q:RAG 系统支持多轮对话时,如何管理历史上下文、检索与回答一致性?
来源:恒生电子技术岗ai面
新手答:“多轮 RAG 需要管理会话历史、控制上下文长度、改写当前问题并分别检索历史和知识库,最后处理冲突后再回答。”
高手答:
多轮 RAG 通常将原始问题、会话摘要、近期窗口和结构化用户状态分开管理,不能把全部历史无差别塞进提示词。先用当前轮问题结合必要历史做指代消解或查询改写,再分别检索对话记忆与外部知识;历史适合保留用户意图、约束和已确认结论,知识库则提供可引用事实。融合时要去重、按来源和时间排序,明确外部知识优先级,并在证据不足或冲突时要求澄清,不能让模型自行编造统一结论。工程上需限制 token、记录版本和来源、隔离用户数据,评估改写召回、证据覆盖、答案一致性与跨轮错误累积。
差距在哪:浅层只关注截断历史和扩大上下文,深入回答还要区分记忆与知识检索、处理冲突和时效性,并用可追溯评估验证跨轮一致性。
Q:多轮历史对话检索与外部知识库检索的排序策略有什么区别?
来源:恒生电子技术岗ai面
新手答:“历史对话更看重与当前意图和时间的相关性,外部知识库更看重语义匹配、权威性、时效性和证据质量。”
高手答:
多轮历史检索的目标是恢复当前问题所依赖的对话状态,因此排序通常优先当前轮相关性、指代依赖、用户约束、已确认事实和时间新鲜度,并可对重复或已被后续消息修正的内容降权。外部知识库检索则更强调查询与文档的语义匹配、字段过滤、权威来源、版本有效期和证据完整性,常用关键词与向量召回后再重排。两者融合不能只按一个相似度分数排序,应保留来源标签和冲突规则;例如用户偏好可来自记忆,但产品事实应以当前有效文档为准。还要防止历史内容携带提示注入,评估各路召回、融合后的证据覆盖、时效准确率和答案可追溯性。
差距在哪:浅层只区分“历史按时间、知识按相似度”,深入回答还应覆盖状态依赖、来源权威、版本冲突、注入防护和分路评估。
Q:大模型翻译能力已经很强时,为什么翻译系统仍需要 ES 语义召回?
新手答:“ES 语义召回可以先找到相似的历史译文和术语,再让大模型结合上下文翻译,从而提高一致性和稳定性。”
高手答:
ES 语义召回的角色不是替代大模型,而是提供可复用、可追溯的翻译记忆、术语和相似上下文。系统可将源文切片并生成向量,在 ES 中做向量或混合检索,再把高相关结果注入提示词,由大模型完成改写、决策或兜底翻译。这样能改善专有名词一致性、风格稳定性和长尾领域表现,但会引入索引更新、召回延迟、噪声结果、隐私隔离和上下文长度约束。工程上建议同时评估召回命中率、术语准确率、译文质量、延迟与成本,并设置阈值、重排和无结果回退;取舍是增加检索维护成本,换取可控性与一致性,而不是默认每句话都检索。
差距在哪:浅层只会说“先检索再翻译”,面试官更关注召回与生成的分工、噪声和延迟边界,以及如何用离线集和线上指标验证收益。
这类题的答题模式
RAG 与检索题的核心是完整链路 + 工程细节:
1. RAG 不是"向量搜索"——是离线切片 + 在线召回 + 精排的完整管线
2. 查询改写不是"扩展"——是多维度变换 + 槽位填充 + 主动澄清
3. 召回不是"一路搜索"——是多路召回 + 融合 + 精排
4. 性能优化用并行化——串行意图识别会引入延迟和错误级联
下一篇建议继续看: