# OCR 中台设计方案

版本：0.4  
日期：2026-05-10  
定位：从 0 开始建设的新一代 OCR 中台

## 1. 设计立场

OCR 中台不是现有 `zmocr` 原型项目的重构版，也不是历史 OCR 项目的延续，更不是 PaddleOCR 的管理壳。它应该作为一个独立平台从 0 开始设计和实现。

现有项目只作为经验输入：

- 已验证“智能识别填表”这个业务场景成立。
- 已验证 PaddleOCR / PP-ChatOCR 可以作为外部算法能力接入。
- 已暴露出算法结果结构、键值对抽取、可视化评估、任务监控、高并发控制等平台级问题。

新中台不继承现有代码结构、表结构、类名和前端页面约束。新系统只继承业务目标：把图片、PDF、扫描件、拍照件中的内容识别出来，形成统一可信的数据资产，并通过稳定 API 服务业务系统。

## 2. 产品定位

OCR 中台是一个面向业务系统的文档智能识别平台。

它对上提供：

- OCR 任务 API。
- 文档结构化结果 API。
- 全文识别结果 API。
- 键值对抽取 API。
- 文档转换导出 API。
- 表单回填数据 API。
- 人工校验工作台。
- 算法效果评估 API。
- 运行监控和审计能力。

它对下接入：

- 开源 OCR 引擎，例如 PaddleOCR、RapidOCR、Tesseract。
- 商业云 OCR 引擎，例如百度、阿里、腾讯、华为、火山等。
- 多模态大模型或文档理解模型。
- 自研 KIE / SER / RE / LayoutLM 类模型。
- 规则抽取、表格解析、字典归一化等轻量能力。

平台目标不是“绑定一个最好的 OCR”，而是让不同 OCR 算法可以被统一接入、统一评估、统一治理，并最终服务业务。

## 3. 核心业务场景

### 3.1 智能识别填表

窗口工作人员打开业务办理页面，点击“智能识别填表”，上传图片或摄像头拍照。OCR 中台完成识别、键值对抽取、人工校验和表单回填，业务系统最终提交一笔业务。

### 3.2 批量材料录入

工作人员批量上传扫描件或 PDF，平台自动拆页、识别、抽取字段，生成待校验任务列表。

### 3.3 全文识别与文档转换

业务系统或工作人员上传一张图片、扫描件或 PDF，OCR 中台输出全文文本、Markdown、版面结构、表格结构，并可生成可检索 PDF、Word/DOCX 或带图片的文档归档件。

### 3.4 业务系统 API 调用

业务系统通过 API 创建 OCR 任务，异步查询结果，按业务字段获取标准化数据。

### 3.5 算法效果评估

同一批样张可以同时跑多个 OCR 引擎，平台统计字段覆盖率、人工确认准确率、耗时、失败率和成本，用数据决定哪个引擎适合哪类表单。

### 3.6 人工校验与学习闭环

低置信度字段进入人工校验。人工修正结果沉淀为训练样本、字段别名、映射规则或提示词样例。

## 4. 总体架构

```mermaid
flowchart LR
  A["业务系统"] --> B["API Gateway"]
  C["后台工作台"] --> B
  B --> D["任务服务"]
  D --> E["文件服务"]
  D --> F["工作流 / 队列"]
  F --> G["引擎编排服务"]
  G --> H1["OCR 引擎适配器"]
  G --> H2["文档理解适配器"]
  G --> H3["LLM / MLLM 适配器"]
  G --> H4["规则与字典适配器"]
  H1 --> I["统一文档模型"]
  H2 --> I
  H3 --> I
  H4 --> I
  I --> J["结构化抽取服务"]
  J --> K["字段标准化服务"]
  K --> L["人工校验服务"]
  K --> M["数据服务 API"]
  L --> M
  M --> A
  D --> N["监控与审计"]
  G --> N
  J --> N
```

核心服务：

- API Gateway：认证、限流、租户识别、请求路由。
- 任务服务：任务创建、状态流转、重试、取消、优先级。
- 文件服务：上传文件、预览图、可视化图、结果附件。
- 工作流 / 队列：异步调度、失败恢复、削峰。
- 引擎编排服务：选择 OCR 引擎、并发控制、旁路评估、兜底策略。
- 统一文档模型服务：把不同算法结果转换为标准结构。
- 结构化抽取服务：抽取文本块、表格、键值对、明细表。
- 文档导出服务：把 OCR 结果导出为 TXT、Markdown、HTML、PDF、Word/DOCX 等格式。
- 字段标准化服务：字段映射、字典归一、格式校验、置信度融合。
- 人工校验服务：人工确认、修改、审核、修正沉淀。
- 数据服务 API：向业务系统提供稳定查询接口。
- 监控与审计：任务指标、引擎指标、质量指标、安全审计。

## 5. 技术路线

技术选择以新系统为准，不受当前原型限制。

### 5.1 后端

推荐：

- Java 25 LTS。
- Spring Boot 4.x。
- Spring Framework 7.x。
- 软件包前缀统一使用 `com.zhengmeng`；OCR 中台后端默认根包为 `com.zhengmeng.ocrplatform`。
- Gradle 9.x 或 Maven 4.x。
- Spring Web MVC / WebFlux 按接口类型混用，业务 API 优先 MVC，长连接或事件流可用 WebFlux。
- Spring Security OAuth2 Resource Server。
- Spring Modulith 或清晰的模块化单体作为第一阶段架构。
- 后续按负载拆分为任务服务、引擎编排服务、文件服务、数据服务。

建议第一阶段不要过早上复杂微服务。OCR 中台的业务复杂度主要在数据结构、任务调度和算法治理，先用模块化单体更容易形成稳定边界。

### 5.2 前端

推荐：

- Vue 3.5+。
- TypeScript。
- Vite 8。
- TanStack Query 或 Vue Query 做服务端状态管理。
- Pinia 做轻量本地状态。
- shadcn-vue / Radix Vue 风格组件。
- Tailwind CSS 4。
- ECharts 或 Apache Superset / Grafana 嵌入用于监控视图。

页面风格：

- 后台工作台采用 Windows 风格后台布局。
- 左侧菜单、顶部标题区、右侧工作区、标签页。
- 不做营销式首页，首页就是任务概览和运行状态。

### 5.3 数据库与存储

推荐：

- MySQL 8.4 LTS 作为第一阶段主数据库，匹配现有服务器环境。
- JSON / LONGTEXT 保存算法原始结果摘要和标准结构片段。
- 向量索引暂不进入第一阶段；后续可按检索需求引入独立向量库。
- 第一阶段使用 MySQL 任务表完成队列、状态流转和恢复扫描。
- 第一阶段使用本地文件目录保存原始文件；后续可替换为 MinIO 或兼容 S3 的对象存储。

中台标准模型和 API 不应依赖 MySQL 私有特性，避免未来替换数据库或拆服务时被锁死。

### 5.4 任务队列与工作流

第一阶段：

- MySQL 表驱动任务队列。
- Spring Scheduler / Quartz 做恢复扫描。
- 独立 Worker 线程池执行 OCR 任务。

第二阶段：

- Redis Stream、RabbitMQ 或 Kafka。
- Temporal / Camunda 8 用于复杂长流程。

建议优先使用“数据库任务表 + Worker”起步，等吞吐、任务时长、失败恢复需求清晰后再引入专用工作流引擎。

### 5.5 OCR 与文档智能引擎

第一批适配：

- PaddleOCR PP-StructureV3：可选外部结构解析 provider，输出文本块、表格、版面。
- PP-ChatOCR：基于字段清单的语义键值对抽取。
- RapidOCR：轻量 OCR 备选。
- 规则引擎：表格 HTML、同行邻近、正则、字典归一。

第一阶段落地方式：

- Java 后端只依赖统一 `OcrEngineAdapter`，不直接加载 Python 模型。
- PaddleOCR 通过已部署容器的 `/layout-parsing` 接入；PP-ChatOCR 通过已部署容器的 `/chatocr-visual` 与 `/chatocr-chat` 接入。二者都是外部服务适配器，中台不内置算法服务实现。
- Java HTTP 适配器通过 `PP_CHAT_OCR_EXTRACTION_KEYS` 下发字段清单。
- PP-ChatOCR 容器侧负责配置 LLM、Retriever、MLLM；中台只保存调用快照和返回结果，不把算法服务实现代码混入平台。

