AI辅助开发的账单管理工具

12k words

第一章 工具的工作流程

1. 系统概述

1.1 系统是做什么的?

账单识别工具是一个自动化账单处理系统,能够:

  • 读取律师事务所的PDF账单
  • 自动识别账单中的文字和表格
  • 提取关键信息(日期、金额、律师工时等)
  • 保存到数据库供后续查询和导出

1.2 支持的账单类型

账单类型 律所名称 货币 特点
QE账单 Quinn Emanuel(奎恩伊曼纽尔) 人民币 (¥) 包含折扣和增值税
Steptoe账单 Steptoe & Johnson 美元 ($) 通常无折扣

1.3 系统架构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
flowchart TB
subgraph 用户界面["🖥️ 用户界面"]
A[网页界面]
end

subgraph 核心功能["⚙️ 核心功能"]
B[文件管理]
C[任务调度]
D[智能识别]
E[数据提取]
end

subgraph 数据存储["💾 数据存储"]
F[账单数据库]
G[PDF文件库]
end

subgraph AI引擎["🤖 AI引擎"]
H[本地AI模型]
I[在线AI服务]
end

A --> B
B --> C
C --> D
D --> H
D --> I
D --> E
E --> F
B --> G

2. 完整流程概览

2.1 端到端流程图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
sequenceDiagram
participant 👤 as 用户
participant 🖥️ as 界面
participant 📁 as 文件系统
participant 🤖 as AI识别引擎
participant 📊 as 数据提取器
participant 💾 as 数据库

👤->>🖥️: ① 上传PDF文件
🖥️->>📁: ② 保存文件
📁->>📁: ③ 检查是否重复
📁->>🤖: ④ 提交识别任务

Note over 🤖: 后台自动处理

🤖->>🤖: ⑤ 预处理PDF
🤖->>🤖: ⑥ AI识别文字和表格
🤖->>📊: ⑦ 转换为结构化文本

📊->>📊: ⑧ 提取日期和金额
📊->>📊: ⑨ 提取律师明细
📊->>💾: ⑩ 保存到数据库

💾-->>🖥️: ⑪ 通知完成
🖥️-->>👤: ⑫ 显示识别结果

2.2 处理时间线

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
gantt
title 单个账单处理时间分布
dateFormat X
axisFormat %s

section 文件处理
上传和保存 :0, 5

section 预处理
类型识别 :5, 10
页面筛选 :10, 15

section AI识别
文字识别 :15, 70
表格识别 :70, 85

section 数据提取
正则匹配 :85, 95
数据验证 :95, 100

3. 上传阶段

3.1 上传流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
flowchart TD
A[👤 用户选择PDF文件] --> B{文件格式检查}
B -->|❌ 非PDF| C[提示错误]
B -->|✅ PDF| D[计算文件指纹]

D --> E{检查是否已存在}
E -->|✅ 已存在| F[跳过并提示]
E -->|❌ 新文件| G[保存文件]

G --> H[创建账单记录]
H --> I[提交识别任务]
I --> J[✅ 上传成功]

style C fill:#ffcccc
style F fill:#fff3cd
style J fill:#d4edda

4. 任务管理

4.1 任务状态

1
2
3
4
5
6
7
8
9
10
11
12
stateDiagram-v2
[*] --> 等待处理: 文件上传
等待处理 --> 正在识别: 开始处理
正在识别 --> 待校对: 识别成功
正在识别 --> 待校对: 识别失败
待校对 --> 已完成: 用户确认
已完成 --> [*]

note right of 等待处理: 排队等待
note right of 正在识别: AI正在工作
note right of 待校对: 需要人工检查
note right of 已完成: 可以导出使用

4.2 并发处理

系统支持同时处理多个账单

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
flowchart LR
A[任务队列] --> B[工作线程1]
A --> C[工作线程2]
A --> D[工作线程3]
A --> E[工作线程N]

B --> F[账单A]
C --> G[账单B]
D --> H[账单C]
E --> I[账单...]

style A fill:#e3f2fd
style B fill:#fff9c4
style C fill:#fff9c4
style D fill:#fff9c4
style E fill:#fff9c4

并发数量:

  • 默认:同时处理 3个 账单
  • 可配置:1-10个(在设置中调整)
  • 建议:根据电脑性能调整

4.3 进度显示

系统会实时显示处理进度:

