# leaudit-oss-yaml-files 规则体检报告 > 体检对象:`/home/wren-dev/Porject/leaudit-platform/leaudit-oss-yaml-files` > 体检时间:2026-05-21 > 体检方式:使用当前平台后端 `RuleValidator.ValidateYaml` 执行 YAML schema + DSL 语义校验,并补充扫描历史视觉写法、错误视觉字段引用、全文上下文字段引用。 ## 1. 总体结论 当前目录共有 31 份 `rules.yaml`。 | 项 | 数量 | 说明 | |----|------|------| | 总规则文件 | 31 | 合同、公文、行政卷宗规则混合 | | 可通过 schema + DSL 校验 | 21 | 可以作为后续发布候选,但仍可能存在历史兼容写法 | | 校验失败 | 10 | 不能直接发布,发布接口会被后端拦截 | | 存在历史视觉写法 | 13 | 部分能通过校验,但会影响规则编辑器正确回显/保存 | 核心问题不是租户隔离,而是规则 YAML 自身存在三类格式风险: | 风险类型 | 影响 | |----------|------| | `field: ctx` | 当前 DSL 会把 `ctx` 当成抽取字段校验,因未声明 `ctx` 导致发布失败 | | `check: visual + element` | 历史兼容写法,运行可部分兼容,但编辑器保存时容易变形成错误依赖 | | `field: visual.xxx` | 把视觉要素当普通抽取字段,属于错误配置,应迁移为正式视觉 stage | ## 2. 校验失败文件 以下 10 份当前不能直接发布。 | 文件 | 失败原因 | 直接影响 | |------|----------|----------| | `contract.construction.general/v3/rules.yaml` | `GC-OUR-001 stage 1 references unknown field: ctx` | 建设工程合同 v3 不能发布 | | `contract.entrust/v9/rules.yaml` | `MM-ENT-035 stage 1 references unknown field: ctx` | 通用委托合同 v9 不能发布 | | `contract.evaluation.delegation/0.1/rules.yaml` | `rules.1.messages/type Extra inputs are not permitted`,并包含 `field: ctx` | 委托评估合同 0.1 结构错误,不能发布 | | `contract.gift.charity/1.0/rules.yaml` | `ZY-CHY-023 stage 1 references unknown field: ctx` | 慈善赠与合同不能发布 | | `contract.gift.general/1.0/rules.yaml` | `ZY-GEN-016 stage 1 references unknown field: ctx` | 通用赠与合同不能发布 | | `contract.lease/2.0/rules.yaml` | `ZL-LEASE-036 stage 1 references unknown field: ctx` | 租赁合同不能发布 | | `contract.loan.general/1.0/rules.yaml` | `JK-OUR-001 stage 1 references unknown field: ctx` | 借款合同不能发布 | | `contract.purchase.general/1.0/rules.yaml` | `MM-OUR-001 stage 1 references unknown field: ctx`,且有 `field: visual.xxx` | 买卖合同不能发布,且视觉补救动作配置错误 | | `contract.sale/2.1/rules.yaml` | `MM-SALE-029 stage 1 references unknown field: ctx` | 销售合同不能发布 | | `contract.tech/1.0/rules.yaml` | `JS-TECH-035 stage 1 references unknown field: ctx` | 技术合同不能发布 | ## 3. 可通过但仍需迁移的文件 以下文件 schema + DSL 当前能过,但还存在历史视觉写法 `check: visual`。 | 文件 | 规则 | 当前问题 | |------|------|----------| | `contract.entrust/2.0/rules.yaml` | `MM-ENT-031` | `check: visual + element: 骑缝章` | | `contract.entrust/v2/rules.yaml` | `MM-ENT-031` | `check: visual + element: 骑缝章` | | `contract.entrust/v3/rules.yaml` | `MM-ENT-031` | `check: visual + element: 骑缝章` | | `contract.entrust/v4/rules.yaml` | `MM-ENT-031` | `check: visual + element: 骑缝章` | | `contract.entrust/v5/rules.yaml` | `MM-ENT-031` | `check: visual + element: 骑缝章` | | `contract.entrust/v6/rules.yaml` | `MM-ENT-031` | `check: visual + element: 骑缝章` | | `contract.entrust/v7/rules.yaml` | `MM-ENT-031` | `check: visual + element: 骑缝章` | | `contract.entrust/v8/rules.yaml` | `MM-ENT-031` | `check: visual + element: 骑缝章` | 这类文件不是立即阻断发布的问题,但不建议继续保留旧写法。原因是规则编辑页面现在应该以正式视觉 stage 为准,否则会出现你前面看到的 `visual.xxx`、视觉编码、YAML 片段不一致等问题。 ## 4. 具体问题定位 ### 4.1 `field: ctx` 命中的规则如下: | 文件 | 规则 ID | 说明 | |------|---------|------| | `contract.construction.general/v3/rules.yaml` | `GC-OUR-001` | 我方缔约地位及不利条款审查 | | `contract.entrust/v9/rules.yaml` | `MM-ENT-035` | 我方缔约地位及不利条款审查 | | `contract.evaluation.delegation/0.1/rules.yaml` | `EVAL-OUR-001` | 我方缔约地位及不利条款审查 | | `contract.gift.charity/1.0/rules.yaml` | `ZY-CHY-023` | 我方缔约地位及不利条款审查 | | `contract.gift.general/1.0/rules.yaml` | `ZY-GEN-016` | 我方缔约地位及不利条款审查 | | `contract.lease/2.0/rules.yaml` | `ZL-LEASE-036` | 我方缔约地位及不利条款审查 | | `contract.loan.general/1.0/rules.yaml` | `JK-OUR-001` | 我方缔约地位及不利条款审查 | | `contract.purchase.general/1.0/rules.yaml` | `MM-OUR-001` | 我方缔约地位及不利条款审查 | | `contract.sale/2.1/rules.yaml` | `MM-SALE-029` | 我方缔约地位及不利条款审查 | | `contract.tech/1.0/rules.yaml` | `JS-TECH-035` | 我方缔约地位及不利条款审查 | 当前错误写法: ```yaml stages: - id: '1' check: ai field: ctx prompt: |- 合同全文:{{ctx}} ``` 当前引擎的 AI prompt 插值只读取 `ctx.fields + ctx.derived`。`ctx` 不是内置字段名,所以 DSL 校验会失败,运行时也无法正确插入全文。 推荐修复方向有两种: | 方案 | 做法 | 是否推荐 | |------|------|----------| | A | 在规则文件 `extract` 中声明一个真实字段,例如 `合同全文`,prompt 使用 `{{合同全文}}` | 不推荐,全文不是普通抽取字段,容易拖慢抽取并污染字段语义 | | B | 后端引擎提供正式全文上下文变量,例如 `full_text` 或 `document_text`,DSL validator 将其列为系统内置字段 | 推荐,符合“全文上下文不是抽取字段”的语义 | 短期如果只想让 YAML 先通过发布,可以将 `field: ctx` 删除,并把 prompt 中 `{{ctx}}` 改成已声明字段拼接。但这会降低“我方不利条款审查”的覆盖面,不建议作为最终方案。 ### 4.2 旧视觉写法 `check: visual` 命中的规则如下: | 文件 | 规则 ID | 当前写法 | |------|---------|----------| | `contract.entrust/*/rules.yaml` | `MM-ENT-031` | `check: visual + element: 骑缝章` | | `contract.lease/2.0/rules.yaml` | `ZL-LEASE-032` | `check: visual + element: 骑缝章` | | `contract.tech/1.0/rules.yaml` | `JS-TECH-032` | `check: visual + element: 骑缝章` | | `contract.evaluation.delegation/0.1/rules.yaml` | `EVAL-SEAL-001` | `check: visual + element: seal + expect: type_in` | | `contract.evaluation.delegation/0.1/rules.yaml` | `EVAL-SEAL-002` | `check: visual + element: seal + expect: text_match` | | `contract.evaluation.delegation/0.1/rules.yaml` | `EVAL-CROSS-001` | `check: visual + element: cross_page_seal + expect: present` | | `contract.evaluation.delegation/0.1/rules.yaml` | `EVAL-CROSS-002` | `check: visual + element: cross_page_seal + expect: complete` | | `contract.evaluation.delegation/0.1/rules.yaml` | `EVAL-SIGN-001` | `check: visual + element: signature + expect: present` | 正确迁移方向: ```yaml visual_elements: cross_page_seals: - id: 骑缝章 name: 合同骑缝章 required: true required_from: executed rules: - group: 默认规则组 rules: - rule_id: JS-TECH-032 name: 骑缝章检查 risk: medium score: 2 type: deterministic applies_in: - executed stages: - id: '1' type: cross_page_seal.complete seal_id: 骑缝章 logic: '1' ``` ### 4.3 `field: visual.xxx` 当前命中文件: | 文件 | 位置 | 问题 | |------|------|------| | `contract.purchase.general/1.0/rules.yaml` | remediation actions | `field: visual.甲方签章`、`field: visual.乙方签章` | 这不是 stage 校验字段,所以当前失败优先暴露为 `ctx`,但它仍是错误语义。补救动作不应让用户“重查 visual.xxx 字段”,而应指向具体视觉要素或普通抽取字段。 推荐改法: ```yaml actions: - type: recheck_visual label: 核对甲方印章文字 visual_type: seal seal_id: 甲方签章 - type: recheck_visual label: 核对乙方印章文字 visual_type: seal seal_id: 乙方签章 ``` 如果前端暂时没有 `recheck_visual` 动作渲染能力,则先改成普通说明类动作,避免继续写 `field: visual.xxx`。 ## 5. `contract.evaluation.delegation/0.1` 额外结构错误 该文件除 `field: ctx` 和旧视觉写法外,还有 YAML 层级错误: ```text rules.1.messages Extra inputs are not permitted rules.1.type Extra inputs are not permitted ``` 这说明 `messages` 和 `type` 被放到了 `rules` 顶层列表的第二个元素上,而不是某个具体 rule 内。正确结构必须是: ```yaml rules: - group: 签字合规 rules: - rule_id: EVAL-SIGN-001 name: 甲乙双方签名存在 risk: high score: 10 stages: - id: '1' type: signature.present signature_id: 甲乙方代理人签名 logic: '1' messages: pass: 合同存在甲乙双方的手写签名 fail: 合同缺少甲方或乙方的手写签名 type: deterministic ``` ## 6. 入库/发布前建议顺序 建议不要一口气把 31 份全部入库。按以下顺序处理可控: 1. 先修复 10 份校验失败文件,目标是 `RuleValidator.ValidateYaml` 全部通过。 2. 再迁移 13 处旧视觉写法,目标是规则详情页回显、保存、发布后 YAML 不再出现 `check: visual`。 3. 单独处理 `field: ctx` 的系统级方案,建议由引擎支持 `full_text/document_text` 内置上下文,而不是把全文伪装成抽取字段。 4. 修复 `contract.evaluation.delegation/0.1` 的层级错误后再做视觉迁移。 5. 对每个 `rule_type` 选择一个当前版本做租户物化,不要把历史所有版本一次性设为所有租户当前版本。 ## 7. 可重复校验命令 在平台根目录执行: ```bash python - <<'PY' from pathlib import Path from fastapi_modules.fastapi_leaudit.leaudit_bridge.ruleValidator import RuleValidator root = Path('leaudit-oss-yaml-files') validator = RuleValidator() total = ok = 0 for path in sorted(root.rglob('*.yaml')): total += 1 result = validator.ValidateYaml(path.read_text(encoding='utf-8')) if result.valid: ok += 1 continue print(f'\nFAIL {path}') for error in result.errors or []: print(error) print(f'\nTOTAL={total} OK={ok} FAIL={total - ok}') PY ``` 当前结果应为: ```text TOTAL=31 OK=21 FAIL=10 ``` ## 8. 当前不建议立即做的事 | 不建议动作 | 原因 | |------------|------| | 直接把这 31 份全部导入生产库 | 有 10 份发布校验失败 | | 用 `ctx` 作为普通 extract 字段补丁 | 会污染抽取字段语义,且运行时全文来源不稳定 | | 继续让前端生成 `visual-时间戳` | 业务不可读,回滚/对比/迁移都困难 | | 保留 `field: visual.xxx` | 视觉要素不是抽取字段,后续页面和执行器都会继续出错 | ## 9. 后续开发任务 | 优先级 | 任务 | 验收点 | |--------|------|--------| | P0 | 引擎/校验器支持正式全文上下文变量 | `field: ctx` 不再需要,全文 AI 规则可发布可执行 | | P0 | 修复 10 份失败 YAML | 31 份全部通过 `RuleValidator.ValidateYaml` | | P1 | 旧视觉 stage 迁移为正式 stage | 不再出现 `check: visual`,规则详情页 YAML 片段正确 | | P1 | 修复 `contract.evaluation.delegation/0.1` 层级 | schema 校验通过 | | P1 | 修复 `contract.purchase.general` 的视觉补救动作 | 不再出现 `field: visual.xxx` | | P2 | 增加批量规则体检脚本 | 本地、CI、入库前都能重复执行同一套检查 |