无状态的文档预处理服务,供 Dify 工作流通过 HTTP 调用。接收用户上传的原始文档,完成解析 → 清洗 → 摘要生成 → 智能切片四步处理,返回结构化 JSON 切片数据。
- 多格式解析:PDF / DOCX / TXT / MD / CSV
- 文档类型识别:自动识别
notice(通知)/meeting_minutes(会议纪要)/manual(操作手册),也可由调用方显式指定 - 差异化切片:按文档类型映射默认策略(
hierarchical/paragraph/fixed_size),步骤列表保持原子性不拆散 - LLM 摘要:Anthropic Messages API 兼容,调用失败自动降级为文档前 200 字,不影响整体处理
- 图片提取:文字型图片 OCR 提取文字替代图片;非文字型图片上传对象存储(S3 兼容),切片中保留
 - 结构化元数据:每个切片绑定
page/section/heading/doc_type/file_name
FastAPI · PyMuPDF · python-docx · RapidOCR(ONNX) · boto3 · httpx · uv
uv sync
uv run uvicorn app.main:app --reloadpip install -r requirements.txt # 运行依赖(版本锁定)
pip install -r requirements-dev.txt # 开发/测试依赖(pytest)
uvicorn app.main:app --reload启动后接口文档见 http://localhost:8000/docs(Swagger UI)。
# 基础解析 + 切片(自动识别文档类型与策略)
curl -F "file=@manual.pdf" http://localhost:8000/api/v1/documents/parse-and-chunk
# 指定文档类型与切片策略
curl -F "file=@notice.txt" -F "doc_type=notice" -F "chunk_strategy=paragraph" \
http://localhost:8000/api/v1/documents/parse-and-chunk
# 开启图片提取
curl -F "file=@manual.pdf" -F "extract_images=true" http://localhost:8000/api/v1/documents/parse-and-chunk成功响应(HTTP 200):
{
"status": "success",
"metadata": {
"file_name": "操作手册v2.pdf",
"file_type": "pdf",
"file_size": 2048000,
"page_count": 15,
"doc_type": "manual",
"parse_time": "2026-08-13T10:30:00Z"
},
"summary": "本文档为XX系统操作手册,涵盖用户管理、权限配置、数据导出等核心功能的操作说明。",
"chunk_strategy": {
"method": "hierarchical",
"chunk_size": 512,
"chunk_overlap": 50,
"separators": ["\n## ", "\n### ", "\n\n", "\n", "。"]
},
"chunks": [
{
"index": 0,
"content": "## 第一章 用户管理\n\n本章节介绍系统的用户管理功能...",
"metadata": {
"page": 1,
"section": "第一章",
"heading": "用户管理",
"doc_type": "manual",
"file_name": "操作手册v2.pdf"
}
}
],
"images": [],
"total_chunks": 23
}错误响应(HTTP 4xx / 5xx):
{
"status": "error",
"error_code": "UNSUPPORTED_FORMAT",
"message": "不支持的文件格式: .exe,支持的格式为: pdf, docx, txt, md, csv",
"metadata": { "file_name": "test.exe", "file_type": "exe", "file_size": 1024 }
}错误码:UNSUPPORTED_FORMAT(400) / FILE_TOO_LARGE(400) / FILE_CORRUPTED(400) / MISSING_FILE(400) / PARSE_FAILED(500) / STORAGE_NOT_CONFIGURED(500) / IMAGE_UPLOAD_FAILED(500)。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
file |
File | 是 | 上传的文档,支持 pdf / docx / txt / md / csv,上限 50MB |
doc_type |
String | 否 | notice / meeting_minutes / manual,不传时自动识别 |
chunk_strategy |
String | 否 | auto(默认)/ hierarchical / paragraph / fixed_size |
chunk_size |
Integer | 否 | 最大切片字符数,默认 512,范围 100~2000 |
chunk_overlap |
Integer | 否 | 相邻切片重叠字符数,默认 50,范围 0~200 |
generate_summary |
Boolean | 否 | 是否生成 LLM 摘要,默认 true |
extract_images |
Boolean | 否 | 是否提取文档图片,默认 false |
默认复用当前接入的 Anthropic 兼容端点,可用 LLM_* 覆盖:
| 环境变量 | 默认来源 | 说明 |
|---|---|---|
LLM_BASE_URL |
ANTHROPIC_BASE_URL(如 DeepSeek Anthropic 兼容端点 https://api.deepseek.com/anthropic) |
端点地址 |
LLM_API_KEY |
ANTHROPIC_AUTH_TOKEN |
API 密钥 |
LLM_MODEL |
ANTHROPIC_MODEL |
模型名 |
LLM_MAX_OUTPUT_TOKENS |
300 | 输出上限(中文 200 字 ≈ 200-300 token) |
LLM_TIMEOUT |
30(秒) | 请求超时 |
LLM_MAX_INPUT_CHARS |
None(全文不截断) | 可设上限控制输入长度 |
未配置或调用失败时降级为文档前 200 字,不影响整体处理。
S3 兼容存储(MinIO / 阿里云 OSS):
| 环境变量 | 说明 |
|---|---|
STORAGE_ENDPOINT |
存储端点,本地 MinIO 如 http://127.0.0.1:9000 |
STORAGE_BUCKET |
存储桶名 |
STORAGE_ACCESS_KEY / STORAGE_SECRET_KEY |
访问凭据 |
STORAGE_REGION |
区域(可选) |
STORAGE_PUBLIC_URL_PREFIX |
公开访问 URL 前缀(如 CDN 域名),为空时用 endpoint/bucket 拼接 |
STORAGE_PATH_PREFIX |
对象 key 前缀,默认 docs/ |
未配置对象存储时,若遇到需存储的非文字型图片将返回 STORAGE_NOT_CONFIGURED(500)。
├── app/
│ ├── main.py # FastAPI 入口
│ ├── api/v1/ # 路由层(documents.py / router.py)
│ ├── core/ # 配置与异常(config.py / exceptions.py)
│ ├── domain/ # 领域模型(block.py)
│ ├── schemas/ # Pydantic 请求/响应模型
│ ├── services/
│ │ ├── document_service.py # 服务编排(校验→解析→识别→摘要→切片)
│ │ ├── chunking.py # 切片策略(hierarchical/paragraph/fixed_size)
│ │ ├── doc_type.py # 文档类型识别
│ │ ├── llm.py # LLM 摘要(httpx + Anthropic Messages API)
│ │ ├── image_processor.py # 图片分类(OCR vs 存储)
│ │ ├── ocr.py # RapidOCR 封装
│ │ ├── storage.py # S3 对象存储上传
│ │ ├── validation.py # 文件校验
│ │ └── parsers/ # 格式解析器(pdf/docx/text/csv/base)
│ └── utils/ # 日志等
├── tests/ # pytest 测试
├── pyproject.toml # 项目元数据与依赖(uv 为准)
├── uv.lock # 依赖锁文件
├── requirements.txt # pip 运行依赖(由 uv.lock 导出)
└── requirements-dev.txt # pip 测试依赖(由 uv.lock 导出)
uv run pytest -v- 不支持整页扫描件的文本层重建(图片内文字通过图片级 OCR 提取)。
- DOCX 页码为字符数估算,块级
page为 null。 fixed_size策略不保留 page/section/heading 元数据,图片提取建议配合 hierarchical/paragraph 使用。
本项目目前未指定开源许可证,如有需要可自行添加(如 MIT)。