阶段 说明 进度占比
🔄 加载模型 准备AI模型 10%
📐 识别布局 分析页面结构 25%
🔍 检测文本 定位文字位置 15%
📝 识别文字 提取文字内容 30%
📊 识别表格 提取表格数据 10%
✅ 提取数据 整理结构化信息 10%

5. PDF预处理

5.1 为什么需要预处理?

律师账单PDF通常有很多页,但并非所有页面都包含关键信息。预处理的目的是:

  • 🎯 只提取关键页面,跳过冗余内容
  • 加快识别速度
  • 💰 节省API调用成本(在线模式)

5.2 预处理流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
flowchart TD
A[📄 读取PDF] --> B[📖 提取所有页面文字]
B --> C{识别账单类型}

C -->|包含 quinn emanuel| D[QE账单]
C -->|包含 www.steptoe.com| E[Steptoe账单]

D --> F[查找关键标记]
E --> G[查找关键标记]

F --> H[提取有效页面]
G --> I[提取有效页面]

H --> J[✅ 生成精简PDF]
I --> J

style D fill:#e1f5fe
style E fill:#fff3e0
style J fill:#c8e6c9

5.3 账单类型识别

系统通过关键词自动识别账单类型:

账单类型 识别关键词 货币
🏢 QE账单 “quinn emanuel” ¥ 人民币
🏛️ Steptoe账单 www.steptoe.com $ 美元

5.4 有效页面提取规则

QE账单提取规则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
flowchart LR
A[第1页] --> B[第2页]
B --> C[第3页 Statement Detail ⭐]
C --> D[第4页 详细工时]
D --> E[第5页 详细工时]
E --> F[第6页 Fee Summary ⭐]
F --> G[第7页 汇总]

style A fill:#c8e6c9
style B fill:#c8e6c9
style C fill:#c8e6c9
style D fill:#ffcccc
style E fill:#ffcccc
style F fill:#c8e6c9
style G fill:#c8e6c9

H[✅ 保留: 1-3页, 6-7页]
I[❌ 跳过: 4-5页]

提取逻辑:

  • 找到 “Statement Detail“ → 该页及之前的页面保留
  • 找到 “Fee Summary“ → 该页及之后的页面保留
  • 中间的详细工时页面跳过

Steptoe账单提取规则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
flowchart LR
A[第1页] --> B[第2页 FEE DETAIL ⭐]
B --> C[第3页 详细工时]
C --> D[第4页 详细工时]
D --> E[第5页 EXPENSE DETAIL ⭐]
E --> F[第6页 汇总]

style A fill:#c8e6c9
style B fill:#c8e6c9
style C fill:#ffcccc
style D fill:#ffcccc
style E fill:#c8e6c9
style F fill:#c8e6c9

G[✅ 保留: 1-2页, 5-6页]
H[❌ 跳过: 3-4页]

提取逻辑:

  • 找到 “FEE DETAIL“ → 该页及之前的页面保留
  • 找到 “EXPENSE DETAIL“ → 该页及之后的页面保留
  • 中间的详细工时页面跳过

6. 智能识别

系统提供两种识别模式,可在设置中切换:

6.1 识别模式对比

特性 🖥️ 本地模型 ☁️ 在线模型
网络要求 无需网络 需要网络
识别速度 较快 取决于网络
识别准确度 良好 优秀
成本 免费 按次收费
首次启动 慢(需加载模型)
适用场景 离线环境、批量处理 高精度要求

6.2 识别模式选择流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
flowchart TD
A[开始识别] --> B{检查设置}

B -->|本地模型| C[🖥️ 本地识别]
B -->|在线模型| D[☁️ 在线识别]

C --> E[加载AI模型]
E --> F[PDF转Markdown]
F --> G[提取数据]

D --> H[PDF转图片]
H --> I[调用在线API]
I --> J[获取Markdown]
J --> G

G --> K[✅ 返回结果]

style C fill:#e3f2fd
style D fill:#fff3e0
style K fill:#c8e6c9

6.3 本地模型识别

6.3.1 使用的AI技术

本地模型使用 Marker 开源工具,内部集成多个AI模型:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
mindmap
root((Marker AI))
布局检测模型
识别标题
识别段落
识别表格区域
识别图片区域
OCR文字识别
识别中文
识别英文
识别数字
识别符号
表格识别模型
检测表格边界
识别单元格
重建表格结构
文本检测模型
定位文字区域
检测文字方向

6.3.2 识别阶段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
gantt
title 本地模型识别各阶段
dateFormat X
axisFormat %s

section 准备
加载AI模型 (10%) :done, 0, 10

