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+ 小伙伴加入学习,欢迎点击围观

面试考察点

  1. 故障画像能力:你能不能按 RAG 的管线把失败点拆开讲?数据层、检索层、生成层各自有啥典型病症,得能说清楚。

  2. 排查方法论:RAG 答得不好,到底是检索没召回,还是召回了但 LLM 没用上?得会用数据说话,凭感觉调参不行。

  3. 优化手段储备:Query 改写、HyDE、Hybrid Search、Rerank、上下文压缩……这些手段你用过哪些,分别适合什么场景?

核心答案

RAG 的失败原因挺杂,按管线可以分成三大类,对应三种不同的病根:

失败层 典型症状 根因
数据/索引层 检索结果牛头不对马嘴、知识缺失 文档解析丢内容、Chunk 切分不当、知识库过时、元数据缺失
检索层 召回的 Chunk 跟问题相关度低、关键信息没召回 Query 与 Doc 语义鸿沟、Top-K 太小、Embedding 模型不适配、缺少 Rerank
生成层 答非所问、出现幻觉、引用编造 Prompt 模板不清、上下文窗口溢出、"lost in the middle"、LLM 忽略检索内容

排查思路就一句话:先用量化指标定位是哪一层出了问题,再对症下药。凭感觉调参是 RAG 调优最容易栽的坑。

深度解析

一、按管线拆解失败模式

RAG 失败模式:数据层、检索层、生成层
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。

三、检索优化三板斧:前置改写、混合检索、后置重排

检索层是优化空间最大的一层。按管线顺序走,通常有三招:

检索优化:前置改写、Hybrid Search、Rerank
检索优化:前置改写、Hybrid Search、Rerank

前置阶段做 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 的头尾位置。

面试高频追问

  1. Faithfulness 低一定是 LLM 的问题吗?

    不一定。也可能是检索召回了错的内容,LLM 老实引用了错的。排查时要把 Context Precision 和 Faithfulness 放一起看,才能分清是检索带歪的,还是 LLM 自己跑偏的。

  2. HyDE 什么时候用,什么时候别用?

    知识库是技术文档、风格化写作这种 "文档语言和问题语言差异大" 的场景,HyDE 收益比较明显。但事实型问答、实时数据查询别用,LLM 编出来的假想答案可能把检索带歪。另外还得算一下延迟成本能不能接受。

  3. 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" 和 "知识库质量优先" 这两点,分数就稳了。