312 lines
15 KiB
Markdown
312 lines
15 KiB
Markdown
# 架构搭建思路汇报稿(基于 Demo 版)
|
||
|
||
## 一、设计路径:先锁规格,再实现代码
|
||
|
||
各位老师好,我本次 Demo 搭建的是一个面向体外诊断试剂注册资料准备与审核的智能体原型。
|
||
|
||
这次开发没有直接从代码开始,而是采用“文档先行、规格锁定、再实现代码”的路径。原因是注册资料审核不是一个简单问答场景,它涉及文件解析、法规规则、RAG 依据、工作流状态、导出文件、人工确认和整改闭环。如果一开始就写代码,很容易出现功能能跑但边界不清、结果不可追溯、后续难维护的问题。
|
||
|
||
所以整体设计路径分为四步:
|
||
|
||
```text
|
||
需求拆解
|
||
-> 生成需求分析、功能设计、详细设计、数据库设计和开发计划
|
||
-> 用文档锁定实现规格
|
||
-> 按规格实现 Django 代码、工作流、前端页面和测试
|
||
```
|
||
|
||
当前仓库中可以看到完整的规格文档链路:
|
||
|
||
| 阶段 | 产物 | 作用 |
|
||
| --- | --- | --- |
|
||
| 需求分析 | `docs/1.需求分析` | 明确业务目标、用户动作、输入输出和异常场景 |
|
||
| 功能设计 | `docs/2.功能设计` | 把需求拆成文件汇总、法规核查、自动填表、飞书通知等模块 |
|
||
| 详细设计 | `docs/3.详细设计` | 锁定工作流节点、字段结构、状态流转和服务边界 |
|
||
| 数据库设计 | `docs/4.数据库设计` | 锁定批次、附件、节点、风险项、导出文件等模型 |
|
||
| 开发计划 | `docs/5.开发计划` | 将实现拆成可验证的开发任务和前端线框图 |
|
||
|
||
因此,这个 Demo 的核心不是“让大模型临时回答一个问题”,而是先用文档定义清楚系统应该如何工作,再把这些规格落实到代码、数据库、前端和测试中。最终形成的是一个可追溯、可复核、可继续扩展的审核工作台。
|
||
|
||
## 二、系统定位和 Demo 目标
|
||
|
||
这个 Demo 的目标不是简单做文件上传、文件解析或法规问答,而是把注册资料审核中几个高频、耗时、容易出错的环节串成一个智能工作流,包括:
|
||
|
||
```text
|
||
资料上传
|
||
-> 文件目录和页数汇总
|
||
-> NMPA 法规完整性核查
|
||
-> 法规依据 RAG 检索
|
||
-> 产品关键信息抽取
|
||
-> 一致性核查和风险预警
|
||
-> 申报文件自动填表
|
||
-> 报告导出和整改复核
|
||
```
|
||
|
||
从产品形态上看,它更像是一个“注册资料审核工作台”。用户上传一批申报资料后,系统先把资料包结构化,再按法规规则做核查,然后输出风险清单、整改建议、证据来源和导出文件。后续还可以继续复用抽取到的产品信息,自动填入申报模板。
|
||
|
||
## 三、技术栈和总体架构
|
||
|
||
本 Demo 采用轻量、可本地运行、便于测试和可解释的技术栈。
|
||
|
||
| 层级 | 技术/工具 | 作用 |
|
||
| --- | --- | --- |
|
||
| Web 框架 | Django | 路由、视图、模板、认证、ORM 和后台能力 |
|
||
| 数据库 | SQLite / Django ORM | Demo 阶段保存会话、附件、批次、节点、风险项和导出文件 |
|
||
| 前端 | Django Template + 原生 JS + CSS | 实现首页工作台、审核智能体、知识库管理、附件管理和流式对话 |
|
||
| 文件解析 | `pypdf`、`python-docx`、`python-pptx`、`openpyxl`、`xlrd`、`py7zr`、`zipfile` | 解析 PDF、Word、PPT、Excel、压缩包和旧 Office 文件 |
|
||
| 规则配置 | YAML | 维护 NMPA 体外诊断试剂注册资料核查规则 |
|
||
| RAG | ChromaDB + embedding provider | 构建法规材料向量索引,检索法规依据片段 |
|
||
| LLM | SiliconFlow / 可配置大模型接口 | 做意图路由、低置信度抽取、自然语言总结和辅助复核 |
|
||
| 流式交互 | SSE | 将工作流启动、节点进度和模型回复实时推给前端 |
|
||
| 自动化验证 | pytest + Django test client | 验证路由、页面、模型、工作流和导出结果 |
|
||
|
||
整体架构可以概括为:
|
||
|
||
```text
|
||
用户界面
|
||
-> Django 视图层
|
||
-> 对话服务和 Skill 路由器
|
||
-> 文件汇总 / 法规核查 / 自动填表工作流
|
||
-> ORM 状态记录和导出文件
|
||
-> RAG/LLM/规则服务
|
||
-> 前端工作流卡片和报告下载
|
||
```
|
||
|
||
这里的关键设计原则是:规则判断要稳定,RAG 负责补证据,LLM 做辅助,不把高风险合规结论完全交给大模型自由发挥。
|
||
|
||
## 四、对话流程:先识别意图,再决定 RAG 或工作流
|
||
|
||
审核智能体页面不是单纯把用户输入直接发给大模型,而是有一层对话编排流程。
|
||
|
||
一次用户消息进入系统后,大致会经历以下步骤:
|
||
|
||
```text
|
||
用户输入
|
||
-> 保存用户消息
|
||
-> Skill Router 判断意图
|
||
-> 根据意图选择普通问答、附件读取或工作流
|
||
-> 必要时先检查附件和前置批次
|
||
-> 启动对应工作流或执行 RAG 问答
|
||
-> 保存助手回复和工作流事件
|
||
-> 前端通过 SSE 展示增量内容和节点状态
|
||
```
|
||
|
||
当前路由动作包括:
|
||
|
||
| action | 场景 | 后续动作 |
|
||
| --- | --- | --- |
|
||
| `normal_chat` | 普通法规问答或项目问答 | 先检索知识库,再把 RAG 片段放入大模型上下文 |
|
||
| `attachment_reader` | 用户要求阅读、提取、总结上传附件 | 调用附件读取 Skill,返回文件内容摘要 |
|
||
| `file_summary` | 用户要求汇总文件目录、页数、清单 | 启动文件汇总工作流 |
|
||
| `regulatory_review` | 用户要求法规核查、完整性核查、风险预警、整改建议 | 必要时先生成文件汇总批次,再启动法规核查工作流 |
|
||
| `application_form_fill` | 用户要求申报文件填表、模板填充、安全和性能清单 | 必要时先生成文件汇总批次,再启动自动填表工作流 |
|
||
|
||
也就是说,普通问题是“先 RAG,再回答”;工作流问题是“先路由,再检查前置条件,再启动工作流”。例如用户问“注册检验报告要求是什么”,系统会走 RAG 问答;用户说“请对当前资料做法规核查”,系统会进入法规核查工作流。
|
||
|
||
## 五、Skill 调用方式:路由器统一调度工具能力
|
||
|
||
Demo 中的 Skill 不是一个单独页面,而是对话服务后面的工具调用机制。用户不需要手动选择复杂功能,系统会根据用户话语和当前附件状态判断是否调用某个 Skill 或工作流。
|
||
|
||
当前实现中,`review_agent/skill_router.py` 负责意图路由。它采用两层判断:
|
||
|
||
```text
|
||
确定性规则预判
|
||
-> LLM 路由判断
|
||
-> 规则兜底
|
||
```
|
||
|
||
第一层是确定性规则。例如用户输入中包含“法规核查”“NMPA 核查”“风险预警”“自动填表”“申报模板”等明确关键词,系统可以直接判断要启动对应工作流。这样可以避免每次都依赖大模型判断。
|
||
|
||
第二层是 LLM 路由。系统会把用户消息和当前 active 附件列表发给路由模型,让模型只输出结构化 JSON:
|
||
|
||
```json
|
||
{
|
||
"action": "regulatory_review",
|
||
"confidence": 0.9,
|
||
"reason": "用户要求对当前注册资料进行法规完整性核查"
|
||
}
|
||
```
|
||
|
||
第三层是规则兜底。如果 LLM 不可用、配置缺失或返回异常,系统会退回关键词和附件状态判断,保证 Demo 在本地环境也能稳定运行。
|
||
|
||
这个设计的好处是:用户体验上像是在和一个智能体对话,技术实现上则是由路由器把对话分发到不同工具、不同工作流和不同数据服务。
|
||
|
||
## 六、RAG 方式:法规依据和用户知识库共同参与
|
||
|
||
RAG 在 Demo 中有两类来源:
|
||
|
||
| 来源 | 说明 |
|
||
| --- | --- |
|
||
| 内置法规材料 | 来自 `docs/0.原始材料` 和 NMPA 相关法规文件,用于法规依据检索 |
|
||
| 用户管理知识库 | 由用户在“知识库管理”页面上传,可作为当前账号所有对话的补充知识 |
|
||
|
||
法规材料会被切分为文本块,写入 ChromaDB 向量库。每个 chunk 保留来源文件、chunk 编号、文本片段和元数据。embedding 支持真实语义 embedding,也支持 deterministic/local embedding,后者主要用于测试和 dry run。
|
||
|
||
RAG 在系统中的定位有两种:
|
||
|
||
### 1. 普通问答中的 RAG
|
||
|
||
如果用户提出普通问题,系统会先检索知识库,把命中的法规片段或用户知识库片段拼入上下文,再调用大模型回答。这样回答不会只依赖模型记忆,而是带有本地法规材料和用户资料依据。
|
||
|
||
```text
|
||
用户问题
|
||
-> 知识库检索
|
||
-> 过滤和排序相关片段
|
||
-> 组装为知识上下文
|
||
-> 调用 LLM 生成回答
|
||
```
|
||
|
||
### 2. 工作流中的 RAG
|
||
|
||
在法规核查工作流里,RAG 不直接决定是否合规,而是为规则判断补充法规依据。例如结构化规则已经判断“缺少注册检验报告”,RAG 再检索相关法规要求,给出来源文件和依据片段。
|
||
|
||
这种方式避免了“让大模型自由判断合规”的不稳定性,同时让报告具备可解释依据。
|
||
|
||
## 七、三条核心工作流
|
||
|
||
当前 Demo 拆成三条主链路:文件汇总、法规核查、自动填表。
|
||
|
||
### 1. 文件汇总链路
|
||
|
||
对应模块:`review_agent/file_summary`
|
||
|
||
```text
|
||
文件上传
|
||
-> 附件固化
|
||
-> 压缩包解压
|
||
-> 文件扫描
|
||
-> 页数统计
|
||
-> 产品名识别
|
||
-> Markdown/Excel 报告输出
|
||
```
|
||
|
||
这个链路负责把原始资料包转换成结构化文件清单。系统会生成 `FileSummaryBatch` 和 `FileSummaryItem`,后续法规核查和自动填表都复用这套文件清单,不再重复扫描资料。
|
||
|
||
输出字段包括序号、目录层级、文件名、文件类型、页数、相对路径、统计状态、重试次数和异常说明。
|
||
|
||
### 2. 法规核查链路
|
||
|
||
对应模块:`review_agent/regulatory_review`
|
||
|
||
```text
|
||
准备资料
|
||
-> 适用条件确认
|
||
-> 规则范围裁剪
|
||
-> 完整性核查
|
||
-> 文本抽取
|
||
-> 章节核查
|
||
-> 一致性核查
|
||
-> RAG 法规依据补充
|
||
-> 风险评估
|
||
-> 报告输出
|
||
-> 整改复核
|
||
```
|
||
|
||
这条链路使用 `review_agent/regulatory_review/rules/nmpa_ivd_registration_v1.yaml` 作为结构化规则文件。规则中配置了附件 4 的资料要求,包括监管信息、综述资料、非临床资料、临床评价资料、说明书和标签样稿、质量管理体系文件等。
|
||
|
||
系统会检查是否缺少关键资料,例如注册申请表、符合性声明、产品技术要求、注册检验报告、说明书、标签样稿、临床评价资料和质量管理体系文件。缺失项会转成 `RegulatoryIssue`,并按阻断项、高风险、中风险、低风险和提示项分级。
|
||
|
||
### 3. 自动填表链路
|
||
|
||
对应模块:`review_agent/application_form_fill`
|
||
|
||
```text
|
||
准备资料
|
||
-> 模板选择
|
||
-> 模板复制
|
||
-> 字段抽取
|
||
-> 冲突归并
|
||
-> Word 填写
|
||
-> 追溯清单导出
|
||
-> 结果通知
|
||
```
|
||
|
||
这条链路会复用前面抽取到的产品信息,自动选择申报模板,并将字段填入 Word 模板。对于冲突字段,Demo 中采用明确的归并策略,同时在结果中保留冲突摘要和来源追溯。
|
||
|
||
## 八、页面和数据工作台
|
||
|
||
前端目前包括四个主要页面:
|
||
|
||
| 页面 | URL | 作用 |
|
||
| --- | --- | --- |
|
||
| 首页工作台 | `/` | 展示对话、附件、知识库、批次状态和最近处理记录 |
|
||
| 审核智能体 | `/chat/` | 对话、上传附件、启动工作流、查看节点进度 |
|
||
| 知识库管理 | `/knowledge-base/` | 管理用户上传知识库、查看内置法规材料和索引状态 |
|
||
| 附件管理 | `/attachments/` | 管理不同对话下的上传附件、版本、启用状态和下载 |
|
||
|
||
首页工作台重点不是营销展示,而是运行态数据,包括:
|
||
|
||
```text
|
||
对话总数
|
||
附件总数
|
||
知识库材料数
|
||
执行中批次
|
||
已处理批次
|
||
成功批次
|
||
等待确认批次
|
||
失败批次
|
||
最近处理记录
|
||
```
|
||
|
||
知识库材料中同时统计用户管理文档和内置法规材料,避免把“知识库”误解成只包含用户上传文件。
|
||
|
||
## 九、过程留痕和可追溯设计
|
||
|
||
审核类系统不能只输出一个结论,还必须说明结论从哪里来。因此 Demo 对关键过程都做了结构化留痕。
|
||
|
||
| 过程 | 留痕内容 |
|
||
| --- | --- |
|
||
| 对话 | 用户消息、助手消息、会话标题、更新时间 |
|
||
| 附件 | 原始文件名、版本号、启用状态、存储路径、文件大小 |
|
||
| 文件汇总 | 批次号、文件明细、页数、统计状态、异常说明 |
|
||
| 工作流节点 | 节点编码、节点名称、进度、状态、错误信息 |
|
||
| 法规核查 | 规则编码、缺失项、风险等级、证据、整改建议 |
|
||
| RAG 检索 | 来源文件、片段文本、相似度、chunk 元数据 |
|
||
| 自动填表 | 字段来源、冲突摘要、模板选择、追溯清单 |
|
||
| 导出文件 | Markdown、Excel、JSON、Word 等结果文件 |
|
||
|
||
这保证了 Demo 输出的结果不是一次性回答,而是可以复核、下载、整改和继续追踪的过程资产。
|
||
|
||
## 十、Demo 可展示结果
|
||
|
||
本次 Demo 可以展示以下核心结果:
|
||
|
||
### 1. 文件目录汇总表
|
||
|
||
用户上传注册资料文件夹、散装文件或压缩包后,系统自动完成附件固化、解压、扫描和页数统计,最终生成 Markdown 汇总报告和 Excel 明细表。
|
||
|
||
### 2. 法规完整性报告
|
||
|
||
系统基于文件汇总结果和 NMPA 规则库做完整性核查,输出 Markdown 法规核查报告、Excel 问题清单和 JSON 结构化结果包。
|
||
|
||
### 3. 产品关键信息提取对照表
|
||
|
||
系统从说明书、产品技术要求、注册检验报告、申请表等文件中抽取产品名称、型号规格、预期用途、管理类别、分类编码、注册类型和临床评价路径,并保留来源文件和证据片段。
|
||
|
||
### 4. 风险预警列表
|
||
|
||
系统把完整性缺失、章节异常、字段冲突、文本抽取失败、页数不可确定、通知失败等问题统一沉淀为风险项,并按阻断项、高风险、中风险、低风险和提示项分级。
|
||
|
||
### 5. 申报文件自动填表结果
|
||
|
||
系统根据资料内容和适用条件选择模板,自动填充 Word 文件,并导出字段追溯清单,说明每个字段来自哪个文件、哪个证据片段。
|
||
|
||
## 十一、总结
|
||
|
||
整体来看,本 Demo 的架构搭建思路可以概括为:
|
||
|
||
```text
|
||
先用文档锁定规格
|
||
再用规则结构化审核逻辑
|
||
再用 RAG 补充法规依据
|
||
再用 Skill Router 调度工具和工作流
|
||
再用 ORM 和导出文件沉淀过程资产
|
||
最后通过工作台页面呈现状态和结果
|
||
```
|
||
|
||
它体现的是一个“资料输入、规则判断、证据追溯、风险输出、整改闭环”的智能体原型。
|
||
|
||
当前 Demo 已经完成了首页工作台、审核智能体对话、附件管理、知识库管理、文件汇总、法规核查、RAG 依据检索、风险预警、报告导出和自动填表主链路。后续如果继续增强,可以重点补充 OCR、扫描件识别、复杂 PDF 版式解析、规则后台维护、人工确认界面、飞书真实消息闭环,以及更完整的多智能体编排能力。
|
||
|
||
最终希望这个智能体能够从一个 Demo 原型,逐步演进为注册资料准备和审核过程中的智能协作平台。
|