ios-projects/docs/system-map/capabilities/03-资料上传与处理.md

22 KiB
Raw Permalink Blame History

03 资料上传与处理 — 跨项目完整能力分析

项目角色分类主链路参与者iOS、主 API、COS、Python RAG Worker、Qdrant——资料上传后必须经过这些项目才能完成处理、运维可观测Admin。 Rust Document Runtime 不参与上传与处理链路。Heavy Runtime 不参与此链路。 注意Python RAG Worker 和 Qdrant 在本能力中是主链路参与者;在"知识库与知识点管理"和"AI 对话与知识库问答"能力中角色不同(分别为上游支撑和不参与对话上下文加载)。


1. 能力目标

用户将外部学习资料PDF、Word、Markdown、图片等上传至知识库系统自动完成文本解析、分块、向量索引和知识点候选提取使资料成为可阅读、可检索、可被 AI 引用的结构化知识。


2. C 端入口

入口页面 触发方式 进入场景
知识库详情页 操作菜单 → "上传" 向已有知识库导入资料
知识库详情页 操作菜单 → "添加" → 文件模式 以文件形式添加知识点
添加知识点页·文件模式 点击"选择文件"或"图片"按钮 选择文件/照片作为知识点
导入资料页 点击"文件导入"/"相册导入"/"链接导入" 三种导入方式

用户可执行的操作:

  • 从系统文件选择器选择文件PDF、纯文本、图片等
  • 从相册选择照片(自动压缩大于 2MB 的图片)
  • 输入 URL 进行链接导入
  • 查看上传进度
  • 查看导入任务的 AI 处理状态(处理中/就绪/失败)
  • 审核 AI 提取的知识点候选(接受/拒绝/批量接受)

3. 用户主流程

用户选择资料
→ iOS 校验文件类型和大小(图片 >2MB 自动压缩)
→ iOS 调用 API 获取 COS 预签名上传 URL
→ iOS 将文件直接 PUT 到 COS
→ iOS 调用 API 确认上传完成API 验证 COS 中文件存在)
→ API 创建资料记录KnowledgeSource
→ API 创建导入任务DocumentImport状态 QUEUED
→ Python RAG Worker 轮询获取导入任务
→ Worker 下载文件 → 解析文本 → 清洗 → 分块 → 向量嵌入 → 索引到 Qdrant → 生成知识点候选
→ Worker 更新 KnowledgeSource 的 parseStatus/indexStatus/learningStatus
→ 用户可在资料详情页查看 AI 处理状态
→ 用户可在导入候选审核页审核 AI 提取的知识点候选
→ 用户接受候选 → API 创建 KnowledgeItem
→ 资料进入可阅读、可被 AI 检索的状态

4. 处理阶段与状态

资料上传后经历多个异步处理阶段,每个阶段有独立的状态追踪:

4.1 原文件上传状态

  • 谁创建: iOS 调用 API 确认上传后API 创建 UploadedFile 记录。
  • 谁更新: 上传完成后状态不再变化。文件删除时 API 从 COS 和数据库移除。
  • 用户在哪里看到: iOS 上传过程中显示进度指示器;上传完成后在资料详情页看到文件名、格式、大小。
  • Admin 在哪里看到: Admin 文件管理页查看所有上传文件列表,可按类型筛选。
  • 失败后如何处理: COS 上传失败时 iOS 显示错误提示,用户可重试。

4.2 文本解析状态parseStatus

  • 谁创建: API 创建 KnowledgeSource 时默认为 pending
  • 谁更新: Python RAG Worker 在处理过程中更新pending → processing → complete/failed。同时更新 textLength、parsedObjectKey、errorCode、errorMessage。
  • 用户在哪里看到: iOS 资料详情页的 AI 处理状态横幅(处理中为琥珀色、就绪为绿色、失败为红色)。
  • Admin 在哪里看到: Admin 来源文件页的 parseStatus 列;导入监控页的步骤日志。
  • 失败后如何处理: Admin 可触发重新解析POST /knowledge-bases/:kbId/sources/:id/parse导入任务自动重试最多 3 次。

