Files
DEMO-AGENT/docs/2.功能设计/3.产品关键信息提取与申报文件自动填表.md

817 lines
32 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 产品关键信息提取与申报文件自动填表功能设计
## 文档信息
| 项目 | 内容 |
| --- | --- |
| 需求分析文档 | docs/1.需求分析/3.产品关键信息提取与申报文件自动填表.md |
| 依赖功能设计 | docs/2.功能设计/1.自动汇总.mddocs/2.功能设计/2.NMPA注册资料法规核查与整改闭环.md |
| 功能名称 | 产品关键信息提取与申报文件自动填表 |
| 所属模块 | 审核智能体 review_agent |
| 设计日期 | 2026-06-07 |
| 设计版本 | V1.0 |
---
## 一、设计目标
本功能作为独立工作流 `application_form_fill` 建设,由用户在 AI 对话中触发,例如“帮我填注册证”“给我这个内容对应的表格”“为我该方案生成申报模板”“生成安全和性能基本原则清单”“把产品信息填到申报模板里”等。用户可以明确指定目标模板;未指定时,系统根据识别出的注册类型生成当前注册类型适用的全部模板。
本功能复用第一批文件汇总结果作为文件来源复用第二批法规核查中的文本抽取、适用条件识别、LLM 调用、飞书通知和导出下载能力,但拥有独立批次、独立工作流卡片和独立过程产物。系统复制原始法规模板到批次工作目录,不覆盖原始文件;随后按模板配置识别应填字段,使用规则/正则抽取与 LLM 结构化抽取并行处理,合并字段、识别冲突、写入 Word 模板,并在 AI 对话框和飞书通知中提示生成结果与冲突摘要。
Demo 阶段优先保证 Word 模板自动填写和下载。PDF 转换作为待办增强项:功能设计保留 PDF 导出节点和数据结构,实施时可先返回 Word 与追溯清单,并在待办清单记录 PDF 转换能力。
---
## 二、与既有功能的关系
### 2.1 复用边界
| 能力 | 处理方式 | 现有代码/模型 |
| --- | --- | --- |
| 对话与用户权限 | 复用 | `Conversation``Message` |
| 附件上传与文件绑定 | 复用 | `FileAttachment``FileSummaryBatchAttachment` |
| 文件汇总与页数统计 | 复用 | `FileSummaryBatch``FileSummaryItem``file_summary.workflow` |
| 文本抽取 | 复用并扩展 | `regulatory_review/services/text_extract.py``rag_index.py` |
| 适用条件候选 | 复用并扩展 | `regulatory_review/services/info_extract.py` |
| LLM 调用 | 复用 | `review_agent/llm.py``regulatory_review/services/llm_review.py` |
| 导出记录与下载 | 扩展复用 | `ExportedSummaryFile` |
| 过程产物 | 复用 | `RegulatoryArtifact` 或新增填表过程产物 |
| 飞书通知 | 复用并扩展 | `regulatory_review/services/feishu_notifier.py` |
| SSE 工作流事件 | 复用 | `WorkflowNodeRun``WorkflowEvent` |
### 2.2 新增边界
| 能力 | 说明 |
| --- | --- |
| 独立填表批次 | 新增 `ApplicationFormFillBatch`,不强绑法规核查批次 |
| 模板配置 | 新增 YAML 配置,维护模板路径、适用条件、字段映射和输出规则 |
| 模板选择 | 根据用户指定模板和注册类型选择生成范围 |
| 规则/正则与 LLM 并行抽取 | 两路抽取并行执行,最后统一合并 |
| 字段冲突归并 | 按来源文件优先级处理,说明书优先;冲突字段高亮 |
| Word 模板填充 | 使用 `python-docx``.docx` 表格、段落和占位字段写入 |
| `.doc` 模板转换 | 使用 LibreOffice/soffice 或预转换 `.docx` 模板 |
| 字段来源追溯 | 输出 Excel/JSON 追溯清单,记录抽取、合并和冲突证据 |
---
## 三、总体架构
### 3.1 架构原则
| 原则 | 说明 |
| --- | --- |
| 独立工作流 | 填表流程拥有独立批次、节点和卡片workflow_type 为 `application_form_fill` |
| 复用文件汇总 | 填表不重新实现上传扫描,默认使用当前对话最近成功的 `FileSummaryBatch` |
| 用户指令优先 | 用户明确指定模板或注册类型时,优先使用用户指令 |
| 配置驱动 | 模板路径、字段映射、适用条件和输出规则写入 YAML 配置 |
| Word 优先 | Demo 阶段优先生成可编辑 WordPDF 作为增强项进入待办 |
| 可追溯 | 规则抽取、LLM 抽取、合并结果、冲突列表和来源证据均留底 |
| 失败隔离 | 单字段、单模板或 PDF 转换失败不影响其他模板输出 |
| 通知可控 | 填表完成后可通过飞书通知上传人,通知内容只包含摘要和下载提示 |
### 3.2 逻辑架构
```mermaid
flowchart TD
A["AI 对话页"] --> B["意图识别 application_form_fill"]
B --> C{"本次消息是否带附件"}
C -->|"是"| D["先执行文件汇总工作流"]
C -->|"否"| E["查找最近成功 FileSummaryBatch"]
D --> E
E --> F["ApplicationFormFillBatch"]
F --> G["FormFillWorkflowExecutor"]
G --> H["模板配置 YAML"]
G --> I["模板选择服务"]
G --> J["文本抽取服务"]
J --> K1["规则/正则抽取"]
J --> K2["LLM 结构化抽取"]
K1 --> L["字段合并与冲突归并"]
K2 --> L
L --> M["Word 模板填充服务"]
M --> N["追溯清单导出"]
M --> O["PDF 转换服务 P1"]
N --> P["ExportedSummaryFile"]
O --> P
G --> Q["WorkflowEvent/SSE"]
Q --> R["自动填表工作流卡片"]
G --> S["FeishuNotifier"]
S --> T["上传人通知"]
```
### 3.3 技术选型
| 设计项 | Demo 方案 | 后续演进 |
| --- | --- | --- |
| Web 框架 | Django沿用当前 `review_agent` 应用 | 保持 Django必要时拆分独立 app |
| 工作流编排 | 新增轻量 `FormFillWorkflowExecutor` | 接入 LangGraph 子图 |
| 后台执行 | Django 后台线程,沿用现有工作流方式 | Celery/RQ + Redis |
| 工作流状态 | `WorkflowNodeRun` + `WorkflowEvent`,新增 workflow_type | 独立工作流事件中心 |
| 模板配置 | YAML建议路径 `review_agent/application_form_fill/templates/application_form_templates_v1.yaml` | 数据库模板管理后台 |
| Word 处理 | `python-docx` 写入 `.docx` 表格和段落,高亮冲突字段 | OOXML 精细 patch、内容控件 SDT |
| `.doc` 转换 | LibreOffice/soffice headless 转 `.docx`;无法部署时预置 `.docx` 工作模板 | 模板入库前统一转换和人工校验 |
| PDF 导出 | P1 待办LibreOffice/soffice headless 转 PDF | 逐页渲染 QA、版式差异检测 |
| Excel 追溯清单 | `openpyxl` | 增加多 Sheet 审核视图 |
| 文本抽取 | 复用 `text_extract.py``rag_index.py` | OCR、文档文本缓存 |
| 字段抽取 | 规则/正则与 LLM 结构化抽取并行,合并后输出 | 可配置抽取器和置信度模型 |
| 飞书通知 | 复用 `FeishuNotifier`Demo 可 mock 或 CLI | 飞书 Webhook/API |
---
## 四、触发与模板选择设计
### 4.1 意图识别
填表工作流通过用户对话触发。意图识别可先采用关键词规则,必要时调用现有 LLM 路由能力。
| 触发表达 | 触发结果 |
| --- | --- |
| 帮我填注册证 | 触发填表,指定注册证格式 |
| 给我这个内容对应的表格 | 触发填表,未指定模板 |
| 为我该方案生成申报模板 | 触发填表,未指定模板 |
| 生成安全和性能基本原则清单 | 触发填表,指定安全和性能基本原则清单 |
| 把产品信息填到申报模板里 | 触发填表,未指定模板 |
| 只生成变更注册备案文件 | 触发填表,指定变更注册(备案)文件 |
### 4.2 文件来源选择
| 场景 | 处理方式 |
| --- | --- |
| 本次消息带新附件 | 先自动执行文件汇总,汇总成功后启动填表 |
| 本次消息无附件 | 默认使用当前对话最近一次成功 `FileSummaryBatch` |
| 无成功汇总批次 | 对话框提示用户先上传资料或补充附件 |
| 用户明确指定历史批次 | 校验批次属于当前对话和当前用户后使用 |
### 4.3 注册类型识别优先级
注册类型用于决定默认生成哪些模板。优先级如下:
```text
用户话语明确指定
-> 当前对话已确认的法规核查条件
-> 上传文件内容抽取结果
-> 无法识别
```
### 4.4 模板选择规则
| 场景 | 生成模板 |
| --- | --- |
| 用户未指定模板,注册类型为首次注册 | 注册证格式;安全和性能基本原则清单 |
| 用户未指定模板,注册类型为变更注册或备案 | 变更注册(备案)文件;安全和性能基本原则清单 |
| 用户未指定模板,注册类型无法识别 | 安全和性能基本原则清单;注册证/变更文件进入待确认提示 |
| 用户明确指定模板且与注册类型一致 | 只生成用户指定模板 |
| 用户明确指定模板但与注册类型不一致 | 允许生成,并在摘要和追溯清单提示“与识别注册类型不一致,需人工确认” |
| 用户指定“全部模板” | 生成三个目标模板,并提示用户核对注册类型适用性 |
---
## 五、工作流设计
### 5.1 节点图
```mermaid
flowchart LR
N1["准备资料"] --> N2["选择模板"]
N2 --> N3["复制模板"]
N3 --> N4["抽取字段"]
N4 --> N5["冲突归并"]
N5 --> N6["填写 Word"]
N6 --> N7["转换 PDF P1"]
N6 --> N8["追溯清单"]
N7 --> N9["输出下载"]
N8 --> N9
N9 --> N10["飞书通知"]
N10 --> N11["完成"]
```
### 5.2 节点定义
| 节点编码 | 节点名称 | 触发服务 | 成功条件 | 失败处理 |
| --- | --- | --- | --- | --- |
| prepare | 准备资料 | `FormFillWorkflowExecutor` | 找到或生成成功的 `FileSummaryBatch` | 无文件汇总则暂停提示上传 |
| template_select | 选择模板 | `TemplateSelectionService` | 输出本次目标模板列表 | 无适用模板则失败 |
| template_copy | 复制模板 | `TemplateRepository` | 模板副本进入批次工作目录 | 单模板失败不影响其他模板 |
| field_extract | 抽取字段 | `FieldExtractionService` | 规则/正则与 LLM 结果留底 | 单文件失败记录并继续 |
| conflict_merge | 冲突归并 | `FieldMergeService` | 输出最终字段和冲突列表 | 无字段时仍生成空模板 |
| word_fill | 填写 Word | `WordTemplateFillService` | 生成填好后的 Word 文件 | 单模板失败记录失败 |
| pdf_convert | 转换 PDF | `PdfConversionService` | P1生成 PDF 文件 | PDF 失败标记 partial_success |
| trace_export | 追溯清单 | `TraceabilityExportService` | 生成 Excel/JSON 追溯清单 | 失败不影响 Word |
| output_export | 输出下载 | `FormFillExportService` | 写入 `ExportedSummaryFile` 并生成下载链接 | 关键 Word 失败则批次失败 |
| notify | 飞书通知 | `FeishuNotifier` | 通知上传人生成完成 | 通知失败不影响下载 |
| completed | 完成 | 工作流执行器 | 更新批次状态和对话消息 | - |
### 5.3 状态设计
| 状态 | 含义 |
| --- | --- |
| pending | 已创建,等待执行 |
| running | 执行中 |
| waiting_user | 缺少文件或关键条件,等待用户补充 |
| success | Word 和必要追溯产物生成成功 |
| partial_success | Word 已生成但部分模板、PDF、追溯清单或通知失败 |
| failed | 所有目标 Word 模板均生成失败 |
| skipped | 当前节点不适用,例如 Demo 阶段跳过 PDF |
---
## 六、模板配置设计
### 6.1 配置文件路径
建议新增:
```text
review_agent/application_form_fill/templates/application_form_templates_v1.yaml
```
### 6.2 配置结构
```yaml
version: application_form_templates_v1
source_dir: docs/0.原始材料/关于公布体外诊断试剂注册申报资料要求和批准证明文件格式的公告
templates:
- code: registration_certificate
name: 中华人民共和国医疗器械注册证(体外诊断试剂)(格式)
source_file: 中华人民共和国医疗器械注册证(体外诊断试剂)(格式).docx
output_label: 注册证格式
applies_when:
registration_type: ["首次注册"]
file_format: docx
fields:
- key: product_name
label: 产品名称
target:
type: table_row
row_label: 产品名称
sources: ["说明书", "产品技术要求", "注册检验报告"]
- key: package_specification
label: 包装规格
target:
type: table_row
row_label: 包装规格
sources: ["说明书", "产品技术要求"]
```
### 6.3 模板配置项
| 配置项 | 说明 |
| --- | --- |
| code | 模板编码,用于用户指定和导出分类 |
| name | 模板中文名称 |
| source_file | 原始模板文件名 |
| working_template | 可选,预转换 `.docx` 工作模板 |
| output_label | 文件命名中的模板标签 |
| applies_when | 默认适用注册类型 |
| fields | 字段映射列表 |
| checklist_items | 安全和性能基本原则清单条目映射 |
| conversion | `.doc``.docx` 和 PDF 的转换策略 |
### 6.4 已知模板字段
注册证格式当前已从 `.docx` 表格识别到以下字段:注册人名称、注册人住所、生产地址、代理人名称、代理人住所、产品名称、包装规格、主要组成成分、预期用途、产品储存条件及有效期、附件、其他内容、备注。
变更注册(备案)文件和安全和性能基本原则清单当前为 `.doc`,实施前需通过 LibreOffice/soffice 转换或预置人工确认版 `.docx` 工作模板,再补齐字段映射。
---
## 七、字段抽取与合并设计
### 7.1 三层提取链路
```text
模板字段配置
-> 文档字段候选提取
-> 规则/正则抽取与 LLM 结构化抽取并行
-> 字段归一化
-> 来源优先级合并
-> 冲突识别
-> 最终字段包
```
### 7.2 规则/正则抽取
| 能力 | 说明 |
| --- | --- |
| 标签字段识别 | 识别 `产品名称:``预期用途:``储存条件:` 等标签行 |
| 表格字段识别 | 从 Word/Excel 表格中识别左侧字段名、右侧字段值 |
| 章节范围识别 | 从说明书、产品技术要求中按章节提取连续文本 |
| 文件类型识别 | 根据文件名、目录名和首页标题判断说明书、产品技术要求、检验报告 |
| 证据片段截取 | 保存字段前后上下文,用于追溯清单 |
### 7.3 LLM 结构化抽取
LLM 输入为模板字段清单、文件上下文和候选文本片段,输出严格 JSON
```json
{
"fields": [
{
"key": "storage_condition",
"label": "产品储存条件及有效期",
"value": "2-8℃保存有效期12个月",
"source_file": "说明书.docx",
"evidence": "产品储存条件2-8℃保存...",
"confidence": 0.86
}
],
"checklist_items": [
{
"item_code": "A1",
"applicability": "适用",
"compliance_evidence": "产品技术要求中规定了性能指标和检验方法",
"proof_location": "产品技术要求.docx 第2章"
}
]
}
```
### 7.4 并行合并规则
| 场景 | 处理规则 |
| --- | --- |
| 规则和 LLM 值一致 | 合并为同一字段,提高置信度 |
| 规则和 LLM 值不一致,但来源文件不同 | 按来源文件优先级处理,说明书优先 |
| 规则和 LLM 值不一致,来源文件相同 | 标记冲突,模板中高亮 |
| 说明书与其他文件冲突 | 采用说明书值,黄色底色、红色字体标记 |
| 说明书缺失,多个来源冲突 | 取最高优先级文件值并标记冲突;无法判断则留空 |
| 字段缺失 | 模板留空,追溯清单记录未提取 |
### 7.5 过程产物留底
字段抽取结果保存为 `field_extract_result.json`,至少包含:
| 内容 | 说明 |
| --- | --- |
| regex_results | 规则/正则抽取结果 |
| llm_results | LLM 结构化抽取结果 |
| merged_fields | 合并后的最终字段 |
| conflicts | 冲突字段列表 |
| source_evidence | 来源文件和文本片段 |
| selected_templates | 本次选择的模板 |
---
## 八、安全和性能基本原则清单设计
### 8.1 判断策略
安全和性能基本原则清单采用“候选判断 + 高置信度写入”策略。
| 步骤 | 说明 |
| --- | --- |
| 条目拆解 | 从模板配置中读取条目编号、原则内容、适用性栏、证据栏、证明文件位置栏 |
| 候选判断 | 规则和 LLM 均可给出适用/不适用候选 |
| 证据匹配 | 从产品技术要求、说明书、性能研究、稳定性研究、风险管理资料中匹配证明文件 |
| 高置信度写入 | 仅将高置信度判断写入 Word |
| 低置信度留空 | 证据不足或判断不一致时 Word 留空,追溯清单记录候选判断 |
| 冲突提示 | 冲突条目在对话框和追溯清单中提示,不强行填入 |
### 8.2 输出字段
| 字段 | 说明 |
| --- | --- |
| 条目编号 | 基本原则清单中的条目编码 |
| 条目内容 | 原始原则或要求 |
| 适用性 | 适用/不适用,低置信度留空 |
| 符合性证据 | 高置信度证据摘要 |
| 证明文件位置 | 文件名、章节、页码或文本定位 |
| 置信度 | 用于判断是否写入 Word |
| 候选来源 | 规则、LLM 或两者一致 |
---
## 九、Word 与 PDF 生成设计
### 9.1 Word 模板填充
| 能力 | 说明 |
| --- | --- |
| 模板副本 | 原始模板复制到批次工作目录后再写入 |
| 表格行填充 | 根据行首字段名定位目标单元格 |
| 段落占位填充 | 支持 `{{field_key}}` 等占位符 |
| 清单条目填充 | 按条目编号和配置列写入适用性、证据和证明位置 |
| 冲突高亮 | 冲突字段使用黄色底色和红色字体 |
| 缺失字段 | 保持空白,不写“待补充” |
| 版式保持 | 尽量不改变表格结构、分页和字体 |
### 9.2 PDF 转换
PDF 转换作为 P1 待办增强项设计:
| 阶段 | 处理 |
| --- | --- |
| Demo 主链路 | 优先生成 Word不因 PDF 能力缺失阻断工作流 |
| P1 增强 | 使用 LibreOffice/soffice headless 将 Word 转为 PDF |
| 失败处理 | Word 已生成但 PDF 失败时,批次状态为 `partial_success` |
| QA 增强 | 后续增加 PDF 页数非 0、逐页截图或版式差异检查 |
---
## 十、输出与下载设计
### 10.1 输出文件
| 文件 | Demo 阶段 | P1/P2 |
| --- | --- | --- |
| 填好后的 Word | 必须生成 | 持续支持 |
| PDF 预览 | 待办增强 | LibreOffice 转换生成 |
| 字段来源追溯清单 Excel | 允许生成,建议实现 | 增加多 Sheet |
| 字段抽取 JSON | 过程产物留底 | 支持下载或调试查看 |
### 10.2 文件命名
```text
批次号-产品名称-注册证格式.docx
批次号-产品名称-注册证格式.pdf
批次号-产品名称-变更注册备案文件.docx
批次号-产品名称-变更注册备案文件.pdf
批次号-产品名称-安全和性能基本原则清单.docx
批次号-产品名称-安全和性能基本原则清单.pdf
批次号-产品名称-字段来源追溯清单.xlsx
```
### 10.3 ExportedSummaryFile 扩展
继续复用 `ExportedSummaryFile`,但需要扩展 `ExportType`
| export_type | 说明 |
| --- | --- |
| markdown | 既有 Markdown 报告 |
| excel | Excel 追溯清单 |
| json | 字段抽取 JSON 或结果包 |
| word | 填好的 Word 文件,新增 |
| pdf | Word 转换后的 PDF新增 |
填表工作流导出记录建议:
| 字段 | 值 |
| --- | --- |
| workflow_type | `application_form_fill` |
| workflow_batch_id | `ApplicationFormFillBatch.id` |
| export_category | `filled_template``traceability``extract_result` |
| export_type | `word``pdf``excel``json` |
导出服务入参应包含目标输出类型列表,例如:
```json
{
"output_types": ["word", "pdf", "excel"],
"template_codes": ["registration_certificate", "essential_principles"]
}
```
系统根据入参决定生成哪些类型的内容。
---
## 十一、数据模型设计
### 11.1 ApplicationFormFillBatch
新增自动填表批次表。
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| id | BigAutoField | 主键 |
| conversation | ForeignKey(Conversation) | 绑定对话 |
| user | ForeignKey(User) | 发起用户 |
| source_summary_batch | ForeignKey(FileSummaryBatch) | 文件来源批次 |
| source_regulatory_batch | ForeignKey(RegulatoryReviewBatch, null=True) | 可选,复用已确认法规条件 |
| batch_no | CharField | 填表批次号,如 AFF-YYYYMMDDHHMMSS |
| status | CharField | pending、running、waiting_user、success、partial_success、failed |
| trigger_message | ForeignKey(Message, null=True) | 触发消息 |
| requested_templates | JSONField | 用户指定模板 |
| selected_templates | JSONField | 实际生成模板 |
| output_types | JSONField | 请求输出类型,如 word、pdf、excel |
| registration_type | CharField | 注册类型 |
| product_name | CharField | 产品名称 |
| conflict_summary | JSONField | 冲突摘要 |
| risk_notes | JSONField | 不适用模板、低置信度等提示 |
| work_dir | CharField | 批次工作目录 |
| error_message | TextField | 异常说明 |
| created_at | DateTimeField | 创建时间 |
| started_at | DateTimeField | 开始时间 |
| finished_at | DateTimeField | 完成时间 |
### 11.2 ApplicationFormFillArtifact
可新增独立过程产物表,也可复用 `RegulatoryArtifact`。考虑到这是独立工作流,建议新增轻量产物表,结构与 `RegulatoryArtifact` 保持一致。
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| id | BigAutoField | 主键 |
| batch | ForeignKey(ApplicationFormFillBatch) | 所属填表批次 |
| artifact_type | CharField | template_copy、field_extract_result、merged_fields、traceability、notification_record |
| file_format | CharField | json、excel、docx、pdf |
| name | CharField | 产物名称 |
| storage_path | CharField | 存储路径 |
| metadata | JSONField | 模板编码、输出类型、生成状态等 |
| content_hash | CharField | 文件 hash |
| created_at | DateTimeField | 创建时间 |
### 11.3 与既有模型关系
```text
Conversation 1:N ApplicationFormFillBatch
FileSummaryBatch 1:N ApplicationFormFillBatch
RegulatoryReviewBatch 0:N ApplicationFormFillBatch
ApplicationFormFillBatch 1:N ApplicationFormFillArtifact
ApplicationFormFillBatch 1:N WorkflowNodeRun
ApplicationFormFillBatch 1:N ExportedSummaryFile
```
---
## 十二、后端服务设计
### 12.1 FormFillWorkflowExecutor
| 方法 | 说明 |
| --- | --- |
| run(batch) | 串行执行自动填表节点 |
| run_node(node) | 执行单节点并记录进度 |
| resolve_source_summary_batch() | 根据本次附件或最近成功批次确定来源 |
| emit_event() | 写入 `WorkflowEvent` |
| complete_or_partial() | 根据 Word/PDF/通知结果更新批次状态 |
### 12.2 TemplateSelectionService
| 方法 | 说明 |
| --- | --- |
| parse_requested_templates(message) | 从用户话语中识别指定模板 |
| detect_registration_type() | 按用户话语、法规确认条件、文件抽取识别注册类型 |
| select_templates() | 根据注册类型和用户指令输出模板列表 |
### 12.3 TemplateRepository
| 方法 | 说明 |
| --- | --- |
| load_config() | 读取 YAML 模板配置 |
| resolve_source_template(code) | 找到原始模板或预转换模板 |
| copy_to_work_dir(code, batch) | 复制模板到批次目录 |
| convert_doc_to_docx(path) | `.doc``.docx` |
### 12.4 FieldExtractionService
| 方法 | 说明 |
| --- | --- |
| extract_by_rules(texts, template_fields) | 规则/正则抽取 |
| extract_by_llm(texts, template_fields) | LLM 结构化抽取 |
| run_parallel() | 并行执行两路抽取 |
| save_extract_artifact() | 保存 `field_extract_result.json` |
### 12.5 FieldMergeService
| 方法 | 说明 |
| --- | --- |
| normalize_fields() | 字段名、单位、空白和同义词归一 |
| rank_sources() | 按说明书、产品技术要求、检验报告等来源排序 |
| merge() | 输出最终字段 |
| detect_conflicts() | 输出冲突列表和高亮标记 |
### 12.6 WordTemplateFillService
| 方法 | 说明 |
| --- | --- |
| fill_table_rows() | 根据行名定位表格单元格并写入 |
| fill_placeholders() | 替换段落占位符 |
| fill_checklist_items() | 写入安全和性能基本原则清单 |
| apply_conflict_highlight() | 黄底红字标记冲突字段 |
| save_docx() | 保存填好后的 Word |
### 12.7 TraceabilityExportService
| 方法 | 说明 |
| --- | --- |
| build_excel() | 生成字段来源追溯清单 |
| build_json() | 生成结构化追溯 JSON |
| create_export_records() | 写入 `ExportedSummaryFile` |
### 12.8 FormFillNotifier
复用或包装 `FeishuNotifier`
| 通知场景 | 说明 |
| --- | --- |
| 填表成功 | 通知上传人文件已生成 |
| 部分成功 | 通知 Word 已生成,但 PDF/部分模板失败 |
| 冲突字段存在 | 通知中提示存在冲突字段,需下载核对 |
| 失败 | 可选通知失败原因Demo 可只在对话框展示 |
---
## 十三、接口设计
### 13.1 发起自动填表
| 项目 | 内容 |
| --- | --- |
| URL | POST /api/review-agent/application-form-fill/start/ |
| 认证 | 登录用户 |
| 请求 | conversation_id、message_id、file_summary_batch_id 可选、template_codes 可选、output_types 可选 |
| 响应 | batch_id、workflow_type、status、selected_templates |
处理规则:
```text
校验 conversation 属于当前用户
-> 如本次消息带附件,先执行文件汇总
-> 否则查找当前对话最近成功 FileSummaryBatch
-> 创建 ApplicationFormFillBatch
-> 初始化 WorkflowNodeRun
-> 启动 FormFillWorkflowExecutor
-> 返回工作流卡片初始状态
```
### 13.2 查询自动填表状态
| 项目 | 内容 |
| --- | --- |
| URL | GET /api/review-agent/application-form-fill/{batch_id}/ |
| 认证 | 登录用户 |
| 响应 | 批次状态、节点状态、选择模板、冲突摘要、导出文件 |
### 13.3 下载导出文件
继续复用:
| 项目 | 内容 |
| --- | --- |
| URL | GET /api/review-agent/file-summary/exports/{export_id}/download/ |
| 认证 | 登录用户 |
| 响应 | 文件流 |
权限规则:
```text
export_id -> workflow_type/workflow_batch_id -> ApplicationFormFillBatch -> conversation -> user
必须等于当前登录用户,才允许下载。
```
---
## 十四、前端设计
### 14.1 自动填表工作流卡片
前端新增独立卡片类型 `application_form_fill`,展示节点:
| 节点 | 展示文案 |
| --- | --- |
| prepare | 准备资料 |
| template_select | 选择模板 |
| template_copy | 复制模板 |
| field_extract | 抽取字段 |
| conflict_merge | 冲突归并 |
| word_fill | 填写 Word |
| pdf_convert | 转换 PDF |
| output_export | 输出下载 |
| notify | 飞书通知 |
| completed | 已完成 |
### 14.2 对话框结果展示
工作流完成后AI 对话框展示 Markdown 摘要:
```markdown
已生成申报模板自动填表文件。
| 文件 | Word | PDF |
| --- | --- | --- |
| 注册证格式 | 下载 | 待生成 |
| 安全和性能基本原则清单 | 下载 | 待生成 |
| 冲突字段 | 采用值 | 冲突来源 | 处理 |
| --- | --- | --- | --- |
| 储存条件 | 2-8℃保存 | 产品技术要求:-20℃保存 | 已按说明书填入,并在模板中高亮 |
[下载字段来源追溯清单](download-url)
```
### 14.3 指定模板交互
用户可以通过自然语言指定模板。前端无需额外表单,后端意图识别后在卡片中展示本次选择模板。
---
## 十五、事件设计
### 15.1 SSE 事件结构
```json
{
"event": "workflow",
"workflow_type": "application_form_fill",
"batch_id": 3001,
"conversation_id": 1001,
"node_code": "field_extract",
"node_group": "form_fill",
"status": "running",
"progress": 55,
"message": "正在并行抽取模板字段",
"payload": {
"selected_templates": ["registration_certificate", "essential_principles"],
"processed_files": 8,
"total_files": 20
}
}
```
### 15.2 节点进度
| 节点 | 进度口径 |
| --- | --- |
| 准备资料 | 是否找到来源批次 |
| 选择模板 | 模板数量 |
| 复制模板 | 已复制模板数/总模板数 |
| 抽取字段 | 已处理文件数/总文件数 |
| 冲突归并 | 字段数量和冲突数量 |
| 填写 Word | 已生成 Word 数/目标 Word 数 |
| 转换 PDF | 已生成 PDF 数/目标 PDF 数 |
| 输出下载 | 已创建下载记录数 |
| 飞书通知 | 通知状态 |
---
## 十六、异常与降级设计
| 场景 | 处理 |
| --- | --- |
| 无成功文件汇总批次 | 进入 waiting_user提示上传资料 |
| 新附件汇总失败 | 填表工作流不启动或标记失败 |
| 用户指定不适用模板 | 允许生成,摘要提示需人工确认 |
| `.doc` 转换失败 | 该模板失败,其他模板继续 |
| 单字段缺失 | Word 留空,追溯清单记录未提取 |
| 规则和 LLM 冲突 | 按来源优先级合并,冲突高亮 |
| 所有 Word 生成失败 | 批次 failed |
| 部分 Word 生成失败 | 批次 partial_success |
| PDF 转换失败 | 批次 partial_success保留 Word 下载 |
| 飞书通知失败 | 不影响文件下载,记录通知失败 |
---
## 十七、安全设计
| 设计点 | 说明 |
| --- | --- |
| 原始模板保护 | 只读原始模板,所有写入发生在批次工作目录副本 |
| 对话隔离 | 填表批次必须绑定当前 Conversation |
| 文件读取权限 | 只能读取关联 `FileSummaryBatch` 下的文件 |
| 下载权限 | 根据 workflow_type 和 workflow_batch_id 校验当前用户 |
| LLM 输入控制 | 只传必要文本片段和字段上下文,避免发送整包敏感资料 |
| 飞书脱敏 | 通知仅包含生成状态、模板名称、冲突数量和系统内下载提示 |
| 命令调用安全 | LibreOffice/飞书 CLI 使用结构化参数,不拼接用户输入 |
---
## 十八、验收设计
| 序号 | 验收项 | 验收标准 |
| --- | --- | --- |
| 1 | 意图触发 | 用户说“帮我填注册证”等语句可触发 `application_form_fill` |
| 2 | 指定模板 | 用户指定模板时只生成指定模板 |
| 3 | 默认模板 | 未指定模板时按注册类型生成适用的全部模板 |
| 4 | 新附件串联 | 本次消息带附件时先自动汇总,再执行填表 |
| 5 | 最近批次复用 | 无附件时复用当前对话最近成功文件汇总批次 |
| 6 | 工作流卡片 | 前端展示准备资料、选择模板、复制模板、抽取字段、填写 Word 等节点 |
| 7 | 字段并行抽取 | 规则/正则和 LLM 抽取结果均进入过程产物 |
| 8 | 冲突归并 | 说明书优先,冲突字段在 Word 中黄底红字 |
| 9 | 缺失字段 | 未提取字段在 Word 中留空 |
| 10 | 基本原则清单 | 高置信度条目写入,低置信度候选留在追溯清单 |
| 11 | Word 下载 | 对话框提供填好后的 Word 下载链接 |
| 12 | PDF 待办 | Demo 阶段 PDF 可展示为待生成,不阻断 Word |
| 13 | 追溯清单 | 生成字段来源追溯清单包含规则、LLM、合并和冲突信息 |
| 14 | 飞书通知 | 填表完成后可通知上传人,失败不影响下载 |
| 15 | 权限隔离 | A 对话生成的 Word/追溯清单不能被 B 对话访问 |
---
## 十九、实施建议
1. 新增 `ApplicationFormFillBatch``ApplicationFormFillArtifact` 数据模型,扩展 `ExportedSummaryFile.ExportType` 支持 `word``pdf`
2. 新增模板配置 `application_form_templates_v1.yaml`,先录入注册证格式 `.docx` 的已识别字段。
3. 将两个 `.doc` 模板转换为 `.docx` 工作模板,或在配置中标记为待转换模板。
4. 实现 `TemplateSelectionService`,支持用户指定模板、注册类型识别和默认模板选择。
5. 实现规则/正则与 LLM 并行字段抽取,并保存 `field_extract_result.json`
6. 实现 `FieldMergeService`,按说明书优先规则处理冲突。
7. 实现 `WordTemplateFillService`,优先支持表格行填充和冲突高亮。
8. 实现追溯清单 Excel 导出和 Word 下载记录。
9. 改造前端工作流卡片,新增 `application_form_fill` 类型。
10. 接入飞书通知摘要。
11. 将 PDF 转换、逐页版式 QA 和更完整的 `.doc` 模板转换纳入后续待办。
---
## 二十、待办与待确认事项
| 序号 | 项目 | 当前建议 |
| --- | --- | --- |
| 1 | PDF 转换 | 放入待办Demo 优先 Word 下载 |
| 2 | `.doc` 模板转换 | 优先 LibreOffice/soffice不可用时预置 `.docx` 工作模板 |
| 3 | 安全和性能基本原则清单条目拆解 | 需转换模板后补齐 YAML 条目配置 |
| 4 | LLM 结构化抽取提示词 | 需约束输出 JSON schema 和置信度 |
| 5 | 飞书通知渠道 | Demo 可 mock 或 CLI正式版接 Webhook/API |
| 6 | 低置信度阈值 | 建议功能实现阶段先配置为 0.75 |
| 7 | 版式验证 | P1 增加 PDF 页数检查和逐页截图 QA |