Agent 面试通关 / 09
RAG 与检索系统:从 chunk 设计到多路召回
RAG 是 Agent 系统的“外部知识接口”。面试官考 RAG 时不想听“向量数据库”四个字——他想知道的是离线怎么切片、在线怎么召回、召回后怎么排序,以及面对复杂查询时怎么做改写和意图识别。
Q:RAG 的检索如何实现?
来源:阿里 AI Agent 开发一面
新手答:“用向量数据库做相似度搜索。”
高手答:
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 带上标题、章节路径、来源元信息,提升召回相关性。
差距在哪:新手只说了“向量数据库”——这是一个组件,不是方案。高手的回答覆盖了离线和在线两条链路,且点出了 chunk 设计这个影响效果的关键因素。面试官考的是你对 RAG 工程的完整认知。
Q:多维度的查询改写是什么?改写遇到需要用户补充信息时怎么设计?
来源:抖音基础架构 Agent 一面
新手答:“用大模型把用户的查询扩展一下。”
高手答:
多维度查询改写是指同时从多个角度对原始 query 做变换,提升召回的全面性:
原始 query:"北京周末带娃去哪玩"
维度1-意图展开:亲子活动 / 儿童乐园 / 博物馆 / 户外游
维度2-实体补全:北京市 → 朝阳区/海淀区/...
维度3-同义改写:"带娃" → "亲子" / "儿童" / "适合小朋友"
维度4-约束提取:时间=周末,地点=北京,人群=有孩子的家庭
需要用户补充信息时,用槽位填充 + 主动澄清机制:
- 意图识别后,检查必要槽位是否完整(比如“订酒店”需要日期、城市、人数)
- 缺失槽位时,不是笼统地问“你能说得更清楚吗”,而是生成具体的选择题:“你想去哪个城市?”或“入住日期是什么时候?”
- 多个槽位都缺时,按优先级排序,先问最关键的
技术实现上,查询改写用模型生成 + 规则约束混合:模型负责语义理解和改写,规则负责实体标准化和格式校验。槽位检测用一个轻量分类器判断缺失情况,避免每次都调大模型。
差距在哪:新手的“扩展一下”是单维度思考。高手的多维度改写覆盖了意图、实体、同义、约束四个角度,且有用户交互的槽位填充机制。面试官考的是你对查询理解链路的完整认知。
Q:并行化意图识别是什么?为什么要并行化?如何实现的?
来源:抖音基础架构 Agent 一面
新手答:“用多线程跑意图分类。”
高手答:
并行化意图识别是指同时执行多个意图维度的判断,而不是串行地先判大类再判小类。
串行方案的问题是链路长、延迟高。比如先判“是不是搜索意图” → 再判“搜索什么品类” → 再判“有没有比较意图”,三级串行加起来可能 300ms+。而且前一级判断错了,后面全错——错误级联放大。
并行化把多个维度同时发出去:
┌→ 意图大类分类器(搜索/导航/交易)
user query ──┼→ 品类识别器(美食/旅游/购物/...)
├→ 行为意图检测器(比较/推荐/查询/...)
└→ 情感倾向检测器(正面/负面/中性)
每个分类器独立运行,结果汇总后做融合决策。实现关键点:
- 各分类器用异步并发执行(
asyncio.gather或线程池),总延迟 = 最慢的那个 - 每个分类器可以用不同规模的模型——简单维度用小模型,复杂维度用大模型
- 设置超时兜底:某个分类器超时不影响其他维度,用默认值填充
差距在哪:新手的“多线程”只答了实现手段,没答为什么要并行化。高手先解释了串行方案的问题(延迟高 + 错误级联),再给出并行化的架构和融合策略。面试官考的是性能优化思维。
Q:讲一下项目里召回的流程
来源:抖音基础架构 Agent 一面
新手答:“用向量搜索召回相关文档。”
高手答:
召回是一个多路召回 → 合并去重 → 精排的三阶段流程:
第一阶段:多路召回
┌→ 向量召回(语义相似度,覆盖同义表达)
改写后 query ──┼→ 关键词召回(BM25,覆盖精确匹配)
├→ 标签召回(实体/品类标签匹配)
└→ 图召回(知识图谱关联路径)
每路召回各取 top-K,各有优势:向量召回抓语义,关键词召回抓精确词,标签召回抓结构化属性,图召回抓实体关系。
第二阶段:合并去重
多路结果合并,同一文档被多路召回的加分。去重用文档 ID 做精确去重 + 内容指纹做近重复去重。
第三阶段:精排
用 Cross-Encoder 或精排模型对候选集做细粒度相关性打分。精排模型能看到 query 和文档的交互特征,精度远高于召回阶段的双塔模型。关键工程细节:每路召回的 K 值怎么定——K 太小漏结果,K 太大精排压力大,通常根据各路历史准确率动态调整。
差距在哪:新手只知道向量检索一路。高手的多路召回 + 精排是搜索系统的标准范式,面试官考的是你对召回-精排两阶段架构的完整理解。
Q:如果 RAG 召回了很多相互矛盾的文档,Agent 应该怎么处理,而不是直接让模型自己总结?
来源:腾讯大模型应用开发二面
新手答:“让模型自己综合判断。”
高手答:
不能直接把矛盾文档一股脑丢给模型让它自己“综合”,那样很容易生成一个看起来圆滑但实际上没有依据的答案。
更合理的做法是先做证据归一化和冲突检测:
- 分组:按来源、时间、可信度对召回文档分组
- 冲突检测:抽取同一字段的不同取值,判断冲突类型——是时间差异导致的,还是来源本身互相打架
- 冲突消解:
- 时间敏感信息 → 新版本优先
- 来源权威性不同 → 官方文档优先
- 无法判断 → 明确告诉用户存在冲突,说明目前最可信的依据
Agent 在这里更像证据调解器,而不是万能总结器。核心是在模型生成前就把冲突处理好,而不是让模型在矛盾信息中自己编一个“看起来合理”的答案。
差距在哪:新手直接把矛盾丢给模型——这会生成看似合理但无依据的答案。高手在模型生成前加了冲突检测和消解层,按时间、权威性、可判断性三个维度做处理。面试官考的是你有没有意识到 RAG 不只是“召回 + 生成”,中间还需要证据治理。
Q:Embedding 和 ReRank 模型具体怎么做的微调?
来源:腾讯 AI 应用开发
新手答:“用自己的数据训练一下。”
高手答:
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),否则通用检索能力退化
差距在哪:新手只说了“用数据训”。高手覆盖了完整链路——数据构造(三元组 + hard negative)、loss 选择、框架、评估、防过拟合。面试官考的是你有没有真正微调过检索模型。
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:如何用通俗易懂的方式向非技术人员解释 RAG?有没有好的类比?
来源:携程 Agent 开发实习一面
新手答:“就是让模型先搜索再回答。”
高手答:
给非技术同事解释 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)、客服系统(产品手册检索)、法律/医疗等需要精确引用的领域、代码文档助手。
差距在哪:新手的解释太技术化,非技术人员听不懂。高手用图书馆类比把 RAG 的三个角色(用户 → 检索员 → 专家)讲清楚了,再用三点核心价值说明“为什么需要”。面试官考的不只是你懂不懂 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 系统检索到的文档很多但回答质量差,怎么排查?
来源:携程 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 模板,加引用约束
差距在哪:新手第一反应是“换模型”——这是最贵且通常无效的做法。高手按 RAG 链路逐段排查(检索 → 排序 → 组装 → Prompt),每段都有具体的症状、排查方法和解法。面试官考的是你排查问题时的系统性思维。
Q:什么是余弦相似度?在 RAG 系统中用来做什么?
来源:携程 Agent 开发实习一面
新手答:“衡量两个向量的相似程度。”
高手答:
余弦相似度衡量的是两个向量方向的接近程度,不关心长度,只关心角度:
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 开发实习一面
新手答:“把文本变成数字,方便计算。”
高手答:
嵌入(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 在 RAG 管线中的核心作用。
Q:RAG 中如何提高文档召回率?
来源:蚂蚁集团智能体与大模型应用一面
新手答:“换更好的 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。
差距在哪:新手只想到换模型。高手从离线端(chunk/文档增强/Embedding 微调)和在线端(查询改写/混合召回/HyDE)六个方向给出了完整方案,且点出了优先级排序。面试官考的不是你知不知道某个技术,而是你能不能系统性地优化一条 RAG 管线。
Q:RAG 为什么需要向量检索?和传统关键词检索有什么本质区别?
来源:蚂蚁集团智能体与大模型应用一面
新手答:“向量检索更准。”
高手答:
不是“更准”——是解决了不同的问题。传统检索和向量检索的核心差异在于匹配方式:
| 维度 | 传统关键词检索(BM25) | 向量检索(Embedding) |
|---|---|---|
| 匹配方式 | 词级精确匹配 | 语义级相似度匹配 |
| 核心算法 | TF-IDF / BM25 | ANN(近似最近邻) |
| 能处理同义词 | ❌ “退货”搜不到“退款” | ✅ 语义相近就能匹配 |
| 能处理精确术语 | ✅ 搜“order_id=123”直接命中 | ❌ 向量化后精确性丢失 |
| 计算成本 | 低(倒排索引,O(1)级) | 高(向量距离计算 + ANN 索引) |
| 索引存储 | 小(倒排表) | 大(每条文档一个高维向量) |
| 对新词/专业术语 | 好(只要文档里有就能匹配) | 差(模型没见过的词 embedding 质量低) |
RAG 为什么需要向量检索:
用户提问的方式和文档的表述方式几乎不可能完全一样。用户问“服务器老是挂”,文档里写的是“服务可用性异常”——没有一个共同关键词,但语义完全匹配。传统检索在这种场景下召回率为零,向量检索能轻松解决。
但向量检索不能完全替代关键词检索:
查具体的错误码(ERR_CONNECTION_REFUSED)、精确的文件路径、特定的 API 名称——这些场景关键词检索比向量检索更快更准。向量化反而会把精确信息“模糊化”。
生产环境的最佳实践是混合检索:
向量检索(语义匹配)─┐
├→ 合并去重 → ReRank 精排 → Top-K
关键词检索(精确匹配)─┘
两路互补:向量路保证语义覆盖,关键词路保证精确命中。合并后用 ReRank 统一排序。
差距在哪:新手用“更准”一词概括——其实向量检索在精确匹配上反而不如关键词检索。高手明确了两者的优劣势互补关系,且指出生产环境用混合检索。面试官考的是你对检索系统的工程认知——不是“哪个更好”,而是“什么场景用什么”。
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 架构演进方向的认知——从单次检索到多跳检索到图检索,是检索系统面对大规模文档的自然演化路径。
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 题
新手答:“加 ReRank 重排就行。”
高手答:
三个控制点都需要,但投入产出比不同:
召回层——控制“进来什么”:
问题:召回 50 条,30 条不相关
解法:① 优化 query(多维度改写)② 收紧召回阈值 ③ 加关键词路补充精确匹配
效果:减少噪声进入下游,降低精排压力
召回层的控制是成本最低、效果最直接的——垃圾在入口就拦住,比在后面处理便宜得多。
重排层——控制“排在前面的是什么”:
问题:相关文档被召回了,但排在第 8 位,top-3 都是噪声
解法:用 Cross-Encoder 精排,把真正相关的推到前面
效果:精度提升显著,但增加延迟和计算成本
重排层解决的是顺序问题,前提是相关文档已经被召回了。如果召回阶段就漏了,重排也救不了。
Agent 规划层——控制“怎么用检索结果”:
问题:top-3 文档质量还行,但信息分散,模型拼出了错误答案
解法:Agent 在使用检索结果前做质量判断——
"这些证据是否足够回答问题?是否有矛盾?需不需要再查一次?"
效果:提升最终回答质量,但增加一轮模型调用
规划层是最后一道防线,也是唯一能做“再查一次”决策的地方。
优先级排序:
投入优先级:召回优化(成本低效果大)> ReRank(精度提升明显)> 规划层判断(兜底)
先把召回质量做好,再加精排提升排序,最后在 Agent 层做质量兜底。很多团队跳过前两步直接在 Agent 层“让模型自己判断”,这是最贵且最不可靠的做法。
差距在哪:新手只想到 ReRank 一个点。高手从召回、重排、规划三层分别分析了控制方法和投入产出比,且给出了明确的优先级排序。面试官考的是你对 RAG 质量控制的全链路思维。
Q:Agent 场景下,什么时候该做一次检索、多次使用;什么时候该边执行边检索?
来源:Agent 开发面试 30 题
新手答:“复杂问题多查几次。”
高手答:
判断标准是信息需求在任务开始时是否完全可知:
一次检索、多次使用(Retrieve-once):
适用条件:
- 任务开始时就能确定需要什么信息
- 信息需求不会随执行过程变化
- 检索结果在整个任务周期内有效
典型场景:
- 客服问答:用户问"退货政策是什么"→ 一次检索产品文档,回答完整问题
- 报告生成:给定主题,一次性检索所有相关数据,然后生成报告
- FAQ 类问答:一问一答,信息需求明确
优势是延迟低、成本低,只调用一次检索管线。
边执行边检索(Iterative Retrieval):
适用条件:
- 下一步需要查什么取决于上一步的结果
- 任务目标可能在过程中细化或变化
- 单次检索无法覆盖所有需要的信息
典型场景:
- 故障排查:"服务挂了"→ 查架构文档 → 发现依赖 Redis → 查 Redis 变更记录 → 定位根因
- 竞品分析:查到竞品 A 的信息后,发现需要对比的维度,再查竞品 B
- 多跳推理:答案分布在多个文档中,需要逐步追溯
优势是信息覆盖全,但延迟和成本成倍增加。
工程上的混合策略:
先做一次广泛的初始检索,如果 Agent 判断信息不足再触发增量检索。设一个检索预算上限(如最多 3 次),避免无限检索。
第一次:广泛检索,覆盖主要信息需求
执行中判断:信息够 → 继续执行。信息不够 → 生成更精确的子查询,再检索一次
最多追加 2 次,超过后用已有信息给出最优答案
差距在哪:新手用“复杂度”判断。高手用“信息需求是否可预知”做精确判断,且给出了一次检索和迭代检索的各自适用场景,以及“初始广泛 + 按需增量”的混合策略。面试官考的是你在 RAG 和 Agent 结合时的架构设计能力。
Q:如果 RAG 返回了看似可信但实际过时的信息,你会怎么降低 Agent 被误导的概率?
来源:Agent 开发面试 30 题
新手答:“定期更新知识库。”
高手答:
定期更新是必要的,但更新和检索之间一定有时间差——今天更新的文档可能要到明天才入库,而在这个窗口期内返回的就是过时信息。更根本的问题是:很多文档没有明确的“过期时间”,系统不知道它过时了。
需要多层防线:
第一层:离线端——给文档打时间标签和可信度标签
- 每个 chunk 存储文档创建时间、最后更新时间、来源权威等级
- 有明确时效性的内容(价格、政策、版本号)标记为“时效敏感”
- 建立文档更新监控——源文档变更后自动触发重新入库
第二层:检索端——时间感知的检索和排序
- 检索时对结果按时间新鲜度加权——同等相关性下,新文档排在前面
- 对“时效敏感”标签的 chunk,如果超过 TTL(如 30 天)直接降权或过滤
- 返回结果时附带时间元信息,让 Agent 知道证据的时效性
第三层:Agent 端——生成前做时效性判断
在 Prompt 中明确要求模型:
注意:以下检索结果附带了文档日期。如果信息可能已过时(如价格、政策、版本号),
请在回答中标注"此信息来源于 YYYY-MM-DD 的文档,建议确认是否仍然有效"。
模型看到日期后会主动判断时效性,并在回答中加上免责提示。
第四层:用户端——可追溯的引用
回答中附带引用来源和日期,让用户自行判断信息是否过时。这是最后一道防线——即使系统没发现过时,用户看到“来源:2024 年 3 月的文档”也会自己注意。
差距在哪:新手只想到“更新知识库”——这是必要但不充分的。高手从离线(时间标签)、检索(时间加权)、Agent(时效性判断)、用户(可追溯引用)四层构建了防过时信息的完整体系。面试官考的是你对 RAG 系统“证据可靠性”这个核心问题的工程化思考。
Q:在渐进式披露的架构下,还需要 RAG 吗?RAG 的角色会怎么变?
来源:蚂蚁集团 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”的线性思维。高手看到了 RAG 在新架构下的角色转变——从一次性的知识注入变成多阶段的动态信息供给。面试官考的是你对 RAG 技术演进方向的理解,以及能不能把 RAG 放到更大的架构图景中思考。
这类题的答题模式
RAG 与检索题的核心是完整链路 + 工程细节:
1. RAG 不是"向量搜索"——是离线切片 + 在线召回 + 精排的完整管线
2. 查询改写不是"扩展"——是多维度变换 + 槽位填充 + 主动澄清
3. 召回不是"一路搜索"——是多路召回 + 融合 + 精排
4. 性能优化用并行化——串行意图识别会引入延迟和错误级联
下一篇建议继续看: