Files
leaudit-platform-backend/docs/规则编辑/为什么仍然需要Bridge适配层.md
T

7.4 KiB

为什么仍然需要 Bridge 适配层

1. 结论先行

即使当前项目已经确认:

  • 后续应使用 leaudit 原生 AuditCtx
  • 后续不应继续由平台自己手写主流程编排
  • 正式执行入口应收敛到 AuditService.audit(ctx)

也仍然需要保留 Bridge / 适配层。

原因不是因为不用原生 CTX,而恰恰是因为:

要正确使用原生 CTX,就更应该把它封装在 Bridge 里。

也就是说,正确架构不是:

平台层 -> 直接调用 leaudit AuditCtx / AuditService

而是:

平台层 -> Bridge 适配层 -> leaudit AuditCtx / AuditService

2. 误区澄清

一个很容易出现的误区是:

  • 既然 leaudit 已经有原生 AuditCtx
  • 那平台直接调用它就好了
  • Bridge 似乎没有必要

这个判断看起来简化了结构,但实际上会把平台和 leaudit 深度耦合起来,后续维护成本更高。

真正应该取消的是:

  • 平台自己重写 7 阶段编排

不应该取消的是:

  • 平台和 leaudit 之间的正式边界层

所以:

  • 不要自己编排
  • 但要保留适配层

3. 适配层到底在适配什么

Bridge 的本质,是把“平台世界”翻译成“引擎世界”,再把“引擎结果”翻译回“平台世界”。

3.1 平台世界

平台里实际关心的是这些对象:

  • document_id
  • document_file_id
  • rule_set_id
  • rule_version_id
  • oss_url
  • run_id
  • 用户触发信息
  • 权限信息
  • 数据库记录
  • 前端 DTO / VO

3.2 引擎世界

leaudit 原生执行关心的是这些对象:

  • file_path
  • rules_file
  • AuditServices
  • AuditConfig
  • AuditCtx
  • AuditService.audit(ctx)

这两套概念体系并不相同,因此天然需要一层转换。


4. 为什么不能让平台层直接碰 leaudit 原生对象

4.1 会导致架构边界失守

如果 Controller / Service / Model 层直接构造 AuditCtx,那就意味着:

  • 平台业务代码开始直接依赖 leaudit
  • leaudit 的内部概念会渗透到整个项目
  • 后面任何原生字段调整都会扩散到平台层

这会破坏当前项目一直强调的边界原则:

  • 平台层不直接感知 leaudit 内核细节
  • leaudit_bridge/ 是唯一正式桥接层

4.2 会让平台逻辑和引擎逻辑搅在一起

平台侧还必须处理这些事情:

  • 文档文件从哪里取
  • OSS 文件如何下载
  • 规则版本从哪里查
  • run 如何创建
  • run 如何更新状态
  • 结果如何写回 leaudit_*
  • 前端如何查询结果

这些都不是 leaudit 原生 CTX 的职责。

如果平台层直接碰 AuditCtx,这些平台职责和引擎职责就会混在同一个 service 里,结构会越来越乱。


4.3 会让未来升级风险更大

如果以后 leaudit 升级:

  • AuditCtx 字段变更
  • AuditService 签名调整
  • AuditServices 装配方式变化
  • AuditConfig 配置项增加

那么:

  • 如果只有 bridge 感知这些对象,改动范围很小
  • 如果平台层很多地方直接依赖这些对象,改动会扩散全项目

因此,适配层的价值就在于:

leaudit 变化锁死在边界层里。


5. Bridge 的正确职责

确认使用原生 CTX 后,Bridge 的职责应该重新定义为:

5.1 输入适配

  • 根据 document_id 找到待执行文档
  • 根据 document_file_id 找到文件真源
  • 如有需要,从 OSS 下载文档到本地临时路径
  • 根据 type_id / rule_type_binding 找到本次评查规则版本
  • 从 OSS 下载规则 YAML
  • 解析出 RulesFile

5.2 运行装配

  • 创建 AuditServices
  • 创建 AuditConfig
  • 创建原生 AuditCtx
  • 调用 AuditService.audit(ctx)

5.3 输出适配

  • 从最终 ctx 读取:
    • normalized_doc
    • extraction
    • phase
    • evaluation
    • fallback_tasks
    • timing
  • 写入:
    • leaudit_audit_runs
    • leaudit_rule_results
    • leaudit_field_results
    • leaudit_artifacts
    • leaudit_run_metrics
    • leaudit_run_errors

5.4 边界保护

  • 平台 Controller / Service 不直接 import leaudit.services.*
  • 只有 leaudit_bridge/ 感知原生 AuditCtxAuditServiceAuditServices

6. 三层结构图

推荐的结构应该是三层,而不是两层:

┌────────────────────────────────────────────┐
│                平台层                      │
│ Controller / Service / Model / API / DB    │
│ 文档、规则、权限、任务、结果查询           │
└──────────────────┬─────────────────────────┘
                   │
                   ▼
┌────────────────────────────────────────────┐
│             Bridge 适配层                  │
│ file resolve / rules resolve / ctx build    │
│ AuditServices / AuditConfig / AuditCtx      │
│ persist ctx outputs to leaudit_*            │
└──────────────────┬─────────────────────────┘
                   │
                   ▼
┌────────────────────────────────────────────┐
│             leaudit 原生内核层             │
│ AuditCtx / AuditService / Evaluation /      │
│ Extraction / Rescue / DSL loader            │
└────────────────────────────────────────────┘

这个结构的关键点是:

  • 平台层不直接碰 leaudit 细节
  • leaudit 不直接感知平台数据库和 OSS
  • 所有翻译工作都集中在 Bridge

7. 为什么这比“平台直接调原生 CTX”更稳

优势 1:边界清晰

  • 平台只管业务
  • leaudit 只管评查
  • Bridge 只管适配

优势 2:变化可控

  • leaudit 升级时改 Bridge
  • 平台结构基本不动

优势 3:便于替换

将来如果评查引擎变化:

  • 平台不需要全面改造
  • 只需替换适配层实现

优势 4:测试更容易

Bridge 可以单独测试:

  • 是否正确组装 AuditCtx
  • 是否正确调用 AuditService.audit(ctx)
  • 是否正确写回平台结果表

8. 对当前项目的直接要求

既然已经确认:

  • 必须使用原生 AuditCtx
  • 不能继续自己编排主流程

那么当前项目应该同步修正为:

不再推荐的方向

  • fastapi_modules/fastapi_leaudit/leaudit_bridge/pipeline.py 中继续手写 7 阶段流程
  • 在平台侧继续直接串联:
    • OCR
    • Extract
    • Phase
    • Evaluate
    • Rescue

推荐的方向

  • pipeline.py 改造成薄包装器
  • 新增 audit_ctx_builder.py
  • 新增 audit_service_factory.py
  • 由 bridge 统一:
    • build ctx
    • run audit
    • persist result

9. 最终结论

确认使用原生 AuditCtx 之后,不是 Bridge 就没用了,反而说明:

Bridge 不该负责重写编排,但必须负责原生编排的接入适配。

所以最终应该坚持这条原则:

  • 主流程执行:交给 leaudit 原生 AuditService.audit(ctx)
  • 平台边界控制:交给 leaudit_bridge/

这才是当前项目最稳妥、最可维护的长期方案。