4.3 向量索引状态indexStatus

  • 谁创建: API 创建 KnowledgeSource 时默认为 pending
  • 谁更新: Python RAG Worker 在嵌入和索引阶段更新pending → processing → complete/failed
  • 用户在哪里看到: iOS 不单独展示索引状态(合并在 AI 处理状态中)。
  • Admin 在哪里看到: Admin 来源文件页的 indexStatus 列。
  • 失败后如何处理: 同解析失败Admin 可触发重新解析,系统自动重试。

4.4 学习内容提取状态learningStatus

  • 谁创建: API 创建 KnowledgeSource 时默认为 pending
  • 谁更新: Python RAG Worker 在知识点候选生成完成后更新为 complete
  • 用户在哪里看到: 不直接展示;用户通过导入候选审核页间接感知(有候选 = 已完成提取)。
  • Admin 在哪里看到: Admin 来源文件详情中查看。
  • 失败后如何处理: 候选生成是非致命步骤——即使失败,解析和索引仍可成功。

4.5 候选审核状态

  • 谁创建: Python RAG Worker 生成候选后API 创建 ImportCandidate 记录(状态 PENDING
  • 谁更新: iOS 用户操作:接受 → ACCEPTED拒绝 → REJECTED编辑 → EDITED。内容安全拦截 → BLOCKED。
  • 用户在哪里看到: iOS 导入候选审核页(候选列表含置信度分数、标题、摘要)。
  • Admin 在哪里看到: Admin 知识运营页的候选巡检 Tab。
  • 失败后如何处理: 被内容安全拦截的候选标记为 BLOCKEDAdmin 可查看但不可恢复。

5. 项目职责

iOS — 主链路参与者

  • 提供文件选择器、相册选择器、链接输入弹窗
  • 校验文件类型和大小(图片 >2MB 自动 JPEG 压缩)
  • 调用 API 获取 COS 预签名上传 URL
  • 直接 PUT 文件到 COS
  • 调用 API 确认上传
  • 展示上传进度和 AI 处理状态
  • 提供导入候选审核界面(接受/拒绝/批量接受)

主 API — 主链路参与者

  • 提供 COS 预签名上传 URLPOST /files/upload-url
  • 验证文件类型和大小iOS 端进行初步校验文件选择器限制可选类型、图片压缩API 端进行最终校验(允许 PDF/TXT/Markdown/CSV/XLSX/DOCX/PNG/JPEG/WebP最大 20MB
  • 文件名内容安全检查
  • 确认上传完成POST /files/complete验证 COS 中文件存在后创建记录
  • 创建 KnowledgeSource 记录并自动创建 DocumentImport 任务
  • 管理导入任务状态Redis 实时状态 + 数据库持久化)
  • 提供导入状态查询GET /imports/:id/status
  • 提供候选审核 APIaccept/reject/batch-accept
  • 文件下载 URL 生成COS 预签名链接)
  • 速率限制(文件上传端点)

COS腾讯云对象存储— 主链路参与者

  • 存储用户上传的原始文件
  • 提供预签名 PUT URLiOS 直接上传,不经 API 中转)
  • 提供预签名 GET URLiOS 下载Python RAG Worker 下载)
  • 对象键格式:{userId}/{YYYYMM}/{sanitizedFilename}

