☰
RAG中badcase分析
2026/10/17 6:55:08 网站建设 项目流程

目录

1.常见指标:

1.1指标之间区别

疑问一

例子

2.badcase分析

2.1 回答与问题高度相关,但事实错误。

2.2正确答案在库里但没进 top5

2.3 rag中用户提问一直检索不到正确的内容你怎么进行排查


在项目的评测阶段,badcase 分析往往是项目调优的关键环节。


1.常见指标:

context_precision上下文精确度:检索出来的片段里,正真和问题相关的占比;低=检索的噪声大,混入很多无关的文档块

context_recall上下文召回率:知识库中正真相关的片段,有没有被检索出来;低:相关问题答案没有找全

faithfulness忠诚度:大模型回答是否严格依据检索到的上下文,不变编造信息;低=模型幻觉在编瞎话

response relevancy回答相关性: 生成的答案是否贴切用户问题

Answer Correctness正确性/相似度:当你有参考答案(ground truth)时可用;没有参考答案时通常以 Faithfulness/Context 相关指标为主。

1.1指标之间区别

1.1.1召回率和精确度定义上的区别:

都是比较rag检索出来的上下文质量但是其中:

Context Recall(上下文召回率):以标准答案为参照,看标准答案里的知识点被召回了多少。

Context Precision(上下文精确度):以检索结果为参照,看检索出来的 Chunk 有多少是相关的,以及相关 Chunk 的排名。

Recall 关注有没有漏掉重要知识,Precision 关注召回结果中有多少有效信息,以及排序是否合理。Recall 和 Precision 确实都关注有效信息,但它们统计的对象不一样。

疑问一

假设你的项目中,用户提问:

A-100 产品安装需要哪些步骤?

知识库中的标准答案有 6 个步骤:

情况一:只召回一个 Chunk

检索结果:

retrieved_contexts = [ "步骤1:检查设备;步骤2:安装底座;步骤3:连接电源" ]

此时:

Context Recall = 3 / 6 = 0.5

因为标准答案有 6 条,但只找到了 3 条。

Context Precision = 1.0

因为检索出来的唯一一个 Chunk 是相关的,而且排在第一名。

发现了吗?

虽然只找回了三个知识点,但是检索出来的内容没有无关信息。

所以 Recall 低,Precision 高。

情况二:召回两个 Chunk

retrieved_contexts = [ "步骤1、2、3", "步骤4、5、6" ]

此时:

  • Context Recall = 6 / 6 = 1.0

  • Context Precision = 1.0

既没有遗漏知识点,也没有无关 Chunk。

情况三:召回三个 Chunk

retrieved_contexts = [ "步骤1、2、3", "A-100产品品牌发展历史", "步骤4、5、6" ]

此时:

Context Recall = 1.0

因为 6 个知识点全部召回了。

但是 Context Precision 会下降,因为第二个 Chunk 与用户的问题无关。

按照 RAGAS 常用的排名加权精确度公式计算:

这里的数值是按简化的人工相关性标签计算的,实际 RAGAS 还需要模型判断相关性。

所以一句话总结:

Context Recall 解决的是“找得全不全”,Context Precision 解决的是“找得准不准、排得好不好”。

在 RAG Bad Case 分析中,前者主要帮助发现知识遗漏,后者主要帮助发现无关召回和排序质量问题。

例子

情况一:Precision 高,但 Recall 低

假设检索只返回三个 Chunk:

检索排名

Chunk 内容

是否相关

Top1

关闭仪表电源

相关

Top2

断开测试表笔

相关

Top3

断开被测电路

相关

此时:

  • Context Precision 很高:三个 Chunk 都相关,而且都排在前面。

  • Context Recall 较低:标准答案有 6 个知识点,却只召回了 3 个。

情况二:Recall 高,但 Precision 低

假设检索返回六个 Chunk:

检索排名

Chunk 内容

是否相关

Top1