第二批适配：

- 云 OCR 引擎。
- 文档多模态大模型。
- 自研 KIE / SER / RE 模型。
- 针对固定表单的小样本训练模型。

### 5.6 观测与运维

推荐：

- OpenTelemetry 作为统一埋点标准。
- Micrometer + Prometheus 采集 JVM 和业务指标。
- Grafana 展示任务、引擎和 GPU 指标。
- Loki / OpenSearch 收集日志。
- Tempo / Jaeger 做链路追踪。
- DCGM Exporter 采集 NVIDIA GPU 指标。

### 5.7 部署

推荐：

- Docker Compose 作为开发和小规模生产起步。
- Kubernetes 作为中后期部署形态。
- GPU 节点单独打标签，OCR 引擎容器按 GPU 资源调度。
- 对外 API、管理后台、Worker、OCR 引擎容器分开部署。

## 6. 领域模型

### 6.1 OcrTask

表示一次识别任务。

```json
{
  "taskId": "T202605090001",
  "sourceSystem": "business-app",
  "businessType": "food_license",
  "templateCode": "food_license_apply",
  "status": "RUNNING",
  "priority": 5,
  "createdAt": "2026-05-09T10:00:00+08:00"
}
```

### 6.2 OcrDocument

OCR 中台的核心标准结构。所有算法结果都必须转换成它。

```json
{
  "documentId": "D202605090001",
  "taskId": "T202605090001",
  "pages": [
    {
      "pageNo": 1,
      "width": 1240,
      "height": 1754,
      "orientation": 0,
      "textBlocks": [],
      "layoutBlocks": [],
      "tableBlocks": [],
      "keyValues": [],
      "imageBlocks": [],
      "visualAssets": []
    }
  ],
  "fullText": "经营者名称 某某餐饮店 ...",
  "markdown": "# 申请表\n\n| 字段 | 内容 |\n| --- | --- |",
  "providers": ["paddle-structure-v3", "pp-chatocr"],
  "quality": {
    "textConfidenceAvg": 0.94,
    "fieldCoverage": 0.82,
    "needsReview": true
  }
}
```

### 6.3 FullText

全文识别结果是 OCR 的基础能力，不依赖业务字段和 key-value 抽取。

```json
{
  "taskId": "T202605090001",
  "documentId": "D202605090001",
  "text": "经营者名称：某某餐饮店\n统一社会信用代码：9145...\n经营场所地址：...",
  "format": "PLAIN_TEXT",
  "pageTexts": [
    {
      "pageNo": 1,
      "text": "第一页全文文本..."
    }
  ],
  "generatedAt": "2026-05-09T10:03:00+08:00"
}
```

全文输出要求：

- 按页输出。
- 保留自然阅读顺序。
- 可选择是否保留换行。
- 可选择是否包含表格文本。
- 可选择是否包含页眉页脚。
- 可选择输出纯文本、Markdown 或 HTML。

### 6.4 DocumentArtifact

文档导出产物包括 TXT、Markdown、HTML、PDF、Word/DOCX、JSON。

```json
{
  "artifactId": "A202605090001",
  "taskId": "T202605090001",
  "artifactType": "DOCX",
  "renderMode": "LAYOUT_RECONSTRUCTED",
  "fileRef": "s3://ocr/artifacts/2026/05/09/T202605090001.docx",
  "includeImages": true,
  "includeTables": true,
  "includeTextLayer": false,
  "createdAt": "2026-05-09T10:05:00+08:00"
}
```

导出模式：

- `PLAIN_TEXT`：只导出识别文本。
- `MARKDOWN`：按标题、段落、表格组织。
- `SEARCHABLE_PDF`：保留原图页面，并叠加不可见文本层，便于搜索和复制。
- `LAYOUT_RECONSTRUCTED`：尽量按版面重建 Word/DOCX 或 HTML。
- `ARCHIVE_JSON`：导出完整标准结构和原始引用。

### 6.5 ImageBlock

图片区域是文档结构的一部分。对于扫描件或拍照件，所谓“图片”通常是页面中的非文字图像区域，需要通过版面分析检测并裁切；对于原生 PDF，则可以同时尝试提取嵌入图片。

```json
{
  "id": "image-1-0001",
  "pageNo": 1,
  "imageType": "PHOTO",
  "bbox": [120, 600, 520, 900],
  "fileRef": "s3://ocr/crops/T202605090001/image-1-0001.png",
  "caption": null,
  "provider": "layout-detector"
}
```

图片区域用途：

- 在 Word/DOCX 导出时嵌入对应位置。
- 在 HTML / Markdown 导出时作为图片引用。
- 在可视化校验页面中显示非文字区域。
- 给多模态模型作为补充输入。

### 6.6 TextBlock

```json
{
  "id": "text-1-0001",
  "pageNo": 1,
  "text": "经营者名称",
  "confidence": 0.9823,
  "bbox": [120, 80, 380, 112],
  "polygon": [[120, 80], [380, 80], [380, 112], [120, 112]],
  "provider": "paddle-structure-v3"
}
```

### 6.7 TableBlock

```json
{
  "id": "table-1-0001",
  "pageNo": 1,
  "html": "<table>...</table>",
  "cells": [
    {
      "rowIndex": 0,
      "colIndex": 0,
      "rowSpan": 1,
      "colSpan": 1,
      "text": "经营者名称",
      "bbox": [100, 200, 240, 232]
    }
  ],
  "provider": "paddle-structure-v3"
}
```

### 6.8 KeyValue

```json
{
  "key": "经营者名称",
  "value": "某某餐饮店",
  "normalizedValue": "某某餐饮店",
  "confidence": 0.88,
  "provider": "pp-chatocr",
  "evidence": {
    "pageNo": 1,
    "textBlockIds": ["text-1-0012"],
    "tableBlockId": "table-1-0001",
    "bbox": [240, 200, 680, 232]
  },
  "reviewStatus": "PENDING"
}
```

### 6.9 FormBinding

业务表单字段与 OCR 标准字段的绑定关系。

```json
{
  "templateCode": "food_license_apply",
  "fieldCode": "spjy_foodopername",
  "fieldTitle": "经营者名称",
  "aliases": ["经营者", "企业名称", "个体工商户名称"],
  "valueType": "STRING",
  "required": true,
  "dictionaryCode": null
}
```

## 7. OCR 引擎抽象

中台不直接依赖具体 OCR SDK 或 HTTP 结构。每个 OCR 能力都封装成引擎。

```java
public interface OcrEngine {
    OcrEngineDescriptor descriptor();

    OcrEngineHealth health();

    OcrEngineResult execute(OcrEngineRequest request);
}
```

### 7.1 OcrEngineDescriptor

```json
{
  "engineCode": "external-layout-provider",
  "engineName": "External Layout OCR Provider",
  "engineType": "DOCUMENT_STRUCTURE",
  "deploymentType": "HTTP_SERVICE",
  "capabilities": {
    "image": true,
    "pdf": true,
    "textBlocks": true,
    "tables": true,
    "layout": true,
    "semanticKeyValue": false,
    "visualization": true,
    "requiresLlm": false
  }
}
```

### 7.2 OcrEngineRequest

```json
{
  "taskId": "T202605090001",
  "fileRef": "s3://ocr/files/2026/05/09/a.jpg",
  "fileType": "IMAGE",
  "pages": [1],
  "templateCode": "food_license_apply",
  "keyList": ["经营者名称", "统一社会信用代码"],
  "options": {
    "visualize": true,
    "tableRecognition": true,
    "language": "zh-CN"
  }
}
```

### 7.3 OcrEngineResult

```json
{
  "engineCode": "external-layout-provider",
  "operation": "recognize-layout",
  "status": "SUCCESS",
  "elapsedMs": 12680,
  "rawRequestRef": "raw-request-id",
  "rawResponseRef": "raw-response-id",
  "documentPatch": {},
  "warnings": []
}
```

## 8. 引擎编排策略

### 8.1 单引擎模式

只调用一个 OCR 引擎，适合简单表单和低成本场景。

### 8.2 主链路 + 旁路模式

