RAG 系统常见的失败模式有哪些?检索质量差怎么排查和优化?
一则或许对你有用的小广告
欢迎加入小哈的星球,你将获得:专属的实战项目(4个项目都能学) / 1v1 提问 / 简历修改 / Java 学习路线 / 社群讨论 / 学习打卡 / 每月赠书
《Spring AI 项目实战(问答机器人、RAG 智能客服、联网搜索)》已完结,基于
Spring AI + Spring Boot 3.x + JDK 21...,查看介绍《从零手撸:仿小红书(微服务架构)》 已完结,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...,查看介绍;演示链接:http://116.62.199.48:7070/《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接:http://116.62.199.48/
新开坑项目:《从零手撸:秒杀系统高并发优化实战》 正在更新中...,查看介绍
截止目前,星球内专栏累计输出 150w+ 字,讲解图 5110+ 张,还在持续爆肝中.. 后续还会上新更多项目,已有 4700+ 小伙伴加入学习,欢迎点击围观
面试考察点
-
故障画像能力:你能不能按 RAG 的管线把失败点拆开讲?数据层、检索层、生成层各自有啥典型病症,得能说清楚。
-
排查方法论:RAG 答得不好,到底是检索没召回,还是召回了但 LLM 没用上?得会用数据说话,凭感觉调参不行。
-
优化手段储备:Query 改写、HyDE、Hybrid Search、Rerank、上下文压缩……这些手段你用过哪些,分别适合什么场景?
核心答案
RAG 的失败原因挺杂,按管线可以分成三大类,对应三种不同的病根:
| 失败层 | 典型症状 | 根因 |
|---|---|---|
| 数据/索引层 | 检索结果牛头不对马嘴、知识缺失 | 文档解析丢内容、Chunk 切分不当、知识库过时、元数据缺失 |
| 检索层 | 召回的 Chunk 跟问题相关度低、关键信息没召回 | Query 与 Doc 语义鸿沟、Top-K 太小、Embedding 模型不适配、缺少 Rerank |
| 生成层 | 答非所问、出现幻觉、引用编造 | Prompt 模板不清、上下文窗口溢出、"lost in the middle"、LLM 忽略检索内容 |
排查思路就一句话:先用量化指标定位是哪一层出了问题,再对症下药。凭感觉调参是 RAG 调优最容易栽的坑。
深度解析
一、按管线拆解失败模式
上图把 RAG 全链路的失败点列了一下。下面挑几个最容易踩的展开聊。
数据层最容易翻车的是 Chunk 切分。一个完整的技术方案被切成两半,关键步骤刚好卡在切分边界,检索召回了上下文却拼不出完整答案。另外像 PDF 表格解析丢数据、扫描件没做 OCR、知识库半年没更新,也都是常见问题。
检索层的核心病灶叫 "语义鸿沟"。用户问 "怎么部署",知识库里写的是 "应用上线流程",字面差挺远但意思一样。纯向量检索在这种场景下召回率会很拉胯,所以才需要 Hybrid Search。
生成层有个容易被忽略的坑叫 "lost in the middle"。LLM 对长上下文中间位置的信息,注意力会下降。塞 10 个 Chunk 进 Prompt,中间那几个经常被无视,模型只能自己脑补答案,幻觉就这么来的。
二、排查方法论:先度量再动手
调 RAG 最忌讳凭感觉改参数。正确做法是先用评估框架做体检,定位到底是哪一层出了问题。业界主流用 RAGAS 这套指标:
| 指标 | 测什么 | 出问题说明 |
|---|---|---|
| Context Precision | 检索回来的内容里,真正相关的占比 | 低 → 检索层召回质量差 |
| Context Recall | 应该召回的内容,召回了多少 | 低 → 检索层漏召回,可能 Chunk 切坏或知识缺失 |
| Faithfulness | 答案是否忠于检索内容 | 低 → 生成层有幻觉,LLM 没老实引用上下文 |
| Answer Relevancy | 答案是否切题 | 低 → 生成层跑题,可能是 Prompt 模板问题 |
排查流程一般是这样:
- 第一步:拿一批标注好 "问题—标准答案—相关文档" 的测试集,跑 RAGAS。
- 第二步:看四个指标哪个低。
- Context Recall 低 → 知识库和检索层的问题,回去查 Chunk 和 Embedding。
- Context Precision 低 → 检索精度问题,上 Rerank 或调 Top-K。
- Faithfulness 低 → 生成层在瞎编,查 Prompt 模板、换更强的 LLM、做引用约束。
- Answer Relevancy 低 → Prompt 模板要改,或者 Query 改写没做好。
- 第三步:定位到具体层,再针对性地改。
能把这一套讲清楚,面试官基本就知道你真做过 RAG 评估,不是只跑过 Demo。
三、检索优化三板斧:前置改写、混合检索、后置重排
检索层是优化空间最大的一层。按管线顺序走,通常有三招:
前置阶段做 Query 改写。原始 Query 往往口语化、信息量不足,有三种改写思路:
- 同义改写:用 LLM 把 "怎么部署" 改成 "应用的部署流程、安装步骤、上线方法",再用多个改写结果并行检索,结果取并集。
- HyDE(Hypothetical Document Embeddings):让 LLM 先根据 Query 编一个 "假想答案",再拿这个假想答案的向量去检索。背后的逻辑是,答案和文档的语义更接近,比拿问题直接检索更准。HyDE 在知识库风格化写作、技术文档这类场景效果不错,但要注意它会拉高首 Token 延迟。
- 子问题分解:复杂问题拆成多个子问题分别检索。比如 "对比 A 和 B 两款数据库的优缺点" 拆成 "A 的优缺点" 和 "B 的优缺点" 分别查。
检索阶段上 Hybrid Search:BM25(关键词)+ Dense(向量)双路召回,用 RRF(Reciprocal Rank Fusion)算法把结果融到一起。这基本是生产环境的标配,纯向量检索覆盖不了专有名词、代码、型号这种字面敏感的查询。
后置阶段加 Rerank:先召回 Top-50,用 Cross-Encoder 精排到 Top-5 再喂给 LLM。Cross-Encoder 比 Bi-Encoder 慢,但精度高,因为它把 Query 和 Doc 拼一起做联合编码。常用的 Rerank 模型有 bge-reranker-v2-m3、Cohere Rerank。
四、Java 落地:LangChain4j 的检索增强管线
LangChain4j 在 RAG 这块抽象做得比较完整,RetrievalAugmentor 接口把整个检索增强流程拆成了几个能单独替换的组件:
import dev.langchain4j.rag.RetrievalAugmentor;
import dev.langchain4j.rag.DefaultRetrievalAugmentor;
import dev.langchain4j.rag.query.transformer.QueryTransformer;
import dev.langchain4j.rag.content.retriever.ContentRetriever;
import dev.langchain4j.rag.content.aggregator.ContentAggregator;
import dev.langchain4j.rag.content.injector.ContentInjector;
// 1. ContentRetriever: 负责检索(可组合多个,做 Hybrid Search)
ContentRetriever vectorRetriever = EmbeddingStoreContentRetriever.builder()
.embeddingStore(embeddingStore)
.embeddingModel(embeddingModel)
.maxResults(20) // 先召回多一点,留给 Rerank 筛
.build();
// 2. QueryTransformer: Query 改写(LangChain4j 内置 ExpandingQueryTransformer 做多查询扩展)
QueryTransformer queryTransformer = ExpandingQueryTransformer.builder()
.chatLanguageModel(chatModel)
.n(3) // 把一个 Query 改写成 3 个变体
.build();
// 3. ContentAggregator: 多路召回结果聚合,可用 RRF 融合
ContentAggregator aggregator = DefaultContentAggregator.builder()
.reciprocalRankFuser() // 用 RRF 融合多路检索结果
.build();
// 4. 组装成 RetrievalAugmentor
RetrievalAugmentor augmentor = DefaultRetrievalAugmentor.builder()
.queryTransformer(queryTransformer)
.contentRetriever(vectorRetriever)
.contentAggregator(aggregator)
.contentInjector(DefaultContentInjector.builder().build())
.build();
// 5. 挂到 AI Service 上
Assistant assistant = AiServices.builder(Assistant.class)
.chatLanguageModel(chatModel)
.retrievalAugmentor(augmentor)
.build();
这套结构的好处是每个环节都能单独换:检索不行换 ContentRetriever,Query 不行换 QueryTransformer,聚合不行换 ContentAggregator。排查的时候也方便做 A/B 对比,把某个组件换掉,看指标怎么变。
Rerank 这块 LangChain4j 没做原生抽象,一般是自己实现一个 ContentRetriever,内部先做向量召回,再调 Rerank 模型精排。
五、几个常被忽视的坑
-
Embedding 和 LLM 别混在一起评估:检索差和生成差得分开看,不然改半天都不知道是哪头的功劳。RAGAS 那四个指标就是干这个用的。
-
知识库质量永远比算法重要:再花哨的检索策略,也救不了一份切得稀烂、解析丢数据的语料。上线前花点时间做 Chunk 质量人工抽检,比堆算法收益高得多。
-
别忘了加缓存:Query 改写、Embedding 计算、检索结果这些环节都值得加缓存。RAG 的延迟大头经常不在 LLM 生成,而在检索管线本身。
-
"Lost in the middle" 得主动应对:要么减少塞进 Prompt 的 Chunk 数(靠 Rerank 提精度),要么上 LongLLMLingua 这类上下文压缩方案,要么把最相关的 Chunk 放在 Prompt 的头尾位置。
面试高频追问
-
Faithfulness 低一定是 LLM 的问题吗?
不一定。也可能是检索召回了错的内容,LLM 老实引用了错的。排查时要把 Context Precision 和 Faithfulness 放一起看,才能分清是检索带歪的,还是 LLM 自己跑偏的。
-
HyDE 什么时候用,什么时候别用?
知识库是技术文档、风格化写作这种 "文档语言和问题语言差异大" 的场景,HyDE 收益比较明显。但事实型问答、实时数据查询别用,LLM 编出来的假想答案可能把检索带歪。另外还得算一下延迟成本能不能接受。
-
Rerank 模型怎么选?
中文场景可以看
bge-reranker-v2-m3、Cohere Rerank Multilingual;预算够、想要极致精度,可以试试Qwen3-Reranker。选型标准是 MTEB/BEIR 榜单加上自己业务测试集上的实测,别只看榜单。
常见面试变体
- "RAG 答非所问,怎么排查?"
- "检索召回率低怎么办?"
- "RAG 怎么避免幻觉?"
- "如何评估 RAG 系统效果?"
记忆口诀
失败三层:数据脏、检索弱、生成飘。
排查四指标:Precision 看精度、Recall 看召回、Faithfulness 看忠实、Relevancy 看切题。
优化三招:前置改写补 Query、Hybrid 双路补语义、Rerank 精排补精度。
总结
RAG 的失败模式按数据、检索、生成三层拆解,排查靠 RAGAS 的四个量化指标定位病根,优化沿检索管线做 "前置改写 + Hybrid Search + Rerank" 三连。面试时把失败画像、量化排查、Java 框架落地串起来讲,再点出 "lost in the middle" 和 "知识库质量优先" 这两点,分数就稳了。
