Files
Auto-Finance/.agents/docs/plans/架构分析-2026-06-15.md
wandering 1b35f07fd7 refactor: 架构重组 — doc/bot → core/infra,新增 Agent 调度模块
- src/doc/ 拆分为 src/core/extraction/, matching/, validation/(核心业务逻辑)
- src/bot/ 重命名为 src/infra/browser/(浏览器自动化基础设施)
- fill_consumable_doc.py → src/infra/documents/consumable.py
- 新增 Agent 调度模块:coordinator.py, events.py, session.py,重构 orchestrator.py
- 更新 AGENTS.md、README.md 及所有子目录 README
2026-07-02 18:36:19 +08:00

7.7 KiB
Raw Permalink Blame History

项目架构分析与重构建议

一、当前架构总览

src/
├── main.py              # CLI 入口
├── pipeline.py          # CLI 管道编排
├── pipeline_core.py     # CLI/Web 公共管道逻辑
├── config.py            # 配置加载
├── exceptions.py        # 异常定义
│
├── doc/                 # 文档处理模块(职责过重)
│   ├── extractor.py     # 发票提取编排
│   ├── llm_extractor.py # LLM 提取核心
│   ├── invoice.py       # 发票数据模型 + CSV 工具
│   ├── matcher.py       # 发票匹配逻辑
│   ├── validator.py     # 信息校验规则
│   ├── prompt.py        # 提示词加载
│   ├── pdf.py           # PDF 渲染
│   ├── fill_consumable_doc.py # 出库单填写
│   └── prompts/         # LLM 提示词模板
│
├── agent/               # Agent 调度模块
│   └── orchestrator.py  # 校验-修正循环调度
│
├── bot/                 # 浏览器自动化模块
│   ├── base.py          # 浏览器基类
│   ├── travel.py        # 差旅填报
│   └── normal.py        # 普通报销填报
│
└── web/                 # Web 界面模块
    ├── app.py           # Flask 应用
    ├── routes.py        # 路由定义
    ├── pipeline_web.py  # Web 管道逻辑(与 pipeline_core 重复)
    ├── sse_handler.py   # SSE 日志流处理
    └── static/templates/ # 前端资源

二、问题分析

2.1 职责不清(高耦合)

问题 位置 说明
doc 模块职责过重 src/doc/ 同时负责提取、匹配、校验、提示词、PDF渲染、出库单填写、CSV操作
Web 层重复逻辑 pipeline_web.py vs pipeline_core.py 两者的 is_travel_invoiceextract_and_cache_* 逻辑重复
提示词与校验耦合 validator.py 校验规则直接引用提示词相关函数,缺乏分层
bot 模块位置 src/bot/ 浏览器自动化属于基础设施,却被放在 src 根目录而非独立模块

2.2 逻辑混乱

  1. src/doc/validator.py 的问题:

    • 校验规则(TRAVEL_VALIDATION_RULES)硬编码在模块中,修改需改代码
    • FieldRuleArrayRule 类与校验逻辑紧耦合
    • 数组元素字段支持简单格式和详细格式两种配置,增加了理解成本
  2. src/doc/prompt.py 的问题:

    • 简单的文件读取包装,但调用方分散
    • build_invoice_system_prompt()build_travel_info_system_prompt() 分别调用,但结构相似
  3. src/agent/orchestrator.py 的问题:

    • 校验循环与提取逻辑混合在 _do_extraction_with_validation
    • SSE 事件发射逻辑(_emit_agent_event)与业务逻辑混杂
    • 状态机转换逻辑分散

2.3 分层不合理

当前分层(按目录):
  main.py → pipeline.py → doc/ + bot/
                    ↓
              pipeline_web.py → web/

建议分层(按职责):
  应用层:    main.py, pipeline.py, pipeline_web.py
  业务层:    agent/orchestrator.py, doc/validator.py, doc/matcher.py
  提取层:    doc/extractor.py, doc/llm_extractor.py
  基础设施层: bot/, web/, doc/pdf.py, doc/fill_consumable_doc.py

三、重构建议

3.1 目录重组