Python RAG Worker — 主链路参与者

  • 轮询 API 获取待处理导入任务(每 5 秒)
  • 定期发送心跳保持任务活跃(每 30 秒)
  • 完整处理管线:下载文件 → 解析文本 → 清洗(当前仅做 >10 字符长度验证,无实质性文本清洗) → 分块 → 向量嵌入 → 索引到 Qdrant → 生成知识点候选
  • 解析器支持PDFPyMuPDF 提取文本层 → 若每页平均 <50 字符则回退到 SiliconFlow Qwen3-VL OCR、DOCXpython-docx、TXT/MD直接读取、CSV/XLSXpandas 转 Markdown 表格、图片SiliconFlow 多模态 OCR
  • 分块策略递归字符分割中文句子边界保护Markdown 标题感知512 token 块 + 64 token 重叠
  • 嵌入模型BAAI/bge-m31024 维),通过 SiliconFlow API
  • 候选生成DeepSeek 分析全文提取知识点(标题、摘要、内容、标签、回忆问题、难度、置信度)
  • 更新 KnowledgeSource 的 parseStatus/indexStatus/learningStatus

Qdrant向量数据库— 主链路参与者

  • 存储文档块的向量索引(集合 zhixi_chunks1024 维,余弦距离)
  • 每个向量点携带 payloaduserId、knowledgeBaseId、sourceId、chunkId、pageNumber、sectionTitle
  • 支持按 sourceId 软删除mark_deleted
  • 为资料范围 AI 问答和语义检索提供向量搜索能力

Admin — 运维与可观测

  • 文件管理页(查看所有上传文件,删除)
  • 来源文件页(查看所有 KnowledgeSource按解析/索引状态筛选)
  • 导入监控页(查看所有导入任务,步骤级日志,重试失败任务)
  • 候选巡检 Tab查看所有候选及其审核状态
  • 分块管理 Tab按 sourceId 查看分块详情)
  • RAG 调试 Tab向量搜索调试

Rust Document Runtime — 不参与

文件上传和异步处理链路不涉及 Rust Document Runtime。Rust 仅在用户打开已上传资料进行阅读时参与文件解析。

Heavy Runtime — 不参与

Heavy Runtime 不参与文件上传、解析、分块、索引和候选生成流程。


6. 项目间调用关系

6.1 iOS → API

调用目的 业务结果
请求上传授权 返回 COS 预签名 PUT URL + objectKey
确认上传完成 API 验证 COS 文件存在,创建 UploadedFile 记录
创建知识源 创建 KnowledgeSource + DocumentImport 任务QUEUED
查询导入状态 返回 Redis 实时状态(进度百分比 + 文字描述)
获取下载 URL 返回 COS 预签名下载链接

6.2 iOS → COS直接

调用目的 业务结果
上传文件 文件直接 PUT 到 COS不经 API 中转

6.3 Python RAG Worker → API

调用目的 业务结果
轮询待处理任务 获取 QUEUED 状态的导入任务
锁定任务 原子转换 QUEUED → CLAIMED
心跳上报 保持任务活跃,防止超时回收
更新任务状态 更新 Redis 进度/消息
更新 KnowledgeSource 更新 parseStatus/indexStatus/learningStatus
保存分块 批量写入 KnowledgeChunk 记录
保存候选 批量写入 ImportCandidate 记录

6.4 Python RAG Worker → COS

调用目的 业务结果
下载文件 通过预签名 URL 下载原始文件用于处理

6.5 Python RAG Worker → Qdrant

调用目的 业务结果
写入向量 将文档块的嵌入向量写入 zhixi_chunks 集合
软删除 标记指定 sourceId 的向量为 deleted

6.6 Python RAG Worker → 模型服务

调用目的 业务结果
文本嵌入 调用 SiliconFlow BAAI/bge-m3 生成 1024 维向量
图片 OCR 调用 SiliconFlow Qwen3-VL 多模态模型提取图片文字
候选生成 调用 DeepSeek 分析全文提取知识点候选

6.7 Admin → API运维可观测

调用目的 业务结果
查看/删除文件 文件管理
查看来源文件 列表 + 按状态筛选
查看导入任务 列表 + 步骤日志
重试导入 重置失败任务为 QUEUED
查看候选 候选巡检
查看分块 按 sourceId 查看分块详情