万用表的发展历史

无关

Top2

安全事项 1、2

相关

Top3

万用表产品介绍

无关

Top4

安全事项 3、4

相关

Top5

万用表品牌信息

无关

Top6

安全事项 5、6

相关

此时:

  • Context Recall 很高:6 个知识点全部召回了。

  • Context Precision 较低:存在大量无关 Chunk,并且相关 Chunk 排名靠后。

这说明系统并没有漏召回知识,但是检索质量和排序仍然需要优化。

评测结果

说明什么问题

优化方向

Recall 低,Precision 高

召回的内容很相关,但知识不完整

扩大召回 TopK、优化 Chunk 切分、补充多路召回

Recall 高,Precision 低

知识比较完整,但夹杂无关 Chunk,排序不佳

优化 RRF 融合、Rerank 重排序

两者都低

知识既不完整,相关性也差

排查实体过滤、Embedding、文档入库和检索策略

两者都高

检索阶段整体较好

继续检查 LLM 生成质量

2.badcase分析

2.1 回答与问题高度相关,但事实错误。

用户提问 A型号的万用表测的最大电压是多少?假设正确的答案是600v,但是模型回答的是1000v

  • Faithfulness(忠实度):低
  • 上下文相关性(Context Relevance,也常和 Context Precision 挂钩):高
    • 因为ragas是这样进行计算的:根据模型的回答,反向生成问题,在比较这些问题和原始问题的相关程度

一、先判断错误发生在哪个阶段

存在两种情况:

检索文档写着600V,但是模型回答600V -----》生成阶段出现幻觉

检索到B型号,上面写着1000V -----》检索阶段召回错误

二、解决

1. 如果是检索正确但是模型回答错误:

说明模型没有严格遵循检索上下文,可以通过提示词约束,添加COT思维链,增加结构 化字段对比,来源引用和结果效验,将大模型的temperature降低等方法降低模型输出错误 的概率

2.如果检索到了错误的文档

这个时候需要优化检索链路,进行ragas测试,再结合其他指标进行判断或者结合日志

文件找到错误的位置(因为检索出来的语义比较相近A-100或A-200,所以单纯提高TopK或增

加向量检索的数量,并不能从根本上解决问题 TOP1: A-200 TOP2:A-100)

2.1 解决问题

1.商品名识别确认用户问的是谁,将用户的自然语言解析成结构化语句,提取商品名,

再和milivus商品实体匹配,将商品映射成唯一的product_id,将这个id放在切片chunk中一起向

量化

2.添加标量过滤条件,dense 和 sparse 混合检索;rrf + rerank,把正确文档排到前面。但 rrf 和 rerank 只能做排序,不能解决所有召回问题

2.1.2 但优化之后还要召回不到正确答案怎么办?

这种情况往往在知识入库阶段排查,调整文档切分策略,可以把 chunk 变成结构化语句{"product_id":"...","title":"...","text":"..."}

2.1.3 还可以添加 “跨物品误召回率”:单次检索结果中错误商品 chunk 所占比例。

此外还可以记录各阶段 TopK 结果,区分正确知识没有入库、正确知识没被召回和正确知识被召回但被排序淘汰。

2.1.4正确知识没有入库:

思路 ① 检查原始 PDF 是否包含正确知识

② 检查 minerU 解析的 markdown 是否完整

③ 检查文档切分时候有没有丢失 / 拆散参数

④ 检查 Embedding 和 milvus 入库是否成功

⑤ 检查 chunk 的 product_id,是否正确

2.1.5 知识已经入库,但没有召回?

①先检查商品标量过滤是否错误,然后再看正确文档在各路检索的排名

检索方式: Dense Top18

Sparse Top2

HYDE Top8

可以增加候选数量,调整 Dense/Sparse 比例 以及改写 query 改写。 例如将 Dense 单 检 limit 提到 20, 但 TopK 只是扩大范围,会增加开销和噪声 需要用评测数据集验证。