src/
├── main.py                 # CLI 入口
├── config.py               # 配置加载
├── exceptions.py           # 异常定义
│
├── apps/                   # 应用层(管道编排)
│   ├── cli/                # CLI 应用
│   │   └── pipeline.py
│   └── web/                # Web 应用
│       ├── app.py
│       ├── routes.py
│       ├── pipeline.py    # Web 专用管道
│       └── sse.py
│
├── core/                   # 核心业务逻辑
│   ├── agent/              # Agent 调度
│   │   ├── orchestrator.py
│   │   └── session.py
│   ├── validation/        # 校验模块
│   │   ├── validator.py
│   │   └── rules/         # 校验规则(可配置化)
│   ├── matching/          # 匹配模块
│   │   └── matcher.py
│   └── extraction/         # 提取模块
│       ├── extractor.py
│       └── llm.py
│
├── infra/                  # 基础设施层
│   ├── browser/            # 浏览器自动化
│   │   ├── base.py
│   │   ├── travel.py
│   │   └── normal.py
│   ├── documents/          # 文档处理
│   │   ├── invoice.py
│   │   ├── pdf.py
│   │   └── consumable.py
│   └── llm/                # LLM 接口
│       └── prompts/       # 提示词模板
│
└── shared/                 # 共享工具
    ├── logging.py
    └── cache.py

3.2 关键重构点

3.2.1 doc 模块拆分

职责 建议移动位置
validator.py core/validation/
matcher.py core/matching/
llm_extractor.py core/extraction/
extractor.py core/extraction/
invoice.py infra/documents/
pdf.py infra/documents/
fill_consumable_doc.py infra/documents/
prompt.py + prompts/ infra/llm/

3.2.2 消除重复逻辑

问题: pipeline_web.pypipeline_core.py 都有相似逻辑:

  • is_travel_invoice()
  • extract_and_cache_travel_info()
  • extract_and_cache_normal_info()

建议: 将这些公共逻辑统一到 core/pipeline/ 目录,两个入口调用同一模块。

3.2.3 Validator 重构

当前问题:

  • 校验规则硬编码
  • FieldRuleArrayRule 类过于复杂

建议:

  • 将校验规则外部化为 JSON/YAML 配置文件
  • 简化 FieldRule 为单一数据结构
  • 统一顶层字段和数组元素字段的校验方式

3.2.4 Agent 拆分

当前问题:

  • orchestrator.py 包含状态机、SSE 事件、校验循环、提取逻辑

建议:

agent/
├── session.py      # 状态机定义 + 会话数据模型
├── coordinator.py  # 校验-修正循环
├── events.py       # SSE 事件发射
└── orchestrator.py # 总调度入口

3.3 接口契约强化

模块 依赖关系 接口契约
core/extraction apps/* 调用 返回 (payment_records, applications, groups)
core/validation agent/* 调用 validate(info, rules) -> ValidationReport
core/matching extraction 调用 match(invoices, cards) -> List[Dict]
infra/browser apps/* 调用 run(bot, info) -> None
infra/llm core/extraction 调用 extract_document(file) -> dict

四、优先重构顺序

第一阶段(降低耦合)

  1. doc/ 拆分为 core/ + infra/
  2. 消除 pipeline_web.pypipeline_core.py 的重复逻辑
  3. bot/ 移动到 infra/browser/

第二阶段(职责清晰化)

  1. 拆分 agent/orchestrator.py 为多个模块
  2. 外部化 validator.py 的校验规则为配置文件
  3. 统一 SSE 事件处理接口

第三阶段(可维护性)

  1. 完善 __init__.py 的接口导出
  2. 添加模块间依赖注入机制
  3. 建立跨模块调用规范

五、当前项目优点

  1. 日志规范: 统一的 get_logger() 方式,全局日志管理
  2. 异常体系: 清晰的 ReimbursementError 异常层次
  3. SSE 事件协议: 良好的实时反馈机制
  4. 缓存设计: llm_extractor.py 的缓存加载逻辑完善
  5. 声明式校验: validator.py 的规则配置思路正确

生成时间: 2026-06-15