7. 核心业务数据

7.1 上传文件UploadedFile

  • 谁创建: API 在确认上传时创建。
  • 谁更新: 不更新(创建后不可变)。
  • 谁查询: iOS 在上传后获取文件信息Admin 在文件管理页查询。
  • 用途: 记录已上传到 COS 的文件,作为 KnowledgeSource 的 fileId 引用来源。

7.2 知识源KnowledgeSource

  • 谁创建: API 在添加来源时创建(关联 fileId
  • 谁更新: Python RAG Worker 更新 parseStatus/indexStatus/learningStatus。
  • 谁查询: iOS 在知识库详情页来源 TabAdmin 在来源文件页。
  • 用途: 知识库中每个导入资料的记录,追踪处理状态。

7.3 导入任务DocumentImport

  • 谁创建: API 在创建 KnowledgeSource 时自动创建(状态 QUEUED
  • 谁更新: Python RAG Worker 更新状态、进度、步骤日志Admin 可重置为 QUEUED重试
  • 谁查询: iOS 查询导入状态Admin 在导入监控页。
  • 用途: 追踪单个文档的完整处理生命周期,从排队到完成或失败。

7.4 知识分块KnowledgeChunk

  • 谁创建: Python RAG Worker 在分块和索引阶段批量创建。
  • 谁更新: 创建后不可修改(软删除通过 Qdrant 实现)。
  • 谁查询: Admin 在分块管理 Tab 按 sourceId 查看;系统内部通过 Qdrant 向量搜索使用。
  • 用途: 文档的语义分块,每个块有向量嵌入,用于资料范围 AI 问答的语义检索。

7.5 导入候选ImportCandidate

  • 谁创建: Python RAG Worker 在候选生成阶段批量创建(状态 PENDING
  • 谁更新: iOS 用户操作accept → ACCEPTEDreject → REJECTEDedit → EDITED。内容安全拦截 → BLOCKED。
  • 谁查询: iOS 在候选审核页按 sourceId 查询Admin 在候选巡检 Tab 查看。
  • 用途: AI 从文档中提取的知识点候选,等待用户审核确认。

7.6 知识点KnowledgeItem由候选接受生成

  • 谁创建: API 在用户接受候选时创建itemType: ai_generated
  • 谁更新: 用户在编辑知识点页修改。
  • 谁查询: iOS 在知识点详情页和知识库详情页。
  • 用途: 用户确认后的正式知识点,进入知识库内容体系。

7.7 向量索引Qdrant Collection

  • 谁创建: Python RAG Worker 在索引阶段写入。
  • 谁更新: 软删除通过 mark_deleted(sourceId) 实现。
  • 谁查询: API 在资料范围 AI 问答时通过向量搜索检索相关块Admin 通过向量管理页查看统计。
  • 用途: 为资料范围 AI 问答提供语义级检索能力。

8. 查询入口

用户查询

  • 上传进度: iOS 添加知识点页/导入资料页的上传进度指示器。
  • AI 处理状态: iOS 资料详情页的 AI 处理状态横幅(处理中/就绪/失败)。
  • 导入候选: iOS 导入候选审核页(列表含置信度、标题、摘要)。
  • 来源文件列表: iOS 知识库详情页来源 Tab含处理状态标签

Admin 查询

  • 文件列表: Admin 文件管理页(按类型查看、删除)。
  • 来源文件列表: Admin 来源文件页(按解析/索引状态筛选)。
  • 导入任务列表: Admin 导入监控页(状态、进度、步骤日志、重试)。
  • 候选巡检: Admin 知识运营页候选巡检 Tab。
  • 分块管理: Admin 知识运营页分块管理 Tab按 sourceId 查看)。
  • RAG 调试: Admin 知识运营页 RAG 调试 Tab向量搜索测试

系统内部查询

  • RAG Worker 轮询任务: Python RAG Worker 定期轮询 QUEUED 导入任务。
  • 向量搜索: API 在资料范围 AI 问答时查询 Qdrant 获取相关块。
  • Redis 状态查询: API 提供导入任务实时状态24 小时 TTL

9. 修改入口

用户操作

  • 上传新文件: iOS 导入资料页/添加知识点页。
  • 接受候选: iOS 候选审核页接受单个候选。
  • 拒绝候选: iOS 候选审核页拒绝单个候选。
  • 批量接受: iOS 候选审核页"全部接受"按钮。
  • 编辑候选: iOS 可编辑候选内容后再接受。

Admin 操作

  • 删除文件: Admin 文件管理页删除上传文件(同时从 COS 删除)。
  • 重试导入: Admin 导入监控页重试失败任务(重置为 QUEUED最多 3 次系统自动重试Admin 手动重置不占重试次数)。
  • 触发重新解析: Admin 可触发知识源的重新解析。

系统自动修改

  • 导入任务自动重试: Python RAG Worker 失败时系统自动重试(最多 3 次,超时后标记 FAILED_FINAL
  • 过期任务回收: 心跳超过 5 分钟的 CLAIMED 任务被重置为 QUEUED。
  • 内容安全检查: 文件名、KB 标题、候选内容接受时自动进行敏感词检查。
  • Redis 状态过期: 导入任务 Redis 状态在 24 小时后自动清除。
  • 分布式锁过期: 重复上传防护锁在 5 分钟后自动释放。

配置修改

  • 允许的文件类型: API 端配置PDF/TXT/Markdown/CSV/XLSX/DOCX/PNG/JPEG/WebP
  • 最大文件大小: API 端硬编码 20MB。
  • COS 预签名 URL 有效期: 上传 1 小时,下载 24 小时(知识点详情页 7 天)。
  • 分块参数: Python RAG Worker 配置512 token 块大小64 token 重叠)。
  • 嵌入模型: Python RAG Worker 配置BAAI/bge-m3
  • 候选生成模型: Python RAG Worker 配置deepseek-chattemperature 0.3)。

10. 异常与恢复

10.1 文件类型不支持

  • 场景: 用户选择不支持的文件类型。
  • iOS 处理: 文件选择器限制可选类型PDF/纯文本/图片API 在请求上传 URL 时二次校验,返回错误。
  • 用户感知: iOS 提示"不支持的文件格式"。

10.2 文件过大

  • 场景: 文件超过 20MB 限制。
  • iOS 处理: 图片 >2MB 自动 JPEG 压缩;非图片文件 >20MB 时 API 拒绝。
  • 用户感知: API 返回文件过大错误。

10.3 COS 上传失败

  • 场景: 网络问题或 COS 服务异常导致 PUT 失败。
  • iOS 处理: 显示上传错误提示,用户可重试。上传使用预签名 URL不经过 API 中转。
  • API 处理: 确认上传时如果 COS 中文件不存在headObject 失败),返回确认失败。