一个引擎产出主结果，其他引擎作为补充或评估。旁路失败不影响主任务完成。

示例：

```text
主链路：文档结构 OCR
旁路：语义键值对抽取
兜底：规则抽取
```

### 8.3 多引擎对比模式

同一文档同时跑多个引擎，输出差异和质量分。

适用：

- 新算法选型。
- 供应商评估。
- 表单类型路由策略优化。

### 8.4 兜底模式

主引擎失败、超时、结果为空或置信度低时触发备用引擎。

### 8.5 分表单路由

不同业务表单可以配置不同策略。

```json
{
  "templateCode": "food_license_apply",
  "strategy": {
    "primary": "paddle-structure-v3",
    "semantic": "pp-chatocr",
    "fallback": ["rapidocr", "table-rule-extractor"]
  }
}
```

## 9. 任务调度设计

### 9.1 状态机

```text
CREATED
QUEUED
PREPROCESSING
RECOGNIZING
NORMALIZING
EXTRACTING
REVIEW_REQUIRED
COMPLETED
FAILED
CANCELLED
```

### 9.2 调度要求

- 支持优先级。
- 支持任务取消。
- 支持失败重试。
- 支持超时控制。
- 支持长时间运行任务恢复。
- 支持按引擎、租户、业务类型限流。
- 支持 GPU 资源感知。

### 9.3 并发控制

每个引擎端点必须有独立的并发上限。

```json
{
  "engineCode": "paddle-structure-v3",
  "endpoint": "http://ocr-engine-1:8080",
  "maxConcurrent": 1,
  "timeoutMs": 180000,
  "queueCapacity": 100
}
```

不要把 HTTP 并发数等同于算法推理并发数。很多 OCR 引擎内部会串行执行 GPU 推理，平台必须在外层控制排队和超时。

## 10. 质量评估体系

### 10.1 任务质量指标

- 文本块数量。
- 表格块数量。
- 键值对数量。
- 必填字段覆盖率。
- 平均置信度。
- 低置信度字段数。
- 人工修改字段数。
- 人工确认准确率。

### 10.2 引擎质量指标

- 平均耗时。
- P95 / P99 耗时。
- 成功率。
- 超时率。
- 错误率。
- 字段覆盖率。
- 字段准确率。
- 单次成本。
- GPU 显存占用。
- GPU 利用率。

### 10.3 评估数据集

中台应内置样张集管理：

- 样张文件。
- 对应表单模板。
- 标准答案。
- 字段级标注。
- 版面复杂度标签。
- 手写 / 打印 / 拍照 / 扫描标签。

算法引擎升级前必须先跑评估集。

## 11. 人工校验与学习闭环

人工校验不是临时补丁，而是中台能力的一部分。

需要保存：

- OCR 原始值。
- 自动标准化值。
- 人工修正值。
- 修正人。
- 修正时间。
- 修正原因。
- 证据区域。

学习闭环输出：

- 字段别名。
- 表单字段映射规则。
- 字典归一规则。
- 正则校验规则。
- LLM few-shot 样例。
- KIE 训练样本。

## 12. 数据模型草案

核心表：

- `ocr_task`：任务主表。
- `ocr_file`：文件元数据。
- `ocr_document`：标准文档结构。
- `ocr_page`：页面信息。
- `ocr_text_block`：文本块。
- `ocr_table_block`：表格块。
- `ocr_key_value`：键值对。
- `ocr_raw_result`：原始引擎结果。
- `ocr_engine`：引擎定义。
- `ocr_engine_endpoint`：引擎服务端点。
- `ocr_engine_call`：引擎调用记录。
- `ocr_task_event`：任务事件。
- `form_template`：业务表单模板。
- `form_field`：业务字段定义。
- `form_binding`：OCR 字段与业务字段映射。
- `review_record`：人工校验记录。
- `evaluation_set`：评估集。
- `evaluation_case`：评估样张。
- `evaluation_run`：评估任务。
- `evaluation_metric`：评估指标。

设计原则：

- 原始结果可以大字段或对象存储保存，但必须可追溯。
- 标准结构必须可以快速查询。
- 字段级结果必须可以独立校验、修改和审计。
- 评估数据和生产任务分开管理。

## 13. API 草案

### 13.1 任务 API

```text
POST /api/v1/ocr/tasks
GET  /api/v1/ocr/tasks/{taskId}
POST /api/v1/ocr/tasks/{taskId}/cancel
POST /api/v1/ocr/tasks/{taskId}/retry
GET  /api/v1/ocr/tasks/{taskId}/events
```

### 13.2 文档结果 API

```text
GET /api/v1/ocr/tasks/{taskId}/document
GET /api/v1/ocr/tasks/{taskId}/pages
GET /api/v1/ocr/tasks/{taskId}/text-blocks
GET /api/v1/ocr/tasks/{taskId}/table-blocks
GET /api/v1/ocr/tasks/{taskId}/key-values
GET /api/v1/ocr/tasks/{taskId}/full-text
GET /api/v1/ocr/tasks/{taskId}/markdown
GET /api/v1/ocr/tasks/{taskId}/artifacts
POST /api/v1/ocr/tasks/{taskId}/artifacts
GET /api/v1/ocr/tasks/{taskId}/artifacts/{artifactId}/download
GET /api/v1/ocr/tasks/{taskId}/fill-data
```

文档导出请求示例：

```json
{
  "artifactType": "DOCX",
  "renderMode": "LAYOUT_RECONSTRUCTED",
  "includeImages": true,
  "includeTables": true,
  "includeKeyValues": false
}
```

### 13.3 人工校验 API

```text
GET  /api/v1/review/tasks
POST /api/v1/review/tasks/{taskId}/fields/{fieldCode}
POST /api/v1/review/tasks/{taskId}/confirm
```

### 13.4 引擎管理 API

```text
GET  /api/v1/engines
POST /api/v1/engines
GET  /api/v1/engines/{engineCode}
POST /api/v1/engines/{engineCode}/health-check
GET  /api/v1/engines/{engineCode}/metrics
```

### 13.5 评估 API

```text
POST /api/v1/evaluation/sets
POST /api/v1/evaluation/runs
GET  /api/v1/evaluation/runs/{runId}
GET  /api/v1/evaluation/runs/{runId}/compare
```

## 14. 前端工作台

后台页面：

- 工作台首页：任务量、成功率、平均耗时、引擎健康。
- OCR 任务列表：状态、业务来源、表单类型、耗时、操作。
- OCR 任务详情：原图、识别块、表格、键值对、原始 JSON。
- 人工校验：字段级校验、证据定位、批量确认。
- 表单模板：字段定义、别名、字典、映射规则。
- 引擎管理：引擎列表、端点、能力、健康状态、限流配置。
- 算法评估：样张集、评估运行、引擎对比。
- 监控中心：队列、耗时、失败率、GPU、日志。

业务侧页面：

- 保持“传统填写”和“智能识别填表”分离。
- 点击智能识别后进入独立识别流程。
- 识别完成后回填原业务表单。

## 15. 安全与治理

必须设计：

- 系统认证与业务系统调用凭证。
- 租户或业务系统隔离。
- 文件访问权限。
- OCR 原始数据保留策略。
- 日志脱敏策略。
- LLM 调用开关和 prompt 日志策略。
- 第三方 OCR 数据出域声明。
- 操作审计。
- 数据删除和归档。

## 16. 部署架构

第一阶段：

```text
api-server
worker
mysql
local-file-storage
ocr-engine-paddle
ocr-engine-chatocr
frontend
```

第二阶段：

```text
api-gateway
task-service
document-service
engine-orchestrator
review-service
evaluation-service
worker-pool
mysql-cluster
redis-cluster
object-storage
prometheus
grafana
gpu-node-pool
```

部署原则：

- API 服务和 Worker 分开。
- OCR 引擎容器和中台业务服务分开。
- GPU 资源只给算法容器。
- 任务队列削峰，业务请求不直接压算法服务。

## 17. 分阶段路线

### 阶段 0：中台立项与样张集

- 明确中台服务边界。
- 收集第一批真实样张。
- 建立标准答案和字段标注。
- 确认第一批业务系统接入方式。

### 阶段 1：新项目骨架

