# 工具:知识库伴侣(基于Markitdown+PyMuPDF+Tesseract+BERTChunkerChinese2) **Repository Path**: low-code-dev-lab/markitdown-api ## Basic Information - **Project Name**: 工具:知识库伴侣(基于Markitdown+PyMuPDF+Tesseract+BERTChunkerChinese2) - **Description**: 轻量级文档转 Markdown API,提供知识库建设所需的文档内容提取与文本切块功能。 功能特性: - 多格式支持:PDF、Word、Excel、PowerPoint、图片、HTML 等格式 - 多图片识别模式: OCR、VL - 内建文本切块:基于BERT Chunker Chinese 2 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2025-11-21 - **Last Updated**: 2025-12-04 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # MarkItDown API Lite 基于 [markitdown](https://github.com/microsoft/markitdown) 的轻量级文档转 Markdown API 服务。 ## 功能特性 - 📄 **多格式支持**:PDF、Word、Excel、PowerPoint、图片、HTML 等格式 - 🔍 **智能图片识别**: - OCR 文字识别(Tesseract,中英文) - Vision API 智能理解(OpenAI 兼容接口) - 可选忽略图片模式 - ✂️ **智能文本切块**: - 基于 BERT Chunker Chinese 2 的语义切分 - 支持自定义切块大小 - PDF 智能切块(paragraph 合并、OCR 切分、VL/table 保持完整) - 纯文本切块接口 - 📊 **详细日志**:完整的处理时间记录和步骤日志 - 🌐 **URL 处理优化**:直接使用原始 URL,无需预编码 - 🎯 **灵活识别**:URL 推断 + 自定义文件名 + 可选识别模式 - 🐳 **Docker 部署**:一键部署,开箱即用 ## 开发环境 如果您是**开发者**,需要修改代码、调试功能,请查看 **[开发调试指南 (DEV_GUIDE.md)](./DEV_GUIDE.md)**。 **开发模式特点**: - ✅ 代码热重载(修改即生效,无需重启) - ✅ 模型缓存(一次下载,永久使用) - ✅ 快速迭代(秒级启动) **快速开始**: ```bash # Windows dev.bat init # 首次使用:构建镜像并下载模型 dev.bat dev # 启动开发模式 # Linux/Mac make init-cache # 首次使用:构建镜像并下载模型 make dev # 启动开发模式 ``` 详细开发指南、完整命令列表、常见场景请查看 [DEV_GUIDE.md](./DEV_GUIDE.md)。 --- ## 快速开始(生产部署) ### 方式一:Docker Compose 部署 **1. 编辑 .env 文件,配置 API 密钥:** ```bash # Vision API 配置(阿里云百炼示例) VL_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1 VL_API_KEY=sk-xxx # 替换为您的 API Key VL_MODEL=qwen-vl-plus ``` **2. 启动服务:** ```bash docker-compose up -d --build ``` 配置会自动从 `.env` 文件加载环境变量。执行前需要确定本地的 Docker 服务(如 Windows Docker Desktop)已经正常启动。 ### 方式二:使用预构建镜像部署 **1. 拉取镜像:** ```bash docker pull crpi-4auaoyyj6r36p6lb.cn-hangzhou.personal.cr.aliyuncs.com/huozige_lab/markitdown-api-lite:[版本号] ``` > **提示**: > - 上述 Docker 镜像为 x64 架构。若在 arm64 架构上运行,需要获取代码,使用 arm64 架构另行编译。 > - [版本号]请参见本项目的[“发行版”](https://gitee.com/low-code-dev-lab/markitdown-api/releases),如2.1.2。 **2. 启动服务:** ```bash docker run -d --name markitdown-api-lite --restart unless-stopped --network=host \ -p 8300:8300 \ -v ./data:/app/data \ -e VL_BASE_URL="https://dashscope.aliyuncs.com/compatible-mode/v1" \ -e VL_API_KEY="sk-xxx" \ -e VL_MODEL="qwen-vl-plus" \ -e DATA_DIR=/app/data \ crpi-4auaoyyj6r36p6lb.cn-hangzhou.personal.cr.aliyuncs.com/huozige_lab/markitdown-api-lite:[版本号] ``` > **注意**: > - 如需在局域网内使用,需要增加--network=host,以便于使用宿主机的DNS地址,用来访问到宿主机或其他服务器上的文件。如果您的宿主机是Windows Docker Desktop,您需要前往Docker Desktop的【设置】界面,在【Resource】下找到【Network】选项卡,勾选【Enable host networking】来启用对该功能的支持。 > - 如需在广域网使用,需确保指定的端口已经允许公开访问。 ### 访问地址 - API 服务:http://localhost:8300 - API 文档:http://localhost:8300/docs ## API 接口 ### POST /convert2 从URL转换文档为 Markdown。 **请求示例(OCR 模式)**: ```bash curl -X POST "http://localhost:8300/convert2" \ -H "Content-Type: application/json" \ -d '{ "url": "http://example.com/document.pdf", "name": "document.pdf", "image_process_model": "ocr" }' ``` **请求示例(Vision API 模式)**: ```bash # 需先配置环境变量(阿里云百炼) export VL_BASE_URL="https://dashscope.aliyuncs.com/compatible-mode/v1" export VL_API_KEY="sk-xxx" export VL_MODEL="qwen-vl-plus" curl -X POST "http://localhost:8300/convert2" \ -H "Content-Type: application/json" \ -d '{ "url": "http://example.com/presentation.pptx", "image_process_model": "vl" }' ``` **参数说明**: - `url`(必需):文档的URL地址 - 直接使用原始 URL,**无需预编码** - 支持中文、特殊字符(`%`、`&`、空格、引号等) - `name`(可选):文件名,用于推断文件类型。如果不提供,则从URL或Content-Type自动推断 - `image_process_model`(可选,默认 `"ocr"`):图片识别模式 - `"ocr"`:使用 Tesseract OCR 识别文字(默认) - `"vl"`:使用 Vision API 理解图片内容(需配置环境变量) - `"none"`:忽略所有图片,仅提取文本 - `max_chunk_size`(可选,默认 `0`):文本切块大小(字符数) - `0`:不切块,返回完整文档 - `> 0`:使用 BERT 语义切分,每个块不超过指定大小 **优势**: - ✅ 使用 JSON body 传递 URL,避免 query 参数的编码问题 - ✅ **URL 处理简化**:直接传递原始 URL,内部智能处理编码 - ✅ 支持指定文件名,精确控制文件类型识别 - ✅ 灵活的图片识别模式:OCR / Vision API / 忽略 - ✅ 完整的错误处理和日志信息 **响应示例**: ```json { "success": true, "url": "http://example.com/document.pdf", "name": "document.pdf", "markdown": "# 文档标题\n\n转换后的内容...\n\n```ocr\n图片识别的文字\n```", "chunks": [ "# 文档标题\n\n第一部分内容...", "第二部分内容...", "图片识别的文字..." ], "logs": "========== 开始处理请求 ==========\nURL: http://example.com/document.pdf\n图片识别模式: OCR\n切块大小: 500 字符\n--- 步骤1: 下载文件 ---\n下载完成,耗时: 1.23秒\n--- 步骤2: 转换为Markdown ---\nPDF处理完成,共生成 45 个区块,总耗时: 8.76秒\n--- 步骤3: 文本切块 ---\n切片完成,共 12 个块,耗时: 2.34秒\n========== 处理完成,总耗时: 12.33秒 ==========" } ``` **使用场景**: 1. **普通 URL(默认 OCR 模式)**: ```bash curl -X POST "http://localhost:8300/convert2" \ -H "Content-Type: application/json" \ -d '{"url": "http://example.com/doc.pdf"}' ``` 2. **包含特殊字符的 URL**(直接传递,无需编码): ```bash curl -X POST "http://localhost:8300/convert2" \ -H "Content-Type: application/json" \ -d '{ "url": "http://server.com/文件/复杂文件名-带特殊字符%26.pptx", "name": "演示文档.pptx" }' ``` 3. **使用 Vision API 模式**(需先配置环境变量): ```bash curl -X POST "http://localhost:8300/convert2" \ -H "Content-Type: application/json" \ -d '{ "url": "http://example.com/presentation.pptx", "image_process_model": "vl" }' ``` 注:需配置阿里云百炼或其他 Vision API 的环境变量 4. **忽略图片,仅提取文本**: ```bash curl -X POST "http://localhost:8300/convert2" \ -H "Content-Type: application/json" \ -d '{ "url": "http://example.com/document.pdf", "image_process_model": "none" }' ``` 5. **URL 无扩展名时指定文件类型**: ```bash curl -X POST "http://localhost:8300/convert2" \ -H "Content-Type: application/json" \ -d '{ "url": "http://example.com/download?id=123", "name": "presentation.pptx" }' ``` 6. **文本切块(500 字符/块)**: ```bash curl -X POST "http://localhost:8300/convert2" \ -H "Content-Type: application/json" \ -d '{ "url": "http://example.com/document.pdf", "image_process_model": "ocr", "max_chunk_size": 500 }' ``` ### POST /chunk 对文本内容进行语义切块(不需要转换文档,直接切块)。 **请求示例**: ```bash curl -X POST "http://localhost:8300/chunk" \ -H "Content-Type: application/json" \ -d '{ "content": "这是一段很长的文本内容...", "max_chunk_size": 500 }' ``` **参数说明**: - `content`(必需):要切块的文本内容(推荐 Markdown 格式) - `max_chunk_size`(可选,默认 `0`):切块大小(字符数) - `0`:不切块,返回完整文本 - `> 0`:使用 BERT 语义切分 **响应示例**: ```json { "success": true, "chunks": [ "第一个文本块...", "第二个文本块...", "第三个文本块..." ], "logs": "========== 开始文本切块 ==========\n文本长度: 2500 字符\n目标块大小: 500 字符\n[BERT切块] BERT分块耗时: 0.45秒,初步分成 8 个块\n切片完成,共 6 个块,耗时: 0.47秒\n========== 处理完成,总耗时: 0.47秒 ==========" } ``` **特点**: - ✅ 基于 BERT Chunker Chinese 2 的语义理解 - ✅ 确保切分点符合语义边界 - ✅ 详细的处理时间和日志 - ✅ 适用于已转换的 Markdown 文本 ### GET /health 健康检查。 ```bash curl http://localhost:8300/health ``` ## URL 处理说明 本服务采用**简化的 URL 处理方式**: ✅ **直接使用原始 URL** - 服务端**直接**使用您传递的 URL,不做任何编码转换 - 这意味着您应该传递**已正确编码**的 URL ✅ **推荐做法** - 如果 URL 来自服务器 API 响应,通常已经正确编码,**直接传递即可** - 如果 URL 包含中文或特殊字符,请在客户端**预先编码** ✅ **工作原理** - 服务端接收到什么 URL,就请求什么 URL - 由 httpx 库负责底层的 HTTP 请求 - 简单透明,避免复杂的编码/解码逻辑 **示例 1 - 已编码的 URL(推荐)**: ```json { "url": "http://server.com/files/document%20with%20spaces.pdf" } ``` ✅ 服务端直接使用此 URL **示例 2 - 服务器返回的 URL**: ```json { "url": "http://10.32.210.55/upload/file-特殊字符%26.pptx" } ``` ✅ 如果这是服务器返回的 URL,直接传递即可 **示例 3 - 如果 URL 包含未编码的中文**: 建议在客户端先编码: ```python from urllib.parse import quote url = f"http://server.com/{quote('文件', safe='')}/doc.pdf" # 结果: http://server.com/%E6%96%87%E4%BB%B6/doc.pdf ``` ## 支持格式 | 格式 | 扩展名 | 图片识别 | |------|--------|----------| | PDF | `.pdf` | ✅ OCR / VL / None | | Word | `.docx`, `.doc` | ✅ OCR / VL / None | | PowerPoint | `.pptx`, `.ppt` | ✅ OCR / VL / None | | Excel | `.xlsx`, `.xls` | ✅ OCR / VL / None | | 图片 | `.jpg`, `.jpeg`, `.png`, `.gif`, `.bmp` | ✅ OCR / VL / None | | HTML | `.html` | ✅ OCR / VL / None | | 文本 | `.txt`, `.json`, `.xml` | - | ## 图片识别模式 ### 1. OCR 模式(默认) 使用 Tesseract OCR 识别图片中的文字。 **特点**: - ✅ 无需额外配置,开箱即用 - ✅ 支持中英文混合识别(`chi_sim+eng`) - ✅ 识别结果以 ` ```ocr ` 代码块格式嵌入 **输出示例**: ````markdown ```ocr 图片中的文字内容 ``` ```` ### 2. Vision API 模式 使用 OpenAI 兼容的 Vision API 理解图片内容。 **智能上下文识别**: - ✅ 自动提取图片前后各 500 字符的原始文本作为上下文 - ✅ 将上下文信息传递给 Vision API,提升识别准确性 - ✅ 超过 500 字符时自动截断,前面显示 "...xxxxxx",后面显示 "yyyyyy..." - ✅ 格式:`参考的上下文信息:{context_before} [需要识别的图片] {context_after}` **获取阿里云百炼 API Key**: 1. 访问 [阿里云百炼控制台](https://bailian.console.aliyun.com/) 2. 进入 API-KEY 管理页面 3. 创建并复制 API-KEY **支持的模型**: - `qwen-vl-max`:效果最佳的视觉理解模型 - `qwen-vl-plus`:速度更快,性价比高(推荐) **其他 OpenAI 兼容服务**: 除了阿里云百炼,也支持其他 OpenAI 兼容接口,例如: - **OpenAI**:`https://api.openai.com/v1`(模型:`gpt-4o`, `gpt-4o-mini`) - **月之暗面**:`https://api.moonshot.cn/v1`(模型:`moonshot-v1-vision`) - **智谱AI**:`https://open.bigmodel.cn/api/paas/v4`(模型:`glm-4v-plus`) **特点**: - ✅ 深度理解图片内容(不仅仅是文字) - ✅ 支持所有 OpenAI 兼容接口 - ✅ **智能上下文感知**:自动提取图片周围文本,提升识别准确性 - ✅ 自动回退:若未配置,自动使用 OCR - ✅ 识别结果以 ` ```vl ` 代码块格式嵌入 **上下文识别工作原理**: 对于 **PDF** 和 **Office** 文档: 1. 系统会自动定位图片在文档中的位置 2. 提取图片前面最多 500 字符的文本 3. 提取图片后面最多 500 字符的文本 4. 将上下文和图片一起发送给 Vision API 5. Vision API 结合上下文理解图片内容,提供更准确的描述 **输出示例**: ````markdown ```vl 这是一张展示产品功能的流程图,包含... ``` ```` ### 3. None 模式 完全忽略图片,仅提取文本内容。 **特点**: - ✅ 跳过所有图片处理 - ✅ 大幅提升处理速度 - ✅ 适合纯文本提取场景 ## 文本切块功能 ### 智能语义切分 基于 **BERT Chunker Chinese 2** 模型进行智能语义切分,确保切分点符合语义边界。 **核心特性**: - ✅ 语义理解:使用 BERT 模型分析文本语义,在合适的位置切分 - ✅ 灵活配置:支持自定义切块大小(字符数) - ✅ 智能回���:如果语义块过大,自动按句子分割 - ✅ 强制切分:如果单句超长,按字符强制切分 ### PDF 文档的特殊切块规则 对于 PDF 文档,系统会根据内容类型采用不同的切块策略: | 内容类型 | 切块策略 | 说明 | |---------|---------|------| | **paragraph**(段落) | ✂️ 合并后语义切分 | 连续段落合并后使用 BERT 切分 | | **OCR**(扫描文字) | ✂️ 语义切分 | 清除代码块标记后使用 BERT 切分 | | **VL**(图片理解) | ✅ 保持完整 | 保持 Vision API 生成的完整描述 | | **table**(表格) | ✅ 保持完整 | 保持表格结构完整 | | **image**(图片) | ✅ 保持完整 | 保持图片描述完整 | | **toc**(目录) | ⏭️ 跳过 | 不输出到切片结果 | **设计理念**: - 对于**纯文本内容**(paragraph、OCR),可以安全地进行语义切分 - 对于**结构化内容**(table、VL、image),保持完整性更重要 - 对于**目录内容**(toc),通常不需要在切片中保留 ### 切块示例 **输入文档**(包含段落、OCR、表格、VL): ```markdown 这是第一段文字,包含大量内容...(400字) 这是第二段文字...(300字) ```ocr 扫描识别的文字内容...(600字) ``` | 表头1 | 表头2 | |------|------| | 数据1 | 数据2 | ...(800字) ```vl 这是一张展示产品功能的流程图...(150字) ``` ``` **切块结果**(max_chunk_size=500): ``` 块1: 这是第一段文字,包含大量内容...这是第二段文字...(700字合并后切分为块1) 块2: ...剩余段落内容...(切分后的块2) 块3: 扫描识别的文字内容第一部分...(OCR内容切分的块1) 块4: 扫描识别的文���内容第二部分...(OCR内容切分的块2) 块5: | 表头1 | 表头2 |...(表格完整保留,800字) 块6: 这是一张展示产品功能的流程图...(VL完整保留,150字) ``` ### 使用建议 **选择合适的切块大小**: - **300-500 字符**:适合问答系统、向量检索 - **500-800 字符**:适合摘要生成、语义搜索 - **800-1000 字符**:适合长文本理解、上下文分析 **注意事项**: - 表格和 VL 描述**不受 max_chunk_size 限制**,会完整保留 - 如果文档包含大量表格,最终切片可能超过预期数量 - 建议根据实际内容类型调整切块策略 ## 环境变量配置 ### 超时配置(针对大文档) 为了支持大尺寸文档的处理,系统提供了可配置的超时时间: | 环境变量 | 默认值 | 说明 | |---------|--------|------| | `DOWNLOAD_TIMEOUT` | 300 秒(5 分钟) | 文件下载超时时间 | | `VL_API_TIMEOUT` | 120 秒(2 分钟) | Vision API 单次调用超时 | **配置方式:** 在 `.env` 文件中添加: ```bash # 增加下载超时到 10 分钟(处理超大文件) DOWNLOAD_TIMEOUT=600 # 增加 Vision API 超时到 3 分钟(处理复杂图片) VL_API_TIMEOUT=180 ``` 或在 Docker 运行时指定: ```bash docker run -d --name markitdown-api-lite \ -e DOWNLOAD_TIMEOUT=600 \ -e VL_API_TIMEOUT=180 \ ... ``` **推荐配置:** - 小文档(< 10MB):使用默认配置 - 中等文档(10-50MB):`DOWNLOAD_TIMEOUT=600` - 大文档(> 50MB):`DOWNLOAD_TIMEOUT=1200`,`VL_API_TIMEOUT=300` ## 项目结构 ``` markitdown-api-lite/ ├── app/ │ ├── main.py # FastAPI 应用 │ ├── routes.py # API 路由 │ ├── core.py # 核心转换逻辑 │ ├── chunk.py # 文本切块模块(BERT Chunker) │ ├── schemas.py # 数据模型 │ ├── config.py # 配置管理 │ ├── download.py # 文件下载模块 │ └── processor/ # 文档处理器 │ ├── pdf_processor.py # PDF 处理 │ ├── office_processor.py # Office 文档处理 │ ├── image_processor.py # 图片处理 │ ├── pdf_types.py # PDF 数据类型 │ └── utils/ # 工具函数 │ ├── pdf_*.py # PDF 处理工具 │ ├── image_ocr_utils.py # OCR 识别 │ ├── image_vl_utils.py # Vision API 识别 │ └── common_utils.py # 通用工具 ├── Dockerfile ├── docker-compose.yml └── pyproject.toml ``` ## 技术栈 - **Web 框架**:FastAPI + Uvicorn - **文档转换**:MarkItDown - **文本切块**:BERT Chunker Chinese 2(语义分块) - **图片识别**: - Tesseract OCR(文字识别) - OpenAI Vision API(智能理解) - **PDF 处理**:PyMuPDF (fitz) - **HTTP 客户端**:httpx(异步) - **运行环境**:Python 3.12 + uv ## License MIT