10.4 上传成功但 API 创建记录失败

  • 场景: COS 上传成功,但确认 API 调用失败(网络中断、服务错误)。
  • 结果: 文件在 COS 中存在但数据库无记录(孤儿文件)。
  • 恢复: 用户重新上传(生成新的 objectKeyAdmin 可手动清理孤儿文件file-cleanup 队列定期执行)。

10.5 导入任务失败

  • 场景: Python RAG Worker 处理过程中出错下载失败、解析失败、API 调用失败)。
  • 系统处理: 自动重试最多 3 次,每次重置为 QUEUED。3 次失败后标记 FAILED_FINAL。
  • 用户感知: iOS 资料详情页 AI 处理状态显示红色"失败"横幅。
  • Admin 恢复: Admin 在导入监控页查看步骤日志,手动重试(不占系统重试次数)。

10.6 RAG 解析失败

  • 场景: PDF 损坏、DOCX 格式异常、OCR 无法识别。
  • Worker 处理: 解析阶段失败 → 任务标记 FAILED更新 parseStatus 为 failed记录 errorCode 和 errorMessage。
  • 影响范围: 解析失败的文件无法进行后续分块、嵌入和索引。
  • 恢复: Admin 触发重新解析;用户可尝试重新上传。

10.7 向量索引失败

  • 场景: Qdrant 不可用、嵌入 API 调用失败。
  • Worker 处理: 索引阶段失败 → 任务标记 FAILED。parseStatus 可能已 complete但 indexStatus 为 failed。
  • 影响范围: 资料可阅读但不可用于语义检索。
  • 恢复: Admin 重试导入任务;系统自动重试。