- 建立独立 Git 仓库。
- 建立后端、前端、部署目录。
- 建立统一代码规范和接口规范。
- 搭建 MySQL、基础后台和本地文件存储。

### 阶段 2：任务与文件平台

- 实现文件上传。
- 实现 OCR 任务状态机。
- 实现异步 Worker。
- 实现任务事件和失败重试。

### 阶段 3：OCR 引擎框架

- 定义 `OcrEngine` 接口。
- 实现引擎注册、健康检查、限流、超时。
- 接入一个外部 OCR provider 作为首批验证引擎，当前可选 PaddleOCR。
- 保存原始请求和原始响应。

### 阶段 4：统一文档模型

- 定义 `OcrDocument`。
- 实现文本块、表格块、版面块、键值对标准结构。
- 实现原生结果查看页面。

### 阶段 5：字段抽取与回填

- 实现字段清单。
- 实现表单字段映射。
- 实现规则抽取和字典归一。
- 接入 PP-ChatOCR 或 LLM 键值对抽取。
- 输出业务表单填表 JSON。

### 阶段 6：人工校验

- 实现字段级校验页面。
- 实现证据定位。
- 保存人工修正。
- 形成字段别名和规则沉淀。

### 阶段 7：算法评估

- 实现样张集。
- 实现多引擎对比。
- 实现字段覆盖率和准确率统计。
- 支持按表单类型选择推荐引擎。

### 阶段 8：运维监控

- 接入 OpenTelemetry。
- 接入 Prometheus / Grafana。
- 展示队列、耗时、失败率、GPU 指标。
- 配置日志和告警。

## 18. 第一版建议范围

第一版应该完成：

- 新项目骨架。
- 文件上传和任务异步处理。
- OCR 引擎抽象。
- 首批外部 OCR provider 接入，当前可选 PaddleOCR。
- 统一 `OcrDocument`。
- 原始结果查看。
- 全文文本、Markdown 和可检索 PDF 导出。
- 键值对列表展示。
- 人工校验基础流程。
- 表单回填 API。
- 基础监控指标。

第一版不做：

- 复杂多租户。
- 大规模分布式调度。
- 自研 OCR 模型训练。
- 完整工作流引擎。
- 复杂权限矩阵。
- 全量算法供应商接入。

## 19. 关键决策

1. OCR 中台从 0 开始建设，不在现有原型代码上重构。
2. 技术路线采用新一代 Java / Spring Boot / Vue / MySQL / OpenTelemetry 体系。
3. PaddleOCR 是当前已验证的一个算法适配器，不是平台核心边界，也不是唯一 OCR 方案。
4. 中台核心资产是统一文档模型、字段标准化、人工校验数据、算法评估数据。
5. 先做模块化单体和受控 Worker，后续按压力拆服务。
6. 必须先建立样张集和评估体系，否则无法判断算法好坏。

## 20. 产品模块总览

OCR 中台的产品能力拆成 9 个一级模块。

| 模块 | 使用者 | 核心目标 | 第一版优先级 |
| --- | --- | --- | --- |
| 工作台首页 | 管理员、运维、业务主管 | 一眼看到任务量、成功率、积压、引擎状态 | P0 |
| OCR 任务中心 | 业务人员、运维 | 管理上传识别任务、查询结果、重试失败任务 | P0 |
| 人工校验中心 | 业务人员、审核人员 | 校验低置信度字段，形成最终可信结果 | P0 |
| 文档结果中心 | 技术支持、业务人员 | 查看 OCR 标准文档、原图、文本块、表格、键值对 | P0 |
| 表单与字段中心 | 实施人员、管理员 | 管理业务表单、字段、别名、字典、回填映射 | P0 |
| OCR 引擎中心 | 算法工程师、运维 | 管理 OCR 引擎、端点、能力、健康、限流 | P0 |
| 算法策略中心 | 算法工程师、管理员 | 配置不同业务表单的引擎编排策略 | P1 |
| 评估中心 | 算法工程师、业务专家 | 用样张集评估算法准确率、覆盖率、耗时和成本 | P1 |
| 监控与审计中心 | 运维、安全管理员 | 监控运行效率、错误、日志、审计和数据治理 | P0 |

第一版要优先把“任务可控、结果可查、人工可改、引擎可管、指标可看”做扎实。算法评估和策略编排可以先做基础版，但数据结构要预留。

## 21. 管理端信息架构

管理端采用后台工作台布局：

- 左侧：一级菜单和二级菜单。
- 顶部：当前模块标题、业务系统选择、全局搜索、消息提醒、用户菜单。
- 右侧：主工作区，支持页签。
- 页面主体：以表格、筛选、详情抽屉、分屏校验为主。

### 21.1 菜单树

```text
OCR 中台
├─ 工作台
│  ├─ 运行概览
│  └─ 今日待办
├─ OCR 任务
│  ├─ 任务列表
│  ├─ 新建任务
│  ├─ 批量上传
│  ├─ 任务详情
│  └─ 原始结果
├─ 人工校验
│  ├─ 待校验任务
│  ├─ 低置信度字段
│  ├─ 异常字段
│  ├─ 已确认任务
│  └─ 修正记录
├─ 表单与字段
│  ├─ 表单模板
│  ├─ 字段定义
│  ├─ 字段别名
│  ├─ 字典映射
│  ├─ 回填映射
│  └─ 版本管理
├─ OCR 引擎
│  ├─ 引擎列表
│  ├─ 服务端点
│  ├─ 能力声明
│  ├─ 健康检查
│  ├─ 限流配置
│  └─ 调用日志
├─ 算法策略
│  ├─ 表单策略
│  ├─ 编排流程
│  ├─ 兜底规则
│  └─ 灰度发布
├─ 算法评估
│  ├─ 样张集
│  ├─ 标准答案
│  ├─ 评估任务
│  ├─ 引擎对比
│  └─ 评估报告
├─ 监控中心
│  ├─ 任务监控
│  ├─ 引擎监控
│  ├─ 队列监控
│  ├─ GPU 监控
│  ├─ 接口监控
│  └─ 告警记录
└─ 系统管理
   ├─ 业务系统
   ├─ 用户与角色
   ├─ API 凭证
   ├─ 数据保留策略
   ├─ 操作审计
   └─ 系统参数
```

### 21.2 管理端全局交互规则

- 所有列表页必须支持筛选、排序、分页、列显隐、导出。
- 所有详情页必须展示创建时间、更新时间、操作人、状态流转。
- 所有任务类页面必须展示任务编号，方便线下沟通和日志排查。
- 所有低置信度、失败、超时、异常状态必须有明确原因。
- 所有涉及算法调用的页面必须能追溯到引擎、端点、请求时间、耗时和错误。
- 所有人工修改必须保留修改前值、修改后值、修改人和修改时间。
- 所有删除动作优先软删除，除非触发数据保留策略的物理清理。

## 22. 管理端功能详设

### 22.1 工作台首页

目标：让管理者和运维人员打开系统后立刻知道 OCR 中台是否健康、是否积压、是否有异常。

核心卡片：

| 卡片 | 指标 | 说明 |
| --- | --- | --- |
| 今日任务数 | created today | 按创建时间统计 |
| 今日成功率 | completed / total | 排除取消任务 |
| 当前排队数 | status = QUEUED | 判断是否积压 |
| 当前处理中 | RECOGNIZING / EXTRACTING | 判断 Worker 压力 |
| 待人工校验 | REVIEW_REQUIRED | 判断业务待办 |
| 失败任务数 | FAILED | 可点击跳转失败列表 |
| 平均总耗时 | completedAt - createdAt | 业务感知耗时 |
| 平均识别耗时 | engine elapsed | 算法耗时 |
| 引擎健康 | healthy / unhealthy | 展示异常引擎 |

图表：

- 近 24 小时任务量折线。
- 近 24 小时成功率折线。
- 引擎平均耗时柱状图。
- 任务状态分布饼图。
- 表单类型任务量排行。
- 失败原因排行。

快捷入口：

- 新建 OCR 任务。
- 批量上传。
- 查看待校验。
- 查看失败任务。
- 查看引擎健康。

### 22.2 OCR 任务列表

目标：管理所有 OCR 任务，支持业务人员和运维人员快速定位任务。