section 布局分析
识别页面布局 (25%) :active, 10, 35

section 文字处理
OCR错误检测 (5%) :35, 40
检测文字边界 (10%) :40, 50
识别文字内容 (30%) :50, 80

section 表格处理
识别表格结构 (10%) :80, 90

section 数据整理
生成Markdown (10%) :90, 100

阶段说明:

  1. 加载模型 (10%): 首次使用时加载AI模型到内存
  2. 识别布局 (25%): 分析页面结构,区分标题、正文、表格
  3. OCR检测 (5%): 检查可能的识别错误
  4. 检测边界 (10%): 定位每个文字的位置
  5. 识别文字 (30%): 使用OCR识别文字内容
  6. 识别表格 (10%): 重建表格结构
  7. 生成结果 (10%): 整理为Markdown格式

6.3.3 模型缓存机制

1
2
3
4
5
6
7
8
9
10
11
12
13
flowchart TD
A[第1次识别] --> B{模型已加载?}
B -->|否| C[加载模型到内存]
C --> D[识别PDF]
B -->|是| D

D --> E[第2次识别]
E --> F{模型已加载?}
F -->|是| G[直接使用]
G --> H[识别PDF]

style C fill:#ffcccc
style G fill:#c8e6c9

优势:

  • ✅ 首次识别较慢(需加载模型)
  • ✅ 后续识别很快(模型已在内存)
  • ✅ 节省时间和资源

6.4 在线模型识别

6.4.1 工作原理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
flowchart TD
A[📄 PDF文件] --> B[转换为图片]
B --> C[图片1]
B --> D[图片2]
B --> E[图片N]

C --> F[发送到AI服务器]
D --> F
E --> F

F --> G[☁️ 在线AI分析]
G --> H[返回Markdown文本]
H --> I[✅ 提取数据]

style A fill:#e3f2fd
style G fill:#fff3e0
style I fill:#c8e6c9

6.4.2 识别阶段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
gantt
title 在线模型识别各阶段
dateFormat X
axisFormat %s

section 准备
读取PDF (5%) :done, 0, 5
PDF转图片 (15%) :active, 5, 20

section 网络通信
上传图片 (10%) :20, 30
AI分析 (40%) :30, 70
下载结果 (10%) :70, 80

section 数据处理
解析响应 (10%) :80, 90
提取数据 (10%) :90, 100

阶段说明:

  1. 读取PDF (5%): 读取PDF文件
  2. 转换图片 (15%): 将每页转为高清图片
  3. 上传图片 (10%): 发送到AI服务器
  4. AI分析 (40%): 在线AI识别(耗时最长)
  5. 下载结果 (10%): 接收识别结果
  6. 解析响应 (10%): 解析返回的数据
  7. 提取数据 (10%): 提取结构化信息

6.4.3 API配置

使用在线模型需要配置:

配置项 说明 示例
API Endpoint 服务器地址 https://api.openai.com/v1
API Key 访问密钥 sk-xxxxx
Model 模型名称 gpt-4o

支持的API:

  • OpenAI GPT-4 Vision
  • 其他兼容OpenAI格式的视觉API

7. 数据提取

7.1 提取流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
flowchart TD
A[Markdown文本] --> B{检测账单类型}

B -->|QE账单| C[QE提取器]
B -->|Steptoe账单| D[Steptoe提取器]

C --> E[提取日期]
C --> F[提取金额]
C --> G[提取明细表格]

D --> H[提取日期]
D --> I[提取金额]
D --> J[提取明细表格]

E --> K[验证数据]
F --> K
G --> K
H --> K
I --> K
J --> K

K --> L[✅ 结构化数据]

style C fill:#e1f5fe
style D fill:#fff3e0
style L fill:#c8e6c9

7.2 提取的数据字段

7.2.1 QE账单字段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
mindmap
root((QE账单))
基本信息
账单日期
账单类型: QE
货币: 人民币
金额信息
费用总额 Fees
折扣 10% Discount
净费用 Net Billed Fees
增值税 VAT at 6.77%
开支 Total Expenses
应付总额 Total Due
明细信息
律师姓名
职位
工时
费率
金额

7.2.2 Steptoe账单字段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
mindmap
root((Steptoe账单))
基本信息
账单日期
账单类型: Steptoe
货币: 美元
金额信息
费用总额 Total Fees
折扣 通常为0
净费用 计算得出
增值税 通常为0
开支 Total Expenses
应付总额 Total Amount Due
明细信息
律师姓名 Timekeeper
职位 Title
工时 Hours
费率 Rate
金额 Amount

