From 3db894b344ef41b69de69c3c7a4d772f0b7d80fa Mon Sep 17 00:00:00 2001 From: imac-maxwell Date: Tue, 9 Dec 2025 09:58:22 +0800 Subject: [PATCH] vault backup: 2025-12-09 09:58:22 --- app_prd/Document Converter Backend Service.md | 216 ++++++++++++++++++ 1 file changed, 216 insertions(+) create mode 100644 app_prd/Document Converter Backend Service.md diff --git a/app_prd/Document Converter Backend Service.md b/app_prd/Document Converter Backend Service.md new file mode 100644 index 0000000..39c70de --- /dev/null +++ b/app_prd/Document Converter Backend Service.md @@ -0,0 +1,216 @@ +这是一个为后端开发团队准备的、基于 RESTful 标准的**通用文档转换服务(Universal Document Converter, UDC)**的产品需求文档(PRD)。 + +--- + +# 产品需求文档:通用文档转换服务 (UDC) +**Universal Document Converter - Backend Service** + +| 文档版本 | V1.0 | +| :--- | :--- | +| **最后更新** | 2025-12-09 | +| **状态** | 待开发 | +| **涉及端** | 后端 API, 异步 Worker, 对象存储 | + +--- + +## 1. 项目背景与目标 +### 1.1 背景 +在构建智能题库、知识库或 RAG(检索增强生成)应用时,需要处理大量非结构化文档(PDF, Word, Excel, 图片等)。当前的痛点在于不同格式的解析方式不统一,且由 OCR 产生的图片资源难以直接被大模型引用。 + +### 1.2 目标 +构建一个独立、无状态、高性能的**文档转换微服务**。 +* **输入**:支持 PDF, DOCX, DOC, XLSX, PPTX, JPG/PNG, Markdown。 +* **核心能力**: + 1. **格式统一**:将异构文档转换为标准 Markdown(便于 LLM 处理)。 + 2. **逆向生成**:将 Markdown 转换为排版精美的 DOCX/PDF(便于人类阅读)。 + 3. **资产云化**:自动提取文档中的图片/公式截图,上传至 MinIO,并替换 Markdown 中的链接为永久 URL。 + 4. **样式定制**:支持通过 Word 模板定义输出文档的排版样式。 +* **输出**:标准 RESTful API,提供转换结果的 JSON 数据(含 MinIO 链接)或文件流。 + +--- + +## 2. 系统架构设计 + +系统采用 **异步任务队列** 架构,以应对 MinerU (OCR) 等高算力消耗场景。 + +### 2.1 核心组件 +1. **API Gateway (FastAPI)**: 接收 HTTP 请求,鉴权,文件校验,上传源文件至 MinIO `raw/` 桶,发布任务至 Redis。 +2. **Task Broker (Redis)**: 维护任务队列(区分 `gpu-queue` 和 `cpu-queue`)。 +3. **Worker Cluster (Celery)**: + * **GPU Worker**: 部署 MinerU (Magic-PDF),处理 PDF/Image -> Markdown。 + * **CPU Worker**: 部署 Pandoc, Python-Pandas, WPS-Python-RPC。处理 Docx/Excel -> Markdown 以及 Markdown -> Docx。 +4. **Storage (MinIO)**: + * `udc-raw`: 存放用户上传的原始文件(生命周期:1天)。 + * `udc-assets`: 存放解析出的图片资源(永久保存)。 + * `udc-results`: 存放生成的 Markdown/Docx 结果文件(永久保存)。 + * `udc-templates`: 存放用户上传的 Word 样式模板。 + +--- + +## 3. 功能需求详细说明 + +### 3.1 核心转换逻辑 (Router Strategy) + +根据输入文件类型 (`input_format`) 和目标格式 (`target_format`) 自动路由。 + +| 输入格式 | 目标格式 | 处理引擎/逻辑 | 资源处理 | 备注 | +| :--- | :--- | :--- | :--- | :--- | +| **PDF / Image** | Markdown | **MinerU (GPU)** | 提取截图 -> 上传 MinIO -> 替换链接 | 核心场景 | +| **DOCX** | Markdown | **Pandoc** | Extract Media -> 上传 MinIO -> 替换链接 | 保留公式 Latex | +| **DOC** | Markdown | **LibreOffice/WPS** 转 PDF -> **MinerU** | 同 PDF 流程 | 解决旧版公式问题 | +| **XLSX / XLS** | Markdown | **Pandas** | 纯文本/Markdown Table 拼接 | 忽略 Excel 内嵌图 | +| **Markdown** | DOCX | **Pandoc** (+Reference Doc) | 下载网络图 -> 嵌入 Word | 支持样式模板 | +| **Markdown** | PDF | **Pandoc** -> DOCX -> **LibreOffice** | 同上 | 间接生成 | + +### 3.2 资产管理 (Asset Pipeline) +任何转换过程中产生的本地图片(如 OCR 截图、Word 中的插图),必须经过以下流水线: +1. **提取**: 解析器将图片存放在临时目录 `/tmp/task_id/images/`。 +2. **哈希重命名**: 计算文件 MD5,重命名为 `md5.jpg` (防止重复存储)。 +3. **上传**: 上传至 MinIO `udc-assets/{date}/{md5}.jpg`。 +4. **替换**: 在生成的 Markdown 文本中,将 `![](images/a.jpg)` 替换为 `![](https://minio.host/udc-assets/.../md5.jpg)`。 + +### 3.3 样式模板管理 +* 允许用户上传 `.docx` 文件作为“参考文档” (Reference Doc)。 +* 在 Markdown -> DOCX 转换时,通过 `--reference-doc` 参数应用字体、字号、页边距等样式。 + +--- + +## 4. API 接口定义 (RESTful) + +**Base URL**: `/api/v1` + +### 4.1 提交转换任务 +* **Endpoint**: `POST /conversions` +* **Content-Type**: `multipart/form-data` +* **Description**: 提交一个文件进行转换。 + +**Request Parameters:** + +| 参数名 | 类型 | 必填 | 说明 | +| :--- | :--- | :--- | :--- | +| `file` | File | 是 | 二进制文件流 | +| `target_format` | String | 是 | `markdown`, `docx`, `pdf` | +| `output_mode` | String | 否 | `url` (默认,存MinIO返回链接), `archive` (返回ZIP流) | +| `template_id` | String | 否 | 仅当 `target_format=docx` 时有效,指定使用的样式模板ID | +| `is_ocr` | Boolean | 否 | 默认 `false`。若为 `true`,即使是电子版 PDF 也强制走 OCR | +| `callback_url` | String | 否 | 任务完成后的 Webhook 回调地址 | + +**Response (202 Accepted):** +```json +{ + "task_id": "550e8400-e29b-41d4-a716-446655440000", + "status": "queued", + "eta_seconds": 30 +} +``` + +### 4.2 查询任务状态/结果 +* **Endpoint**: `GET /conversions/{task_id}` +* **Description**: 轮询任务状态。 + +**Response (Processing):** +```json +{ + "task_id": "...", + "status": "processing", + "progress": 45 // 0-100 +} +``` + +**Response (Success - URL Mode):** +```json +{ + "task_id": "...", + "status": "success", + "completed_at": "2025-12-09T10:00:00Z", + "result": { + // 如果目标是 Markdown,直接把内容返回来方便前端预览/LLM读取 + "content": "# 标题\n\n正文内容...![](https://minio.../img.jpg)", + // 结果文件的下载地址 + "file_url": "https://minio.host/udc-results/task_id/result.md", + // 提取出的图片列表 (方便调试) + "images": [ + "https://minio.host/udc-assets/2025/abc.jpg", + "https://minio.host/udc-assets/2025/def.png" + ] + } +} +``` + +### 4.3 上传样式模板 +* **Endpoint**: `POST /templates` +* **Content-Type**: `multipart/form-data` +* **Description**: 上传一个 `.docx` 文件作为排版模板。 + +**Request:** `file` (binary), `name` (string) + +**Response (201 Created):** +```json +{ + "template_id": "tpl_01HE...", + "name": "学校试卷标准模板", + "url": "https://minio.host/udc-templates/tpl_01HE.docx" +} +``` + +### 4.4 预览/下载文件 (Proxy) +* **Endpoint**: `GET /files/{bucket}/{path}` +* **Description**: (可选) 如果 MinIO 不对外直接暴露,通过此接口代理下载或预览文件。 + +--- + +## 5. 数据存储方案 + +### 5.1 Redis Key 设计 +* `task:queue:gpu`: List, 待处理的 OCR 任务。 +* `task:queue:cpu`: List, 待处理的 Office/Pandoc 任务。 +* `task:status:{task_id}`: Hash, 存储任务状态、进度、结果 JSON。过期时间 24 小时。 + +### 5.2 MinIO Bucket 策略 +* **udc-raw**: Lifecycle Rule = expire after 1 day. +* **udc-assets**: Policy = ReadOnly (Public or Signed URL). +* **udc-templates**: Policy = ReadOnly. + +--- + +## 6. 非功能需求 (NFR) + +1. **幂等性**: 对同一文件的重复上传(MD5相同),如果参数一致,应直接返回之前的 `task_id` 或缓存结果(可选优化)。 +2. **并发控制**: MinerU 极其消耗显存。需要通过 Celery 的 `worker_concurrency` 严格限制 GPU Worker 的并发数(例如 1个 GPU 对应 1-2 个并发),防止 OOM。 +3. **超时处理**: + * Docx 转换超时:60秒。 + * PDF OCR 超时:300秒(视页数而定)。 +4. **异常处理**: + * 如果 OCR 失败,应在 Response 中返回 `error_code` 和 `error_msg`。 + * 支持“部分成功”:如果文档有 100 页,解析到 99 页挂了,应尽量返回已解析的内容。 + +--- + +## 7. 错误码定义 + +| Code | Message | Description | +| :--- | :--- | :--- | +| `4001` | `unsupported_format` | 不支持的文件扩展名 | +| `4002` | `template_not_found` | 指定的 Template ID 不存在 | +| `5001` | `ocr_engine_error` | MinerU 内部错误 (显存不足或模型加载失败) | +| `5002` | `conversion_timeout` | 转换超时 | +| `5003` | `storage_error` | MinIO 上传失败 | + +--- + +## 8. 开发阶段规划 + +### Phase 1: 基础框架 (CPU Worker) +* 完成 FastAPI + Redis + Celery 搭建。 +* 实现 Pandoc 转换逻辑 (Docx <-> Markdown)。 +* 实现 MinIO 上传与链接替换逻辑。 + +### Phase 2: GPU 核心 (GPU Worker) +* 集成 MinerU SDK。 +* 处理 PDF 转 Markdown 流程。 +* 优化大文件上传和处理超时设置。 + +### Phase 3: 模板与优化 +* 实现 `/templates` 接口。 +* 实现 Pandoc `reference-doc` 逻辑。 +* Docker 镜像封装 (分离 CPU/GPU 镜像)。 \ No newline at end of file