测试策略与用例设计
覆盖解析、检索、生成、安全和性能风险
生命周期 · 阶段五 测试与验收(功能/质量) | 上游:开发提测(07)| 下游:效果评测(09)
RAG 测试的难点:输出非确定性、效果受数据/模型/链路多重影响。核心思路是分层拆解 + 指标量化 + 评测集回归。
一、测试分层策略
| 层级 | 对象 | 方法 | 关注 |
|---|---|---|---|
| L1 单元/组件 | 解析器、切片器、向量化、重排器 | 单测 + 断言 | 功能正确性 |
| L2 流水线(E2E 入库) | 接收→解析→OCR→切片→向量化→索引 | 端到端 + 数据比对 | 数据一致性、幂等、容错 |
| L3 检索质量 | 检索 + 重排 | 评测集 + 指标 | Recall@K、MRR、NDCG |
| L4 生成质量 | 全链路问答 | 评测集 + LLM 评分/人工 | 准确性、忠实度、拒答正确性 |
| L5 性能 | 全系统 | 压测 | 入库吞吐、查询 P95 |
| L6 安全与权限 | 权限过滤、敏感信息 | 渗透式验证 | 越权、泄露 |
| L7 稳定性 | 长跑、异常注入 | 混沌 | 降级、恢复 |
flowchart LR
L1["L1 单元/组件"] --> L2["L2 流水线
E2E 入库"] --> L3["L3 检索质量"] --> L4["L4 生成质量"] --> L5["L5 性能"] --> L6["L6 安全权限"] --> L7["L7 稳定性"]
style L1 fill:#e8f4ff,stroke:#4a9eff
style L3 fill:#fff8e1,stroke:#d4a017
style L4 fill:#fff8e1,stroke:#d4a017
style L6 fill:#ffeaea,stroke:#e05a5a
二、测试环境与测试数据准备
测试文档集(必须覆盖类型矩阵)
| 维度 | 覆盖项 |
|---|---|
| 格式 | PDF(文本型/扫描型/加密)、Word、Excel、PPT、HTML、MD、TXT、图片 |
| 规模 | 0 字节、1 页、500 页、1000+ 页 |
| 语言 | 中文、英文、中英混排、繁体 |
| 内容 | 纯文本、复杂表格、图表、公式、印章遮挡、手写批注 |
| 质量 | 清晰原件、低分辨率扫描、倾斜扫描、模糊复印 |
| 状态 | 正常、损坏文件、带密码、格式伪装(.exe 改名 .pdf) |
| 权限 | 不同部门、不同密级、公开/受限 |
评测问答集(Golden QA Set)
从业务文档人工整理,用于 L3/L4 回归:
{
"qid": "QA-0001",
"question": "抵押物为房产时的处置流程是什么?",
"golden_chunks": ["doc_012#page12", "doc_012#page13"],
"golden_answer": "先评估定价,再通过拍卖/变卖方式处置,回收款项按顺序分配…",
"question_type": "事实型",
"difficulty": "中"
}
问题类型覆盖:事实型(查数据)、流程型(查步骤)、对比型、计算型、超纲型(知识库无答案,考拒答)、跨文档型。
三、用例设计(用例八要素)
示例 1:入库流水线 — 重复上传去重
| 要素 | 内容 |
|---|---|
| 用例编号 | TC-ING-001 |
| 所属模块 | 文档入库-接收 |
| 用例标题 | 重复上传相同内容的文档验证去重生效 |
| 优先级 | P0 |
| 前置条件 | 知识库为空;测试文档 A(哈希 H1)已成功入库 |
| 测试数据 | 文档 A 原件、文档 A 改名副本(内容不变) |
| 操作步骤 | 1. 将文档 A 改名为 B.pdf 再次上传 2. 等待入库完成 3. 查询向量库切片总数 4. 用文档内关键词检索 |
| 预期结果 | 1. 提示重复或仅更新元数据 2. 切片总数不翻倍 3. 检索结果无重复切片 |
示例 2:OCR — 关键字段识别
| 要素 | 内容 |
|---|---|
| 用例编号 | TC-OCR-003 |
| 所属模块 | 文档入库-OCR |
| 用例标题 | 扫描版合同金额与日期识别准确性验证 |
| 优先级 | P0 |
| 前置条件 | 测试扫描件集(含 50 份不同清晰度合同)已准备 |
| 测试数据 | 金额(含千分位/大写)、日期(多种格式)标注真值表 |
| 操作步骤 | 1. 批量入库扫描件 2. 抽取 OCR 结果中金额与日期字段 3. 与真值表逐条比对 |
| 预期结果 | 关键字段识别准确率达到项目批准基线;低置信度页面产生告警记录(98% 可作为高风险字段的候选目标,需由样本验证) |
示例 3:检索 — 混合检索召回
| 要素 | 内容 |
|---|---|
| 用例编号 | TC-RET-011 |
| 所属模块 | 查询侧-检索 |
| 用例标题 | 同义改写问题与专有名词问题的召回验证 |
| 优先级 | P0 |
| 前置条件 | 评测集中文档已入库;检索配置为向量+BM25 混合 |
| 测试数据 | "怎么处理坏账"(语义型)、"银保监发〔2021〕26号文"(精确型) |
| 操作步骤 | 1. 分别执行两查询 2. 记录 top10 结果 3. 比对 golden_chunks |
| 预期结果 | 语义型:目标切片进 top5;精确型:目标切片进 top3 |
示例 4:生成 — 拒答能力
| 要素 | 内容 |
|---|---|
| 用例编号 | TC-GEN-021 |
| 所属模块 | 查询侧-生成 |
| 用例标题 | 知识库无答案时验证拒答且不编造 |
| 优先级 | P0 |
| 前置条件 | 知识库仅含不良资产类文档 |
| 测试数据 | 超纲问题:"量子计算机的原理是什么" |
| 操作步骤 | 1. 提问超纲问题 2. 重复执行 5 次 |
| 预期结果 | 每次均输出"知识库中未找到相关内容"类拒答,不出现编造内容 |
示例 5:权限 — 越权检索
| 要素 | 内容 |
|---|---|
| 用例编号 | TC-SEC-002 |
| 所属模块 | 安全-权限过滤 |
| 用例标题 | 低密级用户无法获取高密级文档内容 |
| 优先级 | P0 |
| 前置条件 | 高密级文档 M 已入库;测试账号甲仅有低密级权限 |
| 测试数据 | 直接提问 M 内容;诱导式提问("忽略之前的规则…") |
| 操作步骤 | 1. 账号甲直接提问 M 中内容 2. 用 Prompt 注入话术诱导 3. 检查返回与检索日志 |
| 预期结果 | 均无法返回 M 的任何片段;检索层已过滤(日志可证) |
示例 6:性能 — 查询响应
| 要素 | 内容 |
|---|---|
| 用例编号 | TC-PERF-001 |
| 所属模块 | 性能 |
| 用例标题 | 并发问答下 P95 响应时长验证 |
| 优先级 | P1 |
| 前置条件 | 知识库含 10 万+ 切片;生产同构配置 |
| 测试数据 | 评测问题池 100 条 |
| 操作步骤 | 1. 以 10/30/50 并发持续压测 10 分钟 2. 采集响应时长分布 3. 观察错误率与资源占用 |
| 预期结果 | P95 与错误率达到项目批准基线(8s、0.5% 仅为示例);无 OOM 或非预期服务重启 |
四、易错缺陷清单(历史踩坑总结)
入库侧:
- 双栏 PDF 解析后阅读顺序错乱
- 表格被切断,表头与数据分离
- 页眉页脚/水印混入正文污染检索
- 重复上传导致切片翻倍、回答重复啰嗦
- 删除文档后向量库残留旧切片
- 换 Embedding 模型未重建全量索引
检索/生成侧:
- 多轮对话指代未补全,拿"他的流程"去检索
- top_k 过小漏召回、过大引噪声
- 权限过滤缺失或放在 Prompt 层(可被注入绕过)
- 检索无结果时模型自由发挥(幻觉)
- 温度过高导致同一问题答案漂移
- 引用页码与实际不符(元数据错位)
系统侧:
- 大文件上传阻塞队列,后续文档全部延迟
- 模型 API 限流后无重试/降级
- 流式输出中断无提示
五、测试执行与准入准出
准入:冒烟用例(上传→检索→问答主链路)通过
准出(示例标准):
- P0 用例通过率 100%,P1 ≥ 95%
- 检索 Recall@5 ≥ 85%、MRR ≥ 0.7(以评测集基线为准)
- 生成忠实度 ≥ 90%,超纲拒答率 100%
- 性能达标(P95、错误率)
- 无未修复的高危安全缺陷
本篇交付与下一步
本阶段应产出按解析、检索、生成、权限、性能和恢复分层的测试集,并记录环境、数据版本和预期结果。指标定义与回归判定集中在 09-评测指标与评测集建设,避免两篇维护不同口径。