筛选条件：

- 任务编号。
- 业务系统。
- 业务类型。
- 表单模板。
- 文件名。
- 任务状态。
- 创建时间范围。
- 完成时间范围。
- 是否需要人工校验。
- OCR 引擎。
- 失败原因。
- 操作人。

列表字段：

| 字段 | 说明 |
| --- | --- |
| 任务编号 | 全局唯一，支持复制 |
| 业务系统 | 来源系统 |
| 业务类型 | 例如食品许可、医保、生育津贴 |
| 表单模板 | 绑定的表单 |
| 文件名 | 原始上传文件名 |
| 页数 | 图片为 1，PDF 多页 |
| 状态 | 状态标签 |
| 字段覆盖率 | 已识别字段 / 必填字段 |
| 低置信度字段 | 数量 |
| 总耗时 | 从创建到完成 |
| 创建时间 | 任务创建时间 |
| 操作 | 详情、重试、取消、下载结果 |

操作：

- 查看详情。
- 复制任务编号。
- 重新识别。
- 取消任务。
- 下载标准结果 JSON。
- 下载原始结果包。
- 标记为样张。

### 22.3 新建任务

目标：允许后台人员不通过业务系统也能创建 OCR 任务，用于测试、补录、问题排查和算法评估。

表单项：

- 业务系统。
- 业务类型。
- 表单模板。
- OCR 策略。
- 文件上传。
- 是否生成可视化结果。
- 是否启用语义键值对抽取。
- 是否自动进入人工校验。
- 备注。

校验：

- 文件类型：图片、PDF。
- 文件大小限制。
- 页数限制。
- 表单模板和业务类型是否匹配。
- OCR 策略是否启用。

提交后：

- 创建 `ocr_task`。
- 保存文件。
- 进入 `QUEUED` 状态。
- 返回任务编号并跳转详情页。

### 22.4 批量上传

目标：支持批量扫描件录入和集中识别。

能力：

- 多文件上传。
- ZIP 上传。
- PDF 自动拆页。
- 批次号。
- 批次备注。
- 批量指定业务类型和表单模板。
- 批量任务进度。
- 批量失败重试。

批次列表字段：

- 批次号。
- 文件数。
- 创建任务数。
- 完成数。
- 失败数。
- 待校验数。
- 创建人。
- 创建时间。

### 22.5 任务详情

目标：一页看清 OCR 任务的全貌。

页面结构：

```text
任务详情
├─ 顶部摘要
├─ 左侧原图 / PDF 预览
├─ 中间识别证据层
├─ 右侧字段结果
└─ 底部任务事件、引擎调用、原始结果
```

顶部摘要：

- 任务编号。
- 状态。
- 业务系统。
- 表单模板。
- 文件名。
- 创建时间。
- 完成时间。
- 总耗时。
- 识别引擎。
- 字段覆盖率。
- 是否需要人工校验。

原图预览：

- 缩放。
- 旋转。
- 翻页。
- 适应宽度。
- 显示 / 隐藏 OCR 框。
- 显示 / 隐藏表格框。
- 点击字段定位证据区域。

字段结果：

- 字段名称。
- 识别值。
- 标准化值。
- 置信度。
- 来源引擎。
- 证据。
- 校验状态。
- 人工修正值。

底部页签：

- 任务事件。
- 引擎调用。
- 文本块。
- 表格块。
- 键值对。
- 原始 JSON。
- 可视化图片。

### 22.6 原始结果查看

目标：给技术支持和算法人员查看各引擎原始能力。

页面能力：

- 按引擎查看原始请求。
- 按引擎查看原始响应。
- JSON 格式化、折叠、搜索。
- 响应大小。
- 调用耗时。
- 错误信息。
- 下载原始 JSON。
- 对比标准化结果。

原始结果必须明确标注：

- provider。
- operation。
- endpoint。
- requestId。
- startedAt。
- finishedAt。
- elapsedMs。
- status。

### 22.7 人工校验列表

目标：将需要人工处理的任务组织成可工作的队列。

筛选：

- 业务系统。
- 表单模板。
- 任务状态。
- 字段类型。
- 低置信度。
- 校验失败。
- 待审核。
- 创建时间。

列表字段：

- 任务编号。
- 表单名称。
- 低置信度字段数。
- 缺失必填字段数。
- 校验失败字段数。
- 当前处理人。
- 进入校验时间。
- 超时时长。

操作：

- 领取。
- 释放。
- 开始校验。
- 批量确认高置信度字段。
- 标记无法识别。

### 22.8 字段级校验页面

目标：让业务人员高效确认每个字段。

布局：

```text
左侧：原图和证据定位
右侧：字段校验表单
底部：修正历史和候选值
```

字段校验项：

- 字段标题。
- 业务字段编码。
- OCR 原始值。
- 标准化值。
- 候选值列表。
- 置信度。
- 校验规则结果。
- 证据位置。
- 人工确认值。
- 确认状态。

操作：

- 确认正确。
- 修改值。
- 选择候选值。
- 清空值。
- 标记缺失。
- 标记无法判断。
- 跳到下一个低置信度字段。
- 整单确认。

保存规则：

- 每次字段修改生成一条 `review_record`。
- 保留修改前值和修改后值。
- 保留修改来源：人工输入、候选选择、字典替换。
- 整单确认后生成最终版本快照。

### 22.9 表单模板管理

目标：管理 OCR 中台理解业务表单所需的字段标准。

表单模板字段：

- 模板编码。
- 模板名称。
- 业务类型。
- 版本号。
- 状态：草稿、启用、停用。
- 来源：手工创建、业务系统同步、文件导入。
- 创建人。
- 更新时间。

操作：

- 新建模板。
- 导入模板 JSON。
- 复制模板。
- 发布新版本。
- 停用。
- 查看字段。
- 绑定 OCR 策略。

### 22.10 字段定义管理

目标：统一管理表单字段，保证 OCR 输出可以映射到业务字段。

字段属性：

- 字段编码。
- 字段标题。
- 字段类型：文本、数字、日期、单选、多选、表格明细、地址、证件号、手机号。
- 是否必填。
- 是否参与 OCR。
- 是否允许人工修改。
- 默认值。
- 字典编码。
- 正则校验。
- 示例值。
- 说明。

字段操作：

- 新增字段。
- 编辑字段。
- 调整排序。
- 导入字段。
- 导出字段。
- 配置别名。
- 配置字典映射。
- 配置回填目标。

### 22.11 字段别名管理

目标：让 OCR 识别到的各种标签能映射到标准字段。

示例：

| 标准字段 | 别名 |
| --- | --- |
| 经营者名称 | 企业名称、个体工商户名称、申请人名称、单位名称 |
| 统一社会信用代码 | 社会信用代码、信用代码、统一代码 |
| 证件号码 | 身份证号、身份证号码、证号 |

别名来源：

- 手工维护。
- 人工校验沉淀。
- 算法评估发现。
- 业务系统字段同步。

别名状态：

- 待确认。
- 已启用。
- 已停用。

### 22.12 字典映射管理

目标：将 OCR 文本归一成业务系统可用编码。

示例：

| 字段 | OCR 值 | 标准值 | 业务编码 |
| --- | --- | --- | --- |
| 经济性质 | 企业 | 企业 | 01 |
| 经济性质 | 个体户 | 个体工商户 | 02 |
| 性别 | 男 | 男 | M |
| 性别 | 女 | 女 | F |

能力：

- 模糊匹配。
- 同义词。
- 停用词。
- 字典版本。
- 未命中字典告警。

### 22.13 回填映射管理

目标：把 OCR 中台的标准字段映射到业务系统字段。

映射维度：

- 业务系统。
- 业务类型。
- 表单模板。
- OCR 标准字段。
- 业务字段编码。
- Form3 `inputName`。
- Form3 `fieldId`。
- 明细表路径。
- 转换函数。

操作：

- 新建映射。
- 批量导入。
- 校验映射完整性。
- 查看未绑定字段。
- 生成回填预览。

### 22.14 OCR 引擎列表

目标：统一管理所有 OCR / 文档理解 / LLM 引擎。

引擎字段：