2.1.6 正确知识召回了,但排序淘汰了

同一个 chunk 在各阶段排名变化

Sparse 召回 → rrf 融合 → rerank

2 4 8 被 top5 淘汰

解决:chunk 的文本缺少商品名,章节标题等

重排序模型对产品参数类数据识别效果不好

Rerank 输入的 Query 丢失了关键商品型号。

候选文档存在大量相似内容。 可根据原因尝试补充 chunk 标题,优化重排序输入,调整 rerank 模型,以及进阶扩大最终 TopK。

2.2正确答案在库里但没进 top5

第 1 层:查询层(你刚说的,最表层)

① 每路口 limit:5 → 20/50,放大召回池
② 融合后 topk:同步放大(hybrid_search limit)
③ 权重:看语义路/词级路哪个更适合业务,比如 (0.7, 0.3)

第 2 层:下游截断层
就算 Milvus 返回了 10 条,后面还有三道闸门可能把正确答案砍掉:

混合检索 limit=5 → RRF [:10] → reranker 断崖(差值≥0.5) → 答案节点 2000字符

  • RRF 截断:如果多路召回,看正确答案在 RRF 融合后第几名,[:10] 会不会砍掉它;
  • reranker 断崖:正确答案向量分数不高但内容其实相关,reranker 可能给它低分,又被断崖检测切掉——这时要查 reranker 打分结果,调 0.5 阈值或修 cliff 逻辑;
  • 2000 字符:排前面但太靠后,拼提示词时被字符上限截断。

第 3 层:上游数据层(根本原因,面试加分点)

① 切分粒度:切片太长(语义被稀释)/太短(语境丢失)→ 调整 2000/500 的切分参数
② 向量化质量:embedding 模型和业务语料是否匹配(BGE-M3 对中文产品文档效果好不好,可换模型/微调)
③ 向量化输入:项目里 embed_content = item_name + "\n" + content —— 加了商品名前缀就是为了增强召回
④ 标量过滤误伤:expr = item_name in [...] —— 商品名识别错了,正确答案所在的切片直接被过滤掉,
根本没进检索!这种情况调 limit 一万次也没用
⑤ 查询侧:rewritten_query 写得不好 → 优化重写提示词

第 4 层:检索策略层(项目已内置的补救)

① HyDE 假设文档检索——就是为"查询和文档词汇不匹配"准备的第二路(你向量路 miss,HyDE 路可能 hit)
② 多路召回 + RRF——单路漏了,另一路补上

三、面试推荐话术

"我会先定位问题出在哪一层,而不是直接调参数。第一步看这条正确答案的切片在不在召回候选里——如果压根没被检索到,先查是不是标量过滤把它挡了,再查向量化质量(embedding 输入、切分粒度);如果在候选里但排名低,就放大每路口 limit、调整融合权重;如果进了候选也被截断,就查下游的 RRF 截断和 reranker 断崖。参数层面 limit 是召回旋钮、权重是排序旋钮,两者作用不同。另外项目里我们有多路检索加 HyDE 兜底,单路 miss 还有第二路补。"

2.3rag中用户提问一直检索不到正确的内容你怎么进行排查

一、排查框架(先定性,再逐层)

第一步:定性 —— 个别问题,还是所有问题都检索不到?
├─ 个别 query 失败 → 大概率数据/过滤/改写问题(针对这条查)
└─ 普遍失败 → 大概率切分/向量化/embedding 模型问题(系统性)
│
第二步:逐层排查(顺着检索链路从入口到出口)
│
第三步:对照实验定位(构造标准问法测试)
│
第四步:对症修复

二、结合项目的逐层排查清单
顺着我们项目的链路一层层查:

用户问题 → 商品名确认 → 三路检索 → RRF → reranker → 答案生成

