RAG 合成对抗集怎么做:先拆开错误前提、版本冲突与缺证据
一套RAG系统能回答文档目录里的问题,并不说明它能处理用户的真实问法。用户可能把前提说反,可能引用旧制度,也可能问到知识库从来没有收录的事项。把这些情况合在一个“准确率”里,会让修复工作失去方向。
Anthropic 在10月9日披露的评估与内部使用报告中,讨论了模型在受限任务中绕过限制的行为。这不等于我们的知识库一定会出现同类问题,但提示我们:评测需要覆盖不该完成的动作,不能只奖励“总能给出答案”。研究报告
四类样本,四种正确行为
错误前提题要纠正前提;版本冲突题要检查生效关系;缺证据题应说明无法确认;注入题要把文档内的命令当作不受信数据。它们不能共用一个“必须拒答”的标签:有证据可以纠正的题,直接拒答同样是不好的体验。
我会给每道题同时保存原始文档片段、改写问题、预期行为和关键证据。合成模型只负责扩展问法,不能自己给自己颁发正确答案。业务专家需要复核标签,尤其是旧文件是否真的失效,不能只比较发布日期。
先检查测试集本身
下面是一份不调用模型的测试集检查器。它能发现样本缺证据和标签失配,不能判断自然语言答案是否正确。为了让例子自包含,只用了四条人工教学样本。
cases = [ {"kind": "false_premise", "expected": "correct", "sources": ["p1"]}, {"kind": "old_version", "expected": "resolve", "sources": ["p1", "p2"]}, {"kind": "missing", "expected": "abstain", "sources": []}, {"kind": "injection", "expected": "ignore_instruction", "sources": ["p3"]}, ] expected = {"false_premise": "correct", "old_version": "resolve", "missing": "abstain", "injection": "ignore_instruction"} for row in cases: assert row["expected"] == expected[row["kind"]] assert bool(row["sources"]) == (row["kind"] != "missing") print("4 test families have consistent labels")检查器故意把缺证据题的sources设为空,同时要求其行为是abstain;有证据的错误前提题则是correct。这个区别可以防止“拒得越多分越高”的奖励漏洞。
跑分前先固定评分对象
Ragas的Faithfulness检查回答中的断言能否从检索上下文得到支持;它不直接证明上下文本身是现实中的真相。文档有错,回答忠实复述仍可能造成业务错误。指标定义
| 层次 | 要保留的证据 | 失败后先改哪里 |
|---|---|---|
| 资料 | 版本、生效范围、权威来源 | 文档治理 |
| 检索 | 返回切片与排序 | 召回/过滤 |
| 生成 | 回答断言和引用位置 | 提示词/生成约束 |
| 行动 | 是否调用了禁止工具 | 权限代理 |
合成样本要和真实反馈样本分开报分,开发集与最终评估集也要隔离。固定一批未参与调优的样本,保留每次模型和检索配置;否则改了问题、换了裁判又调了阈值,分数上涨究竟来自哪里就说不清。
本例验证了数据约束,没有连接RAG服务、裁判模型或真实企业文档。合成题能扩大覆盖面,不能替代业务专家对错误后果的判断。