diff --git a/docs/详细设计/1.资料包导入与目录汇总.md b/docs/详细设计/1.资料包导入与目录汇总.md index 3220f26..c76c50b 100644 --- a/docs/详细设计/1.资料包导入与目录汇总.md +++ b/docs/详细设计/1.资料包导入与目录汇总.md @@ -2,599 +2,149 @@ ## 1. 设计目标 -本步骤是注册申报资料审核工作流的入口,目标是把用户上传的注册申报资料包转化为可供后续法规完整性核查、字段抽取、一致性检查和风险预警使用的结构化文档底座。 +本步骤对应最新版原型中的 `资料包` 页面与 `审核智能体` 上传入口,目标是把用户导入的注册申报资料转为: -本步骤需要完成以下业务结果: +1. 可绑定会话的资料包对象 +2. 可展示目录和页数的结构化结果 +3. 可进入后续审核链路的文档底座 -1. 支持单文件、多文件、文件夹和压缩包导入。 -2. 支持 `zip`、`rar`、`7z` 压缩包解包,并保留压缩包内原始相对路径。 -3. 为每个文件建立注册资料记录,包含文件名、类型、大小、原始路径、所属批次和处理状态。 -4. 统计文件页数,`PDF` 和 `DOCX` 必须精确统计,`DOC` 无法精确统计时标记为待人工复核。 -5. 初步识别章节点、资料名称、资料类别和目录类文档。 -6. 生成资料目录汇总结果,供页面展示和 Agent Core 后续任务使用。 - -本步骤不负责最终法规完整性判定,不负责字段抽取,不负责 RAG 入库。但它需要产出足够稳定的文档主数据,作为后续所有审核任务的事实输入。 - -## 2. 所属模块与边界 - -### 2.1 Django Documents - -`apps.documents` 负责接收上传请求、保存原始文件、创建资料包批次、维护文档记录和展示目录汇总。 - -本步骤中 Django 侧建议提供: - -1. 上传页和资料包导入入口。 -2. 资料包批次模型。 -3. 文档主数据模型。 -4. 文档处理状态字段。 -5. 目录汇总服务。 -6. 目录汇总页面。 - -### 2.2 Agent Core - -`agent_core` 负责沉淀可复用的资料包处理 Skill 和 Tool Registry 注册项。 - -本步骤中 Agent Core 建议提供: - -1. `资料包导入Skill` -2. `压缩包解包Skill` -3. `资料包扫描Skill` -4. `文档页数统计Skill` -5. `章节点识别Skill` -6. `目录汇总Skill` - -这些 Skill 不直接依赖 Django View。Django View 只负责收集参数并调用服务层,服务层再调用 Agent Core 的 Skill 或 Tool。 - -### 2.3 Audit - -`apps.audit` 在本步骤中只记录资料包导入过程,不做审核结论留痕。 - -建议记录: - -1. 导入入口。 -2. 导入文件数量。 -3. 解包结果。 -4. 页数统计结果。 -5. 失败文件数量。 -6. 待人工复核文件数量。 - -## 3. 输入输出 - -### 3.1 输入 - -用户可以通过以下方式导入资料: - -1. 单文件上传。 -2. 多文件批量上传。 -3. 文件夹上传,前端传递每个文件的相对路径。 -4. 压缩包上传,后端解压后还原相对路径。 - -支持文件类型: - -1. `pdf` -2. `docx` -3. `doc` -4. `txt` -5. `md` -6. `zip` -7. `rar` -8. `7z` - -### 3.2 输出 - -本步骤输出 `registration_overview_report` 的第一版结构,核心字段如下: - -```json -{ - "batch_id": "SUB-20260603-001", - "workflow_type": "registration", - "source_role": "submission", - "file_count": 8, - "supported_file_count": 7, - "failed_file_count": 1, - "total_page_count": 36, - "page_count_status": "partial_review_required", - "chapter_summary": [ - { - "chapter_code": "CH1.2", - "chapter_name": "监管信息目录", - "file_count": 1, - "page_count": 3 - } - ], - "documents": [], - "warnings": [] -} -``` - -每个 `documents` 元素至少包含: - -```json -{ - "document_id": 1001, - "original_filename": "CH1.4 申请表.docx", - "relative_path": "第1章 监管信息/CH1.4 申请表.docx", - "file_type": "docx", - "file_size": 1048576, - "chapter_code": "CH1.4", - "chapter_name": "申请表", - "document_role": "application_form", - "page_count": 5, - "page_count_method": "docx_exact", - "page_count_confidence": "exact", - "processing_status": "summarized", - "review_status": "normal", - "needs_manual_review": false -} -``` - -## 4. 主工作流 - -```text -用户选择导入资料 --> 创建资料包批次 --> 校验上传文件 --> 判断是否压缩包 --> 解包或登记原始文件 --> 扫描文件树 --> 过滤不支持文件 --> 创建文档主数据 --> 统计页数 --> 初步识别章节点 --> 识别目录类/声明类/沟通类文件 --> 汇总目录与页数 --> 写入导入审计 --> 返回目录汇总页面 -``` - -## 5. 节点详细设计 - -### 5.1 节点一:创建资料包批次 - -业务功能: - -1. 为一次导入创建独立批次。 -2. 记录导入来源、导入人、任务类型和资料来源角色。 -3. 建立隔离存储目录,避免不同项目或不同批次文件混在一起。 - -建议模型: - -```python -class SubmissionBatch(models.Model): - batch_no = models.CharField(max_length=64, unique=True) - name = models.CharField(max_length=255) - workflow_type = models.CharField(max_length=32, default="registration") - source_role = models.CharField(max_length=32, default="submission") - import_status = models.CharField(max_length=32, default="created") - created_by = models.ForeignKey(User, null=True, on_delete=models.SET_NULL) - created_at = models.DateTimeField(auto_now_add=True) -``` - -使用技术: - -1. Django ORM -2. Django Storage -3. `uuid` 或业务编号生成器 - -产生方法: - -1. `create_submission_batch(params) -> SubmissionBatch` -2. `build_batch_storage_path(batch) -> Path` - -对应 Skill: - -1. `资料包导入Skill` - -### 5.2 节点二:上传文件校验 - -业务功能: - -1. 校验文件扩展名是否支持。 -2. 校验文件大小是否超过配置限制。 -3. 校验文件名是否包含危险路径。 -4. 识别普通文件和压缩包。 - -使用技术: - -1. Django uploaded file API -2. `pathlib.PurePath` -3. `python-magic` 或 `mimetypes` - -校验规则: - -1. 禁止绝对路径。 -2. 禁止 `..` 路径穿越。 -3. 禁止空文件。 -4. 允许中文文件名。 -5. 对扩展名和 MIME 不一致的文件标记为待复核。 - -产生方法: - -1. `validate_uploaded_file(uploaded_file) -> FileValidationResult` -2. `detect_upload_kind(uploaded_file) -> Literal["document", "archive"]` - -对应 Skill: - -1. `资料包导入Skill` - -### 5.3 节点三:压缩包解包 - -业务功能: - -1. 支持 `zip`、`rar`、`7z`。 -2. 解包到批次隔离目录。 -3. 保留压缩包内多层相对路径。 -4. 记录每个解包文件来自哪个压缩包。 -5. 对空包、损坏包、加密包、嵌套异常给出业务状态。 - -使用技术: - -1. `zipfile` -2. `rarfile` 或纯 Python rar 解析依赖 -3. `py7zr` -4. `pathlib` -5. 文件路径安全检查函数 - -关键状态: - -1. `extracted` -2. `empty_archive` -3. `encrypted_archive` -4. `unsupported_archive` -5. `extract_failed` -6. `path_rejected` - -产生方法: - -1. `extract_archive(archive_path, target_dir) -> ArchiveExtractionResult` -2. `safe_extract_member(member_name, target_dir) -> Path` -3. `normalize_relative_path(raw_path) -> str` - -对应 Skill: - -1. `压缩包解包Skill` - -### 5.4 节点四:扫描文件树 - -业务功能: - -1. 遍历本次批次目录。 -2. 过滤临时文件、系统隐藏文件和不支持文件。 -3. 生成待处理文件清单。 -4. 保留相对于资料包根目录的路径。 - -使用技术: - -1. `pathlib.Path.rglob` -2. 文件哈希 `hashlib.sha256` -3. 后缀白名单 - -过滤规则: - -1. 跳过 `__MACOSX`。 -2. 跳过 `.DS_Store`。 -3. 跳过 Office 临时文件,如 `~$申请表.docx`。 -4. 对 `.exe` 等不支持文件记录为 `unsupported`,不进入后续页数统计。 - -产生方法: - -1. `scan_submission_package(root_dir) -> PackageScanResult` -2. `build_file_fingerprint(file_path) -> str` -3. `is_supported_document(file_path) -> bool` - -对应 Skill: - -1. `资料包扫描Skill` - -### 5.5 节点五:创建文档主数据 - -业务功能: - -1. 为每个文件创建文档记录。 -2. 写入文件名、相对路径、文件类型、大小、哈希、来源压缩包。 -3. 标记初始处理状态。 -4. 区分业务申报资料和法规依据资料。 - -建议模型: - -```python -class RegistrationDocument(models.Model): - batch = models.ForeignKey(SubmissionBatch, on_delete=models.CASCADE) - original_filename = models.CharField(max_length=255) - relative_path = models.CharField(max_length=1024) - file_type = models.CharField(max_length=32) - file_size = models.PositiveBigIntegerField(default=0) - file_hash = models.CharField(max_length=128, blank=True) - source_archive_name = models.CharField(max_length=255, blank=True) - source_role = models.CharField(max_length=32, default="submission") - workflow_type = models.CharField(max_length=32, default="registration") - processing_status = models.CharField(max_length=32, default="created") -``` - -使用技术: - -1. Django ORM -2. 批量创建 `bulk_create` -3. 唯一性约束:`batch + relative_path` - -产生方法: - -1. `create_document_records(batch, scanned_files) -> list[RegistrationDocument]` -2. `mark_unsupported_file(batch, scanned_file, reason) -> RegistrationDocument` - -对应 Skill: - -1. `资料包导入Skill` -2. `资料包扫描Skill` - -### 5.6 节点六:页数统计 - -业务功能: - -1. 为每份文档统计页数。 -2. 写入页数统计方法和可信度。 -3. 对无法精确统计的文档标记待人工复核。 - -使用技术: - -1. PDF:`pypdf` 或 `PyMuPDF` -2. DOCX:优先读取 Word 兼容统计结果,必要时通过 LibreOffice headless 转 PDF 后精确统计 -3. DOC:尝试转换或解析,失败时标记 `manual_review_required` -4. TXT/MD:页数不作为强制指标,可按 `not_applicable` 或导出预览后统计 - -页数状态: - -1. `exact` -2. `not_applicable` -3. `manual_review_required` -4. `failed` - -产生方法: - -1. `count_document_pages(document) -> PageCountResult` -2. `count_pdf_pages(path) -> PageCountResult` -3. `count_docx_pages(path) -> PageCountResult` -4. `count_doc_pages(path) -> PageCountResult` - -对应 Skill: - -1. `文档页数统计Skill` - -### 5.7 节点七:章节点与资料名称识别 - -业务功能: - -1. 从文件名、相对路径和标题文本中识别章节点。 -2. 识别资料名称。 -3. 标记目录类、声明类、申请表、产品列表、历史沟通说明等文档角色。 -4. 对无法确认的文件标记待人工确认。 - -使用技术: - -1. 正则表达式 -2. 本地章节点规则 YAML -3. `python-docx` 抽取首页标题 -4. 简单关键词规则 - -识别优先级: - -1. 相对路径中的章名,如 `第1章 监管信息` -2. 文件名中的章节点编码,如 `CH1.4` -3. 文件名中的标准资料名称,如 `申请表` -4. 文档首页标题 -5. 用户手动选择的章节点 - -产生方法: - -1. `classify_chapter_node(document) -> ChapterClassificationResult` -2. `extract_chapter_code_from_path(relative_path) -> str | None` -3. `detect_document_role(filename, title_text) -> str` - -对应 Skill: - -1. `章节点识别Skill` - -### 5.8 节点八:目录汇总生成 - -业务功能: - -1. 汇总当前批次所有文档。 -2. 计算文件数量、支持文件数量、失败数量、总页数。 -3. 按章节点聚合文件和页数。 -4. 输出待人工复核清单。 -5. 生成页面展示和 Agent Core 输入使用的统一结构。 - -使用技术: - -1. Django ORM 聚合查询 -2. Python dataclass 或 Pydantic schema -3. JSONField 存储结构化结果 - -产生方法: - -1. `build_directory_summary(batch_id) -> RegistrationOverviewReport` -2. `summarize_chapters(documents) -> list[ChapterSummary]` -3. `collect_import_warnings(documents) -> list[ImportWarning]` - -对应 Skill: - -1. `目录汇总Skill` - -### 5.9 节点九:审计留痕 - -业务功能: - -1. 记录资料包导入执行过程。 -2. 记录失败文件和待人工复核文件。 -3. 为后续完整性核查提供可追溯基础。 - -使用技术: - -1. `apps.audit` 服务层 -2. JSONField -3. 敏感信息脱敏函数 - -产生方法: - -1. `record_import_audit(batch, overview_report) -> AuditLog` -2. `sanitize_import_context(context) -> dict` - -对应 Skill: - -1. 本步骤不单独产生 Audit Skill,由 Django 服务层调用 Audit 服务完成。 - -## 6. Skill 清单 - -本步骤产生以下 Skill 设计文档: - -1. [资料包导入Skill](skill/资料包导入Skill.md) -2. [压缩包解包Skill](skill/压缩包解包Skill.md) -3. [资料包扫描Skill](skill/资料包扫描Skill.md) -4. [文档页数统计Skill](skill/文档页数统计Skill.md) -5. [章节点识别Skill](skill/章节点识别Skill.md) -6. [目录汇总Skill](skill/目录汇总Skill.md) - -## 7. 数据状态设计 - -### 7.1 批次状态 - -| 状态 | 含义 | -|---|---| -| `created` | 已创建批次,尚未完成文件登记 | -| `importing` | 正在导入或解包 | -| `summarizing` | 正在统计页数和目录 | -| `completed` | 导入与目录汇总完成 | -| `partial_completed` | 部分文件失败或需复核 | -| `failed` | 整体导入失败 | - -### 7.2 文档状态 - -| 状态 | 含义 | -|---|---| -| `created` | 已创建记录 | -| `unsupported` | 文件类型不支持 | -| `page_counted` | 已完成页数统计 | -| `classified` | 已完成章节点识别 | -| `summarized` | 已进入目录汇总 | -| `manual_review_required` | 需要人工复核 | -| `failed` | 处理失败 | - -### 7.3 页数可信度 - -| 状态 | 含义 | -|---|---| -| `exact` | 精确页数 | -| `not_applicable` | 不适用 | -| `manual_review_required` | 无法精确统计,需人工复核 | -| `failed` | 统计失败 | - -## 8. 异常处理 - -本步骤需要业务化处理以下异常: - -1. 上传空文件:拒绝导入,提示文件为空。 -2. 文件名路径穿越:拒绝该文件,记录安全拦截。 -3. 压缩包损坏:批次标记为 `failed` 或 `partial_completed`。 -4. 压缩包加密:标记为 `manual_review_required`。 -5. 解包后无支持文件:批次标记为 `partial_completed`,页面提示未发现可处理资料。 -6. DOC 页数无法精确统计:文档标记待人工复核,不阻断目录汇总。 -7. DOCX 页数无法精确统计:文档标记失败或待复核,并在汇总结果中突出提示。 -8. 文件内容与扩展名不一致:记录风险提示,仍可尝试解析。 -9. 同名相对路径重复:保留第一份,后续文件加版本后缀或标记重复。 -10. 混入不支持文件:记录为 `unsupported`,不进入页数统计。 - -## 9. 页面展示 - -资料包导入完成后,Documents 页面建议展示: - -1. 批次名称和导入时间。 -2. 导入文件总数。 -3. 支持文件数量。 -4. 页数合计。 -5. 待人工复核数量。 -6. 解包失败或不支持文件数量。 -7. 按章节点聚合的目录表。 -8. 文件明细表。 - -文件明细表字段: - -1. 原始相对路径。 -2. 文件名。 -3. 文件类型。 -4. 页数。 -5. 页数可信度。 -6. 章节点。 -7. 资料名称。 -8. 处理状态。 -9. 是否需人工复核。 - -## 10. 与后续步骤的接口 - -后续法规完整性核查需要读取: +本步骤执行完成后,系统应至少产出: 1. `batch_id` -2. `workflow_type` -3. `source_role` -4. `documents[].document_id` -5. `documents[].relative_path` -6. `documents[].chapter_code` -7. `documents[].document_role` -8. `documents[].page_count` -9. `documents[].processing_status` -10. `documents[].needs_manual_review` +2. `product_name` +3. `conversation_id` +4. `registration_overview_report` -后续 RAG 入库需要读取: +## 2. 页面与模块对应 -1. 文件路径。 -2. 文件类型。 -3. 章节点。 -4. 资料名称。 -5. 业务资料或法规资料角色。 -6. 文档处理状态。 +### 2.1 `资料包` 页面 -## 11. 测试设计 +用于展示: -### 11.1 单元测试 +1. 资料包列表 +2. 产品名称搜索框 +3. 资料包与会话关联关系 +4. 文件目录、页数、章节点和异常 -1. 上传文件校验。 -2. 路径安全校验。 -3. 压缩包解包。 -4. 文件扫描过滤。 -5. 页数统计。 -6. 章节点识别。 -7. 目录汇总聚合。 +### 2.2 `审核智能体` 页面 -### 11.2 服务层测试 +用于触发: -1. 单文件导入生成文档记录。 -2. 多文件导入生成同一批次。 -3. 压缩包导入保留相对路径。 -4. 解包失败时批次状态正确。 -5. DOC 无法统计页数时标记待复核。 -6. 目录汇总结果包含文件数量、页数、章节点和警告。 +1. 上传资料包 +2. 自动创建或绑定会话 +3. 在对话中插入“目录汇总”节点结果 -### 11.3 页面测试 +### 2.3 `apps.documents` -1. 上传成功后跳转到目录汇总页。 -2. 页面展示页数可信度。 -3. 页面展示待人工复核提示。 -4. 不支持文件有清晰提示。 +负责: -## 12. V1 实现建议 +1. 资料包模型 +2. 文档模型 +3. 页数统计 +4. 章节点识别 +5. 目录汇总服务 -V1 建议先完成以下最小闭环: +## 3. 核心数据结构 -1. 支持单文件和多文件上传。 -2. 支持 `zip` 解包,并预留 `rar`、`7z` 依赖接入点。 -3. 支持 `PDF`、`DOCX` 页数统计。 -4. `DOC` 文件先标记待人工复核。 -5. 基于文件名和路径识别 `CH1.*` 章节点。 -6. 生成目录汇总页面和结构化 `registration_overview_report`。 +### 3.1 SubmissionBatch -在 V1 后续增强中补齐: +建议包含: -1. `rar`、`7z` 纯 Python 解包。 -2. DOC 转换后精确统计。 -3. 目录类文档内容解析。 -4. 文件夹上传前端体验。 -5. 后台人工修正章节点和资料名称。 +1. `batch_no` +2. `product_name` +3. `workflow_type` +4. `conversation_id` +5. `file_count` +6. `page_count` +7. `import_status` +8. `exception_count` + +### 3.2 UploadedDocument + +建议增加: + +1. `batch_id` +2. `relative_path` +3. `chapter_code` +4. `document_role` +5. `page_count` +6. `page_count_confidence` +7. `chapter_match_status` +8. `needs_manual_review` + +## 4. 主流程 + +```text +上传资料包 +-> 创建批次 +-> 保存原始文件 +-> 解包 / 扫描目录 +-> 统计页数 +-> 识别产品名称 +-> 识别章节点 +-> 生成目录汇总 +-> 创建或绑定会话 +-> 返回资料包页与对话节点 +``` + +## 5. 关键节点设计 + +### 5.1 产品名称解析 + +优先来源: + +1. 申请表 +2. 目标产品说明书 +3. 产品列表 + +结果用途: + +1. 作为资料包主标题 +2. 作为会话标题 +3. 作为资料包搜索主字段 + +### 5.2 资料包与会话绑定 + +规则固定为: + +1. 新导入资料包默认生成一个主会话 +2. 主会话标题使用解析后的 `product_name` +3. 资料包页“查看对话”跳转到 `conversation_id` + +### 5.3 目录汇总输出 + +输出对象 `registration_overview_report` 至少包含: + +1. `batch_id` +2. `product_name` +3. `file_count` +4. `total_page_count` +5. `chapter_summary` +6. `documents` +7. `warnings` + +## 6. 异常策略 + +以下情况标记为待复核: + +1. DOC 页数无法精确统计 +2. 章节点无法确定 +3. 产品名称来源冲突 +4. 目录路径疑似错放 + +## 7. 与后续步骤的接口 + +本步骤向后续步骤提供: + +1. `batch_id` +2. `conversation_id` +3. `product_name` +4. `document_scope` +5. `chapter_summary` + +## 8. 验收标准 + +1. 资料包导入后形成批次记录。 +2. 会话标题使用解析出的产品名称。 +3. 资料包页支持按产品名称搜索。 +4. 目录汇总结果可直接进入 Agent 节点展示。 diff --git a/docs/详细设计/2.法规完整性检查.md b/docs/详细设计/2.法规完整性检查.md index d34bbe8..848feb9 100644 --- a/docs/详细设计/2.法规完整性检查.md +++ b/docs/详细设计/2.法规完整性检查.md @@ -2,609 +2,65 @@ ## 1. 设计目标 -本步骤承接“资料包导入与目录汇总”的输出,目标是对照 NMPA 体外诊断试剂注册申报资料要求,检查当前资料包是否齐套、章节点是否匹配、资料是否错放、是否存在需要人工复核的完整性问题。 +本步骤对应 `审核智能体` 中的“完整性检查”节点,目标是基于结构化规则和法规 RAG 证据判断资料包是否齐套、是否错放、是否存在高风险缺失项。 -本步骤需要完成以下业务结果: - -1. 识别当前审核任务适用的法规流程,V1 默认使用 `registration` 注册申报流程。 -2. 装载本地法规规则包,默认以公告附件包为主规则来源。 -3. 将资料包目录结果与法规目录模板进行匹配。 -4. 区分已提供、缺失、疑似提供、错放、待人工复核等状态。 -5. 对缺失、错放和不确定项生成完整性风险等级和处理建议。 -6. 通过 RAG 检索法规原文证据,但不把 RAG 命中结果作为最终裁判。 -7. 输出结构化 `registration_completeness_report`,供 Chat 页面、Audit 和后续风险预警使用。 - -本步骤不负责产品字段抽取,不负责跨文档字段一致性检查,不负责最终综合风险报告。它只产出法规完整性维度的结论和证据。 - -## 2. 所属模块与边界 - -### 2.1 Scenarios - -`apps.scenarios` 负责定义“法规完整性核查”任务入口。 - -建议配置项: - -1. `scenario_id`: `registration_completeness_check` -2. `workflow_type`: `registration` -3. `required_input`: `registration_overview_report` -4. `rule_package`: `nmpa_ivd_registration_v1` -5. `enable_rag_evidence`: `true` -6. `output_schema`: `registration_completeness_report` - -### 2.2 Documents - -`apps.documents` 提供第一步生成的文档主数据和目录汇总结果。 - -本步骤读取: - -1. 批次信息。 -2. 文件相对路径。 -3. 文件名。 -4. 文件类型。 -5. 页数。 -6. 章节点。 -7. 文档角色。 -8. 处理状态。 -9. 待人工复核标记。 - -### 2.3 Agent Core - -`agent_core` 是本步骤的执行主体,负责编排规则包加载、流程识别、规则匹配、完整性判定、法规证据检索和报告生成。 - -本步骤建议产生以下中文 Skill: - -1. `法规完整性检查Skill` -2. `法规规则包加载Skill` -3. `法规流程识别Skill` -4. `资料要求匹配Skill` -5. `缺失错放判定Skill` -6. `法规证据检索Skill` -7. `完整性报告生成Skill` - -### 2.4 RAG - -RAG 只负责证据定位和解释引用。 - -RAG 可以回答: - -1. 当前缺失项对应公告附件中的哪段要求。 -2. 当前章节点属于哪类资料要求。 -3. 当前格式要求来源于哪份附件。 - -RAG 不负责决定: - -1. 某资料是否必交。 -2. 当前资料是否合规。 -3. 缺失项是否高风险。 - -这些结论必须来自结构化规则。 - -### 2.5 Audit - -`apps.audit` 记录本次完整性检查的输入、规则版本、匹配结果、缺失项、证据和错误。 - -审计中必须保留: +## 2. 输入 1. `batch_id` -2. `scenario_id` -3. `workflow_type` -4. `rule_package_id` -5. `rule_version` -6. `selected_document_ids` -7. `matched_items` -8. `missing_items` -9. `misplaced_items` -10. `manual_review_items` -11. `evidence_refs` +2. `conversation_id` +3. `product_name` +4. `chapter_summary` +5. `document_scope` +6. 规则包与法规知识索引 -## 3. 输入输出 +## 3. 规则与 RAG 分工 -### 3.1 输入 +### 3.1 规则负责 -```json -{ - "batch_id": 1001, - "scenario_id": "registration_completeness_check", - "workflow_type": "registration", - "rule_package_id": "nmpa_ivd_registration_v1", - "chapter_scope": ["CH1"], - "selected_document_ids": [1, 2, 3], - "enable_rag_evidence": true -} -``` +1. 必交项判断 +2. 章节点匹配 +3. 缺失/错放分类 +4. 风险等级映射 -其中 `chapter_scope` 可为空。为空时默认检查当前批次已识别章节点及 V1 默认范围;演示首版建议优先检查 `CH1`,同时保留全六章规则结构。 +### 3.2 RAG 负责 -### 3.2 输出 +1. 定位法规依据片段 +2. 提供条款解释 +3. 为对话输出引用依据 -本步骤输出 `registration_completeness_report`: - -```json -{ - "report_type": "registration_completeness_report", - "batch_id": 1001, - "workflow_type": "registration", - "rule_package_id": "nmpa_ivd_registration_v1", - "rule_version": "2026-06-03", - "chapter_scope": ["CH1"], - "summary": { - "required_item_count": 8, - "provided_item_count": 6, - "missing_item_count": 1, - "suspected_item_count": 1, - "misplaced_item_count": 0, - "manual_review_item_count": 1, - "highest_risk_level": "high", - "pass_status": "failed" - }, - "matched_items": [], - "missing_items": [], - "misplaced_items": [], - "manual_review_items": [], - "evidence_refs": [], - "suggestions": [] -} -``` - -### 3.3 结果状态 - -| 状态 | 含义 | -|---|---| -| `provided` | 已提供,命中文档和章节点 | -| `missing` | 必交资料未找到 | -| `suspected` | 疑似提供,但命名、章节点或文档角色不确定 | -| `misplaced` | 文件存在,但章节点或路径位置不匹配 | -| `manual_review_required` | 规则无法直接判断,需人工复核 | -| `not_applicable` | 当前流程或适用条件下不要求 | - -## 4. 主工作流 +## 4. 主流程 ```text -用户发起法规完整性检查 --> 读取资料包目录汇总结果 --> 确认法规流程类型 --> 装载法规规则包 --> 展开章节和必交项规则 --> 将实际文档与规则项匹配 --> 判定已提供/缺失/疑似/错放/待复核 --> 映射风险等级与处理建议 --> 检索法规原文证据 --> 生成完整性检查报告 --> 写入审计留痕 --> 返回 Web/飞书可展示结果 +读取资料包目录 +-> 加载完整性规则包 +-> 比对章节点与资料要求 +-> 输出缺失项 / 错放项 / 待复核项 +-> 通过 RAG 补充法规依据 +-> 生成完整性节点结果 ``` -## 5. 节点详细设计 +## 5. 输出对象 -### 5.1 节点一:读取目录汇总结果 +`registration_completeness_report` 至少包含: -业务功能: +1. `missing_items` +2. `misplaced_items` +3. `manual_review_items` +4. `risk_level` +5. `rule_hits` +6. `rag_evidence` -1. 根据 `batch_id` 读取第一步产出的 `registration_overview_report`。 -2. 校验资料包是否完成目录汇总。 -3. 过滤当前检查范围内的文档。 -4. 收集待人工复核文档,作为完整性检查的不确定性输入。 +## 6. 对话节点要求 -使用技术: +完整性检查节点在会话中应展示: -1. Django ORM -2. JSONField -3. Pydantic 或 dataclass schema 校验 +1. 缺失项摘要 +2. 错放项摘要 +3. 风险等级 +4. 法规依据来源 -产生方法: - -1. `load_overview_report(batch_id) -> RegistrationOverviewReport` -2. `select_documents_for_completeness(report, chapter_scope, selected_document_ids) -> list[DocumentFact]` -3. `collect_document_uncertainties(documents) -> list[DocumentUncertainty]` - -对应 Skill: - -1. `法规完整性检查Skill` - -### 5.2 节点二:法规流程识别 - -业务功能: - -1. 确认当前任务属于注册申报、变更备案、变更注册还是延续注册。 -2. V1 默认使用 `registration`。 -3. 如果用户选择了不支持流程,返回业务化提示。 -4. 防止把变更或延续规则误用于首次注册申报。 - -使用技术: - -1. 场景配置 YAML -2. 批次字段 `workflow_type` -3. 规则包元数据 - -产生方法: - -1. `resolve_workflow_type(batch, scenario_config, user_input) -> WorkflowTypeResult` -2. `validate_workflow_supported(workflow_type, rule_package) -> bool` - -对应 Skill: - -1. `法规流程识别Skill` - -### 5.3 节点三:法规规则包加载 - -业务功能: - -1. 加载本地结构化法规规则文件。 -2. 校验规则版本、适用流程和章节结构。 -3. 按“章 -> 条 -> 要求项 -> 模板字段”四级结构展开规则。 -4. 区分资料要求层、结构目录层和格式模板层。 - -使用技术: - -1. YAML 规则文件 -2. Pydantic schema -3. Django cache 或内存缓存 -4. 规则版本号 - -建议规则目录: - -```text -configs/registration/rules/ - nmpa_ivd_registration_v1.yaml - chapter_catalog.yaml - risk_mapping.yaml -``` - -规则项示例: - -```yaml -rule_package_id: nmpa_ivd_registration_v1 -workflow_type: registration -version: "2026-06-03" -chapters: - - chapter_code: CH1 - chapter_name: 监管信息 - requirements: - - requirement_id: CH1.4 - requirement_name: 申请表 - required: true - expected_document_roles: - - application_form - risk_level_if_missing: high - evidence_query: "体外诊断试剂 注册申报 申请表 监管信息" -``` - -产生方法: - -1. `load_rule_package(rule_package_id) -> RulePackage` -2. `validate_rule_package(rule_package) -> RulePackageValidationResult` -3. `expand_requirement_items(rule_package, workflow_type, chapter_scope) -> list[RequirementItem]` - -对应 Skill: - -1. `法规规则包加载Skill` - -### 5.4 节点四:资料要求匹配 - -业务功能: - -1. 将当前资料包文档与法规要求项进行匹配。 -2. 优先使用章节点编码匹配。 -3. 其次使用文档角色匹配。 -4. 再使用文件名和资料名称关键词匹配。 -5. 保留匹配证据和匹配置信度。 - -匹配优先级: - -1. `document.chapter_code == requirement.requirement_id` -2. `document.document_role in requirement.expected_document_roles` -3. 文件名命中规则关键词。 -4. 相对路径命中章节名称。 -5. 人工修正字段命中。 - -使用技术: - -1. Python 规则匹配 -2. 字符串标准化 -3. 简单中文关键词匹配 -4. 可选 rapidfuzz 模糊匹配,V1 谨慎使用 - -产生方法: - -1. `match_documents_to_requirements(documents, requirements) -> RequirementMatchSet` -2. `match_by_chapter_code(document, requirement) -> MatchEvidence | None` -3. `match_by_document_role(document, requirement) -> MatchEvidence | None` -4. `match_by_keywords(document, requirement) -> MatchEvidence | None` -5. `calculate_match_confidence(evidences) -> str` - -对应 Skill: - -1. `资料要求匹配Skill` - -### 5.5 节点五:缺失、错放与待复核判定 - -业务功能: - -1. 对每个法规要求项生成完整性状态。 -2. 判断必交项是否缺失。 -3. 判断文件是否存在但错放章节。 -4. 判断疑似提供但证据不足的情况。 -5. 将第一步处理失败或页数待复核文件纳入不确定性。 - -判定规则: - -| 条件 | 状态 | -|---|---| -| 必交项有高置信匹配文档 | `provided` | -| 必交项无任何匹配文档 | `missing` | -| 有低置信匹配文档 | `suspected` | -| 文档角色匹配但章节点不匹配 | `misplaced` | -| 文档本身待人工复核 | `manual_review_required` | -| 规则项不适用于当前流程 | `not_applicable` | - -使用技术: - -1. Python 规则引擎 -2. 风险映射 YAML -3. dataclass/Pydantic 结果对象 - -产生方法: - -1. `evaluate_requirement_status(requirement, matches, document_uncertainties) -> CompletenessItemResult` -2. `detect_missing_items(requirements, matches) -> list[MissingItem]` -3. `detect_misplaced_items(requirements, matches) -> list[MisplacedItem]` -4. `detect_manual_review_items(requirements, matches, uncertainties) -> list[ManualReviewItem]` - -对应 Skill: - -1. `缺失错放判定Skill` - -### 5.6 节点六:完整性风险映射 - -业务功能: - -1. 根据规则项定义映射风险等级。 -2. 缺失高风险必交项时,本维度判定不通过。 -3. 对待复核项不直接判失败,但标记结果可信度下降。 -4. 生成基础处理建议。 - -风险等级: - -1. `high` -2. `medium` -3. `low` - -准入规则: - -1. 任一高风险缺失项:`pass_status = failed` -2. 无高风险但存在中风险缺失项:`pass_status = review_required` -3. 只有低风险或待复核项:`pass_status = conditional_pass` -4. 无缺失、无错放、无待复核:`pass_status = passed` - -使用技术: - -1. 规则包内风险配置 -2. 本地建议模板 -3. Python 枚举 - -产生方法: - -1. `map_completeness_risk(item_result, risk_rules) -> RiskMappingResult` -2. `calculate_pass_status(item_results) -> str` -3. `build_completeness_suggestion(item_result) -> str` - -对应 Skill: - -1. `缺失错放判定Skill` - -### 5.7 节点七:法规证据检索 - -业务功能: - -1. 针对缺失项、错放项和待复核项检索法规原文。 -2. 返回法规来源文档、章节、片段和匹配查询。 -3. 将证据附加到完整性结果和审计记录。 - -使用技术: - -1. Chroma 或 fallback 检索 -2. 本地法规原文切片 -3. metadata 过滤 -4. 关键词查询兜底 - -检索过滤条件: - -1. `source_role = regulation` -2. `workflow_type = registration` -3. `rule_package_id = nmpa_ivd_registration_v1` -4. `chapter_code` 或 `requirement_id` - -产生方法: - -1. `retrieve_regulation_evidence(requirement_item, query_context) -> list[EvidenceRef]` -2. `build_evidence_query(requirement_item) -> str` -3. `filter_evidence_by_metadata(results, requirement_item) -> list[EvidenceRef]` - -对应 Skill: - -1. `法规证据检索Skill` - -### 5.8 节点八:完整性报告生成 - -业务功能: - -1. 汇总完整性检查结果。 -2. 生成结构化报告。 -3. 生成页面展示摘要。 -4. 生成飞书摘要所需的短消息结构。 -5. 写入审计记录。 - -使用技术: - -1. Pydantic 或 dataclass schema -2. JSONField -3. Django template 或页面组件消费 JSON -4. Audit 服务层 - -产生方法: - -1. `build_completeness_report(context, item_results, evidence_refs) -> RegistrationCompletenessReport` -2. `build_completeness_summary(item_results) -> CompletenessSummary` -3. `build_display_sections(report) -> list[DisplaySection]` -4. `record_completeness_audit(report, execution_context) -> AuditLog` - -对应 Skill: - -1. `完整性报告生成Skill` - -## 6. Skill 清单 - -本步骤产生以下 Skill 设计文档: - -1. [法规完整性检查Skill](skill/法规完整性检查Skill.md) -2. [法规规则包加载Skill](skill/法规规则包加载Skill.md) -3. [法规流程识别Skill](skill/法规流程识别Skill.md) -4. [资料要求匹配Skill](skill/资料要求匹配Skill.md) -5. [缺失错放判定Skill](skill/缺失错放判定Skill.md) -6. [法规证据检索Skill](skill/法规证据检索Skill.md) -7. [完整性报告生成Skill](skill/完整性报告生成Skill.md) - -## 7. 规则数据设计 - -### 7.1 规则包元数据 - -| 字段 | 说明 | -|---|---| -| `rule_package_id` | 规则包标识 | -| `version` | 规则版本 | -| `workflow_type` | 适用流程 | -| `source_documents` | 法规来源文档 | -| `effective_scope` | 适用范围 | -| `chapter_count` | 章节数量 | - -### 7.2 要求项字段 - -| 字段 | 说明 | -|---|---| -| `requirement_id` | 要求项编码,如 `CH1.4` | -| `chapter_code` | 章编码,如 `CH1` | -| `requirement_name` | 要求项名称 | -| `required` | 是否必交 | -| `condition` | 适用条件 | -| `expected_document_roles` | 期望文档角色 | -| `keywords` | 匹配关键词 | -| `risk_level_if_missing` | 缺失风险等级 | -| `evidence_query` | 法规证据检索查询 | -| `template_field_refs` | 后续模板字段映射 | - -### 7.3 匹配结果字段 - -| 字段 | 说明 | -|---|---| -| `requirement_id` | 要求项编码 | -| `status` | 完整性状态 | -| `matched_document_ids` | 命中文档 ID | -| `match_confidence` | 匹配置信度 | -| `match_evidence` | 匹配证据 | -| `risk_level` | 风险等级 | -| `suggestion` | 处理建议 | -| `evidence_refs` | 法规证据引用 | - -## 8. 页面展示 - -Chat/工作台页面建议展示: - -1. 当前规则包名称和版本。 -2. 当前检查流程类型。 -3. 当前检查章节点范围。 -4. 总体结论。 -5. 缺失项数量。 -6. 错放项数量。 -7. 待人工复核数量。 -8. 高风险缺失项。 -9. 完整性检查明细表。 -10. 法规证据引用。 -11. 审计入口。 - -明细表字段: - -1. 章节点。 -2. 法规要求项。 -3. 当前状态。 -4. 命中文档。 -5. 风险等级。 -6. 处理建议。 -7. 法规依据。 - -## 9. 异常处理 - -1. 未找到批次:返回“当前资料包不存在或已删除”。 -2. 目录汇总未完成:提示先完成资料包导入与目录汇总。 -3. 规则包不存在:任务不可执行,记录失败审计。 -4. 规则包版本不支持当前流程:提示流程配置错误。 -5. 文档章节点大量缺失:可执行,但报告标记低可信。 -6. RAG 检索失败:不阻断规则判断,报告中标记证据检索不可用。 -7. 所选文档为空:返回空范围检查结果,并提示用户选择资料范围。 -8. 文档仍待人工复核:完整性报告保留不确定状态。 - -## 10. 与后续步骤的接口 - -后续风险预警读取: - -1. `pass_status` -2. `highest_risk_level` -3. `missing_items` -4. `misplaced_items` -5. `manual_review_items` -6. `suggestions` -7. `evidence_refs` - -后续字段抽取可读取: - -1. 已命中的申请表、产品列表、说明书等文档 ID。 -2. 待人工复核文档清单。 -3. 当前规则包中声明的模板字段映射。 - -## 11. 测试设计 - -### 11.1 单元测试 - -1. 规则包加载成功。 -2. 不支持流程被拦截。 -3. 章节点编码匹配成功。 -4. 文档角色匹配成功。 -5. 必交项缺失被识别。 -6. 错放文件被识别。 -7. 风险等级映射正确。 -8. RAG 失败不影响规则判断。 - -### 11.2 服务层测试 - -1. 基于第一步目录汇总执行完整性检查。 -2. 缺失 `CH1.4` 时输出高风险。 -3. `CH1.2` 目录类文档能作为命中文档进入报告。 -4. 待复核文档会进入 `manual_review_items`。 -5. 规则包缺失时写入失败审计。 - -### 11.3 页面测试 - -1. 页面展示规则包版本。 -2. 页面展示缺失项和风险等级。 -3. 页面展示法规证据。 -4. 页面展示审计入口。 -5. RAG 不可用时页面仍显示规则判断结果。 - -## 12. V1 实现建议 - -V1 建议先完成以下最小闭环: - -1. 基于本地 YAML 规则包实现 `CH1` 完整性检查。 -2. 检查 `CH1.2`、`CH1.4`、`CH1.5`、`CH1.9`、`CH1.11.1`、`CH1.11.5`、`CH1.11.6`。 -3. 基于第一步的 `chapter_code` 和 `document_role` 做规则匹配。 -4. 输出缺失项、疑似项和待复核项。 -5. RAG 证据检索先使用 fallback 检索,后续接 Chroma。 -6. 完整性报告写入审计。 - -增强阶段再补齐: - -1. 第 2 至第 6 章完整规则。 -2. 资料格式要求层检查。 -3. 安全和性能基本原则清单映射检查。 -4. 后台规则人工校订。 -5. 在线法规更新能力。 +## 7. 验收标准 +1. 能区分缺失、错放和待复核。 +2. 规则结论与法规依据分层清晰。 +3. 可直接用于后续风险预警和飞书通知。 diff --git a/docs/详细设计/3.字段抽取与统一字段池.md b/docs/详细设计/3.字段抽取与统一字段池.md index 87be6ea..d0cadce 100644 --- a/docs/详细设计/3.字段抽取与统一字段池.md +++ b/docs/详细设计/3.字段抽取与统一字段池.md @@ -2,657 +2,57 @@ ## 1. 设计目标 -本步骤承接“资料包导入与目录汇总”和“法规完整性检查”的输出,目标是从说明书、申请表、产品列表、声明类文件等注册申报资料中抽取产品核心字段,形成可复用、可追溯、可回填、可一致性核查的统一字段池。 +本步骤负责从说明书、申请表、产品列表等资料中抽取关键字段,并写入统一字段池,供一致性核查、风险判断和 Word 回填复用。 -本步骤需要完成以下业务结果: - -1. 明确本轮字段抽取的资料范围和目标字段范围。 -2. 加载注册申报通用字段 schema。 -3. 按字段来源优先级选择候选文档。 -4. 对固定格式、标题段落、表格字段执行规则抽取。 -5. 对长文本字段使用 LLM 辅助归纳。 -6. 对字段值进行标准化、去噪和来源绑定。 -7. 将字段结果写入统一字段池。 -8. 标记字段置信度、冲突状态和待人工确认状态。 -9. 输出结构化 `registration_field_extraction_report`。 - -本步骤不负责最终一致性判定,不负责 Word 文件生成。字段池会为后续“一致性核查”和“Word 回填导出”提供输入。 - -## 2. 所属模块与边界 - -### 2.1 Documents - -`apps.documents` 提供文档主数据、正文文本、标题结构、表格结构和处理状态。 - -本步骤读取: - -1. 文档 ID。 -2. 文件名和相对路径。 -3. 章节点。 -4. 文档角色。 -5. 正文文本。 -6. 表格结构。 -7. 文档处理状态。 -8. 是否待人工复核。 - -如果某文档尚未完成文本或表格抽取,本步骤应给出业务提示,而不是默认字段缺失。 - -### 2.2 Agent Core - -`agent_core` 是本步骤的执行主体,负责编排字段 schema 加载、抽取范围确认、规则抽取、表格抽取、LLM 归纳、字段标准化、字段池写入和报告生成。 - -本步骤建议产生以下中文 Skill: - -1. `字段抽取编排Skill` -2. `字段抽取范围确认Skill` -3. `字段Schema加载Skill` -4. `规则字段抽取Skill` -5. `表格字段抽取Skill` -6. `长文本字段归纳Skill` -7. `字段标准化Skill` -8. `统一字段池写入Skill` -9. `字段抽取报告生成Skill` - -### 2.3 LLM Provider - -LLM 只用于长文本归纳和无法通过规则稳定提取的字段。 - -LLM 可以处理: - -1. 适用范围 / 预期用途归纳。 -2. 性能指标摘要。 -3. 储存条件段落归纳。 -4. 检测靶标从说明书长段落中提取。 - -LLM 不应处理: - -1. 明确表格字段的直接读取。 -2. 申请表中固定字段的直接抽取。 -3. 字段冲突最终裁判。 -4. 没有来源证据的字段编造。 - -所有 LLM 调用必须经过 Provider,并支持 Mock Provider 离线测试。 - -### 2.4 RAG - -RAG 在本步骤中只作为来源片段定位能力使用。 - -可用于: - -1. 从长文档中定位字段候选段落。 -2. 为 LLM 归纳提供限定上下文。 -3. 为字段来源证据提供片段引用。 - -RAG 不负责最终字段值裁判。 - -### 2.5 Audit - -`apps.audit` 记录字段抽取任务的执行范围、目标字段、抽取结果、来源证据、LLM 使用情况和失败原因。 - -审计中必须保留: +## 2. 输入 1. `batch_id` -2. `scenario_id` -3. `selected_document_ids` -4. `field_schema_version` -5. `extracted_fields` -6. `manual_review_fields` -7. `llm_provider_name` -8. `tool_calls` -9. `evidence_refs` +2. `conversation_id` +3. `product_name` +4. `document_scope` +5. `field_schema` +6. `source_priority` -## 3. 输入输出 +## 3. 字段池模型 -### 3.1 输入 +字段项至少包含: -```json -{ - "batch_id": 1001, - "scenario_id": "registration_field_extraction", - "field_schema_id": "ivd_registration_fields_v1", - "selected_document_ids": [11, 12, 13], - "target_field_keys": [ - "product_name", - "detection_target", - "intended_use", - "storage_condition", - "performance_index" - ], - "enable_llm_fallback": true, - "enable_rag_context": true -} -``` - -### 3.2 输出 - -本步骤输出 `registration_field_extraction_report`: - -```json -{ - "report_type": "registration_field_extraction_report", - "batch_id": 1001, - "field_schema_id": "ivd_registration_fields_v1", - "field_schema_version": "2026-06-03", - "summary": { - "target_field_count": 5, - "extracted_field_count": 4, - "manual_review_field_count": 1, - "conflict_candidate_count": 1, - "field_pool_status": "partial_completed" - }, - "field_pool_items": [], - "manual_review_fields": [], - "evidence_refs": [], - "tool_calls": [] -} -``` - -### 3.3 字段池条目结构 - -```json -{ - "field_key": "product_name", - "field_label": "产品名称", - "standard_value": "新型冠状病毒 2019-nCoV 核酸检测试剂盒", - "raw_value": "新型冠状病毒2019-nCoV核酸检测试剂盒", - "source_document_id": 11, - "source_document_name": "目标产品说明书.docx", - "source_location": { - "chapter_title": "一、产品名称", - "table_index": null, - "page_no": null - }, - "extract_method": "rule_heading", - "confidence": "high", - "conflict_status": "not_checked", - "manual_review_required": false, - "fillable": true -} -``` - -## 4. 主工作流 - -```text -用户发起字段抽取任务 --> 读取资料包和完整性检查上下文 --> 确认抽取文档范围 --> 加载字段 schema --> 加载字段来源优先级 --> 读取文档文本和表格结构 --> 执行规则字段抽取 --> 执行表格字段抽取 --> 对长文本字段执行 RAG 定位与 LLM 归纳 --> 标准化字段值 --> 绑定字段来源证据 --> 写入统一字段池 --> 生成字段抽取报告 --> 写入审计留痕 --> 返回字段池视图 -``` - -## 5. 节点详细设计 - -### 5.1 节点一:抽取任务上下文加载 - -业务功能: - -1. 读取资料包批次。 -2. 读取第一步目录汇总。 -3. 读取第二步完整性检查报告。 -4. 获取命中的申请表、产品列表、说明书等候选文档。 -5. 确认当前资料是否满足字段抽取前置条件。 - -使用技术: - -1. Django ORM -2. JSONField 报告快照 -3. dataclass/Pydantic schema - -产生方法: - -1. `load_field_extraction_context(batch_id, scenario_id) -> FieldExtractionContext` -2. `load_candidate_documents(context, selected_document_ids) -> list[DocumentFact]` -3. `validate_extraction_prerequisites(context) -> ExtractionPrerequisiteResult` - -对应 Skill: - -1. `字段抽取编排Skill` - -### 5.2 节点二:字段抽取范围确认 - -业务功能: - -1. 确认参与字段抽取的文档范围。 -2. 按文档角色筛选候选资料。 -3. 排除法规资料和待处理失败资料。 -4. 对待人工复核文档保留可用但低可信状态。 - -默认候选来源: - -1. 申请表。 -2. 产品说明书。 -3. 产品列表。 -4. 声明类文件。 -5. 历史沟通说明。 - -使用技术: - -1. 文档角色规则 -2. 来源优先级 YAML -3. 文档状态过滤 - -产生方法: - -1. `resolve_extraction_scope(documents, selected_document_ids, target_field_keys) -> ExtractionScope` -2. `filter_extractable_documents(documents) -> list[DocumentFact]` -3. `rank_documents_by_field_source(field_key, documents) -> list[DocumentFact]` - -对应 Skill: - -1. `字段抽取范围确认Skill` - -### 5.3 节点三:字段 Schema 加载 - -业务功能: - -1. 加载注册申报字段 schema。 -2. 确认目标字段、字段类型、来源优先级、抽取方式和回填属性。 -3. 为后续 Word 回填建立字段映射基础。 - -建议 schema 目录: - -```text -configs/registration/fields/ - ivd_registration_fields_v1.yaml -``` - -字段 schema 示例: - -```yaml -field_schema_id: ivd_registration_fields_v1 -version: "2026-06-03" -fields: - - field_key: product_name - field_label: 产品名称 - value_type: text - fillable: true - consistency_required: true - source_priority: - - application_form - - product_instruction - - product_list - extraction_methods: - - rule_heading - - table_cell -``` - -使用技术: - -1. YAML -2. Pydantic schema -3. Django cache - -产生方法: - -1. `load_field_schema(field_schema_id) -> FieldSchema` -2. `validate_field_schema(schema) -> FieldSchemaValidationResult` -3. `select_target_fields(schema, target_field_keys) -> list[FieldDefinition]` - -对应 Skill: - -1. `字段Schema加载Skill` - -### 5.4 节点四:规则字段抽取 - -业务功能: - -1. 从标题、段落、固定标签中提取字段。 -2. 优先处理产品名称、申请人名称、储存条件等明确字段。 -3. 记录抽取方法和来源片段。 - -适用字段: - -1. 产品名称。 -2. 申请人名称。 -3. 包装规格。 -4. 储存条件。 -5. 申报日期。 - -使用技术: - -1. 正则表达式 -2. 标题层级解析 -3. 标签后取值规则 -4. 中文标点标准化 - -产生方法: - -1. `extract_fields_by_rules(document, field_definitions) -> list[FieldCandidate]` -2. `extract_by_heading(text_structure, field_definition) -> FieldCandidate | None` -3. `extract_by_label(text, labels) -> FieldCandidate | None` -4. `build_source_location(document, match) -> SourceLocation` - -对应 Skill: - -1. `规则字段抽取Skill` - -### 5.5 节点五:表格字段抽取 - -业务功能: - -1. 从申请表、产品列表、标准清单等表格中提取字段。 -2. 识别表头和字段标签。 -3. 抽取规格型号、分类编码、标准清单等结构化字段。 - -适用字段: - -1. 产品名称。 -2. 包装规格。 -3. 分类编码。 -4. 申请人名称。 -5. 生产地址。 -6. 标准清单。 - -使用技术: - -1. `python-docx` 表格解析 -2. PDF 表格解析可选 `pdfplumber` -3. 表头标准化 -4. 单元格坐标记录 - -产生方法: - -1. `extract_fields_from_tables(document, field_definitions) -> list[FieldCandidate]` -2. `normalize_table_headers(table) -> NormalizedTable` -3. `match_table_field(table, field_definition) -> FieldCandidate | None` -4. `build_table_source_location(table_index, row_index, col_index) -> SourceLocation` - -对应 Skill: - -1. `表格字段抽取Skill` - -### 5.6 节点六:长文本字段归纳 - -业务功能: - -1. 对规则和表格无法稳定抽取的长文本字段进行归纳。 -2. 先用 RAG 或关键词定位候选片段。 -3. 将有限上下文交给 LLM Provider。 -4. 要求 LLM 返回结构化字段值和引用片段。 - -适用字段: - -1. 检测靶标。 -2. 适用范围 / 预期用途。 -3. 性能指标。 -4. 临床评价路径。 - -使用技术: - -1. RAG fallback / Chroma -2. LLM Provider -3. JSON schema 输出约束 -4. Mock Provider 测试 - -产生方法: - -1. `locate_field_context(document, field_definition) -> list[EvidenceChunk]` -2. `summarize_long_text_field(field_definition, chunks) -> FieldCandidate` -3. `call_llm_for_field_extraction(prompt, schema) -> dict` -4. `validate_llm_field_output(output) -> FieldCandidate` - -对应 Skill: - -1. `长文本字段归纳Skill` - -### 5.7 节点七:字段标准化 - -业务功能: - -1. 对抽取候选值做清洗和标准化。 -2. 合并空格、全半角、中文标点差异。 -3. 标准化单位、日期、枚举值。 -4. 计算字段置信度。 -5. 标记疑似冲突候选,但不做最终一致性裁判。 - -使用技术: - -1. Python 字符串标准化 -2. 字段类型规则 -3. 日期解析 -4. 单位标准化表 - -产生方法: - -1. `normalize_field_candidate(candidate, field_definition) -> NormalizedFieldCandidate` -2. `normalize_text_value(value) -> str` -3. `normalize_date_value(value) -> str` -4. `calculate_field_confidence(candidate, source_priority) -> str` -5. `detect_conflict_candidates(candidates) -> list[ConflictCandidate]` - -对应 Skill: - -1. `字段标准化Skill` - -### 5.8 节点八:统一字段池写入 - -业务功能: - -1. 将字段候选写入统一字段池。 -2. 按字段来源优先级选择推荐值。 -3. 保留所有候选值和来源证据。 -4. 标记字段是否可回填。 -5. 标记字段是否需要一致性核查。 - -建议模型: - -```python -class RegistrationFieldPoolItem(models.Model): - batch = models.ForeignKey(SubmissionBatch, on_delete=models.CASCADE) - field_key = models.CharField(max_length=128) - field_label = models.CharField(max_length=255) - standard_value = models.TextField(blank=True) - raw_value = models.TextField(blank=True) - source_document_id = models.IntegerField(null=True) - source_location = models.JSONField(default=dict) - extract_method = models.CharField(max_length=64) - confidence = models.CharField(max_length=32) - conflict_status = models.CharField(max_length=32, default="not_checked") - manual_review_required = models.BooleanField(default=False) - fillable = models.BooleanField(default=False) -``` - -使用技术: - -1. Django ORM -2. JSONField -3. 批量写入 -4. 字段池版本号 - -产生方法: - -1. `write_field_pool(batch_id, normalized_candidates, field_schema) -> FieldPoolWriteResult` -2. `select_recommended_field_value(field_key, candidates, source_priority) -> FieldPoolItem` -3. `persist_field_candidates(field_pool_item, candidates) -> None` -4. `mark_manual_review_fields(field_pool_items) -> list[FieldPoolItem]` - -对应 Skill: - -1. `统一字段池写入Skill` - -### 5.9 节点九:字段抽取报告生成 - -业务功能: - -1. 汇总字段抽取结果。 -2. 输出字段池表格。 -3. 输出待人工复核字段。 -4. 输出字段来源证据。 -5. 生成页面展示和飞书摘要载荷。 -6. 写入审计记录。 - -使用技术: - -1. dataclass/Pydantic -2. JSONField -3. Audit 服务 -4. 页面展示 schema - -产生方法: - -1. `build_field_extraction_report(context, field_pool_items) -> RegistrationFieldExtractionReport` -2. `build_field_pool_display_rows(field_pool_items) -> list[dict]` -3. `build_field_extraction_audit_payload(report) -> dict` -4. `record_field_extraction_audit(report, context) -> AuditLog` - -对应 Skill: - -1. `字段抽取报告生成Skill` - -## 6. Skill 清单 - -本步骤产生以下 Skill 设计文档: - -1. [字段抽取编排Skill](skill/字段抽取编排Skill.md) -2. [字段抽取范围确认Skill](skill/字段抽取范围确认Skill.md) -3. [字段Schema加载Skill](skill/字段Schema加载Skill.md) -4. [规则字段抽取Skill](skill/规则字段抽取Skill.md) -5. [表格字段抽取Skill](skill/表格字段抽取Skill.md) -6. [长文本字段归纳Skill](skill/长文本字段归纳Skill.md) -7. [字段标准化Skill](skill/字段标准化Skill.md) -8. [统一字段池写入Skill](skill/统一字段池写入Skill.md) -9. [字段抽取报告生成Skill](skill/字段抽取报告生成Skill.md) - -## 7. 字段 Schema 设计 - -### 7.1 V1 目标字段 - -| 字段编码 | 中文名 | 是否回填 | 是否强一致 | -|---|---|---|---| -| `product_name` | 产品名称 | 是 | 是 | -| `detection_target` | 检测靶标 | 是 | 是 | -| `intended_use` | 适用范围 / 预期用途 | 是 | 是 | -| `storage_condition` | 储存条件 | 是 | 是 | -| `performance_index` | 性能指标 | 是 | 否 | -| `package_specification` | 包装规格 | 是 | 是 | -| `applicant_name` | 申请人名称 | 是 | 是 | -| `classification_code` | 分类编码 | 是 | 是 | - -### 7.2 字段来源优先级 - -| 字段 | 来源优先级 | -|---|---| -| 产品名称 | 申请表 > 说明书 > 产品列表 | -| 检测靶标 | 说明书 > 产品列表 > 申请表 | -| 适用范围 | 说明书 > 申请表 | -| 储存条件 | 说明书 > 标签样稿 | -| 性能指标 | 说明书 > 性能研究资料 | -| 包装规格 | 产品列表 > 申请表 > 说明书 | - -## 8. 页面展示 - -字段抽取结果页面建议展示: - -1. 当前字段 schema 版本。 -2. 抽取文档范围。 -3. 字段总数。 -4. 已抽取字段数。 -5. 待人工复核字段数。 -6. 字段池表格。 -7. 字段来源证据。 -8. 工具调用记录。 -9. 审计入口。 - -字段池表格字段: - -1. 字段名。 -2. 推荐值。 -3. 原始值。 -4. 来源文档。 -5. 来源位置。 -6. 抽取方法。 -7. 置信度。 -8. 是否待人工复核。 -9. 是否可回填。 - -## 9. 异常处理 - -1. 无可抽取文档:返回业务提示,不写空字段池。 -2. 文档未完成文本抽取:标记前置条件不足。 -3. 字段 schema 缺失:任务不可执行,写失败审计。 -4. 表格解析失败:跳过表格抽取,保留规则抽取和 LLM 归纳。 -5. LLM 不可用:仅输出规则和表格抽取结果。 -6. LLM 输出非法 JSON:丢弃该候选并记录工具失败。 -7. 多候选值不一致:写入候选值,字段状态标记 `conflict_candidate`。 -8. 来源文档待复核:字段置信度不超过 `medium`。 - -## 10. 与后续步骤的接口 - -后续一致性核查读取: - -1. `field_key` -2. `standard_value` -3. `raw_value` +1. `field_code` +2. `field_name` +3. `field_value` 4. `source_document_id` 5. `source_location` 6. `confidence` -7. `conflict_status` -8. `manual_review_required` +7. `review_status` +8. `fillable` -后续 Word 回填读取: +## 4. 抽取策略 -1. `field_key` -2. `standard_value` -3. `fillable` -4. `manual_review_required` -5. `conflict_status` -6. `template_field_refs` +1. 规则抽取显式字段 +2. 表格抽取规格与结构化字段 +3. LLM 归纳长文本字段 +4. 来源优先级合并同名字段 -## 11. 测试设计 +## 5. 输出对象 -### 11.1 单元测试 +`registration_field_extraction_report` 至少包含: -1. 字段 schema 加载成功。 -2. 字段来源优先级排序正确。 -3. 标题字段抽取正确。 -4. 表格字段抽取正确。 -5. LLM 输出 schema 校验正确。 -6. 字段标准化正确。 -7. 推荐值选择正确。 +1. `field_items` +2. `source_documents` +3. `low_confidence_items` +4. `fillable_items` -### 11.2 服务层测试 +## 6. 对话节点要求 -1. 基于说明书抽取产品名称。 -2. 基于说明书抽取检测靶标。 -3. 基于申请表抽取申请人名称。 -4. 多来源候选写入字段池。 -5. LLM 不可用时任务仍能完成部分结果。 -6. 字段池报告写入审计。 +字段抽取节点应展示: -### 11.3 页面测试 +1. 已抽取字段数 +2. 待复核字段数 +3. 关键字段来源 +4. 是否可回填 -1. 页面展示字段池表格。 -2. 页面展示字段来源文档。 -3. 页面展示待人工复核字段。 -4. 页面展示工具调用记录。 -5. 页面展示审计入口。 - -## 12. V1 实现建议 - -V1 建议先完成以下最小闭环: - -1. 建立字段 schema YAML。 -2. 从 `目标产品说明书.docx` 抽取产品名称、检测靶标、适用范围、储存条件、性能指标。 -3. 从 `CH1.4 申请表.docx` 和 `CH1.5 产品列表.docx` 抽取可比对字段。 -4. 写入统一字段池。 -5. 输出字段抽取报告。 -6. 支持 Mock Provider 离线测试。 - -增强阶段再补齐: - -1. 更多字段类型。 -2. PDF 表格抽取。 -3. OCR 兜底。 -4. 后台人工修正字段池。 -5. 字段池版本管理。 +## 7. 验收标准 +1. 统一字段池可支撑后续一致性核查和回填。 +2. 低置信度字段有明确待复核标记。 +3. 对话中可解释字段来源和采用逻辑。 diff --git a/docs/详细设计/4.一致性核查.md b/docs/详细设计/4.一致性核查.md index c1fc761..89c86bc 100644 --- a/docs/详细设计/4.一致性核查.md +++ b/docs/详细设计/4.一致性核查.md @@ -2,527 +2,55 @@ ## 1. 设计目标 -本步骤承接“字段抽取与统一字段池”的输出,目标是核查同一审核范围内不同文档之间的关键字段是否完全一致,并识别跨产品资料混入、字段冲突、来源不确定和需要人工复核的问题。 +本步骤负责基于统一字段池和资料包上下文,识别跨文档字段冲突、混档风险和待人工确认项。 -本步骤需要完成以下业务结果: - -1. 明确本次一致性核查的审核范围,避免把不同产品样例直接合并审核。 -2. 加载强一致字段规则,V1 默认按完全一致处理。 -3. 从统一字段池读取字段候选值和来源证据。 -4. 按字段和来源文档分组。 -5. 对强一致字段执行完全一致比对。 -6. 识别字段冲突、疑似混档、待人工复核和一致通过项。 -7. 生成冲突明细、风险建议和证据链。 -8. 输出结构化 `registration_consistency_report`。 - -本步骤不负责重新抽取字段,不负责综合风险汇总,不负责自动修正字段池。它只对字段池中已有的字段事实进行一致性判断。 - -## 2. 所属模块与边界 - -### 2.1 Documents - -`apps.documents` 提供文档主数据,用于确认字段来源文档是否属于同一批次、同一审核范围和相同业务资料角色。 - -本步骤读取: - -1. 文档 ID。 -2. 文档名称。 -3. 章节点。 -4. 文档角色。 -5. 批次 ID。 -6. 处理状态。 -7. 是否待人工复核。 - -### 2.2 Agent Core - -`agent_core` 是本步骤的执行主体,负责编排审核范围确认、强一致规则加载、字段池读取、字段分组、完全一致比对、混档识别、报告生成和审计留痕。 - -本步骤建议产生以下中文 Skill: - -1. `一致性核查编排Skill` -2. `审核范围确认Skill` -3. `强一致规则加载Skill` -4. `字段分组Skill` -5. `字段完全一致比对Skill` -6. `混档风险识别Skill` -7. `一致性报告生成Skill` - -### 2.3 LLM Provider - -本步骤默认不使用 LLM 作为判断引擎。 - -LLM 只可用于: - -1. 将规则结论组织成自然语言说明。 -2. 生成处理建议文案。 -3. 对复杂冲突进行解释性摘要。 - -LLM 不可用于: - -1. 将不一致字段判为一致。 -2. 覆盖强一致规则结论。 -3. 无证据地解释跨产品资料混入。 - -### 2.4 Audit - -`apps.audit` 记录一致性核查的审核范围、字段规则、冲突字段、来源文档、处理建议和最终状态。 - -审计中必须保留: +## 2. 输入 1. `batch_id` -2. `selected_document_ids` -3. `scope_confirmation` -4. `field_rule_version` -5. `consistent_fields` -6. `conflict_fields` -7. `mixed_package_warnings` -8. `manual_review_fields` -9. `evidence_refs` +2. `conversation_id` +3. `product_name` +4. `field_pool` +5. `strong_consistency_rules` -## 3. 输入输出 +## 3. 核查维度 -### 3.1 输入 +1. 产品名称 +2. 检测靶标 +3. 适用范围 +4. 储存条件 +5. 规格/型号 -```json -{ - "batch_id": 1001, - "scenario_id": "registration_consistency_review", - "selected_document_ids": [11, 12, 13], - "field_rule_id": "ivd_strict_consistency_v1", - "target_field_keys": [ - "product_name", - "applicant_name", - "package_specification", - "classification_code" - ], - "strict_mode": true -} -``` - -### 3.2 输出 - -本步骤输出 `registration_consistency_report`: - -```json -{ - "report_type": "registration_consistency_report", - "batch_id": 1001, - "field_rule_id": "ivd_strict_consistency_v1", - "summary": { - "checked_field_count": 4, - "consistent_field_count": 2, - "conflict_field_count": 1, - "manual_review_field_count": 1, - "mixed_package_warning_count": 1, - "highest_risk_level": "high", - "pass_status": "failed" - }, - "consistent_fields": [], - "conflict_fields": [], - "manual_review_fields": [], - "mixed_package_warnings": [], - "suggestions": [] -} -``` - -### 3.3 一致性状态 - -| 状态 | 含义 | -|---|---| -| `consistent` | 同一字段在审核范围内完全一致 | -| `conflict` | 同一字段出现不同标准值或原始值 | -| `single_source` | 只有一个来源,无法跨文档比对 | -| `manual_review_required` | 来源文档或字段值不确定 | -| `not_checked` | 字段不在本次核查范围 | -| `mixed_package_suspected` | 疑似跨产品资料混入 | - -## 4. 主工作流 +## 4. 主流程 ```text -用户发起一致性核查 --> 读取统一字段池 --> 确认审核范围 --> 加载强一致字段规则 --> 筛选目标字段 --> 按字段分组候选值 --> 按完全一致规则比对 --> 识别字段冲突 --> 识别疑似混档风险 --> 生成处理建议 --> 写入字段池冲突状态 --> 生成一致性报告 --> 写入审计留痕 --> 返回 Web/飞书可展示结果 +加载字段池 +-> 读取强一致规则 +-> 对比多来源字段值 +-> 识别冲突字段 +-> 判断是否存在混档风险 +-> 输出一致性节点结果 ``` -## 5. 节点详细设计 +## 5. 输出对象 -### 5.1 节点一:读取统一字段池 +`registration_consistency_report` 至少包含: -业务功能: +1. `conflict_items` +2. `consistent_items` +3. `mixed_package_risk` +4. `recommended_value` -1. 根据 `batch_id` 读取字段池。 -2. 过滤本次目标字段。 -3. 读取每个字段的所有候选值和推荐值。 -4. 加载字段来源文档信息。 +## 6. 对话节点要求 -使用技术: +一致性节点应展示: -1. Django ORM -2. JSONField -3. dataclass/Pydantic schema +1. 冲突字段 +2. 来源对比 +3. 是否疑似混档 +4. 建议采用值 -产生方法: - -1. `load_field_pool(batch_id) -> list[FieldPoolItem]` -2. `load_field_candidates(batch_id, field_keys) -> list[FieldCandidateRecord]` -3. `attach_source_documents(candidates) -> list[FieldCandidateWithDocument]` - -对应 Skill: - -1. `一致性核查编排Skill` - -### 5.2 节点二:审核范围确认 - -业务功能: - -1. 确认哪些文档属于同一项目、批次和本次审核范围。 -2. 如果用户选择了文档范围,只对选中范围执行。 -3. 如果未选择范围,默认使用当前批次业务资料。 -4. 对疑似不同产品、不同来源、不同流程资料给出范围警告。 - -范围确认规则: - -1. 同一 `batch_id` 是最低要求。 -2. `source_role` 必须为 `submission`。 -3. 法规资料不进入一致性核查。 -4. 待人工复核文档可以进入,但相关字段不直接判通过。 -5. 疑似跨产品文档进入混档风险提示。 - -使用技术: - -1. 文档主数据 -2. 资料包批次 -3. 文档角色规则 -4. 用户选中文档范围 - -产生方法: - -1. `resolve_review_scope(batch_id, selected_document_ids) -> ReviewScope` -2. `validate_scope_documents(documents) -> ScopeValidationResult` -3. `detect_scope_uncertainties(documents) -> list[ScopeWarning]` - -对应 Skill: - -1. `审核范围确认Skill` - -### 5.3 节点三:强一致规则加载 - -业务功能: - -1. 加载强一致字段规则。 -2. 确认字段是否要求完全一致。 -3. 定义冲突严重度。 -4. 定义字段缺少多个来源时的处理方式。 - -规则示例: - -```yaml -field_rule_id: ivd_strict_consistency_v1 -version: "2026-06-03" -strict_mode: true -fields: - - field_key: product_name - field_label: 产品名称 - consistency_required: true - compare_mode: exact - risk_level_if_conflict: high - - field_key: performance_index - consistency_required: false - compare_mode: not_checked -``` - -使用技术: - -1. YAML -2. Pydantic schema -3. Django cache - -产生方法: - -1. `load_consistency_rules(field_rule_id) -> ConsistencyRuleSet` -2. `validate_consistency_rules(rule_set) -> RuleValidationResult` -3. `select_consistency_fields(rule_set, target_field_keys) -> list[ConsistencyFieldRule]` - -对应 Skill: - -1. `强一致规则加载Skill` - -### 5.4 节点四:字段分组 - -业务功能: - -1. 按 `field_key` 分组字段候选。 -2. 按来源文档分组同一字段。 -3. 保留标准值、原始值、来源位置、置信度。 -4. 标记单来源字段和多来源字段。 - -使用技术: - -1. Python 分组 -2. 字段池候选表 -3. 文档元数据 - -产生方法: - -1. `group_candidates_by_field(candidates) -> dict[str, list[FieldCandidateWithDocument]]` -2. `group_candidates_by_document(candidates) -> dict[int, list[FieldCandidateWithDocument]]` -3. `build_field_compare_units(grouped_candidates) -> list[FieldCompareUnit]` - -对应 Skill: - -1. `字段分组Skill` - -### 5.5 节点五:字段完全一致比对 - -业务功能: - -1. 对强一致字段执行完全一致比对。 -2. 对标准化值不同的字段判定冲突。 -3. 对标准化值相同但原始值差异较大的字段标记待复核。 -4. 对单来源字段标记无法跨文档比对。 - -比对规则: - -1. `compare_mode = exact` 时,标准值必须完全一致。 -2. 不采用语义相近判定。 -3. 空值不参与通过判定。 -4. 待人工复核来源不作为通过证据。 - -使用技术: - -1. Python 严格字符串比较 -2. 字段标准化结果 -3. 风险映射规则 - -产生方法: - -1. `compare_exact(field_compare_unit, rule) -> FieldCompareResult` -2. `detect_value_conflict(values) -> bool` -3. `detect_raw_value_variation(values) -> bool` -4. `build_conflict_detail(result) -> ConflictDetail` - -对应 Skill: - -1. `字段完全一致比对Skill` - -### 5.6 节点六:混档风险识别 - -业务功能: - -1. 基于产品名称、检测靶标、申请人等核心字段识别疑似跨产品资料混入。 -2. 当同一审核范围内出现明显不同产品名称时,输出混档风险。 -3. 区分“字段冲突”和“疑似资料包范围错误”。 - -典型规则: - -1. 产品名称出现两个不同值:高风险混档。 -2. 检测靶标与产品名称指向明显不同产品:高风险混档。 -3. 申请人不同:高风险或待复核。 -4. 同一文档角色出现多个版本:中风险或待复核。 - -使用技术: - -1. 字段比对结果 -2. 文档角色分析 -3. 批次范围校验 -4. 规则映射 YAML - -产生方法: - -1. `detect_mixed_package_risk(compare_results, scope) -> list[MixedPackageWarning]` -2. `detect_product_identity_conflict(field_results) -> MixedPackageWarning | None` -3. `classify_mixed_package_risk(warning) -> str` - -对应 Skill: - -1. `混档风险识别Skill` - -### 5.7 节点七:字段池冲突状态回写 - -业务功能: - -1. 将一致性核查结果回写到字段池。 -2. 对冲突字段标记 `conflict`。 -3. 对待复核字段标记 `manual_review_required`。 -4. 对一致字段标记 `consistent`。 - -使用技术: - -1. Django ORM -2. 批量更新 -3. 字段池版本记录 - -产生方法: - -1. `update_field_pool_consistency_status(compare_results) -> FieldPoolUpdateResult` -2. `mark_conflict_field(field_key, conflict_detail) -> None` -3. `mark_consistent_field(field_key) -> None` - -对应 Skill: - -1. `一致性核查编排Skill` - -### 5.8 节点八:一致性报告生成 - -业务功能: - -1. 汇总一致字段、冲突字段、待复核字段和混档风险。 -2. 生成结构化报告。 -3. 生成页面展示区块。 -4. 生成飞书摘要载荷。 -5. 写入审计记录。 - -使用技术: - -1. dataclass/Pydantic -2. JSONField -3. Audit 服务 -4. 页面展示 schema - -产生方法: - -1. `build_consistency_report(context, compare_results, mixed_warnings) -> RegistrationConsistencyReport` -2. `build_consistency_summary(compare_results, mixed_warnings) -> dict` -3. `build_consistency_display_sections(report) -> list[dict]` -4. `record_consistency_audit(report, context) -> AuditLog` - -对应 Skill: - -1. `一致性报告生成Skill` - -## 6. Skill 清单 - -本步骤产生以下 Skill 设计文档: - -1. [一致性核查编排Skill](skill/一致性核查编排Skill.md) -2. [审核范围确认Skill](skill/审核范围确认Skill.md) -3. [强一致规则加载Skill](skill/强一致规则加载Skill.md) -4. [字段分组Skill](skill/字段分组Skill.md) -5. [字段完全一致比对Skill](skill/字段完全一致比对Skill.md) -6. [混档风险识别Skill](skill/混档风险识别Skill.md) -7. [一致性报告生成Skill](skill/一致性报告生成Skill.md) - -## 7. 强一致字段设计 - -V1 建议强一致字段: - -| 字段编码 | 中文名 | 风险等级 | -|---|---|---| -| `product_name` | 产品名称 | 高 | -| `applicant_name` | 申请人名称 | 高 | -| `package_specification` | 包装规格 | 中 | -| `classification_code` | 分类编码 | 高 | -| `detection_target` | 检测靶标 | 高 | -| `intended_use` | 适用范围 / 预期用途 | 中 | - -## 8. 页面展示 - -一致性核查页面建议展示: - -1. 当前审核范围。 -2. 参与核查文档。 -3. 强一致字段规则版本。 -4. 一致字段数量。 -5. 冲突字段数量。 -6. 待人工复核字段数量。 -7. 混档风险提示。 -8. 字段冲突明细表。 -9. 来源证据。 -10. 审计入口。 - -冲突明细表字段: - -1. 字段名称。 -2. 冲突值。 -3. 来源文档。 -4. 来源位置。 -5. 风险等级。 -6. 建议动作。 - -## 9. 异常处理 - -1. 字段池不存在:提示先执行字段抽取。 -2. 未选择文档且批次为空:返回业务错误。 -3. 审核范围内只有单个文档:输出单来源提示,不判冲突。 -4. 强一致规则缺失:任务不可执行,写失败审计。 -5. 字段全部为空:标记待人工复核。 -6. 来源文档待复核:字段不直接判通过。 -7. 混档风险存在:本步骤 `pass_status` 直接失败。 - -## 10. 与后续步骤的接口 - -后续风险预警读取: - -1. `pass_status` -2. `highest_risk_level` -3. `conflict_fields` -4. `mixed_package_warnings` -5. `manual_review_fields` -6. `suggestions` - -后续 Word 回填读取: - -1. 字段池中的 `conflict_status`。 -2. 冲突字段清单。 -3. 待人工复核字段清单。 -4. 可安全回填字段清单。 - -## 11. 测试设计 - -### 11.1 单元测试 - -1. 审核范围确认正确。 -2. 强一致规则加载成功。 -3. 字段按 `field_key` 分组正确。 -4. 完全一致比对正确。 -5. 字段冲突识别正确。 -6. 单来源字段不判冲突。 -7. 混档风险识别正确。 - -### 11.2 服务层测试 - -1. 产品名称不同输出高风险冲突。 -2. 产品名称相同输出一致。 -3. 申请人不同输出冲突。 -4. 待复核字段进入人工复核清单。 -5. 冲突状态回写字段池。 -6. 一致性报告写入审计。 - -### 11.3 页面测试 - -1. 页面展示审核范围。 -2. 页面展示冲突字段来源。 -3. 页面展示混档风险。 -4. 页面展示待人工复核状态。 -5. 页面展示审计入口。 - -## 12. V1 实现建议 - -V1 建议先完成以下最小闭环: - -1. 从统一字段池读取产品名称、申请人名称、包装规格、分类编码。 -2. 按完全一致规则比对。 -3. 识别样例中可能出现的产品名称冲突。 -4. 输出冲突明细和混档风险。 -5. 回写字段池 `conflict_status`。 -6. 生成一致性核查报告并写审计。 - -增强阶段再补齐: - -1. 更多强一致字段。 -2. 版本重复识别。 -3. 文档结构一致性检查。 -4. 人工确认后重新判定。 -5. 冲突字段修正建议。 +## 7. 验收标准 +1. 能对产品名称等强一致字段给出明确冲突结论。 +2. 能说明冲突来自哪些文档。 +3. 能把冲突结果直接传递给风险预警和飞书通知。 diff --git a/docs/详细设计/5.风险预警.md b/docs/详细设计/5.风险预警.md index 2033f77..8e46e34 100644 --- a/docs/详细设计/5.风险预警.md +++ b/docs/详细设计/5.风险预警.md @@ -2,476 +2,58 @@ ## 1. 设计目标 -本步骤承接法规完整性检查、字段抽取与一致性核查结果,目标是把缺失项、错放项、字段冲突、混档风险、待人工复核项和交付风险统一汇总成可执行的合规风险清单,并给出是否通过、整改优先级和责任建议。 +本步骤汇总完整性检查、字段抽取和一致性核查结果,形成统一风险报告,并决定是否允许正式导出。 -本步骤需要完成以下业务结果: +## 2. 输入 -1. 汇总前序任务报告。 -2. 加载风险分级和准入规则。 -3. 将完整性、字段抽取、一致性等结果映射为风险项。 -4. 合并重复风险和关联风险。 -5. 计算最高风险等级和是否通过。 -6. 生成整改建议、处理优先级和责任角色。 -7. 输出结构化 `registration_risk_report`。 -8. 为飞书通知步骤生成风险摘要载荷。 +1. `registration_completeness_report` +2. `registration_field_extraction_report` +3. `registration_consistency_report` +4. `risk_rule_set` -本步骤不重新执行完整性检查、字段抽取或一致性核查。它只消费前序结构化报告,并在规则基础上生成综合风险预警。 +## 3. 风险类型 -## 2. 所属模块与边界 +1. 缺失必交资料 +2. 资料错放 +3. 字段低置信度 +4. 字段冲突 +5. 混档风险 +6. 导出阻断风险 -### 2.1 Agent Core +## 4. 输出对象 -`agent_core` 是本步骤的执行主体,负责编排报告加载、风险规则加载、风险项生成、风险归并、准入判定、整改建议生成和报告输出。 +`registration_risk_report` 至少包含: -本步骤建议产生以下中文 Skill: - -1. `风险预警编排Skill` -2. `前序报告汇总Skill` -3. `风险规则加载Skill` -4. `风险项生成Skill` -5. `风险归并Skill` -6. `准入判定Skill` -7. `整改建议生成Skill` -8. `风险报告生成Skill` - -### 2.2 LLM Provider - -LLM 可以用于将规则风险结论整理为自然语言建议,但不能改变风险等级、是否通过和整改优先级。 - -LLM 可以处理: - -1. 风险摘要润色。 -2. 整改建议文案组织。 -3. 飞书通知摘要表达。 - -LLM 不可处理: - -1. 修改规则判定的风险等级。 -2. 将高风险降级。 -3. 将不通过改为通过。 - -### 2.3 Audit - -`apps.audit` 记录风险预警的输入报告、风险规则版本、风险项、准入结论和建议动作。 - -审计中必须保留: - -1. `batch_id` -2. `source_report_ids` -3. `risk_rule_version` -4. `risk_items` -5. `pass_status` -6. `highest_risk_level` -7. `manual_review_items` -8. `owner_roles` -9. `suggestions` - -## 3. 输入输出 - -### 3.1 输入 - -```json -{ - "batch_id": 1001, - "scenario_id": "registration_risk_report", - "risk_rule_id": "ivd_registration_risk_v1", - "include_reports": [ - "registration_completeness_report", - "registration_field_extraction_report", - "registration_consistency_report" - ], - "enable_llm_summary": true -} -``` - -### 3.2 输出 - -本步骤输出 `registration_risk_report`: - -```json -{ - "report_type": "registration_risk_report", - "batch_id": 1001, - "risk_rule_id": "ivd_registration_risk_v1", - "summary": { - "risk_item_count": 6, - "high_risk_count": 2, - "medium_risk_count": 2, - "low_risk_count": 1, - "manual_review_count": 1, - "highest_risk_level": "high", - "pass_status": "failed" - }, - "risk_items": [], - "manual_review_items": [], - "suggestions": [], - "owner_notifications": [] -} -``` - -## 4. 主工作流 - -```text -用户发起风险预警 --> 读取前序任务报告 --> 加载风险规则 --> 从完整性报告生成缺失/错放风险 --> 从字段抽取报告生成抽取不确定风险 --> 从一致性报告生成冲突/混档风险 --> 合并重复和关联风险 --> 计算风险等级和准入状态 --> 生成整改建议和责任角色 --> 生成综合风险报告 --> 写入审计留痕 --> 返回 Web/飞书可展示结果 -``` - -## 5. 节点详细设计 - -### 5.1 节点一:前序报告汇总 - -业务功能: - -1. 读取当前批次的完整性检查报告。 -2. 读取字段抽取报告。 -3. 读取一致性核查报告。 -4. 判断哪些报告缺失或过期。 -5. 将报告统一转为风险输入上下文。 - -使用技术: - -1. Django ORM -2. JSONField -3. 报告版本号 -4. dataclass/Pydantic - -产生方法: - -1. `load_source_reports(batch_id, include_reports) -> SourceReportBundle` -2. `validate_source_reports(bundle) -> SourceReportValidationResult` -3. `build_risk_context(bundle) -> RiskEvaluationContext` - -对应 Skill: - -1. `前序报告汇总Skill` - -### 5.2 节点二:风险规则加载 - -业务功能: - -1. 加载风险分级规则。 -2. 加载准入规则。 -3. 加载风险类型和责任角色映射。 -4. 加载整改建议模板。 - -建议规则目录: - -```text -configs/registration/risk/ - ivd_registration_risk_v1.yaml -``` - -规则示例: - -```yaml -risk_rule_id: ivd_registration_risk_v1 -version: "2026-06-03" -admission: - high_risk_policy: fail - multiple_medium_policy: review_required -risk_types: - missing_required_document: - default_level: high - owner_role: 注册申报负责人 - field_conflict: - default_level: high - owner_role: 注册资料负责人 -``` - -使用技术: - -1. YAML -2. Pydantic schema -3. Django cache - -产生方法: - -1. `load_risk_rules(risk_rule_id) -> RiskRuleSet` -2. `validate_risk_rules(rule_set) -> RiskRuleValidationResult` -3. `load_owner_role_mapping(rule_set) -> dict` - -对应 Skill: - -1. `风险规则加载Skill` - -### 5.3 节点三:风险项生成 - -业务功能: - -1. 从完整性报告生成缺失、错放、待复核风险。 -2. 从字段抽取报告生成字段缺失、低可信、抽取失败风险。 -3. 从一致性报告生成字段冲突、混档风险。 -4. 记录风险来源报告和证据。 - -风险类型: - -1. `missing_required_document` -2. `misplaced_document` -3. `field_missing` -4. `field_low_confidence` -5. `field_conflict` -6. `mixed_package` -7. `manual_review_required` -8. `delivery_blocker` - -使用技术: - -1. Python 规则映射 -2. 风险规则 YAML -3. 前序报告 schema - -产生方法: - -1. `build_risks_from_completeness(report, rules) -> list[RiskItem]` -2. `build_risks_from_field_extraction(report, rules) -> list[RiskItem]` -3. `build_risks_from_consistency(report, rules) -> list[RiskItem]` -4. `attach_risk_evidence(risk_item, source_report) -> RiskItem` - -对应 Skill: - -1. `风险项生成Skill` - -### 5.4 节点四:风险归并 - -业务功能: - -1. 合并重复风险。 -2. 关联同一根因风险。 -3. 避免同一字段冲突重复出现在多个列表。 -4. 保留风险来源链路。 - -归并示例: - -1. 产品名称冲突和混档风险可以关联。 -2. 缺失申请表和字段缺失申请人名称可以关联。 -3. 文档待复核导致的字段低可信可以关联。 - -使用技术: - -1. 风险指纹 -2. `risk_type + field_key + document_id` -3. Python 分组 - -产生方法: - -1. `build_risk_fingerprint(risk_item) -> str` -2. `merge_duplicate_risks(risk_items) -> list[RiskItem]` -3. `link_related_risks(risk_items) -> list[RiskGroup]` - -对应 Skill: - -1. `风险归并Skill` - -### 5.5 节点五:准入判定 - -业务功能: - -1. 计算最高风险等级。 -2. 根据规则判断是否通过。 -3. 区分风险等级和人工复核状态。 -4. 输出最终准入结论。 - -准入规则: - -1. 任一高风险项:`pass_status = failed` -2. 无高风险但多个中风险:`pass_status = review_required` -3. 仅低风险:`pass_status = conditional_pass` -4. 无风险但有人工复核项:`pass_status = review_required` -5. 无风险无复核:`pass_status = passed` - -使用技术: - -1. 风险规则 -2. Python 枚举 -3. 评分配置 - -产生方法: - -1. `calculate_highest_risk_level(risk_items) -> str` -2. `calculate_pass_status(risk_items, manual_review_items, rules) -> str` -3. `build_admission_detail(risk_items, status) -> AdmissionDecision` - -对应 Skill: - -1. `准入判定Skill` - -### 5.6 节点六:整改建议生成 - -业务功能: - -1. 为每个风险项生成建议动作。 -2. 按高、中、低风险排序。 -3. 映射责任角色。 -4. 生成可用于飞书通知的摘要。 - -使用技术: - -1. 本地建议模板 -2. 责任角色映射 -3. 可选 LLM Provider 生成自然语言摘要 - -产生方法: - -1. `build_risk_suggestion(risk_item, rules) -> Suggestion` -2. `sort_suggestions_by_priority(suggestions) -> list[Suggestion]` -3. `build_owner_notification_payload(risk_items) -> list[OwnerNotificationPayload]` -4. `summarize_risk_report_with_llm(report) -> str` - -对应 Skill: - -1. `整改建议生成Skill` - -### 5.7 节点七:风险报告生成 - -业务功能: - -1. 汇总风险项和建议。 -2. 生成结构化风险报告。 -3. 生成页面展示区块。 -4. 生成飞书通知载荷。 -5. 写入审计。 - -使用技术: - -1. dataclass/Pydantic -2. JSONField -3. Audit 服务 -4. 飞书摘要 payload schema - -产生方法: - -1. `build_risk_report(context, risk_items, admission, suggestions) -> RegistrationRiskReport` -2. `build_risk_summary(risk_items, admission) -> dict` -3. `build_risk_display_sections(report) -> list[dict]` -4. `record_risk_audit(report, context) -> AuditLog` - -对应 Skill: - -1. `风险报告生成Skill` - -## 6. Skill 清单 - -本步骤产生以下 Skill 设计文档: - -1. [风险预警编排Skill](skill/风险预警编排Skill.md) -2. [前序报告汇总Skill](skill/前序报告汇总Skill.md) -3. [风险规则加载Skill](skill/风险规则加载Skill.md) -4. [风险项生成Skill](skill/风险项生成Skill.md) -5. [风险归并Skill](skill/风险归并Skill.md) -6. [准入判定Skill](skill/准入判定Skill.md) -7. [整改建议生成Skill](skill/整改建议生成Skill.md) -8. [风险报告生成Skill](skill/风险报告生成Skill.md) - -## 7. 风险项结构 - -```json -{ - "risk_id": "RISK-001", - "risk_type": "field_conflict", - "risk_level": "high", - "source_report_type": "registration_consistency_report", - "related_documents": [11, 12], - "related_field_key": "product_name", - "description": "说明书与申请表中的产品名称不一致。", - "suggestion": "请先确认当前审核范围是否混入其他产品资料。", - "owner_role": "注册资料负责人", - "manual_review_required": false -} -``` - -## 8. 页面展示 - -风险预警页面建议展示: - -1. 综合结论。 -2. 是否通过。 -3. 最高风险等级。 -4. 高/中/低风险数量。 -5. 待人工复核数量。 -6. 风险清单。 -7. 整改建议。 -8. 责任角色。 -9. 审计入口。 - -## 9. 异常处理 - -1. 前序报告缺失:生成“报告不完整”风险或提示先执行对应任务。 -2. 风险规则缺失:任务不可执行,写失败审计。 -3. LLM 不可用:使用本地模板生成建议。 -4. 责任角色未配置:使用默认责任角色并提示维护映射。 -5. 风险项为空:输出通过或待复核状态。 - -## 10. 与后续步骤的接口 - -后续 Word 回填读取: - -1. `pass_status` -2. `high_risk_count` -3. `field_conflict` 风险项。 +1. `risk_items` +2. `highest_risk_level` +3. `pass_status` 4. `manual_review_items` -5. 可回填风险拦截状态。 +5. `owner_roles` +6. `suggestions` -后续飞书通知读取: +## 5. 责任角色输出 -1. 风险摘要。 -2. 高风险清单。 -3. 责任角色。 -4. 责任人通知载荷。 -5. Web 详情页链接。 +风险结果必须产出责任角色,为飞书协同做准备。责任角色实体至少包含: -## 11. 测试设计 +1. `owner_role` +2. `owner_name` +3. `department` +4. `feishu_user_id` +5. `feishu_open_id` +6. `feishu_name` +7. `notify_enabled` -### 11.1 单元测试 +## 6. 对话节点要求 -1. 风险规则加载成功。 -2. 完整性缺失项生成风险。 -3. 字段冲突生成高风险。 -4. 混档风险生成高风险。 -5. 风险归并正确。 -6. 任一高风险判不通过。 +风险节点应展示: -### 11.2 服务层测试 +1. 总风险等级 +2. 是否通过 +3. 整改建议 +4. 对应责任角色 -1. 缺少完整性报告时提示前序任务缺失。 -2. 有高风险时 `pass_status = failed`。 -3. 只有低风险时 `conditional_pass`。 -4. 待复核项进入人工复核清单。 -5. 风险报告写入审计。 - -### 11.3 页面测试 - -1. 页面展示最高风险等级。 -2. 页面展示风险清单。 -3. 页面展示整改建议。 -4. 页面展示责任角色。 -5. 页面展示审计入口。 - -## 12. V1 实现建议 - -V1 建议先完成以下最小闭环: - -1. 汇总完整性检查和一致性核查报告。 -2. 生成缺失风险、字段冲突风险、混档风险。 -3. 实现任一高风险即不通过。 -4. 生成整改建议和责任角色。 -5. 输出 `registration_risk_report`。 -6. 写入审计。 - -增强阶段再补齐: - -1. 多维度风险评分。 -2. 历史申报事项风险。 -3. 版本一致性风险。 -4. 飞书责任人通知联动。 -5. 后台风险规则维护。 +## 7. 验收标准 +1. 风险结论可直接决定是否允许正式导出。 +2. 输出中包含责任角色和通知所需字段。 +3. 能向飞书通知步骤直接提供摘要与责任人。 diff --git a/docs/详细设计/6.Word回填导出.md b/docs/详细设计/6.Word回填导出.md index 7ab4c8e..fcdcf39 100644 --- a/docs/详细设计/6.Word回填导出.md +++ b/docs/详细设计/6.Word回填导出.md @@ -2,455 +2,40 @@ ## 1. 设计目标 -本步骤承接字段抽取、统一字段池、一致性核查和风险预警结果,目标是将可回填字段按模板映射写入注册申报表格或对照清单,并生成新的 Word 文件供用户下载、复核和归档。 +本步骤负责把统一字段池中的可回填字段写入注册申报表格或对照清单,并在风险允许时生成导出文件。 -本步骤需要完成以下业务结果: +## 2. 输入 -1. 选择适用的 Word 模板。 -2. 加载模板字段映射。 -3. 从统一字段池读取可回填字段。 -4. 根据风险报告和冲突状态执行回填拦截。 -5. 生成回填数据集。 -6. 按模板写入 Word 文档。 -7. 校验输出文档版式、字段落位和导出状态。 -8. 生成导出记录和下载入口。 -9. 写入审计留痕。 +1. `field_pool` +2. `template_mapping` +3. `registration_risk_report` -本步骤不重新抽取字段,不修改法规判断和风险结论。若字段冲突或高风险未处理,应阻止自动生成可报送文件,或者生成“待复核草稿版”并明确标记。 +## 3. 导出策略 -## 2. 所属模块与边界 +1. 始终允许生成草稿版 +2. 命中高风险阻断正式版 +3. 字段冲突或关键缺失时给出拦截原因 -### 2.1 Documents +## 4. 输出对象 -`apps.documents` 负责保存生成后的 Word 文件、记录导出文件元数据,并提供下载入口。 +`registration_word_export_report` 至少包含: -### 2.2 Agent Core +1. `fillable_items` +2. `blocked_items` +3. `draft_export_status` +4. `formal_export_status` +5. `download_url` -`agent_core` 负责模板选择、字段映射、回填数据集构建、Word 渲染、版式校验和导出报告生成。 +## 5. 页面与会话要求 -本步骤建议产生以下中文 Skill: +在对话或结果展示中应能看到: -1. `Word回填导出编排Skill` -2. `模板选择Skill` -3. `模板字段映射加载Skill` -4. `回填字段集构建Skill` -5. `回填拦截检查Skill` -6. `Word模板渲染Skill` -7. `导出版式校验Skill` -8. `导出记录生成Skill` +1. 哪些字段已回填 +2. 哪些字段被拦截 +3. 为什么正式版不能导出 -### 2.3 Audit - -`apps.audit` 记录本次回填导出的模板版本、字段映射、回填字段、拦截状态、输出文件和失败原因。 - -审计中必须保留: - -1. `batch_id` -2. `template_id` -3. `template_version` -4. `field_mapping_version` -5. `filled_fields` -6. `blocked_fields` -7. `output_file_id` -8. `export_status` -9. `layout_check_result` - -## 3. 输入输出 - -### 3.1 输入 - -```json -{ - "batch_id": 1001, - "scenario_id": "registration_word_fill_export", - "template_id": "registration_application_form_v1", - "target_output_type": "application_form", - "allow_draft_when_blocked": true, - "selected_field_keys": [ - "product_name", - "detection_target", - "intended_use", - "storage_condition", - "performance_index" - ] -} -``` - -### 3.2 输出 - -本步骤输出 `registration_word_export_report`: - -```json -{ - "report_type": "registration_word_export_report", - "batch_id": 1001, - "template_id": "registration_application_form_v1", - "export_status": "draft_generated", - "summary": { - "fillable_field_count": 5, - "filled_field_count": 4, - "blocked_field_count": 1, - "manual_review_field_count": 1, - "layout_check_status": "passed" - }, - "filled_fields": [], - "blocked_fields": [], - "output_file": { - "file_id": 2001, - "filename": "注册申报表格_回填草稿.docx", - "download_url": "/documents/exports/2001/download/" - } -} -``` - -## 4. 主工作流 - -```text -用户发起 Word 回填导出 --> 读取字段池和风险报告 --> 选择目标模板 --> 加载模板字段映射 --> 构建回填字段集 --> 执行冲突和风险拦截检查 --> 渲染 Word 模板 --> 校验字段落位和版式 --> 保存导出文件 --> 生成导出报告 --> 写入审计留痕 --> 返回下载入口 -``` - -## 5. 节点详细设计 - -### 5.1 节点一:导出上下文加载 - -业务功能: - -1. 读取资料包批次。 -2. 读取统一字段池。 -3. 读取一致性核查报告。 -4. 读取风险预警报告。 -5. 确认是否允许生成正式版或草稿版。 - -使用技术: - -1. Django ORM -2. JSONField 报告快照 -3. dataclass/Pydantic - -产生方法: - -1. `load_export_context(batch_id, template_id) -> WordExportContext` -2. `load_fillable_field_pool(batch_id) -> list[FieldPoolItem]` -3. `load_export_blockers(batch_id) -> ExportBlockerContext` - -对应 Skill: - -1. `Word回填导出编排Skill` - -### 5.2 节点二:模板选择 - -业务功能: - -1. 根据输出目标选择模板。 -2. 校验模板是否存在。 -3. 校验模板适用流程。 -4. 校验模板版本是否启用。 - -模板类型: - -1. 注册申报表格模板。 -2. 法规对照清单模板。 -3. 注册证或批准证明文件格式模板。 - -使用技术: - -1. 模板库模型 -2. Django Storage -3. YAML/JSON 模板元数据 - -产生方法: - -1. `select_word_template(template_id, target_output_type) -> WordTemplate` -2. `validate_template_applicability(template, workflow_type) -> TemplateValidationResult` -3. `resolve_template_file_path(template) -> Path` - -对应 Skill: - -1. `模板选择Skill` - -### 5.3 节点三:模板字段映射加载 - -业务功能: - -1. 加载模板字段和统一字段池字段的映射关系。 -2. 校验模板占位符是否完整。 -3. 标记必填字段、可选字段和人工复核字段。 - -映射示例: - -```yaml -template_id: registration_application_form_v1 -version: "2026-06-03" -mappings: - - placeholder: "{{ product_name }}" - field_key: product_name - required: true - - placeholder: "{{ intended_use }}" - field_key: intended_use - required: true -``` - -使用技术: - -1. YAML -2. Pydantic -3. 模板占位符扫描 - -产生方法: - -1. `load_template_field_mapping(template_id) -> TemplateFieldMapping` -2. `validate_mapping_against_template(template, mapping) -> MappingValidationResult` -3. `scan_template_placeholders(template_file) -> list[str]` - -对应 Skill: - -1. `模板字段映射加载Skill` - -### 5.4 节点四:回填字段集构建 - -业务功能: - -1. 从字段池读取映射字段。 -2. 选择推荐值。 -3. 过滤不可回填字段。 -4. 生成待回填字段集。 - -使用技术: - -1. Django ORM -2. 字段池数据 -3. 映射规则 - -产生方法: - -1. `build_fill_dataset(field_pool, mapping) -> FillDataset` -2. `resolve_field_value(field_key, field_pool) -> FillValue` -3. `collect_missing_fill_values(mapping, field_pool) -> list[MissingFillValue]` - -对应 Skill: - -1. `回填字段集构建Skill` - -### 5.5 节点五:回填拦截检查 - -业务功能: - -1. 检查字段是否存在冲突。 -2. 检查字段是否待人工复核。 -3. 检查风险报告是否存在高风险。 -4. 判断是否允许生成正式版或草稿版。 - -拦截规则: - -1. 高风险未处理:禁止生成正式版。 -2. 字段冲突未处理:禁止自动正式回填。 -3. 必填字段缺失:禁止正式版。 -4. 允许生成草稿版时,输出文件必须标记“待复核草稿”。 - -使用技术: - -1. 风险报告 -2. 字段池冲突状态 -3. 回填策略规则 - -产生方法: - -1. `check_fill_blockers(fill_dataset, risk_report) -> FillBlockerResult` -2. `determine_export_mode(blockers, allow_draft) -> str` -3. `build_blocked_field_list(blockers) -> list[BlockedField]` - -对应 Skill: - -1. `回填拦截检查Skill` - -### 5.6 节点六:Word 模板渲染 - -业务功能: - -1. 打开 Word 模板。 -2. 替换占位符。 -3. 写入表格单元格。 -4. 保留标题层级、表格、页眉页脚、盖章位和原始样式。 -5. 输出新的 Word 文件。 - -使用技术: - -1. `python-docx` -2. `docxtpl` 可选 -3. Django Storage -4. 临时文件目录 - -产生方法: - -1. `render_word_template(template_file, fill_dataset, export_mode) -> RenderedWordFile` -2. `replace_paragraph_placeholders(document, values) -> None` -3. `replace_table_placeholders(document, values) -> None` -4. `save_rendered_document(document, output_path) -> Path` - -对应 Skill: - -1. `Word模板渲染Skill` - -### 5.7 节点七:导出版式校验 - -业务功能: - -1. 校验输出文件是否存在。 -2. 校验必填占位符是否已替换。 -3. 校验是否仍残留模板占位符。 -4. 校验基础版式元素是否存在。 -5. 必要时渲染预览用于人工确认。 - -使用技术: - -1. `python-docx` -2. 文档占位符扫描 -3. 可选 LibreOffice 转 PDF -4. 可选 PDF 渲染检查 - -产生方法: - -1. `check_export_layout(output_file, mapping) -> LayoutCheckResult` -2. `detect_unfilled_placeholders(output_file) -> list[str]` -3. `validate_required_sections(output_file) -> list[LayoutWarning]` - -对应 Skill: - -1. `导出版式校验Skill` - -### 5.8 节点八:导出记录生成 - -业务功能: - -1. 保存输出文件记录。 -2. 生成下载地址。 -3. 生成导出报告。 -4. 写入审计。 - -使用技术: - -1. Django ORM -2. Django Storage -3. JSONField -4. Audit 服务 - -产生方法: - -1. `create_export_file_record(batch, output_file) -> ExportedDocument` -2. `build_download_url(export_file) -> str` -3. `build_word_export_report(context, result) -> RegistrationWordExportReport` -4. `record_word_export_audit(report, context) -> AuditLog` - -对应 Skill: - -1. `导出记录生成Skill` - -## 6. Skill 清单 - -本步骤产生以下 Skill 设计文档: - -1. [Word回填导出编排Skill](skill/Word回填导出编排Skill.md) -2. [模板选择Skill](skill/模板选择Skill.md) -3. [模板字段映射加载Skill](skill/模板字段映射加载Skill.md) -4. [回填字段集构建Skill](skill/回填字段集构建Skill.md) -5. [回填拦截检查Skill](skill/回填拦截检查Skill.md) -6. [Word模板渲染Skill](skill/Word模板渲染Skill.md) -7. [导出版式校验Skill](skill/导出版式校验Skill.md) -8. [导出记录生成Skill](skill/导出记录生成Skill.md) - -## 7. 导出模式 - -| 模式 | 含义 | -|---|---| -| `formal` | 正式导出,字段无冲突且无高风险 | -| `draft` | 草稿导出,存在待复核项但允许预览 | -| `blocked` | 拦截导出,不生成文件 | - -## 8. 页面展示 - -Word 回填导出页面建议展示: - -1. 模板名称和版本。 -2. 回填字段数量。 -3. 已回填字段。 -4. 被拦截字段。 -5. 导出模式。 -6. 版式校验结果。 -7. Word 下载入口。 -8. 审计入口。 - -## 9. 异常处理 - -1. 模板不存在:任务失败。 -2. 模板字段映射缺失:任务失败。 -3. 必填字段缺失:正式版导出拦截。 -4. 字段冲突:正式版导出拦截。 -5. 高风险未处理:正式版导出拦截。 -6. Word 渲染失败:记录导出失败。 -7. 版式校验失败:生成文件标记待复核。 - -## 10. 与后续步骤的接口 - -飞书通知读取: - -1. 导出状态。 -2. 下载链接。 -3. 被拦截字段。 -4. 待复核字段。 -5. 责任角色。 - -## 11. 测试设计 - -### 11.1 单元测试 - -1. 模板选择正确。 -2. 字段映射加载正确。 -3. 必填字段缺失被拦截。 -4. 冲突字段被拦截。 -5. 占位符替换正确。 -6. 残留占位符可识别。 - -### 11.2 服务层测试 - -1. 能基于字段池生成 Word 草稿。 -2. 高风险存在时禁止正式导出。 -3. 导出文件记录生成。 -4. 导出报告写入审计。 - -### 11.3 页面测试 - -1. 页面展示导出状态。 -2. 页面展示下载入口。 -3. 页面展示拦截原因。 -4. 页面展示版式校验结果。 - -## 12. V1 实现建议 - -V1 建议先完成以下最小闭环: - -1. 维护一个注册申报表格或对照清单模板。 -2. 支持字段占位符回填。 -3. 支持冲突字段和高风险拦截。 -4. 生成新的 `.docx` 文件。 -5. 提供下载入口。 -6. 写入审计。 - -增强阶段再补齐: - -1. 多模板库管理。 -2. PDF 归档件导出。 -3. 高保真版式自动校验。 -4. 模板版本审批。 -5. 后台模板字段映射维护。 +## 6. 验收标准 +1. 草稿版和正式版策略区分明确。 +2. 风险结果能阻断正式导出。 +3. 导出结果可直接提供给飞书消息摘要使用。 diff --git a/docs/详细设计/7.飞书通知.md b/docs/详细设计/7.飞书通知.md index ad8b367..bab7cd7 100644 --- a/docs/详细设计/7.飞书通知.md +++ b/docs/详细设计/7.飞书通知.md @@ -2,406 +2,130 @@ ## 1. 设计目标 -本步骤承接风险预警和 Word 回填导出结果,目标是在飞书群聊或应用会话中完成任务触发、结果摘要查看、责任人通知和 Web 详情跳转,让注册申报审核流程具备 Web 工作台以外的协同入口。 +本步骤负责在审核任务执行完成或执行异常时,通过飞书 `@` 对应处理人,并回传 Web 详情链接。 -本步骤需要完成以下业务结果: +V1 当前 Demo 固定通知策略: -1. 支持飞书群聊机器人触发审核任务。 -2. 支持在飞书内选择任务或查看任务摘要。 -3. 根据风险项和章节点映射责任角色。 -4. 根据责任角色解析飞书账号。 -5. 生成飞书消息摘要和 @ 通知载荷。 -6. 调用飞书 OpenAPI 或 MCP 工具发送消息。 -7. 记录发送结果、失败原因和回传链接。 -8. 写入审计留痕。 +1. 执行完成后发送结果摘要并 `@` 处理人 +2. 执行异常后发送异常摘要并 `@` 处理人 -本步骤不执行具体审核规则,不改变风险结论,不直接修改字段池或导出文件。它只负责飞书入口和通知协作。 +## 2. 角色信息模型 -## 2. 所属模块与边界 +责任人信息不再只保留角色名,必须扩展为可通知实体,至少包含: -### 2.1 Chat +1. `owner_role` +2. `owner_name` +3. `department` +4. `chapter_scope` +5. `risk_scope` +6. `feishu_user_id` +7. `feishu_open_id` +8. `feishu_name` +9. `notify_enabled` -`apps.chat` 提供 Web 详情页链接和任务执行结果页面,飞书消息中应回传 Web 详情入口。 - -### 2.2 Agent Core - -`agent_core` 负责飞书通知编排、摘要生成、责任人映射和发送载荷构建。 - -本步骤建议产生以下中文 Skill: - -1. `飞书通知编排Skill` -2. `飞书任务入口解析Skill` -3. `飞书责任人映射Skill` -4. `飞书消息摘要生成Skill` -5. `飞书消息发送Skill` -6. `飞书回执记录Skill` - -### 2.3 MCP / OpenAPI - -飞书能力通过两类方式接入: - -1. 飞书机器人 / Channel SDK:作为群聊触发和消息回传入口。 -2. 飞书 OpenAPI MCP:作为 Agent 调用飞书消息、文档、群聊和用户信息的工具层。 - -MCP 只作为外部工具接入层,不承载业务审核逻辑。 - -### 2.4 Audit - -`apps.audit` 记录飞书触发来源、消息载荷、通知对象、发送状态和失败原因。 - -审计中必须保留: +## 3. 输入 1. `batch_id` -2. `scenario_id` -3. `trigger_source` -4. `feishu_chat_id` -5. `feishu_message_id` -6. `mentioned_user_ids` -7. `notification_payload` -8. `send_status` -9. `error_message` +2. `conversation_id` +3. `product_name` +4. `notify_reason` +5. `registration_risk_report` +6. `registration_word_export_report` +7. `owner_mapping` -## 3. 输入输出 +其中 `notify_reason` 固定支持: -### 3.1 输入 +1. `task_completed` +2. `task_failed` -```json -{ - "batch_id": 1001, - "scenario_id": "registration_risk_report", - "trigger_source": "feishu_group_bot", - "feishu_chat_id": "oc_demo_chat", - "feishu_message_id": "om_demo_message", - "notify_owner": true, - "include_web_link": true -} -``` +## 4. 输出对象 -### 3.2 输出 +`feishu_notification_report` 至少包含: -本步骤输出 `feishu_notification_report`: +1. `batch_id` +2. `conversation_id` +3. `notify_reason` +4. `mentioned_users` +5. `message_status` +6. `web_detail_url` +7. `receipt` -```json -{ - "report_type": "feishu_notification_report", - "batch_id": 1001, - "send_status": "sent", - "message_type": "interactive_card", - "mentioned_users": [ - { - "owner_role": "注册资料负责人", - "feishu_user_id": "ou_demo_owner" - } - ], - "web_detail_url": "http://localhost:8000/audit/1001/", - "receipt": { - "message_id": "om_demo_message", - "sent_at": "2026-06-03T10:30:00+08:00" - } -} -``` - -## 4. 主工作流 +## 5. 主流程 ```text -飞书群聊或 Web 触发通知 --> 解析飞书触发上下文 --> 读取风险报告和导出报告 --> 解析责任角色和飞书账号 --> 生成飞书消息摘要 --> 构建消息卡片和 @ 通知 --> 调用飞书 OpenAPI / MCP 发送 --> 记录发送回执 --> 写入审计留痕 --> 返回发送结果 +任务完成或异常 +-> 读取责任角色与飞书账号 +-> 构建飞书摘要 +-> 构建 @ 处理人载荷 +-> 发送飞书消息 +-> 写回发送回执 +-> 写入处理历史和审计 ``` -## 5. 节点详细设计 +## 6. 通知内容要求 -### 5.1 节点一:飞书任务入口解析 +飞书消息至少应包含: -业务功能: +1. 任务名称 +2. 产品名称 +3. 批次号 +4. 结果状态 +5. 风险等级或异常摘要 +6. `@` 处理人 +7. Web 详情链接 -1. 解析飞书消息事件。 -2. 识别任务指令。 -3. 识别批次 ID 或项目上下文。 -4. 将飞书触发请求映射到系统场景。 +## 7. 处理完成通知 -支持指令示例: +触发条件: -1. `检查资料完整性` -2. `生成风险报告` -3. `查看导出结果` -4. `通知责任人` +1. 目录汇总完成 +2. 风险报告完成 +3. 导出状态已生成 -使用技术: +输出重点: -1. 飞书事件订阅 -2. 群聊机器人消息 -3. Django webhook view -4. 场景配置 YAML +1. 风险等级 +2. 是否允许正式导出 +3. 责任人 -产生方法: +## 8. 执行异常通知 -1. `parse_feishu_event(event_payload) -> FeishuTriggerContext` -2. `resolve_scenario_from_command(text) -> str` -3. `resolve_batch_from_message(text, chat_context) -> int | None` +触发条件: -对应 Skill: +1. 资料解析失败 +2. 规则执行失败 +3. 回填导出失败 +4. 外部依赖异常 -1. `飞书任务入口解析Skill` +输出重点: -### 5.2 节点二:通知上下文加载 +1. 异常阶段 +2. 异常摘要 +3. 责任人 +4. 是否建议人工介入 -业务功能: +## 9. 与页面关系 -1. 读取风险报告。 -2. 读取 Word 导出报告。 -3. 读取审计详情链接。 -4. 读取任务状态。 +### 9.1 审核智能体 -使用技术: +可展示: -1. Django ORM -2. JSONField -3. URL reverse +1. 本次是否已触发飞书通知 +2. 飞书发送状态 +3. 被 `@` 的处理人 -产生方法: +### 9.2 处理历史 -1. `load_notification_context(batch_id, scenario_id) -> NotificationContext` -2. `build_web_detail_url(report_or_audit) -> str` -3. `collect_notification_sources(context) -> list[dict]` +可回看: -对应 Skill: +1. 通知原因 +2. 接收人 +3. 消息状态 +4. Web 回链 -1. `飞书通知编排Skill` +## 10. 验收标准 -### 5.3 节点三:责任人映射 - -业务功能: - -1. 根据风险项、章节点和任务类型确定责任角色。 -2. 根据责任角色查找飞书账号。 -3. 支持后台或配置文件手动维护。 -4. 对未配置账号的责任角色给出提示。 - -建议配置: - -```yaml -owners: - CH1: - owner_role: 注册资料负责人 - feishu_user_id: ou_demo_owner - field_conflict: - owner_role: 注册资料负责人 - feishu_user_id: ou_demo_owner - missing_required_document: - owner_role: 注册申报负责人 - feishu_user_id: ou_demo_registration_owner -``` - -使用技术: - -1. YAML 配置 -2. Django Admin 维护表 -3. 飞书用户 ID - -产生方法: - -1. `resolve_owner_roles(risk_items) -> list[OwnerRole]` -2. `load_owner_mapping() -> OwnerMapping` -3. `resolve_feishu_user_ids(owner_roles, mapping) -> list[FeishuMentionTarget]` - -对应 Skill: - -1. `飞书责任人映射Skill` - -### 5.4 节点四:飞书消息摘要生成 - -业务功能: - -1. 生成风险摘要。 -2. 生成高风险列表。 -3. 生成导出结果摘要。 -4. 生成 Web 详情链接。 -5. 生成飞书交互卡片或纯文本消息。 - -消息内容: - -1. 当前任务名称。 -2. 批次名称。 -3. 是否通过。 -4. 最高风险等级。 -5. 高风险数量。 -6. 待复核数量。 -7. 责任人 @。 -8. Web 详情入口。 -9. 导出文件链接。 - -使用技术: - -1. 飞书互动卡片 JSON -2. 文本消息模板 -3. 可选 LLM 摘要 - -产生方法: - -1. `build_feishu_summary(context) -> FeishuSummary` -2. `build_interactive_card(summary, mentions) -> dict` -3. `build_text_message(summary, mentions) -> dict` - -对应 Skill: - -1. `飞书消息摘要生成Skill` - -### 5.5 节点五:飞书消息发送 - -业务功能: - -1. 调用飞书 OpenAPI 或 MCP 发送消息。 -2. 支持群聊消息。 -3. 支持 @ 指定责任人。 -4. 捕获发送结果和失败原因。 - -使用技术: - -1. 飞书 OpenAPI -2. 飞书机器人 -3. MCP 工具封装 -4. 请求重试 - -产生方法: - -1. `send_feishu_message(chat_id, payload) -> FeishuSendResult` -2. `send_feishu_card(chat_id, card_payload) -> FeishuSendResult` -3. `retry_send_on_transient_error(request) -> FeishuSendResult` - -对应 Skill: - -1. `飞书消息发送Skill` - -### 5.6 节点六:飞书回执记录 - -业务功能: - -1. 保存发送状态。 -2. 保存消息 ID。 -3. 保存通知对象。 -4. 保存失败原因。 -5. 写入审计。 - -使用技术: - -1. Django ORM -2. Audit 服务 -3. JSONField - -产生方法: - -1. `record_feishu_receipt(result, context) -> FeishuNotificationRecord` -2. `build_feishu_audit_payload(record, context) -> dict` -3. `record_feishu_audit(payload) -> AuditLog` - -对应 Skill: - -1. `飞书回执记录Skill` - -## 6. Skill 清单 - -本步骤产生以下 Skill 设计文档: - -1. [飞书通知编排Skill](skill/飞书通知编排Skill.md) -2. [飞书任务入口解析Skill](skill/飞书任务入口解析Skill.md) -3. [飞书责任人映射Skill](skill/飞书责任人映射Skill.md) -4. [飞书消息摘要生成Skill](skill/飞书消息摘要生成Skill.md) -5. [飞书消息发送Skill](skill/飞书消息发送Skill.md) -6. [飞书回执记录Skill](skill/飞书回执记录Skill.md) - -## 7. 消息类型设计 - -| 类型 | 使用场景 | -|---|---| -| `text` | 简单摘要和失败提示 | -| `interactive_card` | 风险报告摘要、按钮和详情链接 | -| `mention_text` | @ 责任人 | - -## 8. 页面与飞书展示 - -飞书消息建议展示: - -1. 任务名称。 -2. 批次名称。 -3. 最高风险等级。 -4. 是否通过。 -5. 高风险摘要。 -6. 待人工复核事项。 -7. 责任人 @。 -8. Web 详情链接。 -9. 导出文件链接。 - -## 9. 异常处理 - -1. 飞书事件验签失败:拒绝请求。 -2. 无法识别任务指令:返回帮助提示。 -3. 未找到批次:返回业务提示。 -4. 责任人未配置:发送群消息但不 @。 -5. 飞书 API 失败:记录失败回执,可重试。 -6. Web 链接生成失败:消息中省略链接并记录警告。 - -## 10. 与全流程接口 - -本步骤读取: - -1. `registration_risk_report` -2. `registration_word_export_report` -3. 审计详情链接 -4. 责任人映射配置 - -本步骤输出: - -1. `feishu_notification_report` -2. 飞书消息 ID -3. 通知状态 -4. 审计记录 - -## 11. 测试设计 - -### 11.1 单元测试 - -1. 飞书事件解析。 -2. 任务指令解析。 -3. 责任人映射。 -4. 消息摘要构建。 -5. 发送 payload 构建。 - -### 11.2 服务层测试 - -1. 风险报告可生成飞书卡片。 -2. 责任人可被 @。 -3. 未配置责任人时仍能发送摘要。 -4. API 失败时记录失败回执。 -5. 审计记录包含飞书来源。 - -### 11.3 集成测试 - -1. 群聊机器人触发风险报告查看。 -2. 群聊机器人发送责任人通知。 -3. Web 链接可跳转到详情页。 - -## 12. V1 实现建议 - -V1 建议先完成以下最小闭环: - -1. 支持飞书群聊机器人接收指令。 -2. 支持发送风险报告摘要。 -3. 支持责任人手动配置和 @。 -4. 支持 Web 详情链接。 -5. 支持发送回执和审计记录。 - -增强阶段再补齐: - -1. 飞书应用会话菜单。 -2. 文档评论区 @bot。 -3. 多维表格同步。 -4. 飞书文档写回。 -5. 消息卡片交互按钮。 +1. 角色信息包含飞书账号相关字段。 +2. 执行完成与执行异常两类通知链路完整。 +3. 飞书消息支持直接 `@` 对应处理人。 +4. 通知结果可在处理历史和审计中回溯。