- 引擎编码。
- 引擎名称。
- 引擎类型。
- 部署方式：HTTP、SDK、云 API、容器。
- 供应商。
- 版本。
- 能力声明。
- 是否启用。
- 默认超时。
- 默认并发上限。
- 创建时间。

引擎类型：

- `TEXT_OCR`：纯文本识别。
- `DOCUMENT_STRUCTURE`：版面和表格结构。
- `SEMANTIC_KV`：语义键值对抽取。
- `TABLE_EXTRACTOR`：表格结构化。
- `LLM_EXTRACTOR`：大模型抽取。
- `RULE_EXTRACTOR`：规则抽取。

操作：

- 新增引擎。
- 编辑能力。
- 启用 / 停用。
- 健康检查。
- 测试调用。
- 查看调用统计。

### 22.15 引擎端点管理

目标：一个引擎可以有多个服务端点，支持负载均衡和故障切换。

端点字段：

- 端点名称。
- Base URL。
- 健康检查路径。
- 权重。
- 最大并发。
- 队列容量。
- 超时时间。
- 熔断阈值。
- 当前健康状态。
- 最近健康检查时间。

端点操作：

- 新增端点。
- 健康检查。
- 临时下线。
- 调整权重。
- 清空队列。
- 查看端点调用日志。

### 22.16 算法策略配置

目标：按业务类型和表单模板配置 OCR 编排方式。

策略字段：

- 策略编码。
- 策略名称。
- 适用业务系统。
- 适用业务类型。
- 适用表单模板。
- 主引擎。
- 旁路引擎。
- 兜底引擎。
- 是否启用语义抽取。
- 是否启用人工校验。
- 低置信度阈值。
- 自动通过阈值。
- 灰度比例。

策略示例：

```json
{
  "strategyCode": "food-license-default",
  "primary": "external-layout-provider",
  "semantic": "external-kv-provider",
  "fallback": ["rule-table-kv"],
  "thresholds": {
    "autoPass": 0.92,
    "reviewRequired": 0.75
  },
  "reviewPolicy": {
    "missingRequiredField": true,
    "lowConfidence": true,
    "validationFailed": true
  }
}
```

### 22.17 样张集管理

目标：建立持续评估算法的标准数据资产。

样张字段：

- 样张编号。
- 文件。
- 业务类型。
- 表单模板。
- 来源。
- 图片类型：扫描、拍照、截图。
- 内容类型：打印、手写、混合。
- 清晰度标签。
- 倾斜标签。
- 是否有印章。
- 是否多页。
- 标准答案状态。

操作：

- 上传样张。
- 标记样张。
- 绑定表单模板。
- 录入标准答案。
- 加入评估集。
- 导出样张包。

### 22.18 标准答案管理

目标：为算法评估提供可信基准。

能力：

- 字段级标准答案。
- 明细表标准答案。
- 多人标注。
- 标注冲突检测。
- 标准答案审核。
- 版本管理。

标准答案结构：

```json
{
  "caseId": "case-001",
  "templateCode": "food_license_apply",
  "fields": {
    "operatorName": "某某餐饮店",
    "creditCode": "9145..."
  },
  "tables": {
    "managerList": []
  }
}
```

### 22.19 评估任务

目标：比较不同引擎、策略、版本的效果。

评估配置：

- 评估集。
- 引擎列表。
- 策略列表。
- 是否启用 LLM。
- 是否启用可视化。
- 并发数。
- 重跑次数。

评估输出：

- 总体准确率。
- 字段级准确率。
- 必填字段覆盖率。
- 平均耗时。
- P95 耗时。
- 失败率。
- 成本估算。
- 引擎排名。
- 差异样本列表。

### 22.20 监控中心

任务监控：

- 每分钟任务创建数。
- 每分钟任务完成数。
- 当前队列长度。
- 当前处理中任务数。
- 平均排队时间。
- 平均执行时间。
- 超时任务数。

引擎监控：

- 每个引擎 QPS。
- 成功率。
- 错误率。
- P95 / P99 耗时。
- 并发占用。
- 熔断状态。

GPU 监控：

- GPU 使用率。
- 显存使用。
- 温度。
- 功耗。
- 算法容器显存占用。

接口监控：

- API 请求量。
- HTTP 错误率。
- 慢接口。
- 调用方排行。

### 22.21 审计中心

审计对象：

- 用户登录。
- 任务创建。
- 文件下载。
- 字段修改。
- 整单确认。
- 引擎配置修改。
- 策略发布。
- API 凭证创建和禁用。
- 数据删除。

审计字段：

- 操作人。
- 操作时间。
- 操作对象。
- 操作类型。
- 操作前数据。
- 操作后数据。
- IP。
- User-Agent。
- 请求 ID。

## 23. 后端架构详设

第一阶段建议采用模块化单体，代码边界按领域拆分。每个模块内部可以有 controller、application、domain、infrastructure 四层。

```text
ocr-platform-backend
├─ bootstrap
├─ common
├─ identity
├─ tenant
├─ file
├─ task
├─ engine
├─ document
├─ extraction
├─ form
├─ review
├─ evaluation
├─ monitoring
├─ audit
└─ integration
```

### 23.1 common 模块

职责：

- 统一响应结构。
- 统一异常结构。
- 分页模型。
- 时间处理。
- JSON 工具。
- 操作上下文。
- Trace ID。

不允许：

- 放业务逻辑。
- 放具体 OCR 引擎逻辑。

### 23.2 identity 模块

职责：

- 用户。
- 角色。
- 权限。
- API 凭证。
- OAuth2 / JWT 解析。

核心对象：

- `User`
- `Role`
- `Permission`
- `ApiClient`
- `AccessToken`

### 23.3 tenant 模块

职责：

- 业务系统注册。
- 租户隔离。
- 数据访问边界。
- 调用配额。

第一版如果暂不做复杂多租户，也要保留 `sourceSystem` 和 `tenantId` 字段。

### 23.4 file 模块

职责：

- 文件上传。
- 文件元数据。
- 对象存储读写。
- 文件预览。
- 文件保留策略。
- 文件 hash 去重。

核心对象：

- `StoredFile`
- `FileObject`
- `PreviewImage`
- `RetentionPolicy`

### 23.5 task 模块

职责：

- OCR 任务创建。
- 任务状态机。
- 任务优先级。
- 任务取消。
- 失败重试。
- 任务事件。
- Worker 调度。

核心对象：

- `OcrTask`
- `TaskStatus`
- `TaskEvent`
- `TaskCommand`
- `TaskScheduler`
- `TaskWorker`

状态流转必须由领域服务统一控制，不能由各模块随意更新状态。

### 23.6 engine 模块

职责：

- OCR 引擎注册。
- 端点管理。
- 能力声明。
- 健康检查。
- 并发限流。
- 熔断。
- 引擎调用记录。
- 引擎适配器。

核心对象：

- `OcrEngine`
- `EngineEndpoint`
- `EngineCapability`
- `EngineStrategy`
- `EngineCall`
- `EngineAdapter`
- `EngineRouter`

### 23.7 document 模块

职责：

- 统一 `OcrDocument`。
- 页面、文本块、表格块、版面块。
- 可视化资产。
- 原始结果索引。
- 文档版本。

核心对象：

- `OcrDocument`
- `DocumentPage`
- `TextBlock`
- `TableBlock`
- `LayoutBlock`
- `VisualAsset`
- `RawResultRef`

### 23.8 extraction 模块

职责：

- 键值对抽取。
- 字段候选生成。
- 置信度融合。
- 字典归一。
- 正则校验。
- 规则执行。

核心对象：

- `ExtractedField`
- `FieldCandidate`
- `KeyValuePair`
- `ExtractionRule`
- `NormalizeRule`
- `ValidationResult`

### 23.9 form 模块

职责：

- 表单模板。
- 字段定义。
- 字段别名。
- 字典。
- 回填映射。
- 模板版本。

核心对象：

- `FormTemplate`
- `FormField`
- `FieldAlias`
- `FieldDictionary`
- `FillMapping`
- `TemplateVersion`

### 23.10 review 模块

职责：

- 人工校验任务。
- 字段修正。
- 整单确认。
- 审核记录。
- 修正沉淀。

核心对象：

- `ReviewTask`
- `ReviewRecord`
- `FieldCorrection`
- `ReviewDecision`