层排查问题项目排查手段
① 商品名确认商品名提取对了吗?重写问题对吗?看日志里 LLM 返回的 item_names /rewritten_query(节点有 print)
② 商品名确认商品名被 0.7 阈值拒绝了吗?直接返回 "当前问题无法识别"= 短路了,问题在商品名库或提取
③ 标量过滤item_name in [...] 把正确切片挡了吗?检查库里正确切片的 item_name 和查询的 item_names 是否一致(商品名写错字、别名不一致都会漏)
④ 检索分数正确切片的相似度分数是多少?排第几名?单独把正确切片向量化算相似度 —— 分数低 = 向量化 / 改写问题,分数高但没进 top5 = 截断问题
⑤ 数据入库正确文档真的入库了吗?查 chunks.json 备份、Milvus 直接按主键 / 条件查这个切片在不在
⑥ 切分质量正确答案被切碎 / 切混了吗?看切分结果:答案内容是否完整在一个切片里,还是和无关内容混在一起
⑦ 下游截断进了候选但被砍掉了吗?查 RRF 融合后的名次、reranker 打分数、断崖切点、2000 字符截断
⑧ 模型适配embedding 模型适合业务语料吗?BGE-M3 对中文产品手册的效果,必要时换模型 / 微调做对比

三、两个对照实验(面试加分项)
实验 1:标准问法测试(区分"查询问题"还是"数据问题")

拿一条和正确答案高度相似的"标准问法"直接检索:
├─ 能召回 → embedding 和数据没问题 → 问题在查询重写/口语化
│ (用户问法太口语,rewritten_query 质量差)
└─ 也召不回 → 问题在数据侧 → 查切分/向量化/入库

实验 2:单节点直测(项目每个节点都有 __main__)

不要跑全链路,单独测:
├─ 单测检索节点:固定 rewritten_query 和 item_names,看返回什么(隔离上游变量)
├─ 单测切分节点:喂一份已知 MD,看切片结果(隔离数据质量)
└─ 直接 milvus_client 查库:确认正确切片是否存在、向量是否正常

这两个实验的价值在于二分定位——一次排除一半可能,而不是漫无目的地调参数。

四、面试推荐话术

"我一般先定性:个别问题还是普遍问题。个别问题大概率是标量过滤或者查询改写的问题——比如商品名提取错、和库里写法不一致,正确内容被过滤条件挡在检索之外,这种情况调 topk 没用;普遍问题大概率是切分或向量化质量——比如切片把答案切碎了,或者 embedding 模型和业务语料不匹配。定位手段上我会做对照实验:拿一条和正确答案高度相似的标准问法直接检索,能召回就说明是查询侧问题,召不回就是数据侧问题;然后再逐层看,是压根没进候选、还是进了候选被 RRF 截断或 reranker 断崖砍掉。我们项目里每个节点都能单独跑、还有 chunks.json 中间备份,排查起来很方便。"

五、易错点
1. 别一上来调参数——"没进候选"和"进了被截断"的修法完全不同,先分清是召回问题还是排序问题;
2. 最容易漏的一层是标量过滤——向量分数再高,item_name in [...] 不匹配就直接出局,这是 RAG 加了过滤条件后的特有故障点;
3. "一直检索不到"要先怀疑数据侧——单个 query 失败才优先查查询侧,普遍失败时 embedding/切分/入库出问题的概率远大于参数问题。

2.4文档切分导致语义丢失时,怎么定位和优化?

先从 bad case 入手,看原文里是否有答案,再查召回结果中有没有包含关键切片。如果原文有答案但召回没有命中,重点检查切片粒度、embedding、过滤条件和 RRF;如果召回命中了但 rerank 丢掉,检查重排模型对长文本后半部分是否不敏感。优化手段包括调小 chunk、增加 overlap、保留更多 RRF 候选、提高 rerank TopK、增加标题和商品名上下文。优化后用同一批问题集复测 context_recall、context_precision 和 answer_correctness。

欢迎交流指正

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询