# 文档模块详细设计 ## 1. 模块目标 Documents 模块让用户把复试题材料快速变成 Agent 可检索的知识库。V1 必须支持 `.txt`、`.md`、`.pdf` 和 `.docx`,保证常见复试材料可以进入 RAG。 ## 2. 职责边界 负责: - 文件上传表单和页面。 - 文件保存与元数据记录。 - 读取文本内容。 - 调用 Agent Core RAG 入库。 - 更新入库状态。 不负责: - 不实现向量检索算法。 - 不生成模型回答。 - 不直接写审计日志。 ## 3. 数据模型设计 模型:`UploadedDocument` 字段见 `docs/设计文档/3.数据库设计.md`。 常量: ```python STATUS_UPLOADED = "uploaded" STATUS_INDEXED = "indexed" STATUS_FAILED = "failed" SUPPORTED_EXTENSIONS = {".txt", ".md", ".pdf", ".docx"} ``` 文件保存路径建议: ```text uploads///_ ``` ## 4. 文件上传流程 1. GET `/documents/upload/` 渲染上传表单。 2. POST 校验 `scenario_id` 和文件。 3. 调用 Scenarios 服务确认场景存在。 4. 校验扩展名和文件大小。 5. 保存文件。 6. 创建 `UploadedDocument(status="uploaded")`。 7. 跳转文件列表页并展示成功提示。 ## 5. 文本抽取流程 抽取函数: ```python def extract_text(document: UploadedDocument) -> str: """按文件类型抽取可入库纯文本,失败时抛出可展示的业务异常。""" ``` 规则: - `.txt`:优先 UTF-8,失败时尝试系统默认编码。 - `.md`:UTF-8 读取,保留标题、列表和正文。 - `.pdf`:抽取纯文本,不要求 OCR、表格还原和复杂版式理解。 - `.docx`:抽取段落、标题和普通表格文本,不要求完整保留 Word 样式。 - 空文本视为失败。 - 文件不存在视为失败。 XLSX 暂不作为 V1 必须项,可作为后续结构化业务数据导入能力。 ## 6. RAG 入库触发流程 POST `/documents//index/` 1. 获取 `UploadedDocument`。 2. 调用 `extract_text()`。 3. 调用 `agent_core.rag.ingest.ingest_document()`,传入 `document_id`、`scenario_id`、文件名和抽取文本。 4. 成功后更新 `status="indexed"`,清空 `error_message`。 5. 失败后更新 `status="failed"`,写入 `error_message`。 6. 重定向回文件列表页。 入库动作必须使用 POST,避免 GET 触发写操作。 已入库或失败文档允许重新入库。重新入库前需要按 `document_id` 清理或覆盖旧 chunk,避免重复检索。 ## 7. 页面设计 文件列表页展示: - 文件名。 - 场景 ID。 - 文件类型。 - 文件大小。 - 状态。 - 上传时间。 - 入库按钮。 - 错误信息。 上传页展示: - 场景下拉框。 - 文件控件。 - 支持类型提示。 - 表单错误。 ## 8. 异常处理 | 异常 | 处理 | |---|---| | 场景不存在 | 表单错误 | | 文件为空 | 表单错误 | | 扩展名不支持 | 表单错误 | | 文件保存失败 | 页面提示失败 | | 文本为空 | 状态 failed | | RAG 入库失败 | 状态 failed 并保存原因 | ## 9. 验收标准 - 可以上传 `.txt`、`.md`、`.pdf` 和 `.docx`。 - 文件列表可看到记录。 - 文件可按场景关联。 - 入库成功状态变为 `indexed`。 - 入库失败状态变为 `failed` 且可查看原因。 - 入库失败或已入库文档可重新入库。