| name | cross-document-verification |
| tier | meta |
| description | 建立"跨文档核查的 rule-skill / workflow"——即判定依赖于多份文档中事实的规则。在编写或蒸馏一条需要跨文档比对实体/数值的规则时使用(主合同 + 附件、贷款申请 + 收入证明 + 银行流水 + 征信报告等)。涵盖:规则定义里必须明确的几个锚点(源文档 → 实体 → 目标文档 → 实体 → 一致性等级)、由此生成的 check.py / workflow 怎么遍历一个 case、要处理的矛盾类型、严重性分级。和 `compliance-judgment`(单文档规则)区分——KC 是 builder,不是 executor。 |
Cross-Document Verification —— 构建跨文档规则
KC 在这个阶段的工作是构建跨文档核查规则,不是在运行时执行跨文档检查。最终交付物是一条 rule-skill / workflow,将来可以被 KC 或下游系统应用到任何 case。
如果一条规则的判定依赖多份文档中的事实,这一事实就必须显式编码到规则本身。你不能写一个单文档 check.py,然后期望跨文档核查在生产时凭空发生。
规则定义里必须写清楚什么
对一条跨文档规则来说,目录条目仅有 description + falsifiability_statement 不够。它需要一条显式的跨文档路径:
- 起始文档类型:从哪类文档开始?怎么把一份文档判定为这类?(比如"贷款申请表"、"主合同"、"年度信息披露报告")
- 起始文档中的锚点实体:先抽什么?(申请人 ID、借款人姓名、合同编号、申报总金额等)
- 目标文档类型:要跨核到哪类文档?在同一个 case 里怎么定位目标文档?(共享 anchor、命名模式、起始文档里的显式引用)
- 每个目标文档中的目标实体:从目标文档里抽什么来比?字段名不一定相同 —— "月收入"在申请表上、"月均存款"在银行流水上。
- PASS 的一致性等级:在什么条件下我们判定为一致?精确相等?容差内相等?合理性检查(在另一个值的某个倍数范围内)?互引存在?
- FAIL 是什么样:硬冲突、软矛盾、还是缺失互引 —— 各自带什么严重性。
少了这五个锚点,规则就只是个愿望。有了这些,生成的 check.py 才能确定性地遍历 case。
与 compliance-judgment 的分工
compliance-judgment 处理单文档规则:读一份文档,应用规则,给出 verdict。判定可以是正则、确定性 Python、或 LLM 增强 —— 但输入是 一份文档。
本 skill 处理输入是一个 case(一组相关文档)的规则。这类规则的 check.py:
- 接收 case 级结构(文档列表 + 元数据),不是单份文档。
- 在相关文档上跑实体抽取。
- 为这条规则构建必要的对比矩阵(只包含这条规则关心的字段,不是 "所有实体 × 所有文档"的通用矩阵)。
- 应用规则定义里写明的一致性检查。
- 返回 verdict 加上驱动结论的矩阵单元(证据)。
KC 是构建者,构建这个 check.py / workflow,不是运行时执行者。下面的内容讲的是要设计什么,不是运行时要做什么。
要面向的 case 模式
两种模式覆盖了大多数跨文档规则:
-
主合同 + 附件。同一签发方,正式互相引用。主合同写总额,附件列明分项。要预期的问题:总额和分项加总不一致、引用的附件缺失或过期、主文与附件版本不匹配。
-
多源捆绑。贷款申请 + 收入证明 + 银行流水 + 征信报告 + 评估报告。不同签发方、不同格式、同一借款人/case。要预期的问题:身份信息在多份文档间漂移(姓名拼写、雇主名变体)、数值矛盾(申报收入 vs 实际收入)、可疑的一致性(多份文档版式 / 用语一致 → 可能是伪造)。
编写规则时点明它针对的是哪种模式。两种模式下 check.py 的形状不同 —— 主合同 + 附件这种期望正式引用和互引;多源捆绑这种期望做归一化(跨格式的实体协调)。
矛盾分类(规则可能需要检测的)
跨文档规则可能需要标记其中一类或多类:
硬冲突
应跨文档完全一致的字段出现精确不匹配。
- 身份字段不匹配(姓名、ID、出生日期)。
- 容差以外的金额不匹配(总额、分项、申报收入)。
- 应一致的日期不匹配(生效日期、签署日期)。
硬冲突是二元的:要么匹配(在定义的容差内),要么不匹配。
软矛盾
没有直接冲突,但放在一起看不合理的数值。
- 申报月收入是某水平,但银行流水月均存款显著低于此。
- 评估价接近贷款金额(高 LTV —— 技术上可行,但是信号)。
- 不同文档间出现多月的就业起始日差距。
软矛盾需要阈值和判断。它们是发现,不是判定 —— 规则需要明确:触发 FAIL,还是 WARNING,还是仅作为证据收集供下游复核。
互引失败
正式联结文档内部的结构完整性问题。
- 主合同引用"附件 B —— 还款计划",但附件 B 缺失或标题不同。
- 附件引用主合同某个不存在的条款。
- 缺失互引:附件引用了主合同,但主合同里没列附件。
- 版本不匹配:主合同某日期签署,附件晚得多的日期签署且条款不同。
字段级分类(带容差和严重性模板)见 references/contradiction-taxonomy.md,规则设计者可以借用。
严重性分级(由规则决定)
不是所有矛盾权重相同。规则必须说明它的发现如何映射到严重性:
| 严重性 | 典型例子 |
|---|
| Critical | 身份字段不匹配(多份文档间 ID 不同) |
| High | 显著的金额数值差异 |
| Medium | 日期或就业细节不匹配 |
| Low | 格式 / 缩写差异("ABC Corp" vs "ABC Corporation") |
具体阈值取决于业务领域。开发者用户按字段配置;规则设计应给配置留出空间,而不是把百分比写死在规则里。
规则可以揭示的欺诈信号
有些模式只有在 case 层面才能看到:
- 跨文档的一致小幅差异:每份文档都"夸大约 5%"、每个日期都精确平移一个月。这种一致性错误暗示有协调的伪造,不是诚实的笔误。
- 可疑的文档一致性:声称来自不同签发方的多份文档,使用相同版式、相同措辞、甚至相同的错别字。
- 数值卡在监管阈值上:LTV 正好压着上限,DTI 正好压着上限。一次是巧合;case 上的模式就是信号。
- 时间上的不可能:收入证明早于就业起始日;银行流水覆盖账户开立之前的期间;评估报告日期晚于贷款发放。
如果规则的工作包含这些之一,就编码进去。这些是升级信号,不是结论 —— 规则应输出"已标记"加证据,由开发者用户或下游复核流程做最终判定。
在 check.py 里怎么"走" case
一条跨文档规则的 check.py 通常这样工作:
- 接收 case(文档路径/句柄列表 + 分类元数据)。
- 选出规则声明的起始文档类型对应的文档。
- 用 entity-extraction 抽出锚点实体。
- 通过锚点或正式引用在 case 中定位目标文档。
- 从每份目标文档抽出目标实体。
- 应用规则写明的一致性检查。
- 返回:
- verdict(PASS / FAIL / WARNING / NOT_APPLICABLE)
- 证据(驱动结论的对比矩阵单元,带来源文档 + 页码引用)
- confidence(按
confidence-system)
对比矩阵是规则专属的 —— 只放这条规则需要的字段。建一个通用的 "所有实体 × 所有文档"矩阵又贵又会污染证据。
集成
规则 check.py 的运行时输入:
- case 结构(一组相关文档 + 标识)。
- 单文档实体抽取结果(skill:
entity-extraction)。
- 单文档判定结果可能已经由
compliance-judgment 产出,可作为本规则输入的一部分。
输出:
- case 级 verdict + 对应的对比矩阵切片作为证据。
对接:
confidence-system:跨文档矛盾是强信号,通常降低相关字段的置信度。
evolution-loop:规则没预见到的矛盾模式反复出现时,触发工作流改进。
dashboard-reporting:case 级视图与单文档结果并列展示。
Ground-truth 原则
当开发者用户或终端用户反馈本规则漏掉的跨文档不一致时,那条反馈优先于 agent 判定。把它记下来,作为 corner case (corner-case-management)或规则改进的触发点,并相应调整检测阈值。规则的工作是抓住人能抓住的 —— 然后再走远一步。