### 23.11 evaluation 模块

职责：

- 样张集。
- 标准答案。
- 评估任务。
- 评估指标。
- 引擎对比。

核心对象：

- `EvaluationSet`
- `EvaluationCase`
- `GroundTruth`
- `EvaluationRun`
- `EvaluationMetric`

### 23.12 monitoring 模块

职责：

- 业务指标聚合。
- 引擎指标聚合。
- 队列指标。
- 告警规则。
- 健康状态。

### 23.13 audit 模块

职责：

- 操作审计。
- 数据访问审计。
- 配置变更审计。
- 安全事件。

### 23.14 integration 模块

职责：

- 业务系统回调。
- Webhook。
- Form3 兼容适配。
- 外部 API SDK。

## 24. 关键业务流程详设

### 24.1 创建 OCR 任务流程

```mermaid
sequenceDiagram
  participant B as "业务系统 / 管理端"
  participant A as "API 服务"
  participant F as "文件服务"
  participant T as "任务服务"
  participant Q as "任务队列"

  B->>A: 上传文件并提交任务参数
  A->>F: 保存文件和元数据
  F-->>A: 返回 fileId
  A->>T: 创建 OCR 任务
  T->>T: 校验业务类型、模板、策略
  T->>Q: 写入队列
  T-->>A: 返回 taskId 和状态 QUEUED
  A-->>B: 返回任务编号
```

异常处理：

- 文件保存失败：不创建任务。
- 模板不存在：返回业务错误。
- 策略不存在：使用默认策略或返回错误，取决于业务系统配置。
- 队列已满：返回“系统繁忙”，允许业务系统稍后重试。

### 24.2 Worker 执行流程

```mermaid
sequenceDiagram
  participant W as "Worker"
  participant T as "任务服务"
  participant E as "引擎编排"
  participant D as "文档服务"
  participant X as "抽取服务"
  participant R as "校验服务"

  W->>T: 拉取 QUEUED 任务
  T-->>W: 返回任务并锁定
  W->>T: 状态改为 PREPROCESSING
  W->>E: 按策略调用 OCR 引擎
  E-->>W: 返回引擎结果
  W->>D: 写入 OcrDocument
  W->>X: 执行字段抽取和标准化
  X-->>W: 返回字段结果
  W->>R: 判断是否需要人工校验
  R-->>W: 返回 reviewRequired
  W->>T: 更新为 COMPLETED 或 REVIEW_REQUIRED
```

锁定规则：

- Worker 拉取任务时写入 `lockedBy`、`lockedAt`。
- 超过 `lockTimeout` 未心跳的任务可被恢复。
- 同一任务同一时间只能被一个 Worker 执行。

### 24.3 人工校验流程

```mermaid
stateDiagram-v2
  [*] --> REVIEW_REQUIRED
  REVIEW_REQUIRED --> CLAIMED: 领取
  CLAIMED --> REVIEWING: 开始校验
  REVIEWING --> REVIEW_REQUIRED: 释放
  REVIEWING --> CONFIRMED: 整单确认
  REVIEWING --> REJECTED: 标记无法识别
  CONFIRMED --> [*]
  REJECTED --> [*]
```

校验规则：

- 高置信度且校验通过的字段可以批量确认。
- 必填字段缺失时不能整单自动通过。
- 校验失败字段必须人工确认或标记无法识别。
- 人工确认后的值优先级高于算法值。

### 24.4 多引擎评估流程

```mermaid
sequenceDiagram
  participant U as "算法人员"
  participant P as "评估服务"
  participant E as "引擎编排"
  participant G as "标准答案"
  participant M as "指标计算"

  U->>P: 创建评估任务
  P->>P: 加载样张集
  P->>E: 调用多个引擎
  E-->>P: 返回识别结果
  P->>G: 读取标准答案
  P->>M: 字段级比对
  M-->>P: 返回准确率、覆盖率、耗时
  P-->>U: 生成评估报告
```

## 25. 状态、错误与告警设计

### 25.1 任务状态语义

| 状态 | 含义 | 可操作 |
| --- | --- | --- |
| CREATED | 已创建但未入队 | 取消 |
| QUEUED | 等待 Worker 处理 | 取消、提高优先级 |
| PREPROCESSING | 文件预处理 | 查看 |
| RECOGNIZING | OCR 引擎识别中 | 查看、请求取消 |
| NORMALIZING | 转换统一文档结构 | 查看 |
| EXTRACTING | 字段抽取和标准化 | 查看 |
| REVIEW_REQUIRED | 需要人工校验 | 领取、校验 |
| COMPLETED | 自动完成或人工确认完成 | 查看、下载、回调 |
| FAILED | 失败 | 查看错误、重试 |
| CANCELLED | 已取消 | 查看 |

### 25.2 错误分类

| 错误类型 | 示例 | 处理 |
| --- | --- | --- |
| FILE_ERROR | 文件损坏、格式不支持 | 标记失败，提示重新上传 |
| CONFIG_ERROR | 表单模板缺失、策略缺失 | 标记失败，管理员处理 |
| ENGINE_TIMEOUT | OCR 引擎超时 | 可重试，可触发兜底 |
| ENGINE_ERROR | OCR 引擎 500、返回非法 JSON | 记录原始错误，可重试 |
| NORMALIZE_ERROR | 标准化失败 | 标记技术异常 |
| EXTRACTION_ERROR | 字段抽取失败 | 可进入人工校验 |
| VALIDATION_ERROR | 字段格式不合法 | 进入人工校验 |
| CALLBACK_ERROR | 回调业务系统失败 | 任务完成但回调待重试 |

### 25.3 告警规则

第一版告警：

- 连续 5 分钟任务失败率超过 20%。
- 队列积压超过 100。
- 任一引擎健康检查连续失败 3 次。
- OCR 平均耗时超过基线 2 倍。
- GPU 显存使用超过 95% 持续 5 分钟。
- 回调业务系统失败超过 10 次。

告警渠道：

- 管理端通知。
- 日志。
- 后续可接入短信、邮件、企业微信、钉钉。

## 26. 权限模型

### 26.1 角色

| 角色 | 能力 |
| --- | --- |
| 平台管理员 | 全部配置、用户、引擎、策略、审计 |
| 运维人员 | 任务监控、引擎健康、重试、日志、告警 |
| 算法工程师 | 引擎管理、样张集、评估任务、策略建议 |
| 实施人员 | 表单模板、字段、别名、字典、回填映射 |
| 业务审核员 | 人工校验、字段修正、整单确认 |
| 业务查看员 | 查看任务和结果，不可修改 |
| 外部系统账号 | 通过 API 创建任务、查询结果、接收回调 |

### 26.2 权限点

```text
task:create
task:view
task:cancel
task:retry
task:download
review:claim
review:update
review:confirm
form:manage
engine:manage
engine:test
strategy:publish
evaluation:manage
monitor:view
audit:view
system:manage
```

### 26.3 数据范围

数据范围可按以下维度控制：

- 租户。
- 业务系统。
- 业务类型。
- 表单模板。
- 创建人。
- 所属机构。

第一版至少要支持按业务系统隔离 API 凭证和任务数据。

## 27. API 契约详设

### 27.1 创建任务

```http
POST /api/v1/ocr/tasks
Content-Type: multipart/form-data
Authorization: Bearer <token>
```

请求字段：

| 字段 | 必填 | 说明 |
| --- | --- | --- |
| file | 是 | 图片、PDF、ZIP |
| sourceSystem | 是 | 来源系统 |
| businessType | 是 | 业务类型 |
| templateCode | 否 | 表单模板 |
| strategyCode | 否 | OCR 策略 |
| callbackUrl | 否 | 完成后回调 |
| metadata | 否 | 业务扩展数据 |

响应：

```json
{
  "code": "OK",
  "data": {
    "taskId": "T202605090001",
    "status": "QUEUED",
    "createdAt": "2026-05-09T10:00:00+08:00"
  }
}
```

### 27.2 查询任务

```http
GET /api/v1/ocr/tasks/{taskId}
```

响应重点：

- 当前状态。
- 状态消息。
- 进度。
- 总耗时。
- 是否需要人工校验。
- 失败原因。

### 27.3 获取填表数据

