XinheBot 芯禾巡检平台
复杂文档解析模块(多文档 OCR 解析)· 产品需求文档(PRD)
版本 V3.0 | 洪妍灵 | 2026-09-27 | 状态:待评审
目录
- 背景与目标
- 范围与术语
- 用户与使用场景
- 功能需求
- 技术架构与选型
- 数据管理方案
- RAG 检索链路
- RAG 索引优化
- Map-Reduce 层级递归摘要
- 应对高并发处理方案
- A2A 机器人集群跨地域协作协议方案
- 非功能需求
- 优先级与里程碑
- 验收标准
- 风险与应对
- 附录:简历项目描述建议
1. 背景与目标
1.1 背景
复杂文档解析是 AI Agent / RAG 知识库的通用前置能力,也直接对应岗位任职要求第6条:“具备复杂文档解析经验,能处理 PDF/Office/CSV/图片/扫描件中的文本、表格、图片及版面结构”。在 XinheBot 巡检平台中,该模块是四大新增模块之「多文档 OCR 解析」的深化实现,支撑巡检资料、图纸、扫描件的多模态知识管理与 RAG 问答。
1.2 产品目标
- 将 PDF、Office、CSV、图片、扫描件等非结构化文档,解析为保留版面结构、坐标、页码的结构化文档元素。
- 覆盖文本、表格、图片三类内容,支持复杂图件(CAD 图纸、巡检影像)的图文联合解析。
- 打通大文件上传、异步处理、RAG 检索、索引优化与层级摘要的完整链路,供 RAG 语义检索与 GIS 空间检索使用。
1.3 核心价值
让非结构化文档“传得进、分得清、查得到、能溯源”——支持 GB 级大文件安全上传与异步处理;不只提取文字,更保留版面与坐标;不只入库,更能被 RAG 与空间检索引用到原文位置。
2. 范围与术语
2.1 支持的文件类型
| 类别 | 文件类型 | 处理方式 |
| 原生文本文档 | PDF(可复制文字)、Word、Excel、PPT、CSV | 直接解析,无需 OCR |
| 图片 / 扫描件 | JPG、PNG、TIFF、扫描 PDF | 图像预处理 + OCR |
| 复杂图件 | CAD 矢量(DXF/DWG)、图纸截图 | 矢量走 ezdxf;截图走 OCR |
2.2 抽取能力
- 文本:段落、标题、正文、页眉页脚标注文字。
- 表格:单元格、行列结构、跨页表格,整表结构化。
- 图片:文档内嵌图片、图纸/巡检影像,提取图注与空间位置。
- 版面结构:元素类型、版面坐标(bbox)、页码、分栏、层级。
2.3 术语表
| 术语 | 说明 |
| OCR | 光学字符识别,将图片/扫描件中的文字转为可检索文本 |
| 版面结构 | 文档中标题、段落、表格、图片等元素的类型、位置与层级关系 |
| 版面坐标(bbox) | 元素在页面中的矩形坐标,用于溯源与图文定位 |
| 图文联合 | 将正文文本与图片/图纸的识别结果按元数据关联,实现联合检索 |
| 分片上传 | 将大文件按固定大小切分后逐片上传,支持断点续传与秒传 |
| 幂等 | 同一操作重复执行结果一致,用于防重复上传与重复解析 |
| 向量化 | 将文本/图注切片转为向量,存入向量库供语义检索 |
| Map-Reduce 摘要 | 先分片并行生成局部摘要,再逐层合并生成层级摘要 |
| 结构化输出 | 按统一 Schema 输出 {type, text, bbox, page, metadata} 等元素 |
3. 用户与使用场景
| 用户角色 | 场景 | 核心诉求 |
| 知识库/业务运营 | 上传大体积 PDF、扫描件、图纸说明 | 大文件可靠上传、文档 OCR 解析、入库,供 RAG 问答 |
| 空间数据管理员 | 上传 CAD 图纸、巡检影像 | 图件解析、结构化、空间入库与检索 |
| 巡检运维人员 | 查询设备资料、历史报告 | 快速检索到原文,溯源到页码与位置,查看长文档摘要 |
| 研发/Agent 调用 | Agent 需要读取文档工具 | 解析能力封装为 MCP 工具,供 LangGraph 调用 |
4. 功能需求
4.1 文档路由与解析调度
| 功能 | 需求描述 | 优先级 |
| 自动路由 | 自动判断文件类型(PDF/Office/CSV/图片/扫描件),分派对应解析器 | P1 |
| 统一调度 | 以 Unstructured 为统一编排框架,屏蔽不同文件解析器差异,输出统一 Element 结构 | P1 |
| 异步任务 | Redis/Celery 任务队列驱动异步解析,支持批量、失败重试、限流 | P0 |
| 服务化 | 解析独立服务化,Docker 部署,按需扩容 | P1 |
4.2 原生文本文档解析(PDF/Office/CSV)
| 功能 | 需求描述 | 优先级 |
| 文本 PDF | pdfplumber 提取文字、表格,保留版面坐标 | P1 |
| Office 文档 | docx/xlsx/pptx 提取段落、表格、内嵌图片,保留层级 | P1 |
| CSV | pandas 直接读取为结构化表格数据 | P1 |
4.3 扫描件与图片 OCR
| 功能 | 需求描述 | 优先级 |
| 图像预处理 | 角度矫正、去噪、二值化、对比度增强,提升识别率 | P1 |
| 主力识别 | PaddleOCR 本地识别文字、表格、标注(离线、可微调、低成本) | P1 |
| 版面检测 | PP-Structure 区分标题/正文/表格/图片区块,输出像素 bbox | P1 |
| 兜底引擎 | 低置信度自动降级 DeepSeek-OCR(VLM 版面理解,复杂图文/复杂表格) | P2 |
双引擎策略:PaddleOCR 本地为主(离线可用、可微调、批量成本低);DeepSeek-OCR 兜底(版面理解强、适配密集图文与复杂表格),二者可切换。
4.4 CAD 与复杂图件解析(图文联合)
| 功能 | 需求描述 | 优先级 |
| 矢量 CAD | ezdxf 读取 DXF 图层、图元、标注文字、坐标、块信息,结构化入 PostGIS | P1 |
| 图纸截图 | CAD 导出 PNG/TIFF 走 OCR,提取图面文字与图注 | P1 |
| 坐标映射 | 图片像素坐标映射回地理坐标,实现图文与空间联动 | P2 |
| 图文关联 | 文档内嵌图片识别结果与正文段落按元数据(图片ID/页码/坐标)绑定 | P1 |
关键前提:CAD 矢量文件(.dwg/.dxf)不等于图片,OCR 不能读取矢量图层、坐标,只能识别导出截图上的文字。矢量走 ezdxf,截图才走 OCR。
4.5 版面结构保留
不输出纯文本大段;每个元素保留坐标与类别,示例:
{ type:"table", text:"表格内容", bbox:[x1,y1,x2,y2], page:3 }
好处:RAG 溯源到原文页码与位置;GIS 场景可将图片像素坐标映射地理坐标。
4.6 表格识别与处理
- 原生 PDF/Excel:直接提取表格,转为 Markdown/JSON,保留行列结构。
- 扫描件图片表格:OCR 识别单元格并还原表格。
- 不直接打散成纯文本;表格单独存储并带元数据,RAG 检索时整表召回。
4.7 结构化输出与入库
| 功能 | 需求描述 | 优先级 |
| 结构化输出 | 统一 Element Schema:type/text/bbox/page/metadata | P1 |
| 清洗切片 | 按版面区块分块,标题+正文关联,表格转结构化文本,带坐标/页码元数据 | P1 |
| 入库 | 结构化元数据入 PostGIS,切片向量化入 Milvus,支撑 RAG 混合检索 | P1 |
4.8 大文件上传(Django 分片上传)
支撑 GB 级大文件(图纸、长报告、大影像)可靠上传,避免单次请求超时、断连重传、内存占用过高。
| 功能 | 需求描述 | 优先级 |
| 前端分片 | 浏览器端将大文件按固定分片大小(如 5MB)切片,逐片上传并携带分片序号 | P0 |
| 秒传检测 | 按文件 MD5 判断是否已存在,存在则直接返回已完成,跳过重复上传 | P0 |
| 分片上传接口 | POST /api/upload/chunk,接收分片并落盘/直传 MinIO | P0 |
| 断点续传 | GET /api/upload/progress 返回已接收分片集合,缺失分片自动补传 | P0 |
| 合并还原 | POST /api/upload/merge,服务端校验全部分片后合并还原,二次校验大小与哈希 | P0 |
| 并发分片 | 多分片可并行上传,服务端按分片序号幂等去重 | P1 |
| 校验与限制 | 文件类型、大小上限(如单文件 ≤2GB)、分片大小一致性校验 | P1 |
Django 实现要点:基于 Django REST Framework 提供 check / chunk / progress / merge 四类接口;分片临时存 MinIO 或本地临时目录(带租户+文件标识前缀);合并后触发 Celery 异步解析任务;合并后计算全文件哈希作为幂等键,重复上传直接命中秒传。
4.9 大文件异步处理机制
| 机制 | 需求描述 | 优先级 |
| 任务超时 | 解析任务设超时阈值(如 10 分钟),超时标记失败/可重试;超大文件按页/章节拆分子任务,避免单任务超长 | P0 |
| 内存占用 | 流式/分块读取,OCR 按页处理逐块释放;限制单任务内存峰值,大文件不整体载入内存 | P0 |
| 并发控制 | 信号量/队列限流(如单机 N 个解析并发),按租户配额,防止 OOM 与接口压垮 | P0 |
| 失败重试 | 瞬时错误指数退避重试(如最多 3 次);永久错误落库标记、支持人工重跑;失败原因可追溯 | P0 |
| 重复处理(幂等) | 以 文件MD5 + 任务ID 作幂等键,Redis 校验防重复解析;已处理文件直接返回结果 | P0 |
| 数据一致性 | 任务状态机 pending→processing→success/failed;成功后才提交结构化数据与向量入库;失败回滚/标记,避免半成品入库;PostGIS 与 Milvus 采用事务/补偿保证一致 | P0 |
闭环:上传完成后自动进入异步解析队列;解析状态全程可查(进度/失败原因/重试次数);只有成功落库后才对外提供检索,保证用户看到的一定是完整结果。
5. 技术架构与选型
双技术栈定位:同一套业务能力,两套技术方案——Django(Python)主版本 + SpringBoot(Java)备选版本,按需选用,体现技术选型能力。业务能力完全一致:分片上传、异步任务、文档解析、RAG 索引、Map-Reduce 长文档摘要,只是后端语言框架不同。
5.1 Django(Python)主版本技术路线
5.1.1 整体架构(异步流水线)
文件上传(Django 分片)→ 对象存储 MinIO → Redis/Celery 任务队列(异步解析)→ 文档路由分发 → 分类型解析器 → 结构化元素输出 → PostGIS 入库 → 切片 → Milvus 向量入库 → RAG 检索 / 索引优化 / 层级摘要
5.1.2 技术选型
| 组件 | 选型 | 职责 |
| 统一调度 | Unstructured | 文件类型路由、版面分块、统一 Element 输出 |
| 原生文本 PDF | pdfplumber / PyMuPDF | 文字、表格、坐标提取 |
| Office/CSV | python-docx / openpyxl / python-pptx / pandas | 段落、表格、内嵌图片提取 |
| OCR 主力 | PaddleOCR + PP-Structure | 本地批量文字/表格/版面识别 |
| OCR 兜底 | DeepSeek-OCR(VLM) | 复杂图文、复杂表格增强理解 |
| 矢量 CAD | ezdxf | DXF 图层、图元、标注、坐标提取 |
| 图像预处理 | OpenCV | 矫正、去噪、二值化、增强 |
| 上传/分片 | Django REST Framework + Celery | 分片上传、秒传、断点续传、合并、异步任务 |
| 异步任务/限流 | Celery + Redis | 任务队列、超时、重试、幂等、并发限流 |
| 检索/重排 | bge-m3 / BM25 / BGE Rerank | 多路召回、混合检索、重排 |
5.1.3 双引擎降级策略
PaddleOCR 识别置信度低于阈值,或版面为复杂混排图文时,自动降级 DeepSeek-OCR 二次识别,保证复杂文档识别质量。
5.2 SpringBoot(Java)备选技术路线
5.2.1 选型说明
- 适用场景:高并发文件上传、大流量 API 网关、需要和企业现有 Java 微服务体系对接的场景。
- 不选用场景:快速原型迭代、AI 文档解析、多模态 RAG 快速调试(Python 生态更友好)。
- 核心思路:同一业务逻辑,两套技术实现,按需选用;本项目业务规模(100 客户、日活 200)并发压力不大,优先 Django;如果后续客户侧高并发接入需求,可切换 SpringBoot。
5.2.2 核心组件
| 组件 | 选型 | 职责 |
| 框架 | SpringBoot 3.x + Spring Data JPA / MyBatis-Plus | 业务网关、接口、任务管理 |
| 文件分片上传 | MinIO Java SDK | 分片存储、合并、MD5 校验、断点续传 |
| 异步任务 | Spring Task / RabbitMQ(替代 Redis+Celery) | 任务队列,任务状态持久化到 MySQL |
| 幂等 & 并发控制 | Redisson 分布式锁 | 用请求唯一 ID 防止重复解析任务 |
| 数据库 | PostgreSQL + PostGIS | 和 Django 版本共用同一套数据库与 MinIO 对象存储 |
| 向量库 | Milvus Java SDK | 索引写入、检索逻辑和 Python 版本完全一致 |
| 文档解析 | Java 侧不重写 OCR / 文档解析核心,服务化调用 | 见下 |
跨语言服务化拆分:SpringBoot 作为业务网关,接收文件、管理上传任务、调度任务队列;文档解析、OCR、Map-Reduce 摘要能力封装为独立 Python HTTP/gRPC 服务,Java 远程调用。
理由:PaddleOCR、Unstructured、LangChain、RAGAS 这类 AI 生态,Java 原生支持弱,不适合在 Java 内部重写解析管线,采用跨语言服务调用是工程最优方案。
5.2.3 分片上传接口设计(SpringBoot)
| 接口 | 作用 |
| POST /api/file/init | 文件上传初始化,计算 MD5,校验是否已存在,返回 uploadId(秒传判断) |
| POST /api/file/chunk | 上传单个分片,携带 uploadId、分片序号、文件块 |
| GET /api/file/chunk/list | 查询已上传分片列表,前端断点续传使用 |
| POST /api/file/merge | 分片全部上传完成,触发合并,创建异步文档解析任务 |
5.2.4 异步任务管控(和 Django 相同约束:超时、内存、并发、重试、幂等、数据一致性)
| 机制 | SpringBoot 实现 |
| 任务超时 | MQ 消息设置 TTL,超时任务写入失败表,人工后台查看 |
| 内存占用 | 文件分片落 MinIO,不加载完整文件到 JVM 内存,只处理元数据;解析服务在 Python 侧独立进程,隔离内存风险 |
| 并发控制 | Redisson 分布式锁 + 全局并发数配置,限制同时解析的文档数量 |
| 失败重试 | 分级重试,临时性错误(网络抖动)自动重试 3 次;解析失败(文件损坏)标记终止,不再重试 |
| 防重复处理(幂等) | uploadId 作为全局唯一业务主键,同一 ID 只允许触发一次解析 |
| 数据一致性 | 状态机流转(待上传→上传完成→解析中→成功/失败),数据库事务保证状态更新;失败触发补偿日志,原始文件保留可重试 |
5.2.5 RAG 相关能力(Java 侧职责)
- 检索接口、多路召回、重排、元数据过滤、权限控制、租户隔离,由 SpringBoot 实现。
- Map-Reduce 层级递归摘要、文档切片、向量入库,调用 Python 解析服务 API 完成。
- 索引维护、向量库 CRUD 使用 Milvus Java SDK。
5.2.6 Django vs SpringBoot 对比
| 对比项 | Django (Python) 方案 | SpringBoot (Java) 备选方案 |
| 开发速度 | 开发速度快,AI / 文档生态原生支持,原型快速落地 | 慢,AI 组件需要跨服务调用,开发成本更高 |
| 并发能力 | 中等,适合本项目日活 200 场景 | 高,适合上万 QPS、高并发上传场景 |
| 内存风险 | Celery worker 控制并发,需管控大文件加载 | JVM 内存隔离,文件不落内存,稳定性更强 |
| 维护成本 | Python 环境依赖多,部署要管理 conda/docker | 企业运维成熟,适合传统政企 Java 技术栈对接 |
| 适用场景 | AI 文档解析、RAG、Agent 快速迭代 | 高并发、企业内部 Java 微服务集成场景 |
5.2.7 简历可直接复用描述
设计双技术栈备选方案,主链路采用 Django 实现分片大文件上传与 Celery 异步文档解析;同时提供 SpringBoot 备选架构,SpringBoot 负责文件网关、任务调度、权限与 RAG 检索服务;文档 OCR 解析、Map-Reduce 层级递归摘要等 AI 能力独立封装为 Python 微服务,Java 通过 HTTP/gRPC 跨语言调用;使用 Redisson 分布式锁保证任务幂等,实现任务超时管控、并发限流、失败重试、状态机保障数据一致性;两套方案共用 MinIO、PostGIS、Milvus 存储层,可根据业务并发规模灵活切换。
5.2.8 面试口述精简版
我设计了两套后端实现方案。主方案 Django,适合快速开发 AI 文档解析、RAG 与 Agent 能力。备选 SpringBoot 方案,适合对接企业 Java 微服务或者高并发场景。SpringBoot 负责分片上传、任务管理、RAG 检索、租户权限;但 OCR、文档解析、Map-Reduce 长文档摘要这些 AI 相关逻辑,不放在 Java 内部开发,单独封装 Python 服务,Java 远程调用。通过 Redisson 分布式锁做幂等,同样实现任务超时、并发控制、失败重试,使用状态机保证数据一致性。两套方案底层存储 MinIO、PostGIS、Milvus 是共用的,可以按需切换。
6. 数据管理方案
| 存储层 | 选型 | 存放内容 |
| 原始文件 | MinIO 对象存储 | 原始 PDF、Word、DXF、图片、扫描件、分片临时文件;版本、文件ID、租户ID、MD5 |
| 结构化元数据 | PostgreSQL + PostGIS | 文档信息、版面元素(文本/表格/图片区块/坐标)、GIS 空间字段、表格 JSON、解析任务状态 |
| 向量库 | Milvus | 文本切片、图注 VLM 摘要向量,供语义检索 |
| 任务/缓存 | Redis | 任务状态、幂等键、失败重试、限流、进度缓存 |
| 倒排索引 | Elasticsearch | BM25 关键词检索,与向量库联合混合检索 |
6.1 数据流转
原始文件分片上传 → 合并校验 + 幂等键入库 → Redis/Celery 触发异步任务 → Unstructured 调度解析(原生/OCR)→ 结构化结果写 PostGIS,切片向量化写 Milvus → 原始文件存 MinIO → RAG 检索时同时召回文本 + 关联图件 + 空间位置
6.2 多租户隔离
以 tenant_id 做行级隔离,不同客户/租户的文档、图件、分片与任务数据隔离,沿用既有 RBAC 权限体系。
6.3 异构数据源清洗
面向地质勘察报告、钻孔图表、CAD 图纸截图、扫描件等复杂排版异构数据源(图文混排、百万级行列大表格、倾斜/模糊扫描件),传统"全文 OCR + 固定长度切块"会拍平表格结构、切断语义边界,导致 RAG 召回噪声大、行列关系丢失。本节定义按"版面块"为单位的清洗与入库方案。
6.3.1 清洗链路(按块分割 → 分块解析 → 分类入库 → 多索引)
| 阶段 | 处理内容 | 输出 |
| ① 版面检测 | LayoutLM / PaddleLayout 对页面做视觉语义分块,识别文本块、表格块、图纸/图片块、标题块、注释块、公式块,输出各块 bbox 坐标 | 页面语义块集合 |
| ② 分块单独解析 | 文本块直接提取;表格块交给表格识别引擎还原为 Markdown/JSON 二维结构,保留表头与行列关系;图纸块走 OCR 提取图内文字 + VLM 生成图注摘要 | 结构化块 + 图注摘要 |
| ③ 分类入库打标签 | 每个块写入统一 schema,携带块类型(text/table/image/drawing)、页码、bbox、文档ID、租户ID、表格行列数等元字段;原始图纸图片落 MinIO,结构化块写 PostGIS | 带元数据的块记录 |
| ④ 多索引构建 | 向量索引(Milvus,语义召回)+ 元数据索引(PostGIS,按块类型/租户/文档过滤)+ 倒排索引(ES,BM25 关键词)三路并行;表格块同时保留整表 JSON 以支持整表召回 | 向量库 + 元数据 + ES 联合索引 |
6.3.2 检索期配套策略
query → 意图分类 → 块类型路由(限定 table / text / drawing)→ 三路混合召回 → BGE Rerank → LLM 生成 → 溯源到页码 + bbox
- 用户问钻孔表/地质数据类问题时,检索层自动过滤
block_type=table,避免纯文本噪声。
- 用户问图纸/剖面类问题时,路由到
block_type=drawing,同时召回图注文本与原始图片。
- 表格块不参与固定长度切片,按"整表或按行组"为单位入向量库,保证百万行列大表格不被切碎。
6.3.3 与传统方案对比
| 维度 | 传统全文 OCR + 固定长度切块 | 本方案(按块分割 + 多索引) |
| 表格结构 | 行列被拍平成乱序文本,字段错位 | 还原 Markdown/JSON,行列关系保留,支持整表召回 |
| 语义边界 | 标题/正文/表格易被一刀切断 | 按视觉语义块切分,不跨块切断 |
| 检索精度 | 所有内容混合召回,噪声高 | 按块类型元数据过滤,降低无关召回 |
| 多模态 | 图片仅 OCR 文字,无图像语义 | 图注 VLM 摘要 + 图片向量,支持图文联合召回 |
| 计算成本 | 低 | 版面检测 + 表格识别开销更高,需异步队列(Redis/Celery)兜底 |
| 开发复杂度 | 低 | 需维护版面模型、多类型块 schema、多索引联动 |
适用边界:纯文字 Word、简单公文等无复杂排版的文档,沿用原生解析 + 固定切块即可;本方案主要服务于地质勘察报告、钻孔统计表、CAD 截图、扫描图纸等芯禾平台核心异构数据源场景。
7. RAG 检索链路
7.1 检索流程
query → 意图分类 / 知识库路由 → 多路召回(bge-m3 向量 + BM25 + 关键词)→ BGE Rerank 重排 → LLM 生成 → 溯源引用
| 阶段 | 说明 | 优先级 |
| 路由 | 意图分类,按标签路由到对应知识库(设备/巡检/图纸/制度) | P1 |
| 多路召回 | bge-m3 向量 + BM25 倒排 + 关键词三路并行召回,取并集 | P1 |
| 重排 | BGE Rerank 对召回结果精排,取 TopK 送入大模型 | P1 |
| 生成 | 基于召回片段生成答案,附引用来源(文档/页码/bbox) | P0 |
| 溯源 | 返回引用位置,支持定位原文与图件,抑制幻觉 | P0 |
| 评测 | RAGAS 三维评测(忠实度/相关性/答案质量)驱动优化 | P1 |
8. RAG 索引优化
| 优化项 | 说明 | 优先级 |
| 切片策略 | 按版面区块分块,标题+正文关联,带重叠窗口,避免表格被拆碎 | P1 |
| 元数据增强 | 切片携带页码、坐标、表格结构、图注摘要,支持精确定位与过滤 | P1 |
| 表格索引 | 表格转 Markdown 结构化索引,支持整表召回,不因分块丢失行列关系 | P1 |
| 多路索引 | 向量库(Milvus)+ 倒排(ES)统一 schema,混合检索 | P1 |
| 索引维护 | 增量更新、删除重建、去重、向量索引参数(HNSW)调优 | P2 |
| Query 优化 | 低相关 query 自动重写,降低无效检索率 | P1 |
| 评测反馈 | RAGAS 指标驱动 chunk size / overlap / topK 调参 | P2 |
9. Map-Reduce 层级递归摘要
9.1 背景
针对超大/超长文档(长报告、图纸集、历史资料),单次送入模型会超出上下文限制,且细节易丢失。采用 Map-Reduce 层级递归摘要,先并行分片摘要,再逐层合并,保证覆盖完整、可溯源。
9.2 实现思路
| 阶段 | 说明 |
| Map(分片摘要) | 将文档按版面/章节切片,并行送入大模型生成局部摘要(叶子摘要),保留各切片溯源 |
| Reduce(层级合并) | 相邻叶子摘要逐层合并生成更高层摘要,递归合并直至根摘要(全文摘要) |
| 层级输出 | 分块摘要 → 章节摘要 → 全文摘要;每层摘要可回溯到原切片位置 |
9.3 应用场景
- 知识库概览:长文档一键生成层级摘要,供快速浏览与导航。
- 长文档 RAG 增强:检索时先对命中章节做 Map 摘要,再 Reduce 聚合,控制送入模型的上文长度。
- Agent 长文档理解:为 LangGraph Agent 提供长文档的层级摘要工具,降低上下文压力。
10. 应对高并发处理方案:万级日活用户支撑(SpringBoot + Django 双版本对比)
10.1 业务容量前提定义
目标容量:日活 1 万用户。RAG、VLM 多模态图文分析属于重型请求,单次请求包含文档 IO、OCR 解析、向量检索、大模型推理,不能简单按普通 Web 接口估算 QPS。用户访问分散在工作 8 小时,平均 QPS 很低;业务峰值预估并发 QPS 约 50~100。
核心瓶颈不在 Web 应用接口,瓶颈优先级排序:
- vLLM LLM/VLM GPU 推理服务
- Milvus 向量库检索
- 大文件 OCR、文档解析等 CPU 密集任务
- 业务数据库读写压力
架构设计核心思路:重型任务异步解耦、分层缓存、服务无状态、独立推理集群、流量熔断限流。两套业务能力完全一致,仅后端技术栈不同,用于不同阶段选型。
10.2 方案 A:SpringBoot 高并发生产方案(推荐用于线上万用户生产环境)
整体架构链路:前端 H5 移动端 / PC 端 → Envoy 网关 → SpringBoot 微服务集群 → Redis 缓存 + 消息队列 → PostgreSQL+PostGIS → MinIO 对象存储 → Milvus 向量库 → vLLM 推理集群
flowchart LR
FE["前端 H5 / PC"] --> GW["Envoy 网关
限流·熔断·鉴权·负载均衡"]
GW --> SB["SpringBoot 微服务集群
K8s 无状态 · 弹性扩缩容"]
SB --> RC["Redis 缓存
会话·热点·断点"]
SB --> MQ["消息队列
RocketMQ / RabbitMQ"]
MQ --> TK["异步重型任务
解析·OCR·索引·VLM"]
SB --> PG[("PostgreSQL + PostGIS
主从 · 读写分离")]
TK --> MI["MinIO 对象存储"]
TK --> MV[("Milvus 向量库
分布式分片")]
SB --> MV
GW --> VV["vLLM 推理集群
多卡张量并行"]
TK --> VV
接入网关层(Envoy)
- 统一入口,实现请求鉴权、流量限流、熔断、黑白名单、负载均衡;
- 识别恶意大文件请求,提前拦截,保护后端应用,防止服务雪崩。
应用服务层(SpringBoot)
- 应用设计为无状态服务,部署于 K8s,基于 CPU、内存指标自动弹性扩缩容,多实例横向扩容;
- 线程池隔离:轻量接口(权限校验、列表查询)和重型任务接口使用独立线程池,避免互相抢占资源;
- Redis 缓存:缓存用户会话、知识库元信息、高频向量检索结果、分片上传断点记录,减少数据库与向量库重复查询压力;
- 多租户 RBAC 权限,应用层 + 数据库行级权限双重隔离,保障不同客户知识库数据隔离安全。
异步任务层(RocketMQ/RabbitMQ)
- 耗时重型任务全部异步化:大文件分片解析、PDF/CAD 图纸 OCR、长文档 RAG 索引构建、VLM 图像巡检分析;
- 任务状态持久化到 Redis + 业务数据库,实现失败重试、幂等控制,避免重复解析、重复入库;
- 任务队列设置最大并发阈值,队列堆积超限后触发限流保护。
存储层
- MinIO 分布式对象存储:保存原始遥感影像、巡检图片、PDF/CAD 文档,支持横向扩容,大文件支持分片直传,绕过业务后端直接写入对象存储,降低后端 IO 压力;
- PostgreSQL+PostGIS:存储业务元数据、图纸空间地理信息,采用主从架构,读写分离,读请求走从库分担压力;
- Milvus 分布式向量集群:向量数据分片存储,支撑海量知识库的相似检索,可横向扩容节点。
推理服务层(vLLM 集群,独立部署)
- LLM、VLM 多模态推理独立部署,与业务后端完全解耦;
- 多卡张量并行,Envoy 网关做推理请求负载均衡;依靠 PagedAttention + 连续批处理提升 GPU 利用率,支撑多用户并发推理请求。
SpringBoot 方案优势:Java 生态成熟稳定,线程模型、分布式组件、K8s 云原生、分布式事务、监控告警体系完善;高并发场景下 CPU 密集任务调度稳定性更强,适合企业正式上线、对外客户访问、强 SLA 保障场景。
10.3 方案 B:Django 高并发扩容方案(原型 / 内部业务备选)
整体架构链路:前端 H5 → Nginx 反向代理网关 → Gunicorn+Uvicorn ASGI 异步 Worker → Django 应用集群 → Redis + Celery 消息队列 → PostgreSQL+PostGIS → MinIO → Milvus → vLLM 推理集群
flowchart LR
FE["前端 H5"] --> NG["Nginx 反向代理
限流·静态资源·排队"]
NG --> DJ["Django 应用集群
Gunicorn + Uvicorn ASGI"]
DJ --> RC["Redis 缓存
会话·检索·断点"]
DJ --> CL["Celery 任务队列
Redis Broker"]
CL --> TK["异步任务
解析·OCR·索引·VLM"]
DJ --> PG[("PostgreSQL + PostGIS
读写分离")]
TK --> MI["MinIO 对象存储"]
TK --> MV[("Milvus 向量库")]
CL --> VV["vLLM 推理集群"]
接入层:Nginx 反向代理、静态资源托管、请求限流、连接数控制,做请求排队,拦截超限请求。
Django 应用层
- 应用无状态,多实例水平部署,使用 ASGI 异步 worker 提升 IO 并发;
- HTTP 接口只做轻量校验,禁止在同步 HTTP 请求内执行文档解析、RAG 索引、VLM 推理等长耗时任务;
- Redis 缓存会话、检索结果、分片上传断点信息,减少数据库压力;
- 保留 RBAC 多租户隔离、文档权限体系。
异步任务层:Celery + Redis。文档解析、OCR、长文档摘要、向量入库、VLM 图像分析全部丢入 Celery 异步队列;任务状态持久化,支持失败重试、幂等校验。
存储与推理层:存储、向量库、vLLM 推理集群,和 SpringBoot 方案完全一致。
Django 方案优缺点
✅ 优点:Python 生态对 AI 库友好,PyMuPDF、PaddleOCR、LangGraph、RAGAS 可直接集成,原型迭代速度快,开发成本低。
❌ 短板:受 Python GIL 全局解释器锁限制,单机 CPU 密集计算场景存在性能瓶颈;大规模集群运维成本高于 Java,不适合超高并发、强 SLA 生产场景。
适用场景:内部 Demo、原型验证、中小流量内部知识库场景。
10.4 技术选型决策总结
- 原型开发阶段:优先 Django 方案,快速验证 RAG、多 Agent、VLM 图文巡检、复杂文档解析业务逻辑,快速跑通业务闭环;
- 业务规模达到万级日活、正式对外生产交付:切换 SpringBoot 微服务架构,保障并发稳定性、可观测性、运维能力,满足企业级 SLA。
10.5 面试口述精简版(可直接背诵)
如果平台达到日活 1 万用户,首先要区分峰值并发。RAG+VLM 属于重型请求,瓶颈不在 Web 接口,主要瓶颈是 vLLM 的 GPU 推理、Milvus 向量检索、文档 OCR 解析这类 CPU 重型任务。
生产环境优先采用 SpringBoot 微服务架构:
- 应用做无状态设计,K8s 弹性扩缩容,Envoy 网关做流量管控、限流熔断;
- 所有耗时任务:文档解析、OCR、索引构建、VLM 图像分析全部异步化,通过消息队列解耦,增加任务幂等与失败重试,避免阻塞 HTTP 接口;
- Redis 缓存热点查询、会话、分片断点;数据库读写分离,MinIO 分布式存储文件,Milvus 分布式向量集群;
- LLM/VLM 推理独立部署 vLLM 集群,和业务后端解耦,推理服务单独做负载均衡。
同时我们也设计了 Django 扩容方案,Django 配合 Celery+Redis,同样可以实现异步任务、缓存、多实例部署。但受 Python GIL 限制,大量 CPU 密集场景下,大规模并发稳定性弱于 Java。所以选型策略:原型阶段 Django 快速验证业务;万用户规模线上生产,切换 SpringBoot 方案保障高并发稳定性。
10.6 面试预判问题 & 应答
| 预判问题 | 应答思路 |
| Q1:万用户访问,最大瓶颈在哪? | 瓶颈不在 Web 接口。第一瓶颈是 vLLM 的 GPU 推理;第二是 Milvus 向量检索;第三是大文件 OCR、文档解析这类 CPU 重型任务。所以架构上必须把推理、解析任务和 web 接口解耦,异步化,不能同步阻塞。 |
| Q2:Django 用 Celery 扛并发,最多能扛多少?什么场景下必须换 Java? | 异步任务模型下,Celery 可以横向增加 worker 节点。但大量 CPU 密集计算场景,GIL 会限制单机算力。当业务大量并发的复杂业务计算、分布式事务、强 SLA 要求,就更适合 Java SpringBoot。如果只是 AI 文档业务,以 IO 等待、GPU 推理为主,Django+Celery 也可以支撑万级日活。 |
| Q3:怎么做限流、防止大文件上传打垮后端? | 网关层做请求限流,分片上传,文件直传 MinIO,后端不接收完整文件流;任务队列做任务数量限流,超过阈值直接排队或拒绝新任务,防止服务雪崩。 |
11. A2A 机器人集群跨地域协作协议方案(MCP vs A2A vs gRPC vs MQ)
11.1 背景与定位
Agent 间通信的两个层次:MCP 解决「Agent 怎么用工具」,A2A 解决「Agent 与 Agent 怎么协作」。
MCP(Model Context Protocol)标准化 Agent↔工具(检索、数据库、文档解析服务)的调用;A2A(Agent2Agent)是 Google 牵头、50+ 企业共同制定的开放协议,解决 Agent↔Agent 之间的能力发现、协商、任务委派与协作。二者互补:MCP 把工具接入 Agent,A2A 让多个 Agent(各管理一个机器人或集群)互联成协作网络。
11.2 A2A 协议核心机制
| 机制 | 说明 |
| Agent Card 能力注册 | 每个 Agent 在 /.well-known/agent-card.json 声明身份、能力 skills、endpoint、认证方式;新机器人部署即注册即被发现 |
| Task 任务生命周期 | submitted→working→input-required→completed/failed/canceled;派发即返回 task id,后台执行、状态可查 |
| 异步长任务 | 委派后立即返回,后台执行;用轮询 / SSE 流式 / push 推送取状态,容忍高延迟 |
| 增量产物回流 | 长任务过程中可返回进度、图片/视频等 artifact,适合巡检证据回传 |
| 协商与人工介入 | 任务可停在 input-required / auth-required,支持人机协同(异常巡检需人工确认) |
| 企业级安全 | 内置 OAuth2 / Bearer / apiKey 认证,多租户可用 |
| 异构互操作 | JSON-RPC 2.0 over HTTP(S),任意语言实现即可互联 |
11.3 为什么适合机器人集群协调
- 任务模型为长任务而生:机器人巡检/巡逻是分钟~小时级任务,A2A 的 Task 生命周期天然匹配,而不是“调用一下就等结果”的同步 RPC。
- 能力可发现:Agent Card 让新机器人部署即注册即被发现,无需硬编码对接。
- 异构互操作:不同厂商的 LD08、UAV、巡检/清扫机器人 SDK 不同,统一走 A2A 即可接入。
- 协商 + 人工介入:支持任务暂停请求人工确认,适合人机协同调度。
- 增量产物回流:巡检过程的进度、图片/视频证据可流式回传。
11.4 为什么适合全球分布式部署
- 标准 HTTP 天然跨公网:不依赖共享 broker、不依赖局域网服务发现,每个 Agent 一个 HTTPS endpoint 即可互联。
- 异步解耦容忍高延迟:跨地域 RTT 是百毫秒~秒级,A2A 委派后立即返回、后台执行,用轮询/SSE/推送取状态,地理距离不阻塞协作。
- 无中心依赖、地域自治:各区域集群本地自治,只有跨地域协作才通信;区域断网不影响其他区域(最终一致,不做全局强同步)。
- 水平扩展:新地域 = 部署新 Agent + 发布 Agent Card 即入网。
- 状态与产物本地化:每个 Agent 持有自己的 Task 状态,不需要全球级强一致数据库。
11.5 协议选型对比:MCP vs A2A vs gRPC vs MQ
| 对比维度 | MCP | A2A(本项目采用) | gRPC | 消息队列(Kafka/MQ) |
| 定位 | Agent ↔ 工具调用标准化 | Agent ↔ Agent 协作标准化 | 通用高性能 RPC | 异步消息解耦 |
| 通信方式 | JSON-RPC over HTTP/SSE | JSON-RPC 2.0 over HTTP(S) | HTTP/2 二进制 Protobuf | 发布订阅 / 队列 |
| 长任务 / 异步 | 以同步调用为主 | Task 生命周期,原生异步长任务 | 需自行实现流式/异步 | 异步原生,无任务语义 |
| 跨公网分布式 | 可跨网络,但面向本地工具 | 标准 HTTP,天然跨公网 | 需统一网络栈/服务发现,跨组织难 | 需共享 broker 集群,跨地域部署重 |
| 能力发现 | 按 MCP 服务声明工具 | Agent Card 能力注册 | 依赖注册中心 | 无内建发现 |
| 依赖 / 运维 | 轻量 | 轻量,任意语言实现 | 契约文件 + 代码生成 | broker 集群高可用运维成本高 |
| 适用场景 | 让 Agent 调用数据库/解析等工具 | 多机器人集群跨地域协调、任务委派 | 内部微服务高性能调用 | 事件流、削峰填谷 |
图 11-1 协议选型对比表(MCP vs A2A vs gRPC vs MQ)
选型结论:MCP 解决 Agent↔工具,不解决 Agent↔Agent;gRPC 高效但要求统一网络栈/服务发现,跨组织跨公网难;消息队列需共享 broker 集群,跨地域部署重且有单点风险。A2A 作为开放对等、异步长任务、跨公网的协议,最贴合分布式自治机器人集群。本项目采用 A2A 作为 Agent 间通信标准,MCP 仍用于接入文档解析、向量库等工具。
11.6 落地到 XinheBot 机器人集群(Graineye)
粮仓/园区节点分布多地 → 每个节点跑一个「本地调度 Agent」,通过 Agent Card 向中央协调 Agent 注册在线能力(哪些 UAV、哪些巡检机器人);中央只做全局编排,用 tasks/send 委派巡检任务,本地 Agent 用 LangGraph 编排机器人执行;UAV 长航时任务走 Task 生命周期,断网时本地缓存、恢复后推送回执;VLM 图片分析产物作为 artifact 回流。执行与容错下沉到各地,中央只做编排。
11.7 面试口述精简版
机器人集群跨地域协调,我采用 A2A 开放协议作为 Agent 间通信标准。核心三点:一是 Task 异步长任务模型,巡检/巡逻这种分钟级任务派发后立即返回、后台执行,用轮询/SSE/推送取状态,容忍跨地域高延迟;二是 Agent Card 能力注册,新机器人部署即被发现,无需硬编码;三是标准 HTTP + 无中心自治,各区域集群本地自治,断网不影响其他区域,天然支持全球分布式。对比下来,MCP 管 Agent↔工具、gRPC 要统一网络栈、消息队列要共享 broker,A2A 最贴合 Agent↔Agent 的分布式自治集群。
12. 非功能需求
- 性能:大文件分片异步上传,Redis/Celery 队列限流;批量解析不阻塞主流程。
- 可靠性:PaddleOCR 本地离线可用;任务超时/失败可重试;Redis 幂等防重复派单与重复解析。
- 内存:解析与上传均分块/流式处理,限制单任务内存峰值,防止 OOM。
- 安全:多租户 RBAC 行级权限、数据隔离沿用既有体系;上传接口鉴权与类型校验。
- 可维护:OCR/解析/检索独立服务化,Docker 部署,按需扩容。
- 可溯源:保留完整解析元数据与任务日志,可回溯到原始文档页码与位置。
13. 优先级与里程碑
| 阶段 | 内容 | 说明 |
| 阶段一 | 大文件分片上传 + 原生 PDF/Office/CSV 解析 + 结构化入库 + 异步机制 | 打通上传-解析-入库主链路 |
| 阶段二 | 扫描件/图片 OCR(PaddleOCR 主力)+ 版面检测 + DeepSeek-OCR 兜底 | 覆盖扫描件与图纸截图 |
| 阶段三 | CAD 矢量 ezdxf + 图文联合 + 坐标映射 | 形成完整图文与空间联动能力 |
| 阶段四 | RAG 检索链路 + 索引优化 + Map-Reduce 层级摘要 | 服务问答与长文档理解 |
14. 验收标准
14.1 原生文档
- 文本 PDF 可直接提取文字、表格并保留坐标;Office/CSV 解析正常。
- 解析结果结构化,可被 RAG 检索并溯源到页码。
14.2 扫描件与图片
- 扫描件 OCR 识别文字/表格达标;低置信度文档可自动降级 DeepSeek-OCR。
- 版面检测区分标题/正文/表格/图片区块,表格不被拆碎。
14.3 CAD 与图文联合
- DXF 矢量图层/标注/坐标结构化入 PostGIS;图纸截图 OCR 正常。
- 图片识别结果与正文按元数据关联,检索可同时召回文本+图件。
14.4 大文件上传与异步处理
- GB 级大文件可稳定上传,断点续传、秒传生效,分片合并后文件完整一致。
- 任务超时、内存峰值、并发控制、失败重试、重复处理(幂等)、数据一致性均满足设计要求。
- 失败任务可落库标记并人工重跑;无半成品数据入库。
14.5 检索、索引与摘要
- 混合检索 + 重排 + 溯源可用,RAGAS 指标达标。
- 切片带元数据、表格可整表召回,索引支持增量维护。
- Map-Reduce 层级摘要可生成,且每层可回溯到原切片位置。
14.6 Django(Python)主版本技术路线验收
- 基于 Django REST Framework 的分片上传四类接口(check / chunk / progress / merge)可用,秒传、断点续传、合并一致性生效。
- Celery + Redis 异步任务在超时、内存、并发、重试、幂等、数据一致性六项约束下均满足设计要求。
14.7 SpringBoot(Java)备选技术路线验收
- SpringBoot 网关可实现分片上传(init / chunk / chunk-list / merge)、任务调度与 RAG 检索,OCR / 解析 / Map-Reduce 摘要经 Python 服务跨语言调用可用。
- Redisson 分布式锁保证任务幂等,超时、并发、重试、状态机数据一致性满足要求;两套方案共用 MinIO / PostGIS / Milvus 存储层,可按并发规模切换。
15. 风险与应对
| 风险 | 影响 | 应对 |
| 低质量/倾斜扫描件识别差 | 识别错误率高 | 图像预处理矫正增强 + 规则/LLM 校验纠错 |
| 复杂表格错位 | 表格还原失真 | 表格整表结构化,不拆碎;复杂表格走 DeepSeek-OCR |
| OCR 与 CAD 概念混淆 | 矢量图纸解析失败 | 矢量走 ezdxf,截图才走 OCR,明确双链路 |
| 分片丢失/不完整 | 合并失败、文件损坏 | 分片序号校验 + 合并前完整性检查 + 断点补传 |
| 大批量解析 OOM / 超时 | 阻塞主流程 | 分块流式 + 并发限流 + 超时拆子任务 + 失败重试 |
| 重复上传/重复解析 | 数据冗余、算力浪费 | MD5 秒传 + 幂等键去重,Redis 校验 |
| PostGIS 与 Milvus 不一致 | 检索结果与元数据不匹配 | 状态机 + 事务/补偿,成功后才对外可见 |
| 长文档摘要上下文超限 | 摘要截断、信息丢失 | Map-Reduce 层级递归摘要 + 溯源 |
| 多租户数据泄漏 | 合规风险 | tenant_id 行级隔离,沿用 RBAC |
| 跨语言调用网络开销 | 服务间调用延迟升高、链路抖动 | 增加熔断、降级机制,控制服务间调用稳定性 |
| 服务间版本与接口契约维护 | 接口变更导致联调成本上升 | 维护 OpenAPI 契约,统一版本管理与变更评审 |
| 双栈日志链路排查复杂 | 问题定位成本高 | 统一 traceId 贯穿 Java 与 Python 日志链路,集中日志平台 |
16. 附录:简历项目描述建议
开发多类型复杂文档解析流水线,支持 PDF、Word、Excel、CSV、图片、扫描件解析;基于 Unstructured 统一调度解析引擎,原生文档提取文本、表格与版面坐标;扫描件与图片采用 PaddleOCR 批量识别,复杂图文使用 DeepSeek-OCR 增强版面理解;基于 Django 实现大文件分片上传、秒传、断点续传与异步合并;通过 Celery+Redis 实现解析任务的超时控制、内存管控、并发限流、失败重试、幂等去重与数据一致性;经 ezdxf 解析 DXF 矢量 CAD 图纸,实现图文联合与空间联动;打通 RAG 混合检索、索引优化与 Map-Reduce 层级递归摘要链路;解析结果结构化存入 PostgreSQL(+PostGIS),原始文件存入 MinIO,切片送入 Milvus 向量库,支撑 RAG 知识库问答与长文档理解。