Agent & RAG 测试工程笔记 09:从 PDF 解析到多文档污染,我踩过的 4 个坑
前言:
项目背景:
XR 教学编辑器 RAG Copilot,多 PDF 文档场景,支持 doc_id + scope 控制。
一、问题起点:我以为是检索问题
在两个 PDF 中分别加入专有信息:
A 文档:
-
XR-EDIT-A1
-
top_k 推荐设置为 3
B 文档:
-
XR-EDIT-B1
-
top_k 推荐设置为 5
目标:验证多文档是否会污染。
结果第一轮测试直接异常:
-
debug 显示 token 命中 0
-
检索全部 no-hit
-
系统正常拒答
这时候很多人会去调 top_k。
但我暂时没有。
二、P0:PDF 解析层问题(根本没进 chunks)
我加了简单的 debug:
-
扫描 chunks 中是否包含 XR-EDIT-A1
-
统计命中数量
-
输出 chunk_id
结果:命中 0。
说明:
不是检索问题,是解析层问题。
Word 转 PDF 后,连字符可能被吞掉、字符被合并,
程序实际抽取到的文本 ≠ 我肉眼看到的文本。
结论:
RAG 第一坑不是检索,是解析。
没有进 chunk 的内容,不能被检索命中。
三、P1:多文档污染(scope 只看 top1)
修复解析后进入下一阶段:
实现了多文档支持:
chunk_id 变为:
A-p1-c00
B-p1-c00
并加了 SCOPE 规则:
-
以 top1 的 doc_id 作为 dominant_doc
-
只保留同 doc_id 的 chunks
第一轮回归出现问题:
问题:
B 版本 top_k 是多少?
预期:
锁定 B
实际:
top1 命中 A → scope 锁 A → scope_leak
这不是 bug。
这是规则的天然局限。
当前规则 = 依赖 top1。
但 question 里已经有 “B 版本” 明确约束。
四、P2:显式文档约束未解析
根因:
系统没有优先解析 question 中的:
-
A 版本
-
B 版本
解决方式(最小改动):
新增 forced_doc 规则:
-
若 question 包含 “A 版本” → 强制 doc_scope=A
-
若 question 包含 “B 版本” → 强制 doc_scope=B
-
不再依赖 top1
思路:
显式约束优先级 > 检索结果
修复后:
-
scope_leak 归零
-
该类问题稳定
五、P3:跨文档对比类问题边界不清
用例:
-
请分别给出 A 和 B 的 top_k
-
哪个 top_k 更推荐?
当前系统设计本质是:
单文档回答器
SCOPE 只保留一个 dominant_doc。
对比类问题天然不适配。
如果强行回答:
-
只答其中一个
-
或误导推荐
我选择的策略是:
新增 gate:
若 question 同时包含 A + B
且含关键词:
-
分别
-
对比
-
区别
-
哪个更好
-
推荐哪个
直接:
REFUSE
reason = cross_doc_compare_not_supported
原则:
定义边界,比胡乱回答更重要。
六、P4:检索层的天然波动
即使加入 scope + forced_doc,
仍然存在一个底层现实:
关键词检索是模糊的。
泛词:
-
版本
-
课程
-
模型
容易导致 top1 波动。
所以我最终确定了多层结构:
1️⃣ 解析层
2️⃣ chunk 层
3️⃣ 检索层
4️⃣ scope 层
5️⃣ gate 层
6️⃣ 生成层
每层单独可观测。
这才是 RAG 工程的可控方式。
七、本轮回归数据
v0.4 多文档回归:
-
Overall:70%
-
ANSWER:87.5%
-
REFUSE:0%
-
scope_leak:1
加入 forced_doc + compare gate 后:
-
scope_leak:0
-
REFUSE 正常
-
整体稳定
八、结论
这轮测试让我确认三件事:
① 不验证解析层,后面全是假象
② 多文档污染不是检索问题,是 scope 策略问题
③ 显式约束必须高于检索排序
④ 对比类问题必须定义边界
项目源码(v0.4 多文档稳定版本):
https://github.com/test202005/project2_mvp/tree/v0.4-scope-stable
下一篇:
多文档 RAG 的污染怎么测 + 怎么控(Scope + Gate + 回归断言)
更多推荐


所有评论(0)