Files
X-Financial/document/development/agent plan/11_ocr_invoice_architecture.md

377 lines
7.9 KiB
Markdown
Raw Normal View History

# OCR 票据识别架构
## 1. 定位
OCR 票据识别不是一个简单的图片转文字功能。
它在 X-Financial 中承担四件事:
1. 把用户上传的附件变成结构化票据信息。
2. 为规则中心提供可判断的字段。
3. 为 User Agent 和 Hermes 提供可解释的证据。
4. 为后续审计、复核、争议处理保留可回溯原件。
因此 OCR 应作为独立能力纳入 Capability Registry。
```text
capability_type = mcp | document_processor
capability_code = invoice_ocr
```
## 2. 总体链路
```text
附件上传
文件落盘 / 对象存储
文件分类
OCR 识别
字段结构化
票据类型归一化
发票验真 MCP
与报销明细匹配
规则中心检查
人工修正
修正结果沉淀
```
关键原则:
- 文件先持久化,再做 OCR不允许只在内存里跑完就丢。
- 原件不可覆盖,只能新增版本。
- Agent 不得假设图片内容已知;只有 OCR/VLM 实际解析后才能引用附件内容。
## 3. 阶段拆分
### Phase A附件接入与文件分类
目标:先识别上传的是什么。
输入:
- 图片
- PDF
- Excel
- Word
- 压缩包
输出:
```json
{
"document_type": "invoice",
"mime_type": "image/png",
"page_count": 1,
"confidence": 0.91
}
```
分类结果:
```text
invoice
itinerary
contract
payment_receipt
approval_screenshot
other
```
### Phase BOCR 字段提取
目标:从图片或 PDF 中提取票据字段。
结构:
```json
{
"invoice_code": "",
"invoice_number": "",
"seller_name": "",
"seller_tax_no": "",
"buyer_name": "",
"buyer_tax_no": "",
"issue_date": "",
"total_amount": 0,
"tax_amount": 0,
"currency": "CNY",
"ocr_confidence": 0.88
}
```
### Phase C字段归一化
目标:不同 OCR 服务返回不同字段名,必须统一。
示例:
```text
发票号码 / invoiceNo / invoice_number
-> invoice_number
```
金额统一:
```json
{
"raw": "¥1,280.00",
"value": 1280.00,
"currency": "CNY"
}
```
### Phase D验真与状态检查
调用发票验真 MCP。
输出:
```json
{
"verify_status": "verified",
"voided": false,
"red_reversed": false,
"verified_at": ""
}
```
### Phase E与报销明细匹配
对比:
- 发票金额 vs 报销金额
- 开票日期 vs 费用日期
- 销售方 vs 商户
- 发票类型 vs 费用类型
输出:
```json
{
"match_status": "matched",
"mismatch_fields": [],
"match_confidence": 0.94
}
```
### Phase F人工修正与回流
OCR 结果必须允许人工修正。
修正内容进入反馈池:
```json
{
"field": "invoice_number",
"before": "12345B",
"after": "123456",
"corrected_by": "finance_user",
"corrected_at": ""
}
```
## 4. 文件存储策略
### 4.1 为什么不能直接把文件塞进数据库
- 原始票据、合同、行程单体积大,数据库行膨胀明显。
- 预览件、缩略图、逐页图片、脱敏件都属于衍生文件,不适合和业务行混存。
- 财务原件需要版本留痕和不可变追溯,文件系统或对象存储更适合。
结论:
- 文件二进制存文件系统或对象存储。
- 数据库仅保存元数据、索引、版本、OCR 结果、验真结果、访问审计和业务关联。
### 4.2 开发环境目录方案
根目录使用后端配置中的 `STORAGE_ROOT_DIR`
建议目录:
```text
<STORAGE_ROOT_DIR>/
finance-documents/
expense_claim/
2026/
05/
<claim_id>/
<document_id>/
v1/
original/
source.jpg
preview/
preview.pdf
pages/
page-1.png
thumbs/
thumb.webp
ocr/
ocr-1.json
verify/
verify-1.json
```
说明:
- `claim_id` 为空时,可先挂到 `draft/<conversation_id>/<document_id>/...`,待正式建单后再回填业务关联。
- `v1``v2` 表示文件版本,不允许直接覆盖 `v1`
- 原始文件名用于展示,真实定位依赖 `storage_key``sha256`
### 4.3 生产环境存储方案
生产环境建议使用:
- MinIO
- S3
- 阿里云 OSS
- 腾讯云 COS
对象存储推荐键名:
```text
finance-documents/expense_claim/2026/05/<claim_id>/<document_id>/v1/original/source.jpg
finance-documents/expense_claim/2026/05/<claim_id>/<document_id>/v1/preview/preview.pdf
finance-documents/expense_claim/2026/05/<claim_id>/<document_id>/v1/thumbs/thumb.webp
```
数据库必须保存:
```text
storage_provider
storage_bucket
storage_key
sha256
file_size_bytes
mime_type
current_version_no
```
### 4.4 原件、版本与衍生件规则
- 原件不可变:上传后不得覆盖。
- 替换附件只能新增 `document_asset_versions` 记录。
- OCR 原始输出、验真响应、预览件、缩略图都作为衍生件管理。
- 删除操作默认只允许逻辑删除业务关联,不允许物理删除原件。
- 命中审计或争议流程的单据可切换到 `legal_hold` 保留策略,暂停清理。
### 4.5 去重与追溯
- 每个原始文件必须计算 `sha256`
- 同一个 `sha256` 可提示重复上传,但不能自动覆盖旧版本。
- 发票查重不能只靠文件哈希,还要结合 `invoice_code + invoice_number + issue_date + total_amount`
## 5. 数据模型建议
推荐配套表:
```text
document_assets
document_asset_versions
document_derivatives
document_ocr_results
invoice_structured_records
invoice_verification_records
expense_item_documents
document_access_logs
```
各表职责:
- `document_assets`:文件主索引
- `document_asset_versions`:原件版本
- `document_derivatives`:缩略图、预览、逐页图片、脱敏件
- `document_ocr_results`:每次 OCR 执行结果
- `invoice_structured_records`:标准化票据字段
- `invoice_verification_records`:验真结果
- `expense_item_documents`:报销明细与票据挂接
- `document_access_logs`:文件查看、下载、导出审计
## 6. 与规则中心关系
OCR 输出供规则使用:
```text
重复报销识别规则
作废发票检查规则
发票抬头异常规则
附件完整性规则
金额不一致规则
OCR 低置信度补录规则
```
规则读取原则:
- 读标准化字段,不直接依赖某个 OCR 服务的原始字段名。
- 需要追证时,从 `document_assets``document_asset_versions` 找原件。
- 需要解释时,从 `document_ocr_results``invoice_verification_records` 给证据。
## 7. 与 Agent 关系
User Agent 使用 OCR
- 解释发票为什么被拦截
- 帮用户补充发票信息
- 提醒上传清晰附件
- 根据 OCR 结果自动回填报销草稿
Hermes 使用 OCR
- 夜间批量验真
- 扫描重复票据
- 统计发票异常趋势
- 回刷历史低置信度票据
## 8. 安全与审计要求
### 8.1 访问控制
- 原始票据预览、下载应按用户角色控制。
- 财务、审批人、申请人看到的文件范围可以不同。
- 对象存储不要暴露永久公网链接,统一走签名 URL 或后端代理下载。
### 8.2 敏感信息处理
- 身份证、银行卡、手机号等敏感字段如被识别,应支持脱敏预览件。
- 对外展示尽量用衍生件,不直接暴露原件。
### 8.3 审计要求
必须记录:
- 谁上传了原件
- 谁触发了 OCR
- 谁查看或下载了原件
- 谁修正了 OCR 结果
- 谁发起了验真
- 哪次风险判断引用了哪些票据
## 9. 开发阶段建议
```text
Step 1: 附件上传与 document_assets / document_asset_versions 落库
Step 2: 本地文件目录方案打通
Step 3: 接入 OCR MCP 或 OCR 服务
Step 4: 结构化字段归一化
Step 5: 发票验真 MCP
Step 6: 与 expense_claim_items 匹配
Step 7: 风险规则中心接入
Step 8: 人工修正界面
Step 9: Hermes 夜间批量 OCR 与验真巡检
```
当前阶段优先级:
- 先把“文件原件可存、可找、可追溯”做实。
- 再把 OCR 和验真接进来。
- 最后再做大规模自动巡检和脱敏导出。