系列:RAG 评测工程(0026 实践复盘)·
对应原始记录:memory/0026 阶段 C9(2026-09-07)+ 0027 用例 tag 体系,完整代码及过程记录见开源仓库ai-study-helper , 背景产品定位和边界梳理见目标与边界梳理
30 秒判断
如果你通过调好"文章对 A×B"上的一个 RAG 问题,得出了"检索修好了"的结论,先别庆祝——换一对文章,红因可能根本不在检索。
我们为了防止过拟合到某一对文章,专门设计了一个"换文章"的泛化探针(rag-cmp-005),结果红基线 20/20 fail,但红因构成出乎意料:主要是引用压力(citation 19/20 fail),不是检索(检索信号基本正常)。进一步验证发现,同一用例各 attempt 的注入块完全相同,覆盖矩阵的波动来自生成侧"该写没写"。
由此定下一条判据纪律:探针转绿要拆两个信号——检索信号(白盒充分性无 S2)与生成信号(覆盖 repeat 多数 + 引用红线通过)。只看"覆盖矩阵全绿"会误判检索已修好。
1. 动机:防止过拟合到一对文章
我们的主战场用例 rag-cmp-002 是"OpenAI《Harness engineering》× Anthropic《How we contain Claude》"的跨文档宽问法对比。调好它之后,一个尖锐的问题摆在面前:你是修好了"跨文档宽问法"这一类问题,还是只修好了 O2×A5 这一对文章?
检索策略是固定的、判官是冻结的,如果只在这对文章上验证,任何"修复"都可能只是对这对文章内容的特判。于是我们起草了一个换文章探针 rag-cmp-005:
- 换成 Anthropic《Building Effective Agents》× OpenAI《A Practical Guide to Building Agents》(A1×O1);
- 点表按两文真实章节新写(4 core + 6 ext),不照抄 cmp-002;
- query 用自然全景问法,不点名章节术语——防止检索靠词面命中、掩盖真正的语义定位能力。
预期:如果 cmp-002 的红因(宽问法下检索不充分,S2)是这一类问题的共性,005 应该同样大面积 S2。
2. 打脸现场:红因构成完全出乎意料
Run#135 红基线:20/20 fail,但构成是——
- citation_truth 19/20 fail(典型:引用块 [10] 只是来源行、没有正文,却去支撑一条具体描述);
- answer_correct 12/20 fail(o1-c1 11 缺、o1-e1 12 缺);
- format 20/20 pass;
- 白盒卡点:S2×5 / S3×7——检索确实有缺口,但不是主红因。
结论:A1×O1 的 query 词天然贴近文档主题,检索相对充分;红主要由引用与综合过度断言驱动。换文章并不天然等于换到同类根因(S2)——探针必须按实际红因归类,而不是按"我们当初设计它时的假设"归类。
术语锚 · S2/S3(白盒检索充分性三态):S1 = 本次注入的证据已足以支撑该要点(锅在生成);S2 = 注入里没有、但整个知识库里有(锅在检索/注入);S3 = 全库也没有(语料缺口或金标准期望过高)。白盒只在金标准判 fail 后按需启用,产出归因不产新判分。
3. 更深的发现:注入一致,覆盖却波动
如果红因在检索,那么同用例的不同 attempt 应该共享同一批注入块(检索策略固定)。我们抽查 Run#135 的 UI#1/#2/#6/#11:注入块完全相同(16 块签名逐条一致)——检索没变。
但覆盖矩阵上 o1-c1 有的 attempt covered、有的 not,输出长度无规律。这说明什么?
覆盖波动来自生成侧的包含性取舍(采样),不是检索差异,也不是判官噪声。 同样的材料喂进去,模型这次写了那个点、下次没写——这是 Agent 生成行为的问题,不是检索的问题。
这个发现直接拆掉了一个常见误判链:"覆盖矩阵没全绿 → 检索没修好"。如果按这个链去修检索,你会修一个不存在的问题——料其实已经给了,是模型没写。
4. 判据拆分:双信号转绿
于是"覆盖矩阵全绿"作为检索修复的充分判据被否掉。绿需要两个条件同时成立:
- 材料进上下文(检索信号):白盒充分性卡点从 S2/S3 变全 S1;
- 模型把材料写进回答(生成信号):覆盖按 repeat 多数(如每点 ≥18/20)+ 引用红线通过。
对应地,探针也要按"主要验证哪个根因层"来分类管理:
| 探针 | 素材/问法 | 实测红因 | 定位 |
|---|---|---|---|
| cmp-002/003/004 | O2×A5 宽问法 | S2 检索 | 检索类验证组 |
| rag-cmp-005 | A1×O1 宽问法 | 引用压力为主 | 跨文综合 + 引用压力 |
| rag-cmp-006 | O2×A5 局限切面(窄问法) | 引用(覆盖 20/20 绿) | 引用压力 |
| rag-cmp-007 | O2×A5 角色切面(窄问法) | 引用 + 少量综合 | 综合 + 引用压力 |
注意 006/007 是窄问法(直问切面),覆盖全绿、红全在引用——进一步证明"引用压力"是一类独立的、与问法宽窄无关的根因,值得单独一档探针。
5. 可带走的清单
- 换文章是防过拟合的必要动作,但不是充分验证:换文章后必须重查红因构成,别假设根因跟着你走;
- 探针按实测红因归类,不按设计意图归类:同是"跨文档对比",有的测检索、有的测引用——用 tag 显式标注"验证=检索/引用/生成",避免混用;
- 转绿判据按信号拆分:检索信号看白盒(S2/S3 → S1),生成信号看覆盖 repeat 多数 + 引用红线;"全绿"本身不指向任何单一根因;
- 注入一致性是廉价而有力的诊断:检索策略固定时,抽查几个 attempt 的注入块签名是否一致——一致而覆盖波动,锅在生成侧;
- query 设计防检索泄漏:泛化探针的 query 不点名章节/术语,否则你会测到"词面匹配"而不是"语义定位";
- 探针家族要防套件膨胀:一根因一类,只留代表——005 扛"跨文综合 + 引用压力",006/007 各扛一个切面,不再为每个新素材复制一整套。
6. 边界声明
- 注入一致性的结论基于抽查(UI#1/#2/#6/#11),不是全量逐 attempt 签名比对;全量统计更稳但成本高;
- "≥18/20"是生成信号的噪声容忍线,需按项目对波动容忍度重标;
- 本文的"检索信号 = 白盒无 S2"依赖白盒充分性诊断的可靠性;白盒本身是窄 LLM 判官 + 确定性来源检查的组合,边界见 0026 白盒记录。
- 从"判官系列"到"检索架构"的桥:005/006/007 暴露的引用压力背后,是宽问法下"该引用哪些材料"本身对检索结构的挑战——那是下一篇文章(检索增强的存储结构设计)的素材。
完整跑批数据(Run#135/136/137)、用例 JSON(rag-cmp-005/006/007 的 notes/admin_note)与注入一致性验证脚本见开源仓库 ai-study-helper。