667 lines
21 KiB
Markdown
667 lines
21 KiB
Markdown
# NMPA 注册资料法规核查与整改闭环工作流详细设计
|
||
|
||
## 文档信息
|
||
|
||
| 项目 | 内容 |
|
||
| --- | --- |
|
||
| 需求分析文档 | docs/1.需求分析/2.NMPA注册资料法规核查与整改闭环.md |
|
||
| 功能设计文档 | docs/2.功能设计/2.NMPA注册资料法规核查与整改闭环.md |
|
||
| 数据库设计文档 | docs/4.数据库设计/2.NMPA注册资料法规核查与整改闭环.md |
|
||
| 依赖详细设计 | docs/3.详细设计/1.自动汇总.md |
|
||
| 功能名称 | NMPA 注册资料法规核查与整改闭环 |
|
||
| 所属模块 | 审核智能体 review_agent |
|
||
| 设计日期 | 2026-06-06 |
|
||
| 设计版本 | V1.0 |
|
||
|
||
---
|
||
|
||
## 一、详细设计目标
|
||
|
||
本详细设计用于指导“NMPA 注册资料法规核查与整改闭环”功能开发落地,覆盖代码结构、通用工作流改造、法规核查执行器、规则/RAG/LLM 调用边界、服务拆分、接口契约、前端交互、飞书 CLI 通知、过程产物留底、异常重试和测试建议。
|
||
|
||
核心约束:
|
||
|
||
| 约束 | 说明 |
|
||
| --- | --- |
|
||
| 复用自动汇总 | 不重复实现上传、解压、扫描和页数统计,法规核查基于 `FileSummaryBatch` 执行 |
|
||
| 独立工作流 | 法规核查有独立 `RegulatoryReviewBatch` 和卡片,事件机制与文件汇总共用 |
|
||
| 通用事件模型 | `WorkflowNodeRun`、`WorkflowEvent`、`ExportedSummaryFile` 增加 workflow_type 和 workflow_batch_id |
|
||
| 异步执行 | 启动接口立即返回 batch_id,后台执行并通过 SSE 更新卡片 |
|
||
| 暂停恢复 | 遇到 waiting_user 时后台任务结束,用户确认后重新唤起执行器继续 |
|
||
| 规则优先 | 结构化规则负责合规判断,RAG 只补充依据,LLM 只用于低置信度字段抽取和建议润色 |
|
||
| 过程留底 | 文本抽取、RAG 结果、LLM 输出、通知和复核记录均生成过程产物 |
|
||
|
||
---
|
||
|
||
## 二、代码结构设计
|
||
|
||
### 2.1 目录结构
|
||
|
||
在 `review_agent` 应用内新增 `regulatory_review/` 模块。法规核查与文件汇总并列,通过共享工作流事件和导出服务协同。`review_agent/workflow/` 是对模块 1 中 `file_summary/events.py`、节点状态和导出记录能力的通用化抽取,不是为法规核查重建一套并行事件体系。
|
||
|
||
```text
|
||
review_agent/
|
||
models.py
|
||
urls.py
|
||
views.py
|
||
file_summary/
|
||
...
|
||
workflow/
|
||
__init__.py
|
||
constants.py
|
||
events.py
|
||
node_runs.py
|
||
exports.py
|
||
regulatory_review/
|
||
__init__.py
|
||
constants.py
|
||
schemas.py
|
||
urls.py
|
||
views.py
|
||
workflow.py
|
||
storage.py
|
||
services/
|
||
__init__.py
|
||
rule_loader.py
|
||
rag_citation.py
|
||
info_extract.py
|
||
text_extract.py
|
||
completeness_check.py
|
||
structure_check.py
|
||
consistency_check.py
|
||
risk_assess.py
|
||
export.py
|
||
feishu_notifier.py
|
||
rectification_review.py
|
||
condition_parser.py
|
||
rules/
|
||
nmpa_ivd_registration_v1.yaml
|
||
prompts/
|
||
condition_parse.md
|
||
field_extract.md
|
||
suggestion_polish.md
|
||
```
|
||
|
||
### 2.2 文件职责
|
||
|
||
| 文件 | 职责 |
|
||
| --- | --- |
|
||
| workflow/constants.py | 通用 workflow_type、节点状态、事件类型 |
|
||
| workflow/events.py | 通用 SSE 事件持久化和格式化 |
|
||
| workflow/node_runs.py | 通用节点状态创建、更新和恢复 |
|
||
| workflow/exports.py | 通用导出记录和下载权限校验 |
|
||
| regulatory_review/constants.py | 法规核查节点、风险等级、问题状态常量 |
|
||
| regulatory_review/schemas.py | RegulatoryContext、NodeResult、Finding 等 dataclass |
|
||
| regulatory_review/workflow.py | RegulatoryWorkflowExecutor,负责编排节点和暂停恢复 |
|
||
| regulatory_review/storage.py | 法规核查过程产物路径、hash、文件保存 |
|
||
| services/rule_loader.py | 加载规则版本、校验 hash、裁剪适用规则 |
|
||
| services/rag_citation.py | 基于 findings 批量检索法规依据 |
|
||
| services/info_extract.py | 从文件清单和文本片段抽取适用条件候选值 |
|
||
| services/condition_parser.py | 将用户自然语言确认解析为结构化字段 |
|
||
| services/text_extract.py | 统一抽取关键文件文本并缓存为 JSON 产物 |
|
||
| services/completeness_check.py | 完整性核查,生成 findings |
|
||
| services/structure_check.py | 章节结构核查,生成 findings |
|
||
| services/consistency_check.py | 跨文件一致性核查,生成 findings |
|
||
| services/risk_assess.py | 去重、风险分级、RAG 依据引用、写入 RegulatoryIssue |
|
||
| services/export.py | 生成最终报告和过程产物,支持重试 |
|
||
| services/feishu_notifier.py | 通过飞书 CLI 发送通知,支持 3 次重试 |
|
||
| services/rectification_review.py | 补充资料后的问题复核和状态更新 |
|
||
|
||
---
|
||
|
||
## 三、通用工作流改造
|
||
|
||
### 3.1 WorkflowNodeRun 改造
|
||
|
||
现有节点状态表需要兼容多类工作流。
|
||
|
||
| 字段 | 处理 |
|
||
| --- | --- |
|
||
| batch_id | 保留,兼容文件汇总旧逻辑 |
|
||
| workflow_type | 新增,file_summary、regulatory_review |
|
||
| workflow_batch_id | 新增,保存对应工作流批次 ID |
|
||
| node_group | 新增,可选,用于法规核查卡片主节点聚合 |
|
||
|
||
唯一约束调整为:
|
||
|
||
```text
|
||
unique(workflow_type, workflow_batch_id, node_code)
|
||
```
|
||
|
||
文件汇总旧逻辑写入时同步设置:
|
||
|
||
```text
|
||
workflow_type = file_summary
|
||
workflow_batch_id = file_summary_batch.id
|
||
batch_id = file_summary_batch.id
|
||
```
|
||
|
||
### 3.2 WorkflowEvent 改造
|
||
|
||
事件表同样新增:
|
||
|
||
| 字段 | 说明 |
|
||
| --- | --- |
|
||
| workflow_type | file_summary、regulatory_review |
|
||
| workflow_batch_id | 对应工作流批次 ID |
|
||
| conversation_id | 冗余记录对话 ID,便于 SSE 查询 |
|
||
|
||
SSE 查询时按 `conversation_id` 获取多个工作流事件,前端根据 `workflow_type + workflow_batch_id` 更新对应卡片。
|
||
|
||
### 3.3 ExportedSummaryFile 改造
|
||
|
||
最终下载文件表通用化:
|
||
|
||
| 字段 | 说明 |
|
||
| --- | --- |
|
||
| workflow_type | file_summary、regulatory_review |
|
||
| workflow_batch_id | 对应工作流批次 ID |
|
||
| export_category | summary_report、risk_report、excel_list、json_package |
|
||
|
||
法规核查最终 Markdown、Excel、JSON 结果包进入 `ExportedSummaryFile`;过程产物进入 `RegulatoryArtifact`。
|
||
|
||
---
|
||
|
||
## 四、核心数据结构
|
||
|
||
### 4.1 RegulatoryContext
|
||
|
||
节点间传递统一上下文,避免每个服务重复组装状态。
|
||
|
||
```python
|
||
@dataclass
|
||
class RegulatoryContext:
|
||
regulatory_batch: RegulatoryReviewBatch
|
||
file_summary_batch: FileSummaryBatch | None
|
||
rule_version: RegulatoryRuleVersion | None
|
||
rules: dict[str, Any]
|
||
scoped_rules: list[dict[str, Any]]
|
||
conditions: dict[str, Any]
|
||
file_items: list[FileSummaryItem]
|
||
text_artifacts: dict[str, Any]
|
||
findings: list["Finding"]
|
||
issues: list[RegulatoryIssue]
|
||
artifacts: list[RegulatoryArtifact]
|
||
reference_only: bool = False
|
||
```
|
||
|
||
### 4.2 NodeResult
|
||
|
||
每个节点统一返回 `NodeResult`。
|
||
|
||
```python
|
||
@dataclass
|
||
class NodeResult:
|
||
status: str
|
||
message: str = ""
|
||
payload: dict[str, Any] = field(default_factory=dict)
|
||
findings: list["Finding"] = field(default_factory=list)
|
||
artifacts: list[RegulatoryArtifact] = field(default_factory=list)
|
||
next_node: str | None = None
|
||
```
|
||
|
||
### 4.3 Finding
|
||
|
||
核查服务只返回 findings,不直接写 `RegulatoryIssue`。Issue 由 `RiskAssessService` 统一去重、分级和落库。
|
||
|
||
```python
|
||
@dataclass
|
||
class Finding:
|
||
finding_key: str
|
||
issue_type: str
|
||
initial_risk_level: str
|
||
title: str
|
||
description: str
|
||
rule_id: str | None = None
|
||
file_item_id: int | None = None
|
||
file_path: str | None = None
|
||
page_no: int | None = None
|
||
field_name: str | None = None
|
||
evidence: dict[str, Any] = field(default_factory=dict)
|
||
suggestion_template: str | None = None
|
||
source_node: str | None = None
|
||
```
|
||
|
||
---
|
||
|
||
## 五、工作流执行设计
|
||
|
||
### 5.1 启动流程
|
||
|
||
```text
|
||
POST /regulatory-review/start/
|
||
-> 创建 RegulatoryReviewBatch(status=pending)
|
||
-> 查找当前对话最近一次 success FileSummaryBatch
|
||
-> 如有则绑定并异步启动法规核查
|
||
-> 如无则创建 FileSummaryBatch 并启动自动汇总
|
||
-> 自动汇总 success 后回填 file_summary_batch_id
|
||
-> 继续法规核查 prepare 节点
|
||
```
|
||
|
||
如果用户明确说“重新核查最新上传资料”,系统强制创建新的 `FileSummaryBatch`,再创建新的 `RegulatoryReviewBatch`。
|
||
|
||
### 5.2 暂停与恢复
|
||
|
||
当适用条件缺失或解析冲突时:
|
||
|
||
```text
|
||
RegulatoryWorkflowExecutor
|
||
-> 写入 condition_confirm 节点 status=waiting_user
|
||
-> RegulatoryReviewBatch.status=waiting_user
|
||
-> 发送 workflow SSE
|
||
-> 后台任务结束
|
||
```
|
||
|
||
用户确认后:
|
||
|
||
```text
|
||
POST /regulatory-review/{batch_id}/confirm-condition/
|
||
-> LLM 解析自然语言为结构化 JSON
|
||
-> 字段校验器校验必填字段
|
||
-> 如仍缺失,继续追问并保持 waiting_user
|
||
-> 如完整,写入 batch 核心字段和 condition_json
|
||
-> 重新唤起 RegulatoryWorkflowExecutor,从 rule_scope 节点继续
|
||
```
|
||
|
||
### 5.3 节点调度
|
||
|
||
```text
|
||
prepare
|
||
-> info_extract
|
||
-> condition_confirm 或 rule_scope
|
||
-> rule_scope
|
||
-> completeness_check
|
||
-> text_extract
|
||
-> 并行执行 structure_check 和 consistency_check
|
||
-> risk_assess
|
||
-> report_export
|
||
-> notify
|
||
-> completed
|
||
```
|
||
|
||
章节核查和一致性核查通过后台线程池并行:
|
||
|
||
```python
|
||
with ThreadPoolExecutor(max_workers=2) as pool:
|
||
structure_future = pool.submit(structure_service.run, context)
|
||
consistency_future = pool.submit(consistency_service.run, context)
|
||
```
|
||
|
||
### 5.4 关键节点
|
||
|
||
关键节点失败时终止批次:
|
||
|
||
| 节点 | 失败处理 |
|
||
| --- | --- |
|
||
| prepare | 无法绑定文件汇总批次,批次 failed |
|
||
| rule_scope | 规则 hash 不一致,批次 failed;规则加载失败可降级 reference_only |
|
||
| report_export | 最终报告重试失败,批次 failed |
|
||
|
||
非关键节点失败时生成 `Finding` 或 `RegulatoryIssue`,工作流尽量继续:
|
||
|
||
| 节点 | 失败处理 |
|
||
| --- | --- |
|
||
| text_extract | 对相关文件生成待确认 finding |
|
||
| structure_check | 生成章节核查失败 finding |
|
||
| consistency_check | 生成一致性待确认 finding |
|
||
| notify | 写通知失败记录,批次可 partial_success |
|
||
|
||
---
|
||
|
||
## 六、规则、RAG 与 LLM 设计
|
||
|
||
### 6.1 RuleLoader
|
||
|
||
流程:
|
||
|
||
```text
|
||
读取当前 active RegulatoryRuleVersion
|
||
-> 读取 rule_file_path
|
||
-> 计算文件 hash
|
||
-> 与 rule_file_hash 比对
|
||
-> hash 一致则解析规则
|
||
-> 按适用条件裁剪 scoped_rules
|
||
```
|
||
|
||
处理策略:
|
||
|
||
| 场景 | 处理 |
|
||
| --- | --- |
|
||
| 规则文件 hash 不一致 | 停止执行并标记 failed |
|
||
| 规则文件不存在或解析失败 | 降级 RAG 辅助核查,batch.status=reference_only |
|
||
| RAG 索引版本缺失 | 记录提示项,但规则核查可继续 |
|
||
|
||
### 6.2 RagCitationService
|
||
|
||
RAG 在 `RiskAssessService` 阶段批量调用,而不是每个核查节点实时调用。
|
||
|
||
输入:
|
||
|
||
| 字段 | 说明 |
|
||
| --- | --- |
|
||
| findings | 所有核查 findings |
|
||
| rule_version | 当前法规规则版本 |
|
||
| scoped_rules | 本次适用规则 |
|
||
|
||
输出:
|
||
|
||
| 字段 | 说明 |
|
||
| --- | --- |
|
||
| citations_by_finding | finding_key 到法规依据列表的映射 |
|
||
| rag_result_json | RAG 检索结果过程产物 |
|
||
|
||
### 6.3 LLM 调用边界
|
||
|
||
| 场景 | 是否调用 LLM | 说明 |
|
||
| --- | --- | --- |
|
||
| 自然语言适用条件解析 | 是 | 解析为结构化 JSON,再由字段校验器校验 |
|
||
| 低置信度字段抽取 | 是 | 规则/正则失败或置信度低时调用 |
|
||
| 整改建议润色 | 是 | 规则模板生成标准动作,LLM 润色表达 |
|
||
| 风险等级判断 | 否 | 风险等级由规则和 RiskAssess 决定 |
|
||
| 法规结论判断 | 否 | 合规判断不交给 LLM |
|
||
|
||
LLM 抽取结果需写入过程产物,可使用 `llm_extract_json` 或并入 `text_extract_json`。
|
||
|
||
---
|
||
|
||
## 七、服务详细设计
|
||
|
||
### 7.1 RegulatoryWorkflowExecutor
|
||
|
||
| 方法 | 说明 |
|
||
| --- | --- |
|
||
| start(batch_id) | 创建后台任务并返回 |
|
||
| run(batch_id, start_node=None) | 运行法规核查节点 |
|
||
| build_context(batch_id) | 组装 RegulatoryContext |
|
||
| run_node(node_code, context) | 执行单个节点并处理 NodeResult |
|
||
| run_parallel_checks(context) | 并行执行章节和一致性核查 |
|
||
| pause_for_user(batch, node_code, message) | 写 waiting_user 状态并结束任务 |
|
||
| complete(batch) | 标记批次完成 |
|
||
| fail(batch, error) | 标记批次失败 |
|
||
|
||
### 7.2 ConditionParserService
|
||
|
||
| 方法 | 说明 |
|
||
| --- | --- |
|
||
| parse(raw_user_input, previous_conditions) | 使用 LLM 解析自然语言 |
|
||
| validate(parsed_json) | 校验产品类别、注册类型、临床路径、产品名称、型号规格、预期用途 |
|
||
| merge(batch, parsed_json) | 写入批次字段和 condition_json |
|
||
|
||
### 7.3 RiskAssessService
|
||
|
||
| 方法 | 说明 |
|
||
| --- | --- |
|
||
| deduplicate(findings) | 按 finding_key、rule_id、file_item_id 去重 |
|
||
| attach_citations(findings) | 批量调用 RAG 获取法规依据 |
|
||
| resolve_risk(finding) | 统一风险等级,处理升级/降级 |
|
||
| generate_suggestion(finding) | 规则模板 + LLM 润色 |
|
||
| create_issues(batch, findings) | 统一写入 RegulatoryIssue |
|
||
| build_risk_summary(batch) | 写入 risk_summary_json |
|
||
|
||
### 7.4 RegulatoryExportService
|
||
|
||
| 方法 | 说明 |
|
||
| --- | --- |
|
||
| export_final_markdown(batch) | 生成最终 Markdown 核查报告 |
|
||
| export_final_excel(batch) | 生成 Excel 缺失清单 |
|
||
| export_json_package(batch) | 生成结构化 JSON 结果包 |
|
||
| create_artifact(batch, artifact_type, path) | 写 RegulatoryArtifact 并计算 hash |
|
||
| create_export_record(batch, path, category) | 写 ExportedSummaryFile |
|
||
| retry_export(fn, max_retry=3) | 导出失败重试 |
|
||
|
||
重试策略:
|
||
|
||
| 产物 | 重试后仍失败 |
|
||
| --- | --- |
|
||
| 最终 Markdown/Excel/JSON | 批次 failed |
|
||
| 非关键过程产物 | 批次 partial_success |
|
||
|
||
### 7.5 FeishuNotifier
|
||
|
||
调用方式必须使用参数数组,不拼接 shell 字符串。
|
||
|
||
```python
|
||
subprocess.run(
|
||
[cli_path, "send", "--user", feishu_user_id, "--message", message],
|
||
check=True,
|
||
capture_output=True,
|
||
text=True,
|
||
)
|
||
```
|
||
|
||
处理策略:
|
||
|
||
| 场景 | 处理 |
|
||
| --- | --- |
|
||
| 用户无 feishu_user_id | 写通知失败记录,不阻断 |
|
||
| CLI 执行失败 | 最多重试 3 次 |
|
||
| 仍失败 | send_status=failed,批次可 partial_success |
|
||
| 成功 | 写 external_message_id 和 sent_at |
|
||
|
||
通知内容包含系统内风险报告链接,不附原始文件。
|
||
|
||
---
|
||
|
||
## 八、接口详细设计
|
||
|
||
### 8.1 发起法规核查
|
||
|
||
| 项目 | 内容 |
|
||
| --- | --- |
|
||
| URL | POST /api/review-agent/regulatory-review/start/ |
|
||
| 请求 | conversation_id、file_summary_batch_id 可选、force_resummary 可选 |
|
||
| 响应 | regulatory_batch_id、workflow_type、status |
|
||
|
||
响应示例:
|
||
|
||
```json
|
||
{
|
||
"regulatory_batch_id": 2001,
|
||
"workflow_type": "regulatory_review",
|
||
"status": "pending"
|
||
}
|
||
```
|
||
|
||
### 8.2 确认适用条件
|
||
|
||
| 项目 | 内容 |
|
||
| --- | --- |
|
||
| URL | POST /api/review-agent/regulatory-review/{batch_id}/confirm-condition/ |
|
||
| 请求 | raw_user_input、可选结构化字段 |
|
||
| 响应 | status、missing_fields、next_question |
|
||
|
||
如果解析完整:
|
||
|
||
```json
|
||
{
|
||
"status": "accepted",
|
||
"next_node": "rule_scope"
|
||
}
|
||
```
|
||
|
||
如果仍缺失:
|
||
|
||
```json
|
||
{
|
||
"status": "need_more_info",
|
||
"missing_fields": ["clinical_evaluation_path"],
|
||
"next_question": "请确认临床评价路径:临床试验、免临床,还是同品种比对?"
|
||
}
|
||
```
|
||
|
||
### 8.3 查询状态
|
||
|
||
| 项目 | 内容 |
|
||
| --- | --- |
|
||
| URL | GET /api/review-agent/regulatory-review/{batch_id}/ |
|
||
| 响应 | 批次、节点、风险摘要、导出文件、过程产物 |
|
||
|
||
### 8.4 发起整改复核
|
||
|
||
| 项目 | 内容 |
|
||
| --- | --- |
|
||
| URL | POST /api/review-agent/regulatory-review/{batch_id}/rectify-review/ |
|
||
| 请求 | issue_ids、file_summary_batch_id 或 uploaded_file_ids |
|
||
| 响应 | review_status、updated_issues、review_artifact_id |
|
||
|
||
补充文件必须复用自动汇总上传与汇总能力。上传后先生成新的 `FileSummaryBatch`,再由 `RectificationReviewService` 对原批次问题执行复核。复核不创建新的 `RegulatoryReviewBatch`。
|
||
|
||
---
|
||
|
||
## 九、前端与对话交互
|
||
|
||
### 9.1 工作流卡片
|
||
|
||
| 设计点 | 说明 |
|
||
| --- | --- |
|
||
| 卡片切换 | 多工作流卡片使用轮播切换 |
|
||
| 卡片识别 | 使用 workflow_type + workflow_batch_id |
|
||
| 状态来源 | SSE workflow 事件 |
|
||
| 法规卡片 | 展示主节点和可展开子节点 |
|
||
| waiting_user | 卡片显示等待确认,对话框给出选择和追问 |
|
||
|
||
### 9.2 自然语言确认
|
||
|
||
对话框中用户可以用自然语言确认,例如:
|
||
|
||
```text
|
||
按体外诊断试剂首次注册处理,临床评价路径走同品种比对,产品名称是 XXX,型号规格是 YYY,预期用途是 ZZZ。
|
||
```
|
||
|
||
后端解析并校验后继续工作流。原始输入写入 `condition_json.raw_user_input`。
|
||
|
||
### 9.3 整改复核触发
|
||
|
||
Demo 阶段通过对话指令触发:
|
||
|
||
```text
|
||
我已补充注册检验报告,请复核阻断项。
|
||
```
|
||
|
||
系统识别后调用复核接口,要求用户上传补充文件或选择已上传文件。
|
||
|
||
---
|
||
|
||
## 十、过程产物与报告
|
||
|
||
### 10.1 文件命名
|
||
|
||
过程产物和最终报告采用固定模板:
|
||
|
||
```text
|
||
{batch_no}_{artifact_type}.{ext}
|
||
```
|
||
|
||
示例:
|
||
|
||
```text
|
||
RRB202606060001_rule_matrix.xlsx
|
||
RRB202606060001_risk_list.json
|
||
RRB202606060001_final_report.md
|
||
```
|
||
|
||
### 10.2 文件保存
|
||
|
||
路径:
|
||
|
||
```text
|
||
media/regulatory_review/{user_id}/{conversation_id}/{batch_id}/
|
||
```
|
||
|
||
所有 `RegulatoryArtifact` 必须计算 SHA-256 hash。
|
||
|
||
### 10.3 报告内容
|
||
|
||
最终 Markdown 报告包含:
|
||
|
||
| 模块 | 说明 |
|
||
| --- | --- |
|
||
| 核查概览 | 批次、规则版本、RAG 版本、上传人 |
|
||
| 适用条件 | 系统抽取和用户确认结果 |
|
||
| 风险清单 | 五级风险、状态、责任人、建议 |
|
||
| 法规核查矩阵 | 应有文件、实际文件、缺失情况 |
|
||
| 章节核查结果 | 缺失章节、异常章节 |
|
||
| 一致性核查结果 | 字段冲突和来源文件 |
|
||
| 飞书通知记录 | 发送对象、状态、失败原因 |
|
||
| 整改复核记录 | 复核方式、复核结果、关闭确认 |
|
||
|
||
---
|
||
|
||
## 十一、异常与重试
|
||
|
||
| 场景 | 处理 |
|
||
| --- | --- |
|
||
| 无成功 FileSummaryBatch | 自动启动文件汇总,成功后继续 |
|
||
| 文件汇总失败 | 法规核查批次 failed |
|
||
| 规则 hash 不一致 | 法规核查批次 failed |
|
||
| 规则加载失败 | 降级 reference_only,仅输出参考性结果 |
|
||
| 用户确认信息缺失 | waiting_user,追问缺失字段 |
|
||
| 文本抽取失败 | 生成待确认 finding,继续后续节点 |
|
||
| 章节或一致性节点失败 | 生成对应 issue,继续风险汇总 |
|
||
| RAG 检索无结果 | 规则问题仍输出,依据标记原文待补充 |
|
||
| LLM 调用失败 | 回退规则/正则结果,低置信度项待确认 |
|
||
| 飞书失败 | 重试 3 次,仍失败写通知失败记录 |
|
||
| 最终报告导出失败 | 重试 3 次,仍失败 batch failed |
|
||
| 非关键产物导出失败 | 重试 3 次,仍失败 batch partial_success |
|
||
|
||
---
|
||
|
||
## 十二、测试建议
|
||
|
||
### 12.1 单元测试
|
||
|
||
| 模块 | 测试点 |
|
||
| --- | --- |
|
||
| RuleLoader | hash 校验、规则解析、规则裁剪、加载失败降级 |
|
||
| ConditionParserService | 自然语言解析、缺失字段追问、原始输入留痕 |
|
||
| TextExtractService | 首页文本、章节文本、抽取失败产物 |
|
||
| CompletenessCheckService | 文件名/目录名/首页内容三层匹配 |
|
||
| StructureCheckService | 必需章节缺失识别 |
|
||
| ConsistencyCheckService | 字段冲突、低置信度 LLM 辅助 |
|
||
| RiskAssessService | findings 去重、风险升级/降级、Issue 落库 |
|
||
| RegulatoryExportService | 文件命名、hash、导出重试 |
|
||
| FeishuNotifier | 参数数组调用、3 次重试、失败记录 |
|
||
|
||
### 12.2 集成测试
|
||
|
||
| 场景 | 验证 |
|
||
| --- | --- |
|
||
| 已有汇总批次发起核查 | 默认复用最近 success 批次 |
|
||
| 无汇总批次发起核查 | 自动串联文件汇总后继续 |
|
||
| waiting_user 暂停恢复 | 用户确认后从 rule_scope 继续 |
|
||
| 章节和一致性并行 | 两个节点均完成后进入 risk_assess |
|
||
| 规则加载失败 | batch.status=reference_only |
|
||
| 飞书失败 | 不阻断报告,通知记录 failed |
|
||
| 补充文件复核 | 新 FileSummaryBatch 生成,原 Issue 状态更新 |
|
||
|
||
### 12.3 验收测试
|
||
|
||
| 序号 | 验收项 | 标准 |
|
||
| --- | --- | --- |
|
||
| 1 | 多工作流卡片 | 文件汇总和法规核查卡片可切换且状态独立 |
|
||
| 2 | 条件确认 | 用户自然语言确认后能结构化入库 |
|
||
| 3 | 完整性核查 | 能识别缺失注册检验报告等问题 |
|
||
| 4 | 章节核查 | 能识别关键章节缺失 |
|
||
| 5 | 一致性核查 | 能识别产品名称、型号规格、预期用途冲突 |
|
||
| 6 | 风险报告 | 输出 Markdown、Excel、JSON 结果包 |
|
||
| 7 | 飞书通知 | 阻断项、高风险、中风险能 @ 上传人 |
|
||
| 8 | 过程留底 | RAG、文本抽取、通知、复核均有 artifact |
|
||
| 9 | 整改复核 | 补充文件后原 Issue 可进入复核通过或复核不通过 |
|
||
|
||
---
|
||
|
||
## 十三、实施顺序建议
|
||
|
||
结合当前优先级,建议先打通 RAG 和 LLM 能力,再落完整工作流:
|
||
|
||
1. 构建本地法规材料 RAG 索引,并实现 `RagCitationService`。
|
||
2. 实现适用条件解析和低置信度字段抽取的 LLM 调用封装。
|
||
3. 完成数据库模型和通用 workflow/export 表改造。
|
||
4. 实现 `RuleLoader` 与规则 hash 校验。
|
||
5. 实现 `RegulatoryWorkflowExecutor`、`RegulatoryContext`、`NodeResult`。
|
||
6. 实现完整性、文本抽取、章节核查、一致性核查和风险归并。
|
||
7. 实现报告导出、过程产物 hash 和导出重试。
|
||
8. 接入飞书 CLI 通知和 3 次重试。
|
||
9. 改造前端多工作流卡片和适用条件确认交互。
|
||
10. 实现整改复核和 Issue 状态流转。
|