```http
GET /api/v1/ocr/tasks/{taskId}/fill-data?mode=confirmed
```

`mode`：

- `raw`：算法原始字段值。
- `normalized`：标准化字段值。
- `confirmed`：人工确认后的最终值。

响应：

```json
{
  "taskId": "T202605090001",
  "templateCode": "food_license_apply",
  "status": "COMPLETED",
  "fields": {
    "spjy_foodopername": {
      "title": "经营者名称",
      "value": "某某餐饮店",
      "confidence": 0.96,
      "source": "CONFIRMED",
      "warnings": []
    }
  },
  "tables": {},
  "warnings": []
}
```

### 27.4 回调业务系统

```http
POST <callbackUrl>
```

回调事件：

- `ocr.task.completed`
- `ocr.task.review_required`
- `ocr.task.failed`

回调要求：

- 带签名。
- 支持重试。
- 记录每次回调请求和响应。
- 业务系统返回 2xx 才视为成功。

## 28. 数据库设计细化

### 28.1 表分组

任务组：

- `ocr_task`
- `ocr_task_event`
- `ocr_task_lock`
- `ocr_batch`

文件组：

- `ocr_file`
- `ocr_file_object`
- `ocr_visual_asset`

文档组：

- `ocr_document`
- `ocr_page`
- `ocr_text_block`
- `ocr_layout_block`
- `ocr_table_block`
- `ocr_key_value`

引擎组：

- `ocr_engine`
- `ocr_engine_endpoint`
- `ocr_engine_strategy`
- `ocr_engine_call`

表单组：

- `form_template`
- `form_field`
- `field_alias`
- `field_dictionary`
- `fill_mapping`

校验组：

- `review_task`
- `review_record`
- `field_correction`

评估组：

- `evaluation_set`
- `evaluation_case`
- `ground_truth`
- `evaluation_run`
- `evaluation_metric`

系统组：

- `sys_user`
- `sys_role`
- `sys_permission`
- `api_client`
- `audit_log`
- `system_config`

### 28.2 关键索引

- `ocr_task(status, created_at)`：任务列表和调度。
- `ocr_task(source_system, business_type, created_at)`：业务系统查询。
- `ocr_task(template_code, created_at)`：按表单统计。
- `ocr_engine_call(engine_code, operation, started_at)`：引擎指标。
- `ocr_key_value(task_id, field_code)`：查询填表数据。
- `review_task(status, assigned_to, created_at)`：人工校验队列。
- `audit_log(operator_id, created_at)`：审计查询。

### 28.3 数据保留

建议默认：

- 原始上传文件：30 天。
- 可视化图片：30 天。
- 原始请求响应：90 天。
- 标准化结果：按业务要求长期保留。
- 审计日志：至少 180 天。
- 评估样张和标准答案：长期保留。

保留策略必须可按业务系统配置。

## 29. 非功能需求

### 29.1 性能目标

第一版目标：

- 管理端列表查询 P95 小于 1 秒。
- 单张图片 OCR 任务总耗时可观测，不强行承诺固定秒数。
- 任务创建接口 P95 小于 2 秒。
- 任务状态查询 P95 小于 500ms。
- 支持至少 100 个任务排队。
- 支持至少 2 个 OCR 引擎端点。

### 29.2 可用性目标

- API 服务和 Worker 分离，Worker 故障不影响任务查询。
- OCR 引擎故障不影响管理端访问。
- 单个引擎不可用时可停用端点。
- 任务失败必须可重试。
- Worker 重启后可恢复未完成任务。

### 29.3 可扩展性目标

- 新增 OCR 引擎不修改任务服务核心逻辑。
- 新增业务表单不修改 OCR 引擎逻辑。
- 新增字段映射不修改算法适配器。
- 新增评估指标不影响生产任务。

### 29.4 安全目标

- 所有 API 必须鉴权。
- 文件下载必须鉴权和审计。
- API 凭证可禁用、轮换。
- 敏感配置不入库明文。
- LLM prompt 日志可关闭。

## 30. 第一版验收标准

第一版不是“功能看起来有”，而是要满足下面的验收。

### 30.1 任务链路验收

- 可以上传图片创建任务。
- 任务进入队列。
- Worker 可执行任务。
- 任务状态完整流转。
- 失败任务可查看原因并重试。
- 任务详情可看到原图、OCR 文本块、表格和键值对。
- 可以查看全文文本。
- 可以导出 Markdown。
- 可以生成至少一种文档产物，例如可检索 PDF 或 Word/DOCX。

### 30.2 引擎验收

- 可以在管理端配置 OCR 引擎。
- 可以配置至少一个引擎端点。
- 可以健康检查。
- 可以记录每次引擎调用。
- 可以查看引擎平均耗时和错误率。

### 30.3 校验验收

- 低置信度字段进入人工校验。
- 人工可以修改字段值。
- 修改记录可追溯。
- 整单确认后可以输出最终填表数据。

### 30.4 表单验收

- 可以配置表单模板。
- 可以配置字段。
- 可以配置字段别名。
- 可以配置回填映射。
- 填表 API 按业务字段返回数据。

### 30.5 监控验收

- 工作台能看到任务总量、成功率、失败数、排队数。
- 能看到每个 OCR 引擎健康状态。
- 能看到任务平均耗时。
- 能看到失败原因排行。

## 31. 开发拆分建议

### 31.1 第一个开发里程碑

目标：跑通最小闭环。

范围：

- 新项目骨架。
- MySQL / 本地文件存储开发环境。
- 文件上传。
- OCR 任务表。
- Worker。
- 外部 OCR provider 适配器，当前可选 PaddleOCR。
- 原始结果保存。
- 任务详情页面。

### 31.2 第二个开发里程碑

目标：可用的字段抽取和人工校验。

范围：

- `OcrDocument` 标准化。
- 文本块、表格块、键值对展示。
- 表单模板和字段配置。
- 字段别名。
- 字段匹配。
- 人工校验页面。
- 填表数据 API。

### 31.3 第三个开发里程碑

目标：平台化治理。

范围：

- 引擎管理。
- 策略管理。
- 调用指标。
- 工作台首页。
- 任务监控。
- 操作审计。

### 31.4 第四个开发里程碑

目标：算法评估闭环。

范围：

- 样张集。
- 标准答案。
- 多引擎评估。
- 字段准确率统计。
- 评估报告。

## 32. 新项目推荐目录结构

```text
ocr-platform/
├─ backend/
│  ├─ build.gradle.kts
│  ├─ settings.gradle.kts
│  └─ src/main/java/com/zhengmeng/ocrplatform/
│     ├─ OcrPlatformApplication.java
│     ├─ common/
│     ├─ identity/
│     ├─ tenant/
│     ├─ file/
│     ├─ task/
│     ├─ engine/
│     ├─ document/
│     ├─ extraction/
│     ├─ form/
│     ├─ review/
│     ├─ evaluation/
│     ├─ monitoring/
│     ├─ audit/
│     └─ integration/
├─ frontend/
│  ├─ package.json
│  ├─ vite.config.ts
│  └─ src/
│     ├─ app/
│     ├─ pages/
│     ├─ widgets/
│     ├─ features/
│     ├─ entities/
│     └─ shared/
├─ deploy/
│  ├─ docker-compose.dev.yml
│  ├─ docker-compose.prod.yml
│  └─ k8s/
├─ docs/
│  ├─ architecture/
│  ├─ api/
│  ├─ database/
│  └─ operations/
├─ samples/
│  ├─ images/
│  ├─ ground-truth/
│  └─ evaluation-sets/
└─ scripts/
```

前端建议使用 Feature-Sliced Design 或类似分层：

- `app`：应用启动、路由、Provider。
- `pages`：页面级组合。
- `widgets`：页面区块。
- `features`：业务动作。
- `entities`：业务实体。
- `shared`：通用组件、API、工具。

## 33. 待确认问题

启动新项目前需要确认：

- 新项目名称。
- Git 仓库路径。
- MySQL 实例、账号和部署位置。
- 第一批接入的业务系统。
- 第一批表单模板。
- 第一批样张数量。
- 是否要求完全内网部署。
- LLM 是否允许调用外部 API。
- 上传文件和识别结果保留周期。
- 是否需要多机构、多租户。