7.3 数据字段对比

字段 QE账单 Steptoe账单 说明
账单日期 账单开具日期
费用总额 ✅ Fees ✅ Total Fees 律师费总计
折扣 ✅ 10% Discount ❌ 通常无 优惠折扣
净费用 ✅ Net Billed Fees ✅ 计算得出 扣除折扣后
增值税 ✅ VAT 6.77% ❌ 无 中国税费
开支 ✅ Total Expenses ✅ Total Expenses 其他费用
应付总额 ✅ Total Due ✅ Total Amount Due 最终金额
律师明细 ✅ Fee Summary ✅ FEE SUMMARY 工时明细表

7.4 日期识别

系统支持多种日期格式:

格式 示例 说明
DD Month YYYY 18 November 2025 日 月 年
DD Mon YYYY 18 Nov 2025 日 月缩写 年
Month DD, YYYY November 18, 2025 月 日, 年

月份识别:

  • 支持完整月份名:January, February, March…
  • 支持缩写:Jan, Feb, Mar…
  • 不区分大小写

7.5 金额识别

系统能识别各种金额格式:

格式 示例 说明
带货币符号 CNY1,673,658.15 人民币
带货币符号 $27,108.00 美元
带千位分隔符 1,673,658.15 逗号分隔
无分隔符 1673658.15 纯数字

处理规则:

  • 自动移除货币符号(¥、$、CNY、USD)
  • 自动移除千位分隔符(,)
  • 保留小数点后两位

7.6 表格提取

QE账单表格示例

律师姓名 缩写 职位 工时 费率 金额
Zhang San Z.S. Associate 10.5 ¥1,200 ¥12,600
Li Si L.S. Partner 5.0 ¥2,500 ¥12,500
Wang Wu W.W. Associate 8.0 ¥1,200 ¥9,600

Steptoe账单表格示例

律师姓名 职位 工时 费率 金额
Levin, M.L. Partner 9.30 $1,290.00 $11,997.00
Harris, D.C. Associate 14.60 $1,035.00 $15,111.00

提取内容:

  • 律师姓名
  • 职位(Partner/Associate等)
  • 工作小时数
  • 小时费率
  • 总金额

8. 数据保存

