14 KiB
原生 AuditCtx 接入重构方案
1. 目标
基于对 /home/wren-dev/Porject/leaudit/src 源码的核对,确认当前 leaudit 的正式执行模型应视为:
AuditCtxAuditServicesAuditConfigAuditService.audit(ctx)
因此,leaudit-platform 后续不应继续由平台自己手写主流程编排,而应重构为:
平台层
→ Bridge 适配层
→ build AuditServices
→ build AuditConfig
→ build AuditCtx
→ call AuditService.audit(ctx)
→ persist ctx outputs
→ 返回 run / result
本文档用于说明:
- 为什么要重构
- 重构后的目标架构
- 现有文件怎么迁移
- 建议新增哪些文件
- 如何分阶段实施,避免一次性推翻现有代码
2. 关键结论
2.1 必须使用原生 CTX
这一点已经可以下明确结论:
- 后续应使用
leaudit.services.audit_ctx.AuditCtx - 后续应通过
leaudit.services.audit_service.AuditService.audit(ctx)执行主流程 - 不建议平台继续手工串接:
- OCR
- Extract
- Phase
- Evaluate
- Rescue
- Persist
2.2 但 Bridge 不能取消
Bridge 仍然是必须保留的正式边界层。
Bridge 的职责应改为:
- 平台对象 -> 原生
AuditCtx - 原生
ctx-> 平台数据库结果
也就是说:
- 不要自己编排
- 但要自己适配
3. 当前实现与目标实现的差异
3.1 当前实现(过渡态)
当前 fastapi_modules/fastapi_leaudit/leaudit_bridge/pipeline.py 的角色,是平台侧自编排器:
file_path + rules_file
→ OCR
→ Extraction
→ Phase detection
→ Evaluation
→ Save results
特点:
- 直接调用 engine / extraction / evaluation 低层函数
- 部分阶段逻辑由平台维护
- rescue / finalize 语义未完整对齐原生服务层
- 结果写入与运行编排耦合较高
3.2 目标实现(正式态)
目标应改成:
document + file + rule version
→ build AuditServices
→ build AuditConfig
→ build AuditCtx
→ await AuditService.audit(ctx)
→ persist final ctx
特点:
- 主流程交给
leaudit原生编排器 - Bridge 只负责适配与持久化
- 平台不再复制
leaudit的阶段编排语义 - 后续升级风险更小
4. 目标架构图
┌────────────────────────────────────────────┐
│ 平台层 │
│ Controller / Service / ORM / API / DB │
│ 文档上传、规则管理、任务触发、结果查询 │
└──────────────────┬─────────────────────────┘
│
▼
┌────────────────────────────────────────────┐
│ Bridge 适配层 │
│ │
│ 1. resolve document file │
│ 2. resolve rule version │
│ 3. download doc / yaml to local temp │
│ 4. build AuditServices / AuditConfig │
│ 5. build AuditCtx │
│ 6. call AuditService.audit(ctx) │
│ 7. persist ctx outputs to leaudit_* │
└──────────────────┬─────────────────────────┘
│
▼
┌────────────────────────────────────────────┐
│ leaudit 原生服务层 │
│ AuditCtx / AuditServices / AuditService │
│ normalization / extraction / evaluation │
│ rescue / finalize │
└────────────────────────────────────────────┘
5. Bridge 重构后的职责边界
5.1 Bridge 负责的事情
- 从平台数据库找到本次执行的文档与文件版本
- 从平台规则表找到当前生效规则版本
- 从 OSS 下载文档文件与规则文件到本地临时路径
- 构造
AuditServices - 构造
AuditConfig - 构造原生
AuditCtx - 调用
AuditService.audit(ctx) - 将最终
ctx中的结果持久化到leaudit_*
5.1.1 当前已落地到代码的链路
当前项目已经完成第一批骨架接入:
- 文档文件:
auditServiceImpl.py中从LeauditDocumentFile解析文件来源fileSourceResolver.py已支持localPath和ossUrltasks.py执行前统一写入本地临时文档文件
- 规则文件:
auditServiceImpl.py创建LeauditAuditRun时锁定ruleVersionId/ruleSourceOssUrlruleVersionResolver.py按run_id解析规则版本来源tasks.py已支持OSS URL -> 本地临时 YAML -> RulesLoader -> NativeRunner
因此当前 bridge 的真实职责已经不只是“理论适配层”,而是运行期真正负责把平台侧 DB/OSS 语义转换成 leaudit 原生可消费的本地文件输入。
5.2 Bridge 不再负责的事情
- 不再手工定义 7 个 stage 的顺序
- 不再自己负责 phase 判定与 rescue 调度的业务语义
- 不再自己维护与原生服务层重复的一套编排逻辑
5.3 平台层不应直接做的事情
- 不直接构造
AuditCtx - 不直接调用
AuditService.audit(ctx) - 不直接 import
leaudit.services.*
6. 建议新增的核心文件
6.1 audit_ctx_builder.py
建议新增:
fastapi_modules/fastapi_leaudit/leaudit_bridge/audit_ctx_builder.py
职责:
- 把平台运行对象组装成原生
AuditCtx
建议输入:
run_iddocument_iddocument_file_idrule_version_idlocal_file_pathrules_fileservicesaudit_config
建议输出:
AuditCtx
建议职责细分:
build_services(...)build_config(...)build_ctx(...)
6.2 audit_service_factory.py
建议新增:
fastapi_modules/fastapi_leaudit/leaudit_bridge/audit_service_factory.py
职责:
- 构造原生
AuditService及其依赖服务
建议内部负责:
DocNormalizationServiceExtractionServiceEvaluationServiceRescueServiceAuditServicesAuditService
目标是让平台不直接感知 leaudit 服务装配细节。
6.3 file_source_resolver.py
建议新增:
fastapi_modules/fastapi_leaudit/leaudit_bridge/file_source_resolver.py
职责:
- 根据
document_file_id找到文件真源 - 必要时从 OSS 下载到本地临时路径
说明:
当前 ctx_builder.py 有一部分类似职责,但建议拆得更明确:
- 文档文件解析
- 规则文件解析
- 原生 ctx 组装
不要混在一个“万能 builder”里。
6.4 rule_version_resolver.py
建议新增:
fastapi_modules/fastapi_leaudit/leaudit_bridge/rule_version_resolver.py
职责:
- 根据
document.type_id/binding找到当前生效规则版本 - 从 OSS 下载
rules.yaml - 解析为
RulesFile
说明:
当前 rules_loader.py 偏向本地路径加载器;后续建议保留它做“底层 YAML 解析器”,但把“版本解析 + 规则定位”职责上移到 resolver。
7. 现有文件的重构策略
7.1 pipeline.py
文件:
fastapi_modules/fastapi_leaudit/leaudit_bridge/pipeline.py
当前问题
- 现在是平台自编排器
- 直接串低层 stage
目标定位
重构后应退化为“薄包装器”。
建议最终形态:
ctx = build_audit_ctx(...)
ctx = await audit_service.audit(ctx)
return ctx
也就是说:
- 保留
pipeline.py文件名可以 - 但不再保留其“自定义主编排器”角色
建议处理方式
- 第一阶段:保留现有
LauditPipeline,但新增原生AuditCtxPipeline - 第二阶段:调用方切换到新实现
- 第三阶段:删除或降级旧自编排逻辑
7.2 tasks.py
文件:
fastapi_modules/fastapi_leaudit/leaudit_bridge/tasks.py
当前问题
- 现在既负责任务分发,又负责规则路径解析,又直接触发旧 pipeline
- 仍依赖
LEAUDIT_RULES_DIR与_TYPE_ID_RULES_MAP
重构目标
把它变成真正的“任务入口层”:
- 创建执行上下文
- 调 bridge 执行服务
- 更新 run 状态
建议改造
dispatch_leaudit_task()只做任务分发leaudit_process_document()只做:- resolve run inputs
- call bridge runner
- update run status
不要在这里继续放太多规则解析与 pipeline 内部细节。
7.3 ctx_builder.py
文件:
fastapi_modules/fastapi_leaudit/leaudit_bridge/ctx_builder.py
当前问题
- 当前
ExecutionContext不是原生AuditCtx - 更像平台内部轻量执行输入对象
重构目标
有两种方案:
方案 A:保留并改名
- 保留文件,但改成“平台预上下文 builder”
- 只负责收集文档/文件/规则/本地路径
方案 B:拆分
推荐拆分成:
file_source_resolver.pyrule_version_resolver.pyaudit_ctx_builder.py
我更建议方案 B,更清晰。
7.4 rules_loader.py
文件:
fastapi_modules/fastapi_leaudit/leaudit_bridge/rules_loader.py
当前问题
- 更偏“本地 YAML 加载器”
- 还没有真正承担“规则版本解析器”职责
重构目标
让它只做一件事:
- 输入本地路径 / YAML 文本
- 输出
RulesFile
而以下职责交给 resolver:
- 查绑定表
- 查规则版本
- 查 OSS 路径
- 下载本地临时文件
7.5 storage_adapter.py
文件:
fastapi_modules/fastapi_leaudit/leaudit_bridge/storage_adapter.py
当前问题
- 结果写入还依赖“按
document_id查最新 run” - 与当前平台自编排写法耦合较深
重构目标
让它变成“最终 ctx 持久化器”。
建议接口风格:
persist_run_start(...)persist_ctx_outputs(run_id, ctx, meta)persist_failure(run_id, err)
其中 persist_ctx_outputs() 从原生 ctx 中读取:
normalized_docextractionphaseevaluationfallback_taskstiming
统一落表。
8. 目标执行链路
重构后的理想执行链如下:
AuditServiceImpl.Run()
→ 创建 leaudit_audit_runs
→ dispatch_leaudit_task(run_id, ...)
→ bridge runner
→ resolve document file
→ resolve rule version
→ build AuditServices
→ build AuditConfig
→ build AuditCtx
→ await AuditService.audit(ctx)
→ persist ctx outputs
→ 返回 run_id
这里的关键点是:
- 平台仍然围绕 run 管理
- 引擎仍然围绕 ctx 管理
- bridge 负责把两者接起来
9. 推荐实施步骤
阶段 1:并行引入原生 CTX 路线
目标:
- 不马上删旧
pipeline.py - 先把原生接入链做出来
建议动作:
- 新增
audit_ctx_builder.py - 新增
audit_service_factory.py - 新增一个新的 bridge runner
例如:
fastapi_modules/fastapi_leaudit/leaudit_bridge/native_runner.py
职责:
- 一次性跑通原生 CTX 执行
阶段 2:让任务入口切到 native runner
目标:
tasks.py不再调用旧自编排 pipeline- 改成调用原生 ctx 路线
建议动作:
- 改
dispatch_leaudit_task() - 改
leaudit_process_document() - 保留旧 pipeline 作为 fallback 一小段时间
阶段 3:让结果持久化围绕最终 ctx 收口
目标:
storage_adapter.py从“阶段中途写”转成“最终 ctx 聚合写”
建议动作:
- 显式传
run_id - 从 ctx 中统一提取产物与汇总
阶段 4:删除旧自编排主链
目标:
- 彻底避免出现两套主流程语义
建议动作:
- 删除旧
LauditPipeline.run()中的核心编排 - 或保留文件但只做代理包装
10. 风险与注意事项
10.1 不要一次性重写全部文件
建议采用“双轨过渡”:
- 旧 pipeline 先保留
- 新 native runner 并行引入
- 验证结果一致后再切换
10.2 不要把平台字段直接塞进原生 CTX
例如:
run_idtrigger_user_idbiz_document_id
这些属于平台字段,不应该污染 AuditCtx 本身。
建议放在:
- bridge 层本地元数据对象
- 或持久化上下文对象
10.3 不要让平台业务代码直接 import leaudit.services.*
这条边界必须守住。
即使未来 100% 使用原生 AuditCtx,也应该只允许 leaudit_bridge/ 感知这些类型。
10.4 规则与文件都要先落成本地路径
原生 AuditCtx 依旧是文件路径驱动:
- 文档文件要落地成本地路径
- 规则文件也要落地成本地 YAML 路径
不要试图让 leaudit 直接理解 OSS / DB。
11. 与现有文档的关系
本方案是以下文档的进一步收敛:
docs/规则编辑/yaml规则在线编辑设计.mddocs/规则编辑/跑通全流程所需准备项.mddocs/规则编辑/开发任务拆解清单.mddocs/规则编辑/为什么仍然需要Bridge适配层.md
它的核心新增点是:
- 不再停留在“Bridge 保留 / 自编排废弃”的原则层
- 而是把“如何迁移到原生 AuditCtx 模式”具体化
12. 最终结论
当前项目的 Bridge 应该正式转向下面这条路线:
- 平台负责 run / OSS / DB / 权限 / API
- Bridge 负责 AuditCtx 接入适配
leaudit原生服务层负责评查执行
所以重构的最终方向不是“继续完善旧 pipeline”,而是:
用原生
AuditCtx + AuditService.audit(ctx)替代平台自编排主链,并把 Bridge 重塑为适配层。
这是当前项目最稳、最可维护、最符合 leaudit 演进方向的接入方案。