| name | compliance-judgment |
| tier | meta |
| description | Determine whether extracted entities comply with verification rules. Use after entity extraction to make the pass/fail judgment for each rule on each document. Covers translating natural language rules into executable logic, choosing between Python calculation and LLM semantic judgment, and producing actionable comments on failures. Also use when designing the judgment step of a workflow or when a rule's judgment logic needs debugging. |
合规判定
判定是真相到来的时刻。你已经拿到抽取出来的实体,也有规则在手。它们是否合规?答案必须清晰、正确,并且——当答案为否时——附带一条简洁、可执行的说明。判定环节直接决定整个核查工作流的最终产出质量:抽取做得再细,如果判定阶段含糊或前后不一,下游的合规报告就难以使用。
判定光谱
规则的复杂度跨度很大,从纯粹的确定性检查到深度语义判断都有。要为每条规则挑选合适的工具,不能一刀切。
确定性判定 —— 阈值核查、格式校验、日期运算、跨字段一致性。纯 Python 就够:免费、即时、可复现,并且同一份输入永远给出同一份结果,便于审计与回溯。
语义判定 —— 是否充分披露、是否完整、前后是否一致、是否符合模板、是否存在误导性或暗示性表述、描述是否公允平衡。这类判断需要语言理解能力,规则关键词法或模式匹配无法胜任,应直接使用 worker LLM 完成。
很多真实的合规规则都需要语义判定。"风险揭示必须充分描述主要风险"无法用正则或 Python 核查;"合同描述不得具有误导性或暗示性"需要深层的语言理解;"资产管理产品的宣传材料不得含有承诺收益的暗示"同样如此。这类场景应毫不犹豫地调用 worker LLM,强行用规则匹配反而会牺牲准确率。
也有些规则会两者并用:先抽取数值(确定性),再与阈值比较(确定性),如果结果处于临界区间,再对其解释做语义评估。这种"Python 主跑、LLM 兜底"的组合往往是性价比最高的方案。具体如何组合,取决于规则本身。
正确的方法,是以最低成本达到所需准确率的那一个。简单的阈值核查不需要 LLM,语义评估也无法靠 Python 完成。多数项目都会两者混用——让每条规则的性质决定其判定方法,而不是反过来用方法去硬套规则。
输出格式
对每个"规则 × 文档"的组合:
{
"rule_id": "R001",
"document": "report_2024_q1.pdf",
"result": "pass | fail | missing | error | uncertain",
"extracted_value": "12.5%",
"expected": ">= 8.0%",
"comment": "",
"confidence": 0.95
}
结果取值:
- pass:实体符合规则要求。
- fail:实体不符合规则要求。必须填写 comment。
- missing:文档中未找到该实体。这与 fail 不同——信息缺失,并不代表违规。
- error:抽取或判定过程出现异常(解析失败、API 错误等)。需要排查。
- uncertain:判定结果存在歧义,可能需要人工复核。
先设计退出条件: 在为一条规则编写判定逻辑前,先把退出条件定义清楚:什么算 pass、什么算 fail、什么情况下需要升级到人工、空值/缺失值如何处理、合法的取值范围是什么。显式的退出条件能避免判定模糊或前后不一致,也方便后续在进化循环中复盘判定逻辑的盲区。
Prompt 设计: 提示词要正向描述你想要什么,而不是反向描述你不想要什么。"不要包含推理过程"远不如在结构化输出里抽取判定结果可靠。模型对否定指令的遵循度普遍偏低,不如直接约束输出字段、再用后处理过滤把多余内容去掉。
Comment 写法:
- 仅在 result 为
fail 时必须填写。pass 时不写,除非开发者用户明确要求记录通过项的说明。
- 简洁、陈述事实:"资本充足率为 7.2%,低于 8.0% 的监管最低要求。"
- 不做评论性发挥:不要写"这是严重违规,可能招致处罚"。只陈述事实即可。
- 在 comment 中给出抽取值和期望值/条件,便于读者理解上下文。
轻量标注语法
为了便于人工复核、节省日志 token、做干净的 diff 比对,结果也可以用紧凑的文本标注形式表达:
[PASS] capital_adequacy <- 12.5% (>= 8.0%) | conf:0.95 | src:p3-s2
[FAIL] sign_date_gap <- 75d (<= 30d) | conf:0.90 | src:p1-s4 | note:Signing overdue by 45 days
[MISSING] collateral_value | conf:0.60 | note:Collateral valuation not found in document
这一格式与上面的 JSON 格式可无损互转。在以下场景使用:向开发者用户展示结果以便快速过目、写入进化迭代摘要等对 token 经济敏感的日志、在多次核查运行之间计算 diff 以发现回归。完整规范和转换规则参见 references/output-format.md。
判定执行顺序
部分规则会依赖其他规则的结果:
- 规则 B 可能只在规则 A 通过时才适用。"如果借款人是新客户(规则 A),则需要额外的文件资料(规则 B)。"
- 规则 C 可能要复用规则 A 计算出的数值。"风险加权资本充足率(规则 A)决定了所需的准备金水平(规则 C)。"
把这类依赖关系登记在规则目录中,最好以显式的依赖图形式维护。按依赖顺序执行规则,把上游规则的结果作为上下文传给下游规则,避免下游规则在缺少前置真值时拿到错误的输入。
边界情况处理
- 抽取为空:实体未找到。默认归为
missing,而不是 fail。值缺失属于抽取问题,不是合规问题。
- 多值情况:文档在多处出现同一实体,但取值不一致。标记为
uncertain,并把所有找到的值连同各自的位置都报出来,便于人工复核时定位差异源头。
- 条件规则:"如果贷款金额超过 100 万,则必须有担保。"先核查条件再套用规则。条件不成立时规则不适用——结果记为
pass(如果你额外引入了 not_applicable 类别,也可以使用)。
- 否定型规则:有些规则核查的是"不存在"。"文档中不得存在向关联方提供的担保。"搜索"不存在"比搜索"存在"难,因为要先证伪所有可能的命中位置才能下结论。先把搜索做彻底,再对否定结论保持信心。
跨文档的置信度阈值一致性
对一条要跨多文档判定的规则(常见情况),"通过"的置信度阈值必须在所有文档上保持一致。一条在文档 A 上要求 0.85 置信度才能通过、在文档 B 上只要 0.75 的规则,其实是两条规则伪装成了一条。
当 worker LLM 当判官时,把阈值写在 prompt 里或者写在后处理里,不要 "让 LLM 自己每次决定"。LLM 调用之间的随机性意味着每一次调用都会落到分布上的某个点;你的工作是把分布必须越过的那条线划出来。
两种落实方式:
- 写在 prompt 里:明确写"只有置信度高于阈值才输出 PASS"。便宜,但易受 LLM 多次调用之间漂移影响。
- 写在后处理里:让 LLM 分别输出 verdict 和 confidence,再用一小段 Python wrapper 应用阈值。更可靠,引擎看到的是代码层面的阈值,不是 prompt 文本。
对有稳定模式的规则(格式、存在性核查),优先用后处理。对主观判断(充分性、完整性),prompt 层面的阈值更好写,但值得审计 —— 抽样一个批次看 LLM 有没有遵守那条线。
confidence-system skill 描述了置信度怎么从多个信号合成;本节讨论的是怎么把它在同一规则的不同文档之间一致地应用。