8.1 数据库结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
erDiagram
BILLS ||--o{ BILL_DETAILS : "包含"

BILLS {
整数 账单ID
日期 账单日期
文本 账单类型
文本 货币类型
小数 费用总额
小数 折扣
小数 净费用
小数 增值税
小数 开支
小数 应付总额
文本 状态
文本 PDF路径
文本 Markdown内容
文本 文件指纹
时间 创建时间
时间 更新时间
}

BILL_DETAILS {
整数 明细ID
整数 账单ID
文本 律师姓名
文本 职位
小数 工时
小数 费率
小数 金额
}

8.2 状态流转

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
stateDiagram-v2
[*] --> 识别中: 📤 文件上传
识别中 --> 待校对: ✅ 识别完成
识别中 --> 待校对: ⚠️ 识别失败
待校对 --> 已完成: 👤 用户确认
已完成 --> [*]: 🎉 可以导出

note right of 识别中
系统正在处理
显示进度条
end note

note right of 待校对
需要人工检查
可以修改数据
end note

note right of 已完成
数据已确认
可以导出Excel
end note

8.3 保存时机

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
sequenceDiagram
participant 🤖 as AI识别
participant 📊 as 数据提取
participant 💾 as 数据库
participant 🖥️ as 界面

🤖->>📊: 识别完成
📊->>📊: 提取数据

Note over 📊,💾: 开始保存

📊->>💾: ① 更新账单基本信息
Note right of 💾: 日期、金额、状态等

📊->>💾: ② 保存律师明细
Note right of 💾: 工时、费率等

📊->>💾: ③ 保存Markdown原文
Note right of 💾: 供后续查看

💾-->>🖥️: ④ 通知完成
🖥️-->>🖥️: ⑤ 刷新列表

8.4 数据完整性保证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
flowchart TD
A[开始保存] --> B{数据验证}

B -->|日期为空| C[使用当前日期]
B -->|金额异常| D[标记需要检查]
B -->|数据正常| E[保存到数据库]

C --> E
D --> E

E --> F{保存成功?}
F -->|是| G[更新状态为待校对]
F -->|否| H[记录错误日志]

G --> I[✅ 完成]
H --> J[⚠️ 需要人工处理]

style E fill:#e3f2fd
style G fill:#c8e6c9
style H fill:#ffcccc

总结

完整流程回顾

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
flowchart TB
A[👤 用户上传PDF] --> B[📁 文件保存]
B --> C[🔍 MD5去重检查]
C --> D[📋 创建账单记录]
D --> E[🎯 PDF预处理]
E --> F[🤖 AI智能识别]
F --> G[📊 数据提取]
G --> H[💾 保存到数据库]
H --> I[🖥️ 显示结果]
I --> J[👤 人工校对]
J --> K[✅ 确认完成]

style A fill:#e3f2fd
style F fill:#fff3e0
style K fill:#c8e6c9

核心优势

特性 说明
自动化 无需手工录入,自动提取所有信息
智能化 AI自动识别账单类型和关键信息
高效率 支持并发处理,批量识别
防重复 MD5指纹技术,自动去重
灵活性 支持本地/在线两种识别模式
可追溯 保留原始PDF和识别结果
结构化 数据规范存储,便于查询和导出

第二章 代码工作

(一)系统启动与界面交互

  • 入口main.py 是程序的启动点。它使用 webview 库创建了一个窗口,加载 web/index.html 作为前端界面,并将 Python 后端的 api 对象暴露给前端 JavaScript 调用。
  • 前后端桥梁src/api.py 定义了 Api 类。前端通过 pywebview.api.upload_files() 等方法直接调用后端的 Python 函数,实现了文件选择、任务提交等功能。

(二)任务管理与并发

上传文件后,系统并不会阻塞主界面,而是将任务放入后台队列。

  • 任务调度src/task_manager.py 中的 TaskManager 类维护了一个任务队列 (self.queue)。
  • 并发处理:它启动了多个工作线程(Worker Threads),默认数量是 3 个(max_workers=3)。这意味着工具可以同时并行处理 3 个账单识别任务,提高效率。
  • 流程控制:工作线程不断从队列取任务,调用 self.process_bill(bill_id, file_path) 开始处理单个账单。

(三)第一阶段:PDF 预处理

这是节省 Token和提速的关键步骤。系统不会把整个几十页的 PDF 都扔给 AI,而是先自己“看”一遍。

  • 核心代码src/pdf_preprocessor.py 中的 PDFPreprocessor 类。

  • 步骤 1:类型识别

    • 代码:_detect_bill_type
    • 逻辑:它使用 fitz (PyMuPDF) 读取 PDF 文本。如果发现 “quinn emanuel” 字符串,就标记为 BillType.QE;如果发现 “www.steptoe.com“,就标记为 BillType.STEPTOE
  • 步骤 2:有效页面提取

    • 代码:extract_valid_pages_to_pdf
    • QE 规则 (_extract_qe_pages):找到包含 “Statement Detail” 的页面作为起点,找到 “Fee Summary” 的页面作为终点。只提取这中间的页面。
    • Steptoe 规则 (_extract_steptoe_pages):提取 “FEE DETAIL” 到 “EXPENSE DETAIL” 之间的页面。
    • 结果:生成一个新的、只包含核心表格的精简版 PDF,通常只有几页。

(四)第二阶段:AI 智能识别

根据设置,它会走两条路之一。

核心逻辑由 src/bill_parser.py 中的 BillParser 类调度。

路径 A:在线模型

  • 核心代码src/online_parser.py 中的 OnlineBillParser 类。
  • 流程
    1. 转图片_pdf_to_images_base64 方法将精简后的 PDF 每一页转为高清图片。
    2. 构建 Prompt:使用预定义的 SYSTEM_PROMPT,明确指示 AI:“你是一个专业的账单解析助手… 保留所有表格结构,使用标准 Markdown 表格语法”。
    3. 调用 API_call_vision_api 方法将图片和提示词发送给 OpenAI 兼容接口(如 GPT-4o),获取返回的 Markdown 文本。

路径 B:本地模型

  • 核心代码src/bill_parser.py 中的 _parse_local 方法。
  • 技术:使用开源库 marker。代码中通过 converter(actual_pdf_path) 调用本地模型,将 PDF 转换为 Markdown。

(五)第三阶段:数据提取

AI 返回的是 Markdown 文本,系统需要通过 正则表达式将其转化为结构化数据(JSON)。

  • QE 账单提取器

    • 代码:src/parsers/qe_parser.py
    • 总额提取:使用正则 r'\|\s*Fees\s*\|\s*CNY\s*([\d,]+\.\d{2})\s*\|' 提取表格中的 Fees。
    • 折扣提取:提取 “10% Discount” 对应的负数金额。
    • 表格提取_parse_fee_summary 方法解析类似 | Attorney | Title | Hours | Rate | Amount | 的 Markdown 表格行,将其转为 Python 字典列表。
  • Steptoe 账单提取器

    • 代码:src/parsers/steptoe_parser.py
    • 难点处理:Steptoe 的表头里常有换行符(如 Total<br>Fees),正则设计了兼容逻辑:r'.*Total\s*<br>\s*Fees...'

(六)数据保存 (Data Storage)

最后,提取出的干净数据被存入 SQLite 数据库。

  • 核心代码src/database.py
  • 逻辑
    • Database.update_bill():更新账单的主表信息(总金额、折扣、日期等)。
    • Database.save_bill_details():将律师工时明细表存入 bill_details 表中。

总结图示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[用户上传] -> main.py (UI) -> api.py
|
v
[任务队列] -> task_manager.py
|
v
[预处理] -> pdf_preprocessor.py (提取关键页,扔掉垃圾页)
|
v
[AI 识别] -> bill_parser.py (调度)
|--> 分支A: online_parser.py (GPT-4o 视觉识别 -> Markdown)
|--> 分支B: marker (本地模型识别 -> Markdown)
|
v
[数据提取] -> parsers/qe_parser.py (正则提取 Markdown 中的字段)
|
v
[入库] -> database.py (存入 SQLite)

第三章 开发过程:Cursor 辅助的全栈开发

![](../images/AI辅助开发的账单管理工具/IIurbWfQ7onm4GxbVcScfz15nmh.png)
![](../images/AI辅助开发的账单管理工具/QEInbOjLEo77kQx7GqickEwLn9X.jpeg)

  • 工具链:项目使用 Cursor 进行开发,结合了 Python(后端处理)和 pywebview(前端界面)。
  • **AI 的角色 (Cursor Agent)**:
    • 代码生成:负责生成繁琐的样板代码,例如 src/task_manager.py 中的线程管理逻辑。
    • 正则编写:在 src/parsers/qe_parser.py 中,复杂的正则表达式(如匹配多样的日期格式 r'(\d{1,2})\s+([A-Za-z]+)\s+(\d{4})')通常由 AI 初步生成,再由人工微调。
    • 环境调试:帮助解决 pdf2imagefitz (PyMuPDF) 等库的依赖冲突问题。

整个系统架构分为三个阶段,每个阶段的人工与 AI 参与度不同:

第一阶段:PDF 预处理(人工逻辑主导)

开发背景:直接用 AI 处理几十页的 PDF 成本太高且速度慢,电脑跑不动

  • 人工工作

    • 定义规则:定义了什么是“有效页面”。例如,对于 QE 账单,人工规定只提取从 “Statement Detail” 到 “Fee Summary” 之间的页面。
    • 特征提取:在 PDF 文本中搜索特定关键词(如 “quinn emanuel”)来判断账单类型。
  • AI 工作:将上述逻辑落地成代码

第二阶段:核心识别(AI 能力主导)

开发背景:传统的 OCR 难以处理跨页表格和复杂排版。

  • 人工工作

    • Prompt 工程:在 src/online_parser.py 中,编写了严格的系统提示词(SYSTEM_PROMPT),强制 AI “保留所有表格结构,使用标准 Markdown 表格语法”,并禁止输出废话。
    • 架构设计:设计了“在线模型”和“本地模型”两套策略的切换逻辑。
  • AI 工作

    • 在线模式:调用多模态大模型,利用视觉能力将图片形式的表格转换为 Markdown 文本。
    • 本地模式:集成开源的 Marker 模型,进行本地的 OCR 和布局分析。

第三阶段:数据结构化(人工与 AI 协作)

开发背景:AI 输出的 Markdown 是文本,需要转为数据库可存储的结构化数据。

  • AI 工作:辅助编写正则表达式,用于从 Markdown 表格中提取“律师”“工时”“费率”等字段。
  • 人工工作
    • 兜底逻辑:编写代码处理异常情况。例如,SteptoeBillParser 中处理表头包含 <br> 换行符的特殊情况,需要人工观察数据规律并调整逻辑。
    • 数据清洗:编写逻辑移除金额中的货币符号(CNY, $)和千位分隔符。
Comments