- 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
7.7 KiB
7.7 KiB
项目架构分析与重构建议
一、当前架构总览
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_invoice、extract_and_cache_* 逻辑重复 |
| 提示词与校验耦合 | validator.py |
校验规则直接引用提示词相关函数,缺乏分层 |
| bot 模块位置 | src/bot/ |
浏览器自动化属于基础设施,却被放在 src 根目录而非独立模块 |
2.2 逻辑混乱
-
src/doc/validator.py的问题:- 校验规则(
TRAVEL_VALIDATION_RULES)硬编码在模块中,修改需改代码 FieldRule和ArrayRule类与校验逻辑紧耦合- 数组元素字段支持简单格式和详细格式两种配置,增加了理解成本
- 校验规则(
-
src/doc/prompt.py的问题:- 简单的文件读取包装,但调用方分散
build_invoice_system_prompt()和build_travel_info_system_prompt()分别调用,但结构相似
-
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.py 和 pipeline_core.py 都有相似逻辑:
is_travel_invoice()extract_and_cache_travel_info()extract_and_cache_normal_info()
建议: 将这些公共逻辑统一到 core/pipeline/ 目录,两个入口调用同一模块。
3.2.3 Validator 重构
当前问题:
- 校验规则硬编码
FieldRule和ArrayRule类过于复杂
建议:
- 将校验规则外部化为 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 |
四、优先重构顺序
第一阶段(降低耦合)
- 将
doc/拆分为core/+infra/ - 消除
pipeline_web.py和pipeline_core.py的重复逻辑 - 将
bot/移动到infra/browser/
第二阶段(职责清晰化)
- 拆分
agent/orchestrator.py为多个模块 - 外部化
validator.py的校验规则为配置文件 - 统一 SSE 事件处理接口
第三阶段(可维护性)
- 完善
__init__.py的接口导出 - 添加模块间依赖注入机制
- 建立跨模块调用规范
五、当前项目优点
- 日志规范: 统一的
get_logger()方式,全局日志管理 - 异常体系: 清晰的
ReimbursementError异常层次 - SSE 事件协议: 良好的实时反馈机制
- 缓存设计:
llm_extractor.py的缓存加载逻辑完善 - 声明式校验:
validator.py的规则配置思路正确
生成时间: 2026-06-15