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
This commit is contained in:
225
.agents/docs/plans/架构分析-2026-06-15.md
Normal file
225
.agents/docs/plans/架构分析-2026-06-15.md
Normal file
@@ -0,0 +1,225 @@
|
||||
# 项目架构分析与重构建议
|
||||
|
||||
## 一、当前架构总览
|
||||
|
||||
```
|
||||
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 逻辑混乱
|
||||
|
||||
1. **`src/doc/validator.py`** 的问题:
|
||||
- 校验规则(`TRAVEL_VALIDATION_RULES`)硬编码在模块中,修改需改代码
|
||||
- `FieldRule` 和 `ArrayRule` 类与校验逻辑紧耦合
|
||||
- 数组元素字段支持简单格式和详细格式两种配置,增加了理解成本
|
||||
|
||||
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.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` |
|
||||
|
||||
---
|
||||
|
||||
## 四、优先重构顺序
|
||||
|
||||
### 第一阶段(降低耦合)
|
||||
1. 将 `doc/` 拆分为 `core/` + `infra/`
|
||||
2. 消除 `pipeline_web.py` 和 `pipeline_core.py` 的重复逻辑
|
||||
3. 将 `bot/` 移动到 `infra/browser/`
|
||||
|
||||
### 第二阶段(职责清晰化)
|
||||
4. 拆分 `agent/orchestrator.py` 为多个模块
|
||||
5. 外部化 `validator.py` 的校验规则为配置文件
|
||||
6. 统一 SSE 事件处理接口
|
||||
|
||||
### 第三阶段(可维护性)
|
||||
7. 完善 `__init__.py` 的接口导出
|
||||
8. 添加模块间依赖注入机制
|
||||
9. 建立跨模块调用规范
|
||||
|
||||
---
|
||||
|
||||
## 五、当前项目优点
|
||||
|
||||
1. **日志规范**: 统一的 `get_logger()` 方式,全局日志管理
|
||||
2. **异常体系**: 清晰的 `ReimbursementError` 异常层次
|
||||
3. **SSE 事件协议**: 良好的实时反馈机制
|
||||
4. **缓存设计**: `llm_extractor.py` 的缓存加载逻辑完善
|
||||
5. **声明式校验**: `validator.py` 的规则配置思路正确
|
||||
|
||||
---
|
||||
|
||||
*生成时间: 2026-06-15*
|
||||
Reference in New Issue
Block a user