10.8 重复上传

  • 场景: 用户短时间内上传相同文件多次。
  • API 处理: 使用 Redis 分布式锁(lock:document-import:{fileName}:{timestamp}5 分钟 TTL防止并发重复导入。
  • 边界: 锁只防止并发重复;用户间隔 5 分钟后仍可上传相同文件创建新的 KnowledgeSource。

10.9 用户删除处理中资料

  • 场景: 用户在导入任务处理过程中删除知识源。
  • API 处理: KnowledgeSource 使用软删除(设置 deletedAt。Python RAG Worker 在处理前应检查源是否已被删除(具体行为待确认)。
  • 影响: 已生成的 KnowledgeChunk 和 ImportCandidate 可能成为孤儿数据。

10.10 候选审核失败

  • 场景: 接受候选时内容安全检查失败。
  • API 处理: 候选标记为 BLOCKED返回原因。用户无法强制接受。
  • Admin 查看: Admin 可在候选巡检中看到 BLOCKED 状态的候选。

11. 当前完成状态

组件 状态 说明
iOS 文件选择与上传 已完成 文件选择器 + 相册选择器 + 链接导入
iOS 图片压缩 已完成 >2MB 自动 JPEG 压缩
iOS 上传进度展示 已完成 进度指示器
iOS 候选审核界面 已完成 接受/拒绝/批量接受
iOS AI 处理状态展示 已完成 资料详情页三色横幅(处理中/就绪/失败)
API COS 预签名 URL 上传流程 已完成 请求 URL → 直接 PUT → 确认
API 文件类型与大小校验 已完成 8 种类型,最大 20MB
API 内容安全检查(文件名) 已完成 敏感词匹配
API 速率限制 已完成 文件上传端点
API KnowledgeSource 创建与管理 已完成 含自动 DocumentImport 任务创建
API 导入状态查询 已完成 Redis 实时状态(进度+消息)
API 候选审核 API 已完成 accept/reject/batch-accept
Python RAG Worker 轮询与锁定 已完成 每 5 秒轮询,心跳每 30 秒
Python RAG Worker 文本解析 已完成 PDF/DOCX/TXT/MD/CSV/XLSX/图片 OCR
Python RAG Worker 分块与嵌入 已完成 递归分割 + BAAI/bge-m3
Python RAG Worker 向量索引 已完成 Qdrant zhixi_chunks 集合
Python RAG Worker 候选生成 已完成 DeepSeek 提取知识点
Python RAG Worker 状态更新 已完成 parseStatus/indexStatus/learningStatus
导入任务自动重试 已完成 最多 3 次,过期任务自动回收
Admin 文件管理 已完成 查看/删除
Admin 来源文件查看 已完成 列表 + 按状态筛选
Admin 导入监控 已完成 步骤日志 + 重试
Admin 候选巡检 已完成 列表查看
Admin 分块管理 已完成 按 sourceId 查看
Admin RAG 调试 部分完成 基础向量搜索测试工具,展示原始 JSON 响应;非生产级检索调试界面
孤儿文件自动清理 暂未确认 file-cleanup 队列存在但清理策略待确认
处理中删除源的行为 暂未确认 Worker 是否检查软删除标志待确认