Compare commits
30 Commits
master
...
7836690303
| Author | SHA1 | Date | |
|---|---|---|---|
| 7836690303 | |||
| aa5d4d77f8 | |||
| 12a92ad278 | |||
| 134e0fb5ff | |||
| f53d5a1902 | |||
| c303a2fcc6 | |||
| e75f0a0356 | |||
| 3da774e537 | |||
| 54fc1baa4c | |||
| 5a137b5b45 | |||
| 08251ae5e6 | |||
| cace6cb941 | |||
| 78b841131b | |||
| 7a60af0485 | |||
| cc200a32c4 | |||
| 2876a1b028 | |||
| 0e49eea683 | |||
| 4208f29d77 | |||
| 759939b446 | |||
| 18428e75fd | |||
|
|
11c20593d5 | ||
|
|
56a332a7dd | ||
|
|
5125f79037 | ||
|
|
d670c51d43 | ||
|
|
4017151218 | ||
| b2c1da3f02 | |||
| 77166b5cd3 | |||
| dc4c605723 | |||
| 59d522be0c | |||
| e64dca551c |
24
AGENTS.md
24
AGENTS.md
@@ -4,14 +4,18 @@
|
||||
|
||||
## 项目定位
|
||||
|
||||
Universal Agent Demo Framework 是一个用于复试展示的通用 AI Agent Demo 框架。
|
||||
当前项目已根据真实笔试题切换为:
|
||||
|
||||
```text
|
||||
试剂盒临床注册文件准备与审核智能体平台
|
||||
```
|
||||
|
||||
优先目标:
|
||||
|
||||
- 快速适配未知复试题。
|
||||
- 围绕 NMPA 体外诊断试剂注册申报资料场景完成可演示闭环。
|
||||
- 保证本地可运行。
|
||||
- 保证代码结构清楚,方便讲解。
|
||||
- 避免为了平台完整性牺牲改题速度。
|
||||
- 允许在保留主架构边界前提下进行大幅度业务重构。
|
||||
|
||||
## 架构原则
|
||||
|
||||
@@ -36,23 +40,23 @@ Django 单体 + 独立 Agent Core + Docker Compose
|
||||
|
||||
### apps.scenarios
|
||||
|
||||
负责场景列表、场景配置读取、场景元信息展示。
|
||||
负责注册审核任务列表、任务配置读取、任务元信息展示。
|
||||
|
||||
### apps.documents
|
||||
|
||||
负责文件上传、文件记录、文件状态和触发 RAG 入库。
|
||||
负责注册资料上传、文件记录、章节点归类、页数与文本处理状态和触发 RAG 入库。
|
||||
|
||||
### apps.chat
|
||||
|
||||
负责对话页面、用户输入表单、调用 Agent Core 和展示结果。
|
||||
负责审核工作台、用户输入表单、调用 Agent Core 和展示结构化审核结果。
|
||||
|
||||
### apps.audit
|
||||
|
||||
负责审计日志模型、日志写入服务、日志列表和详情页。
|
||||
负责审计日志模型、日志写入服务、日志列表和详情页,以及审核留痕展示。
|
||||
|
||||
### agent_core
|
||||
|
||||
负责 Agent 编排、RAG、工具注册、LLM Provider、结构化输出和 Adapter 扩展。
|
||||
负责注册审核 Agent 编排、RAG、工具注册、规则执行、LLM Provider 和结构化输出。
|
||||
|
||||
## 开发顺序
|
||||
|
||||
@@ -72,10 +76,10 @@ Django 单体 + 独立 Agent Core + Docker Compose
|
||||
当前仓库状态说明:
|
||||
|
||||
- Django 单体骨架已完成。
|
||||
- 5 个预置场景 YAML 已接通首页和对话页。
|
||||
- 通用场景 YAML、Chat、Documents、Audit 和 Agent Core 已具备可重构基础。
|
||||
- Agent Core 已具备 Prompt 编排、结构化解析、工具注册和 RAG fallback / Chroma 双路径。
|
||||
- Chat、Documents、Audit 页面已经可以形成完整演示闭环。
|
||||
- 全量测试已覆盖主要模块行为,并默认隔离真实 LLM 网络调用。
|
||||
- 当前需求文档已按真实笔试题重写到 `docs/需求分析/`。
|
||||
|
||||
## 编码约定
|
||||
|
||||
|
||||
78
README.md
78
README.md
@@ -1,13 +1,13 @@
|
||||
# Universal Agent Demo Framework
|
||||
# 试剂盒临床注册文件准备与审核智能体平台
|
||||
|
||||
用于复试展示的通用 AI Agent Demo 框架。
|
||||
用于复试展示的体外诊断试剂注册申报资料准备与审核系统。
|
||||
|
||||
项目目标不是提前猜中某一个具体业务题,而是先准备一个可快速改题的基础平台。拿到复试题目后,可以通过修改场景配置、上传知识库、补充少量工具函数,快速完成一个可演示的企业业务 Agent。
|
||||
当前项目已根据真实笔试题重构目标定位,重点服务于 NMPA 境内第三类体外诊断试剂注册申报场景,覆盖资料整理、目录汇总、法规完整性检查、关键信息抽取、跨文档一致性核查、风险预警和审计留痕。
|
||||
|
||||
## 核心理念
|
||||
|
||||
```text
|
||||
业务 Agent = 场景配置 + 知识库 + 工具集 + 输出模板 + 审计日志 + 模型适配器
|
||||
注册审核 Agent = 任务配置 + 资料库 + 法规规则 + 工具集 + 输出模板 + 审计日志 + 模型适配器
|
||||
```
|
||||
|
||||
## 技术路线
|
||||
@@ -24,18 +24,17 @@ V1 采用:
|
||||
|
||||
默认不强依赖 Dify。系统预留 Adapter 设计,后续可以接入 Dify、OpenAI Agents SDK 或其他 Agent 编排平台。
|
||||
|
||||
## 适用复试题型
|
||||
## 当前业务主线
|
||||
|
||||
| 题型 | 推荐场景模板 |
|
||||
|---|---|
|
||||
| SOP 问答 | `knowledge_qa` |
|
||||
| 制度问答 | `knowledge_qa` |
|
||||
| 文档审核 | `document_review` |
|
||||
| 客服工单 | `ticket_assistant` |
|
||||
| 质量异常分析 | `quality_analysis` |
|
||||
| 财务审核 | `risk_audit` |
|
||||
| 采购审核 | `risk_audit` |
|
||||
| 合同风险分析 | `document_review` 或 `risk_audit` |
|
||||
当前系统围绕以下注册申报审核闭环展开:
|
||||
|
||||
1. 导入注册资料。
|
||||
2. 汇总文件目录与页数。
|
||||
3. 对照法规要求检查完整性。
|
||||
4. 抽取产品关键信息。
|
||||
5. 自动填入注册申报表格或对照清单。
|
||||
6. 核查跨文档一致性。
|
||||
7. 输出风险预警与处理建议。
|
||||
|
||||
## 模块划分
|
||||
|
||||
@@ -79,11 +78,11 @@ universal-agent-demo/
|
||||
schemas/
|
||||
|
||||
configs/
|
||||
knowledge_qa.yaml
|
||||
document_review.yaml
|
||||
ticket_assistant.yaml
|
||||
quality_analysis.yaml
|
||||
risk_audit.yaml
|
||||
registration_overview.yaml
|
||||
registration_completeness_check.yaml
|
||||
registration_field_extraction.yaml
|
||||
registration_consistency_review.yaml
|
||||
registration_risk_report.yaml
|
||||
|
||||
data/
|
||||
uploads/
|
||||
@@ -96,20 +95,21 @@ universal-agent-demo/
|
||||
|
||||
V1 需要完成:
|
||||
|
||||
- 场景列表。
|
||||
- Agent 对话页。
|
||||
- 文件上传。
|
||||
- 文档入库。
|
||||
- RAG 检索。
|
||||
- 内置工具调用。
|
||||
- 结构化输出展示。
|
||||
- 审计日志。
|
||||
- 注册审核任务列表。
|
||||
- 审核工作台。
|
||||
- 资料上传与管理。
|
||||
- 文档解析与入库。
|
||||
- 目录与页数汇总。
|
||||
- 法规完整性检查。
|
||||
- 关键信息抽取与注册申报表格 / 对照清单自动回填。
|
||||
- 一致性核查。
|
||||
- 风险预警与审计日志。
|
||||
- 模型 API 可配置。
|
||||
- Docker 一键启动。
|
||||
|
||||
当前代码基线已经落地的能力:
|
||||
当前代码基线已经落地的通用能力:
|
||||
|
||||
- 首页支持展示场景摘要、适用题型、RAG 状态、工具数量。
|
||||
- 首页支持展示场景摘要、RAG 状态、工具数量。
|
||||
- 非法 YAML 场景配置会被自动跳过,并在首页展示错误摘要。
|
||||
- 对话页支持问题输入、文档范围选择、结构化结果、引用片段、工具调用和审计入口展示。
|
||||
- 文档页支持上传、列表查看、手动入库、失败原因提示和重试。
|
||||
@@ -117,6 +117,13 @@ V1 需要完成:
|
||||
- Agent Core 已具备 Prompt 编排、OpenAI 兼容 Provider、结构化输出解析、RAG 检索和工具注册机制。
|
||||
- 测试环境默认固定使用 Mock Provider,避免误调用本地真实模型配置。
|
||||
|
||||
## 本轮需求文档
|
||||
|
||||
本轮已按模块重写需求分析,详见:
|
||||
|
||||
- [V1 总需求文档](F:\PyCharm\DEMO-AGENT\docs\需求分析\1.V1总需求文档.md)
|
||||
- [需求重构总览与待确认事项](F:\PyCharm\DEMO-AGENT\docs\需求分析\0.需求重构总览与待确认事项.md)
|
||||
|
||||
V1 暂不重点做:
|
||||
|
||||
- 多租户。
|
||||
@@ -245,4 +252,15 @@ docker compose config
|
||||
- [模块需求文档索引](docs/需求分析/2.模块需求索引.md)
|
||||
- [智能体总体设计](docs/设计文档/1.智能体总体设计.md)
|
||||
- [设计文档索引](docs/设计文档/0.设计文档索引.md)
|
||||
- [注册审核平台整体原型设计](F:\PyCharm\DEMO-AGENT\docs\原型设计\1.整体原型设计.md)
|
||||
- [原型设计目录](F:\PyCharm\DEMO-AGENT\docs\原型设计)
|
||||
- [单文件演示站 HTML](F:\PyCharm\DEMO-AGENT\docs\原型设计\registration-prototype-demo.html)
|
||||
- [协作与编码约定](AGENTS.md)
|
||||
|
||||
## 原型设计交付
|
||||
|
||||
当前仓库已补充一套围绕注册申报审核主线的原型设计资产,供复试讲解、方案评审和后续页面实现直接参考:
|
||||
|
||||
- 原型文档采用“总览 + 分页细设计”方式组织,覆盖资料包导入、审核任务工作台、法规完整性检查、字段抽取与字段池、一致性核查、风险预警、Word 回填导出、飞书通知视图和知识库治理台。
|
||||
- `docs/原型设计/registration-prototype-demo.html` 提供单文件可交互 mock 演示站,内含 8 个主页面视图和知识库 / 治理台 CRUD 抽屉。
|
||||
- 该演示站仅使用 mock 数据,不依赖 Django 路由或真实 Agent Core 执行结果。
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
SUPPORTED_OUTPUT_TYPES = {
|
||||
"general_answer",
|
||||
"document_review_report",
|
||||
"registration_overview_report",
|
||||
"registration_completeness_report",
|
||||
"registration_field_extraction_report",
|
||||
"registration_consistency_report",
|
||||
"registration_risk_report",
|
||||
"ticket_response",
|
||||
"quality_report",
|
||||
"risk_audit_report",
|
||||
|
||||
@@ -33,6 +33,13 @@ def index(request, scenario_id: str):
|
||||
status=UploadedDocument.STATUS_INDEXED,
|
||||
)
|
||||
form = ChatForm(request.POST or None, documents=documents)
|
||||
task_modes = [
|
||||
{"name": "目录汇总", "description": "汇总文件、页数、章节点和目录型文档。"},
|
||||
{"name": "完整性检查", "description": "对照法规模板检查齐套性、缺失项和错放项。"},
|
||||
{"name": "字段抽取", "description": "抽取产品名称、规格、适用范围、储存条件等核心字段。"},
|
||||
{"name": "一致性核查", "description": "比较申请表、说明书和产品列表的字段一致性。"},
|
||||
{"name": "综合风险报告", "description": "形成高优先级问题、建议动作和责任人通知。"},
|
||||
]
|
||||
if request.method == "POST" and form.is_valid():
|
||||
message = form.cleaned_data["message"]
|
||||
try:
|
||||
@@ -56,5 +63,6 @@ def index(request, scenario_id: str):
|
||||
"document_count": documents.count(),
|
||||
"result": result,
|
||||
"audit_log": audit_log,
|
||||
"task_modes": task_modes,
|
||||
},
|
||||
)
|
||||
|
||||
@@ -12,7 +12,34 @@ from .services import create_uploaded_document, index_document
|
||||
def document_list(request):
|
||||
# 列表页只负责展示文档元数据和可执行操作,不处理入库细节。
|
||||
documents = UploadedDocument.objects.all()
|
||||
return render(request, "documents/document_list.html", {"documents": documents})
|
||||
status_counts = {
|
||||
"uploaded": documents.filter(status=UploadedDocument.STATUS_UPLOADED).count(),
|
||||
"indexed": documents.filter(status=UploadedDocument.STATUS_INDEXED).count(),
|
||||
"failed": documents.filter(status=UploadedDocument.STATUS_FAILED).count(),
|
||||
"total": documents.count(),
|
||||
}
|
||||
processing_pipeline = [
|
||||
{"title": "原始文件接收", "detail": "校验格式、大小和场景归属后保存原件。"},
|
||||
{"title": "文本与表格抽取", "detail": "按 PDF / DOCX / MD / TXT 使用不同解析策略。"},
|
||||
{"title": "页数统计与可信度评估", "detail": "对 Word 页数采用估算与可信度标记。"},
|
||||
{"title": "章节点归类", "detail": "基于文件名、标题和正文线索识别 CH 节点。"},
|
||||
{"title": "切片与索引入库", "detail": "生成知识切片,供 RAG、规则定位和审计引用使用。"},
|
||||
]
|
||||
exception_items = [
|
||||
{"level": "待确认", "title": "CH1.2 监管信息目录.docx", "detail": "目录页码与正文页数存在偏差,建议人工复核。"},
|
||||
{"level": "低可信度", "title": "目标产品说明书.docx", "detail": "Word 页数为估算值,表格抽取质量良好。"},
|
||||
{"level": "失败", "title": "沟通记录扫描件.pdf", "detail": "疑似扫描件,需补做 OCR 或重新上传清晰版。"},
|
||||
]
|
||||
return render(
|
||||
request,
|
||||
"documents/document_list.html",
|
||||
{
|
||||
"documents": documents,
|
||||
"status_counts": status_counts,
|
||||
"processing_pipeline": processing_pipeline,
|
||||
"exception_items": exception_items,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
def upload(request):
|
||||
@@ -28,7 +55,16 @@ def upload(request):
|
||||
return render(
|
||||
request,
|
||||
"documents/upload.html",
|
||||
{"form": form, "scenarios": list_scenarios()},
|
||||
{
|
||||
"form": form,
|
||||
"scenarios": list_scenarios(),
|
||||
"upload_checks": [
|
||||
"文件格式支持 PDF、DOCX、MD、TXT",
|
||||
"业务资料与法规依据资料需分开归属",
|
||||
"目录类文件会优先参与完整性校验",
|
||||
"上传完成后建议立即进入解析与入库流程",
|
||||
],
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
|
||||
1
apps/platform_ui/__init__.py
Normal file
1
apps/platform_ui/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
6
apps/platform_ui/apps.py
Normal file
6
apps/platform_ui/apps.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class PlatformUiConfig(AppConfig):
|
||||
default_auto_field = "django.db.models.BigAutoField"
|
||||
name = "apps.platform_ui"
|
||||
351
apps/platform_ui/services.py
Normal file
351
apps/platform_ui/services.py
Normal file
@@ -0,0 +1,351 @@
|
||||
def get_platform_demo_context():
|
||||
batch = {
|
||||
"name": "2026Q2-呼吸道多联检测试剂注册批次",
|
||||
"product_name": "呼吸道病原体核酸联合检测试剂盒(PCR-荧光探针法)",
|
||||
"owner": "临床注册事务组",
|
||||
"stage": "法规完整性复核中",
|
||||
"completion": "74%",
|
||||
"next_action": "补齐 CH1.11.5 沟通记录并确认产品列表版本",
|
||||
}
|
||||
metrics = [
|
||||
{"label": "资料齐套率", "value": "82%", "note": "42 / 51 个目录项已命中"},
|
||||
{"label": "法规命中率", "value": "89%", "note": "公告附件包 6 类规则已生效"},
|
||||
{"label": "字段抽取完成度", "value": "67%", "note": "48 个核心字段已进入统一字段池"},
|
||||
{"label": "高风险问题", "value": "03", "note": "2 个缺失项,1 个跨文档冲突"},
|
||||
]
|
||||
workflow_overview = [
|
||||
{"title": "资料进入系统", "detail": "批量上传 18 份申报资料与 6 份法规原文"},
|
||||
{"title": "规则与知识装载", "detail": "按章-条-要求项-模板字段建立知识底座"},
|
||||
{"title": "解析与切片", "detail": "页数统计、目录识别、表格抽取、Chroma 入库"},
|
||||
{"title": "Agent 审核执行", "detail": "完整性检查、字段抽取、一致性核查"},
|
||||
{"title": "结论输出", "detail": "形成风险清单、证据引用、责任人动作建议"},
|
||||
]
|
||||
risk_board = [
|
||||
{"level": "高", "title": "CH1.11.5 沟通记录缺失", "owner": "监管信息专员", "action": "补充 NMPA 沟通留痕"},
|
||||
{"level": "高", "title": "产品名称跨文档表述不一致", "owner": "产品资料负责人", "action": "统一申请表与说明书命名"},
|
||||
{"level": "中", "title": "2 份 Word 页数为估算值", "owner": "文控支持", "action": "补做版式校验"},
|
||||
]
|
||||
quick_links = [
|
||||
{"title": "知识库配置", "url_name": "platform_ui:knowledge-base", "desc": "维护法规规则树与切片策略"},
|
||||
{"title": "文件中心", "url_name": "documents:list", "desc": "查看上传、解析、切片与异常状态"},
|
||||
{"title": "审核工作台", "url_name": "chat:index", "url_arg": "document_review", "desc": "发起审核、抽取与一致性核查演示"},
|
||||
{"title": "工作台大屏", "url_name": "platform_ui:command-center", "desc": "面向演示的 Agent 流程解释大屏"},
|
||||
]
|
||||
knowledge_sources = [
|
||||
{
|
||||
"code": "KB-001",
|
||||
"name": "公告附件包 / 资料要求说明",
|
||||
"type": "法规依据",
|
||||
"scope": "registration",
|
||||
"updated_at": "今天 09:20",
|
||||
"status": "已生效",
|
||||
"owner": "法规专员",
|
||||
},
|
||||
{
|
||||
"code": "KB-002",
|
||||
"name": "批准证明文件格式要求",
|
||||
"type": "模板规则",
|
||||
"scope": "registration",
|
||||
"updated_at": "今天 09:35",
|
||||
"status": "已生效",
|
||||
"owner": "模板管理员",
|
||||
},
|
||||
{
|
||||
"code": "KB-003",
|
||||
"name": "安全和性能基本原则清单",
|
||||
"type": "原则规则",
|
||||
"scope": "registration",
|
||||
"updated_at": "今天 10:02",
|
||||
"status": "待人工校订",
|
||||
"owner": "法规专员",
|
||||
},
|
||||
{
|
||||
"code": "KB-004",
|
||||
"name": "CH1 监管信息目录样例",
|
||||
"type": "业务资料",
|
||||
"scope": "batch",
|
||||
"updated_at": "今天 10:30",
|
||||
"status": "已入库",
|
||||
"owner": "文控专员",
|
||||
},
|
||||
]
|
||||
rule_tree = [
|
||||
{
|
||||
"code": "RULE-001",
|
||||
"chapter": "CH1 监管信息",
|
||||
"item": "CH1.2 监管信息目录",
|
||||
"requirement": "必须提供目录与页码映射",
|
||||
"field": "目录文件 / 页码可信度",
|
||||
"status": "启用",
|
||||
},
|
||||
{
|
||||
"code": "RULE-002",
|
||||
"chapter": "CH1 监管信息",
|
||||
"item": "CH1.4 申请表",
|
||||
"requirement": "申请表字段需与说明书一致",
|
||||
"field": "产品名称 / 规格 / 申请人",
|
||||
"status": "启用",
|
||||
},
|
||||
{
|
||||
"code": "RULE-003",
|
||||
"chapter": "CH1 监管信息",
|
||||
"item": "CH1.11.5 沟通记录",
|
||||
"requirement": "涉及沟通事项时需补齐记录",
|
||||
"field": "沟通对象 / 时间 / 结论",
|
||||
"status": "待校订",
|
||||
},
|
||||
{
|
||||
"code": "RULE-004",
|
||||
"chapter": "批准证明文件格式",
|
||||
"item": "注册证输出模板",
|
||||
"requirement": "字段映射需满足版式模板",
|
||||
"field": "注册证字段池 / Word 模板",
|
||||
"status": "启用",
|
||||
},
|
||||
]
|
||||
knowledge_stats = [
|
||||
{"label": "法规知识源", "value": "06"},
|
||||
{"label": "结构化规则项", "value": "128"},
|
||||
{"label": "业务资料切片", "value": "342"},
|
||||
{"label": "最近人工校订", "value": "2 次"},
|
||||
]
|
||||
mcp_connectors = [
|
||||
{"name": "飞书任务通知", "kind": "协同办公", "auth": "App Token", "status": "已连接", "sync": "5 分钟前"},
|
||||
{"name": "法规规则源导入", "kind": "法规服务", "auth": "文件轮询", "status": "待验证", "sync": "今天 08:50"},
|
||||
{"name": "Word 模板服务", "kind": "文档服务", "auth": "API Key", "status": "已连接", "sync": "刚刚"},
|
||||
{"name": "企业主数据源", "kind": "业务系统", "auth": "MCP Bridge", "status": "未启用", "sync": "未同步"},
|
||||
]
|
||||
skills = [
|
||||
{"name": "完整性检查 Skill", "trigger": "目录齐套性 / 章节点核查", "tools": "规则树 + RAG + 风险映射", "status": "发布中"},
|
||||
{"name": "字段抽取 Skill", "trigger": "申请表 / 说明书 / 产品列表抽取", "tools": "表格抽取 + 字段池", "status": "已发布"},
|
||||
{"name": "一致性核查 Skill", "trigger": "跨文档字段冲突检查", "tools": "字段比对 + 解释生成", "status": "灰度测试"},
|
||||
{"name": "Word 回填 Skill", "trigger": "报送版 Word 输出", "tools": "模板映射 + 导出服务", "status": "待校验"},
|
||||
]
|
||||
workflow_steps = [
|
||||
{"time": "09:32", "title": "载入批次资料", "detail": "识别 18 份业务资料与 6 份法规原文,建立本轮审核上下文。"},
|
||||
{"time": "09:34", "title": "规则树装载", "detail": "按注册申报主流程装载 CH1 监管信息与批准证明文件格式规则。"},
|
||||
{"time": "09:36", "title": "字段池初始化", "detail": "从申请表、说明书、产品列表抽取统一字段并建立来源映射。"},
|
||||
{"time": "09:39", "title": "一致性检查", "detail": "检测到产品名称和样本类型存在跨文档冲突,升级为人工复核。"},
|
||||
{"time": "09:42", "title": "风险输出", "detail": "生成 3 条风险项、2 条补件建议与 1 条责任人通知任务。"},
|
||||
]
|
||||
command_batch = {
|
||||
"id": "2025IVD-CL-0520-001",
|
||||
"status": "进行中",
|
||||
"workflow": "境内第三类",
|
||||
"class": "III 类",
|
||||
"created_at": "2025-05-20",
|
||||
"applicant": "某某生物科技有限公司",
|
||||
"reviewer": "张审评员",
|
||||
"role": "审评专家",
|
||||
"standard": "《体外诊断试剂注册与备案管理办法》及配套技术指导原则",
|
||||
"version": "V2.1(2025-04-01)",
|
||||
}
|
||||
command_metrics = [
|
||||
{
|
||||
"key": "completeness",
|
||||
"label": "资料包完整性得分",
|
||||
"value": "68",
|
||||
"suffix": "/100",
|
||||
"level": "较差",
|
||||
"detail": "上次得分 61(2025-05-19)",
|
||||
},
|
||||
{
|
||||
"key": "health",
|
||||
"label": "资料包健康度",
|
||||
"value": "62",
|
||||
"suffix": "项检查项",
|
||||
"segments": [
|
||||
{"label": "完整", "value": "28", "hint": "45%"},
|
||||
{"label": "部分缺失", "value": "18", "hint": "29%"},
|
||||
{"label": "缺失", "value": "16", "hint": "26%"},
|
||||
],
|
||||
},
|
||||
{
|
||||
"key": "risk",
|
||||
"label": "风险分布",
|
||||
"value": "22",
|
||||
"suffix": "项风险",
|
||||
"segments": [
|
||||
{"label": "高风险", "value": "3", "tone": "danger"},
|
||||
{"label": "中风险", "value": "7", "tone": "warning"},
|
||||
{"label": "低风险", "value": "12", "tone": "success"},
|
||||
],
|
||||
},
|
||||
{
|
||||
"key": "progress",
|
||||
"label": "审核进度",
|
||||
"value": "46",
|
||||
"suffix": "%",
|
||||
"detail": "已完成 24 / 52 项任务",
|
||||
},
|
||||
]
|
||||
command_flow = [
|
||||
{"step": "1", "title": "资料准备", "date": "2025-05-20", "state": "done"},
|
||||
{"step": "2", "title": "形式审查", "date": "2025-05-21", "state": "done"},
|
||||
{"step": "3", "title": "技术审评", "date": "进行中", "state": "active"},
|
||||
{"step": "4", "title": "核查检验", "date": "待开始", "state": "todo"},
|
||||
{"step": "5", "title": "综合评审", "date": "待开始", "state": "todo"},
|
||||
{"step": "6", "title": "行政审批", "date": "待开始", "state": "todo"},
|
||||
{"step": "7", "title": "制证发证", "date": "待开始", "state": "todo"},
|
||||
]
|
||||
command_tabs = [
|
||||
{"id": "completeness", "label": "注册完整性核查"},
|
||||
{"id": "consistency", "label": "字段一致性"},
|
||||
{"id": "risk", "label": "风险准入结论"},
|
||||
{"id": "evidence", "label": "证据引用"},
|
||||
{"id": "feishu", "label": "飞书通知状态"},
|
||||
]
|
||||
command_checks = [
|
||||
{
|
||||
"chapter": "1.产品基本信息",
|
||||
"item": "产品名称",
|
||||
"rule": "办法 第十条",
|
||||
"status": "完整",
|
||||
"risk": "低风险",
|
||||
"problem": "-",
|
||||
},
|
||||
{
|
||||
"chapter": "1.产品基本信息",
|
||||
"item": "预期用途",
|
||||
"rule": "办法 第十条",
|
||||
"status": "完整",
|
||||
"risk": "低风险",
|
||||
"problem": "-",
|
||||
},
|
||||
{
|
||||
"chapter": "2.综述资料",
|
||||
"item": "产品描述",
|
||||
"rule": "指导原则4.2.1",
|
||||
"status": "完整",
|
||||
"risk": "低风险",
|
||||
"problem": "-",
|
||||
},
|
||||
{
|
||||
"chapter": "2.综述资料",
|
||||
"item": "作用原理",
|
||||
"rule": "指导原则4.2.2",
|
||||
"status": "部分缺失",
|
||||
"risk": "中风险",
|
||||
"problem": "缺少关键原理图及验证数据说明",
|
||||
},
|
||||
{
|
||||
"chapter": "3.研究资料",
|
||||
"item": "分析性能评估",
|
||||
"rule": "指导原则5.3.1",
|
||||
"status": "部分缺失",
|
||||
"risk": "中风险",
|
||||
"problem": "线性范围验证数据不完整",
|
||||
},
|
||||
{
|
||||
"chapter": "3.研究资料",
|
||||
"item": "阳性判断值",
|
||||
"rule": "指导原则5.3.2",
|
||||
"status": "缺失",
|
||||
"risk": "高风险",
|
||||
"problem": "未提供阳性判断值确定依据",
|
||||
},
|
||||
{
|
||||
"chapter": "4.临床评价资料",
|
||||
"item": "临床试验方案",
|
||||
"rule": "指导原则6.2.1",
|
||||
"status": "完整",
|
||||
"risk": "低风险",
|
||||
"problem": "-",
|
||||
},
|
||||
{
|
||||
"chapter": "4.临床评价资料",
|
||||
"item": "临床试验报告",
|
||||
"rule": "指导原则6.2.2",
|
||||
"status": "部分缺失",
|
||||
"risk": "中风险",
|
||||
"problem": "有效性结果分析不完整",
|
||||
},
|
||||
{
|
||||
"chapter": "4.临床评价资料",
|
||||
"item": "不良事件汇总分析",
|
||||
"rule": "指导原则6.2.4",
|
||||
"status": "缺失",
|
||||
"risk": "高风险",
|
||||
"problem": "未提供不良事件汇总分析报告",
|
||||
},
|
||||
{
|
||||
"chapter": "5.生产资料",
|
||||
"item": "生产工艺验证",
|
||||
"rule": "指导原则7.2.3",
|
||||
"status": "完整",
|
||||
"risk": "低风险",
|
||||
"problem": "-",
|
||||
},
|
||||
]
|
||||
key_risks = [
|
||||
{"title": "阳性判断值确定依据缺失", "level": "高风险"},
|
||||
{"title": "不良事件汇总分析报告缺失", "level": "高风险"},
|
||||
{"title": "临床试验方案偏离未充分说明", "level": "中风险"},
|
||||
]
|
||||
next_actions = [
|
||||
{"title": "退回企业补充资料", "detail": "需企业补充 3 项高风险资料", "state": "待处理", "tone": "danger"},
|
||||
{"title": "补充说明或澄清", "detail": "需企业说明 7 项中风险问题", "state": "待处理", "tone": "warning"},
|
||||
{"title": "进入核查检验环节(可选)", "detail": "风险可控后进入下一环节", "state": "待处理", "tone": "success"},
|
||||
]
|
||||
owners = [
|
||||
{"role": "审评专家", "name": "张审评员", "status": "当前处理人"},
|
||||
{"role": "审核组长", "name": "李组长", "status": "待确认"},
|
||||
{"role": "法规专员", "name": "王法规", "status": "协同处理"},
|
||||
{"role": "临床专家", "name": "陈专家", "status": "协同处理"},
|
||||
]
|
||||
operation_logs = [
|
||||
{"time": "2025-05-21 10:24", "actor": "张审评员", "action": "发起完整性核查"},
|
||||
{"time": "2025-05-21 10:26", "actor": "Agent Core", "action": "命中 62 项检查规则"},
|
||||
{"time": "2025-05-21 10:28", "actor": "Agent Core", "action": "生成风险准入结论"},
|
||||
]
|
||||
knowledge_filters = [
|
||||
{"label": "全部", "active": True},
|
||||
{"label": "法规依据", "active": False},
|
||||
{"label": "模板规则", "active": False},
|
||||
{"label": "业务资料", "active": False},
|
||||
]
|
||||
knowledge_form = {
|
||||
"title": "新增 / 编辑知识源",
|
||||
"fields": [
|
||||
{"label": "知识源名称", "value": "体外诊断试剂注册申报资料要求及说明"},
|
||||
{"label": "知识源类型", "value": "法规依据"},
|
||||
{"label": "适用流程", "value": "registration"},
|
||||
{"label": "状态", "value": "已生效"},
|
||||
{"label": "切片策略", "value": "按章条切片,保留条款编号"},
|
||||
],
|
||||
}
|
||||
rule_form = {
|
||||
"title": "新增 / 编辑规则项",
|
||||
"fields": [
|
||||
{"label": "规则编码", "value": "RULE-005"},
|
||||
{"label": "所属章节", "value": "CH1 监管信息"},
|
||||
{"label": "规则名称", "value": "申请表签章完整性检查"},
|
||||
{"label": "模板字段", "value": "签章页 / 申请人签字"},
|
||||
{"label": "规则说明", "value": "若申请表缺少签章,则标记为高优先级缺失项"},
|
||||
],
|
||||
}
|
||||
return {
|
||||
"batch": batch,
|
||||
"metrics": metrics,
|
||||
"workflow_overview": workflow_overview,
|
||||
"risk_board": risk_board,
|
||||
"quick_links": quick_links,
|
||||
"knowledge_sources": knowledge_sources,
|
||||
"rule_tree": rule_tree,
|
||||
"knowledge_stats": knowledge_stats,
|
||||
"knowledge_filters": knowledge_filters,
|
||||
"knowledge_form": knowledge_form,
|
||||
"rule_form": rule_form,
|
||||
"mcp_connectors": mcp_connectors,
|
||||
"skills": skills,
|
||||
"workflow_steps": workflow_steps,
|
||||
"command_batch": command_batch,
|
||||
"command_metrics": command_metrics,
|
||||
"command_flow": command_flow,
|
||||
"command_tabs": command_tabs,
|
||||
"command_checks": command_checks,
|
||||
"key_risks": key_risks,
|
||||
"next_actions": next_actions,
|
||||
"owners": owners,
|
||||
"operation_logs": operation_logs,
|
||||
}
|
||||
14
apps/platform_ui/urls.py
Normal file
14
apps/platform_ui/urls.py
Normal file
@@ -0,0 +1,14 @@
|
||||
from django.urls import path
|
||||
|
||||
from . import views
|
||||
|
||||
|
||||
app_name = "platform_ui"
|
||||
|
||||
urlpatterns = [
|
||||
path("knowledge-base/", views.knowledge_base, name="knowledge-base"),
|
||||
path("mcp-center/", views.mcp_center, name="mcp-center"),
|
||||
path("skills/", views.skill_studio, name="skills"),
|
||||
path("command-center/", views.command_center, name="command-center"),
|
||||
path("command-center-v2/", views.command_center_v2, name="command-center-v2"),
|
||||
]
|
||||
28
apps/platform_ui/views.py
Normal file
28
apps/platform_ui/views.py
Normal file
@@ -0,0 +1,28 @@
|
||||
from django.shortcuts import render
|
||||
|
||||
from .services import get_platform_demo_context
|
||||
|
||||
|
||||
def knowledge_base(request):
|
||||
context = get_platform_demo_context()
|
||||
return render(request, "platform_ui/knowledge_base.html", context)
|
||||
|
||||
|
||||
def mcp_center(request):
|
||||
context = get_platform_demo_context()
|
||||
return render(request, "platform_ui/mcp_center.html", context)
|
||||
|
||||
|
||||
def skill_studio(request):
|
||||
context = get_platform_demo_context()
|
||||
return render(request, "platform_ui/skill_studio.html", context)
|
||||
|
||||
|
||||
def command_center(request):
|
||||
context = get_platform_demo_context()
|
||||
return render(request, "platform_ui/command_center.html", context)
|
||||
|
||||
|
||||
def command_center_v2(request):
|
||||
context = get_platform_demo_context()
|
||||
return render(request, "platform_ui/command_center_v2.html", context)
|
||||
@@ -12,5 +12,23 @@ def index(request):
|
||||
{
|
||||
"scenarios": list_scenarios(),
|
||||
"scenario_issues": list_scenario_issues(),
|
||||
"hero_metrics": [
|
||||
{"label": "资料齐套率", "value": "82%", "note": "已识别 42 / 51 个法规模板项"},
|
||||
{"label": "法规命中率", "value": "89%", "note": "公告附件包 6 类规则已加载"},
|
||||
{"label": "字段抽取完成度", "value": "67%", "note": "48 个核心字段进入统一字段池"},
|
||||
{"label": "高风险问题", "value": "03", "note": "含 1 个缺失项与 1 个命名冲突"},
|
||||
],
|
||||
"workflow_overview": [
|
||||
{"title": "资料进入系统", "detail": "导入本批次注册申报资料、法规原文与模板文件。"},
|
||||
{"title": "知识底座装载", "detail": "以章-条-要求项-模板字段组织法规规则。"},
|
||||
{"title": "解析与切片", "detail": "完成页数统计、表格抽取、章节点归类和向量入库。"},
|
||||
{"title": "Agent 审核执行", "detail": "发起完整性检查、字段抽取和一致性比对。"},
|
||||
{"title": "结论输出与留痕", "detail": "形成风险清单、证据引用、责任人动作和审计日志。"},
|
||||
],
|
||||
"risk_board": [
|
||||
{"level": "高风险", "title": "CH1.11.5 沟通记录缺失", "detail": "监管沟通事项未形成可追溯文件,无法支撑本轮章节齐套性。"},
|
||||
{"level": "高风险", "title": "产品名称在申请表与说明书中不一致", "detail": "Agent 判定为跨文档命名冲突,需进入人工复核。"},
|
||||
{"level": "中风险", "title": "2 份 Word 文档页数可信度不足", "detail": "版式页数使用估算值,建议复核目录页码与正文总页数。"},
|
||||
],
|
||||
},
|
||||
)
|
||||
|
||||
@@ -55,6 +55,7 @@ INSTALLED_APPS = [
|
||||
"apps.documents",
|
||||
"apps.chat",
|
||||
"apps.audit",
|
||||
"apps.platform_ui",
|
||||
]
|
||||
|
||||
MIDDLEWARE = [
|
||||
|
||||
@@ -11,6 +11,7 @@ urlpatterns = [
|
||||
path("chat/", include("apps.chat.urls")),
|
||||
path("documents/", include("apps.documents.urls")),
|
||||
path("audit/", include("apps.audit.urls")),
|
||||
path("platform/", include("apps.platform_ui.urls")),
|
||||
]
|
||||
|
||||
if settings.DEBUG:
|
||||
|
||||
@@ -1,22 +1,27 @@
|
||||
id: document_review
|
||||
name: 文档审核助手
|
||||
description: 检查合同、制度或 SOP 中的风险点和缺失项
|
||||
name: 注册资料审核助手
|
||||
description: 汇总体外诊断试剂注册申报资料目录与页数,并检查完整性、一致性和合规风险
|
||||
applicable_questions:
|
||||
- 合同审核
|
||||
- 制度审核
|
||||
- 资料目录与页数汇总
|
||||
- NMPA 注册申报资料完整性检查
|
||||
- 产品关键信息抽取
|
||||
- 跨文档一致性核查
|
||||
- 合规风险预警
|
||||
agent:
|
||||
role: 文档审核专家
|
||||
goal: 根据审核规则和知识库内容输出结构化审核意见
|
||||
role: 体外诊断试剂注册资料审核专家
|
||||
goal: 根据 NMPA 注册申报资料要求、法规依据和上传资料输出结构化审核结论
|
||||
instructions:
|
||||
- 优先围绕资料目录、页数、章节点、完整性、字段一致性和风险建议回答
|
||||
- 法规判断应优先依据本地规则和知识库证据,不得凭空补全缺失资料
|
||||
- 不确定的问题必须标记为需人工复核
|
||||
- 输出必须包含风险等级和修改建议
|
||||
- 输出必须包含风险等级、涉及文件、法规或规则依据和处理建议
|
||||
rag:
|
||||
enabled: true
|
||||
collection: document_review
|
||||
collection: registration_documents
|
||||
top_k: 5
|
||||
tools:
|
||||
- check_required_fields
|
||||
output:
|
||||
type: document_review_report
|
||||
type: registration_risk_report
|
||||
audit:
|
||||
enabled: true
|
||||
|
||||
25
design-qa.md
Normal file
25
design-qa.md
Normal file
@@ -0,0 +1,25 @@
|
||||
**Findings**
|
||||
- No actionable P0/P1/P2 findings remain.
|
||||
|
||||
**Open Questions**
|
||||
- The source visual is an Image Gen concept rather than a pixel-locked Figma file, so exact icon glyphs and logo geometry were implemented as code-native UI marks. The final prototype preserves the selected direction's hierarchy, density, risk states, and operational layout.
|
||||
|
||||
**Implementation Checklist**
|
||||
- Source visual truth path: `C:\Users\bruce\.codex\generated_images\019e8bb8-b097-72b3-9c89-97cfca019c7c\ig_0fe578f839e33933016a1fae76771c81918c954bf5cbfe72d2.png`
|
||||
- Implementation screenshot path: `D:\Code\DEMO-AGENT\output\playwright\command-center-v2-desktop.png`
|
||||
- Mobile screenshot path: `D:\Code\DEMO-AGENT\output\playwright\command-center-v2-mobile.png`
|
||||
- Full-view comparison evidence: `D:\Code\DEMO-AGENT\output\playwright\command-center-v2-comparison.png`
|
||||
- Viewport: desktop `1440 x 1024`, mobile `390 x 844`
|
||||
- State: default command-center workbench; desktop screenshot shows the selected direction's primary dashboard state.
|
||||
- Focused region comparison evidence: not separately required; this is a dense dashboard concept and the full-view comparison makes the critical regions visible enough: sidebar, batch strip, metrics, workflow, audit table, and right risk rail.
|
||||
- Fonts and typography: Segoe UI / PingFang SC / Microsoft YaHei fallback stack matches the professional enterprise SaaS feel; hierarchy and body sizes are readable, with no negative letter spacing.
|
||||
- Spacing and layout rhythm: Desktop uses the same left rail, top context strip, four metric blocks, workflow strip, table region, and right-side risk rail as the source. Mobile switches to stacked sections to avoid cramped table-dashboard density.
|
||||
- Colors and visual tokens: Deep navy sidebar, white work surface, cool gray borders, blue primary actions, red/orange/green semantic risk states match the selected visual direction.
|
||||
- Image quality and asset fidelity: The source concept did not require product photos or decorative raster assets. The implementation uses lightweight UI marks and CSS primitives appropriate for a Django dashboard prototype.
|
||||
- Copy and content: Chinese labels are aligned to the requirements: NMPA IVD review, registration batch, completeness check, risk gate, evidence, Feishu notification, responsible owners, and audit trail.
|
||||
- Patches made since previous QA pass: added mobile wrapping for the header and batch strip, converted mobile actions to a single-column grid, adjusted the health legend, and suppressed horizontal overflow.
|
||||
- final result: passed
|
||||
|
||||
**Follow-up Polish**
|
||||
- P3: Replace letter-based placeholder nav icons with an icon font or library if the project later adds a frontend asset pipeline.
|
||||
- P3: Add separate interactive tab bodies for consistency, evidence, and Feishu cards if the prototype needs a longer live demo script.
|
||||
@@ -1,343 +0,0 @@
|
||||
# V1 Django Baseline Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** Build the smallest runnable Django baseline that satisfies the current Chinese requirements and design documents.
|
||||
|
||||
**Architecture:** Use a Django monolith with four apps (`scenarios`, `documents`, `chat`, `audit`) plus an independent `agent_core` package. The first implementation returns deterministic mock Agent results so the UI, audit, documents and module boundaries can be verified before real RAG/LLM integration.
|
||||
|
||||
**Tech Stack:** Python 3.13, Django 5.x, PyYAML, pytest, pytest-django, SQLite, Docker Compose.
|
||||
|
||||
---
|
||||
|
||||
## File Structure
|
||||
|
||||
- Create `requirements.txt`: runtime and test dependencies.
|
||||
- Create `manage.py`, `config/settings.py`, `config/urls.py`, `config/wsgi.py`, `config/asgi.py`: Django project shell.
|
||||
- Create `apps/scenarios/`: YAML scenario loading, homepage, tests.
|
||||
- Create `apps/documents/`: upload model, upload/list/index views, text extraction, tests.
|
||||
- Create `apps/chat/`: message form, chat view, Agent Core call, audit write, tests.
|
||||
- Create `apps/audit/`: audit model, service, list/detail views, tests.
|
||||
- Create `agent_core/`: dataclasses, orchestrator, mock RAG ingest/retrieve, tool registry, structured output parser.
|
||||
- Create `configs/*.yaml`: five required scenarios.
|
||||
- Create `templates/`: minimal Django Templates for pages.
|
||||
- Create `Dockerfile`, `docker-compose.yml`, `.env.example`: one-command startup.
|
||||
|
||||
## Task 1: Dependencies and Django Project Shell
|
||||
|
||||
**Files:**
|
||||
- Create: `requirements.txt`
|
||||
- Create: `manage.py`
|
||||
- Create: `config/__init__.py`
|
||||
- Create: `config/settings.py`
|
||||
- Create: `config/urls.py`
|
||||
- Create: `config/wsgi.py`
|
||||
- Create: `config/asgi.py`
|
||||
- Test: `pytest.ini`
|
||||
|
||||
- [ ] **Step 1: Write failing configuration test**
|
||||
|
||||
Create `tests/test_project_configuration.py`:
|
||||
|
||||
```python
|
||||
from django.conf import settings
|
||||
from django.urls import reverse
|
||||
|
||||
|
||||
def test_core_settings_expose_documented_paths():
|
||||
assert settings.SCENARIO_CONFIG_DIR.name == "configs"
|
||||
assert settings.CHROMA_PATH.name == "chroma"
|
||||
assert settings.MEDIA_ROOT.name == "uploads"
|
||||
|
||||
|
||||
def test_home_url_is_registered(client):
|
||||
response = client.get(reverse("scenarios:index"))
|
||||
assert response.status_code == 200
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Run test to verify it fails**
|
||||
|
||||
Run: `pytest tests/test_project_configuration.py -q`
|
||||
Expected: FAIL because Django project and apps do not exist.
|
||||
|
||||
- [ ] **Step 3: Implement minimal project shell**
|
||||
|
||||
Add dependencies and project files with settings for installed apps, templates, SQLite, media paths, and URL includes.
|
||||
|
||||
- [ ] **Step 4: Run test to verify progress**
|
||||
|
||||
Run: `pytest tests/test_project_configuration.py -q`
|
||||
Expected: either PASS or fail only because `apps.scenarios` is not implemented yet.
|
||||
|
||||
## Task 2: Scenarios Module and Five YAML Configs
|
||||
|
||||
**Files:**
|
||||
- Create: `apps/scenarios/services.py`
|
||||
- Create: `apps/scenarios/views.py`
|
||||
- Create: `apps/scenarios/urls.py`
|
||||
- Create: `apps/scenarios/apps.py`
|
||||
- Create: `configs/knowledge_qa.yaml`
|
||||
- Create: `configs/document_review.yaml`
|
||||
- Create: `configs/ticket_assistant.yaml`
|
||||
- Create: `configs/quality_analysis.yaml`
|
||||
- Create: `configs/risk_audit.yaml`
|
||||
- Create: `templates/scenarios/index.html`
|
||||
- Test: `tests/test_scenarios.py`
|
||||
|
||||
- [ ] **Step 1: Write failing scenario tests**
|
||||
|
||||
```python
|
||||
from apps.scenarios.services import get_scenario, list_scenarios
|
||||
|
||||
|
||||
def test_list_scenarios_loads_five_configs():
|
||||
scenarios = list_scenarios()
|
||||
assert [scenario["id"] for scenario in scenarios] == [
|
||||
"knowledge_qa",
|
||||
"document_review",
|
||||
"ticket_assistant",
|
||||
"quality_analysis",
|
||||
"risk_audit",
|
||||
]
|
||||
|
||||
|
||||
def test_get_scenario_returns_full_agent_config():
|
||||
scenario = get_scenario("quality_analysis")
|
||||
assert scenario["agent"]["role"]
|
||||
assert scenario["rag"]["enabled"] is True
|
||||
assert scenario["output"]["type"] == "quality_report"
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Run test to verify it fails**
|
||||
|
||||
Run: `pytest tests/test_scenarios.py -q`
|
||||
Expected: FAIL because services/configs are missing.
|
||||
|
||||
- [ ] **Step 3: Implement scenario loader and homepage**
|
||||
|
||||
Use `yaml.safe_load()`, validate required fields, and render scenario cards on `/`.
|
||||
|
||||
- [ ] **Step 4: Run tests**
|
||||
|
||||
Run: `pytest tests/test_scenarios.py tests/test_project_configuration.py -q`
|
||||
Expected: PASS.
|
||||
|
||||
## Task 3: Agent Core Mock Orchestrator
|
||||
|
||||
**Files:**
|
||||
- Create: `agent_core/results.py`
|
||||
- Create: `agent_core/orchestrator.py`
|
||||
- Create: `agent_core/structured_output.py`
|
||||
- Create: `agent_core/tool_registry.py`
|
||||
- Create: `agent_core/tools/builtin_tools.py`
|
||||
- Create: `agent_core/rag/ingest.py`
|
||||
- Create: `agent_core/rag/retriever.py`
|
||||
- Test: `tests/test_agent_core.py`
|
||||
|
||||
- [ ] **Step 1: Write failing Agent Core tests**
|
||||
|
||||
```python
|
||||
from agent_core.orchestrator import run_agent
|
||||
|
||||
|
||||
def test_run_agent_returns_structured_mock_result():
|
||||
scenario = {
|
||||
"id": "knowledge_qa",
|
||||
"name": "知识库问答助手",
|
||||
"rag": {"enabled": True, "collection": "knowledge_qa", "top_k": 3},
|
||||
"tools": ["generate_action_items"],
|
||||
"output": {"type": "general_answer"},
|
||||
}
|
||||
result = run_agent(scenario, "如何处理异常?")
|
||||
assert result.status == "success"
|
||||
assert result.answer
|
||||
assert result.structured_output["output_type"] == "general_answer"
|
||||
assert result.tool_calls[0]["tool_name"] == "generate_action_items"
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Run test to verify it fails**
|
||||
|
||||
Run: `pytest tests/test_agent_core.py -q`
|
||||
Expected: FAIL because `agent_core` is missing.
|
||||
|
||||
- [ ] **Step 3: Implement deterministic mock AgentResult**
|
||||
|
||||
Return stable answer, references, tool calls, model name `mock-model`, and latency.
|
||||
|
||||
- [ ] **Step 4: Run tests**
|
||||
|
||||
Run: `pytest tests/test_agent_core.py -q`
|
||||
Expected: PASS.
|
||||
|
||||
## Task 4: Audit Module
|
||||
|
||||
**Files:**
|
||||
- Create: `apps/audit/models.py`
|
||||
- Create: `apps/audit/services.py`
|
||||
- Create: `apps/audit/views.py`
|
||||
- Create: `apps/audit/urls.py`
|
||||
- Create: `apps/audit/admin.py`
|
||||
- Create: `templates/audit/log_list.html`
|
||||
- Create: `templates/audit/log_detail.html`
|
||||
- Test: `tests/test_audit.py`
|
||||
|
||||
- [ ] **Step 1: Write failing audit tests**
|
||||
|
||||
```python
|
||||
from apps.audit.models import AgentAuditLog
|
||||
from apps.audit.services import create_audit_log
|
||||
from agent_core.results import AgentResult
|
||||
|
||||
|
||||
def test_create_audit_log_records_success_result(db):
|
||||
result = AgentResult(answer="回答", structured_output={"x": 1}, status="success")
|
||||
log = create_audit_log("knowledge_qa", "知识库问答助手", "问题", result)
|
||||
assert AgentAuditLog.objects.count() == 1
|
||||
assert log.final_answer == "回答"
|
||||
assert log.structured_output == {"x": 1}
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Run test to verify it fails**
|
||||
|
||||
Run: `pytest tests/test_audit.py -q`
|
||||
Expected: FAIL because audit app is missing.
|
||||
|
||||
- [ ] **Step 3: Implement model, service, admin, views**
|
||||
|
||||
Use JSONField defaults and avoid storing sensitive environment values.
|
||||
|
||||
- [ ] **Step 4: Run migrations and tests**
|
||||
|
||||
Run: `python manage.py makemigrations audit && pytest tests/test_audit.py -q`
|
||||
Expected: PASS.
|
||||
|
||||
## Task 5: Documents Module
|
||||
|
||||
**Files:**
|
||||
- Create: `apps/documents/models.py`
|
||||
- Create: `apps/documents/services.py`
|
||||
- Create: `apps/documents/forms.py`
|
||||
- Create: `apps/documents/views.py`
|
||||
- Create: `apps/documents/urls.py`
|
||||
- Create: `apps/documents/admin.py`
|
||||
- Create: `templates/documents/document_list.html`
|
||||
- Create: `templates/documents/upload.html`
|
||||
- Test: `tests/test_documents.py`
|
||||
|
||||
- [ ] **Step 1: Write failing document tests**
|
||||
|
||||
```python
|
||||
from django.core.files.uploadedfile import SimpleUploadedFile
|
||||
from django.urls import reverse
|
||||
|
||||
from apps.documents.models import UploadedDocument
|
||||
|
||||
|
||||
def test_upload_txt_document_creates_uploaded_record(client, db):
|
||||
file = SimpleUploadedFile("rules.txt", "hello".encode("utf-8"), content_type="text/plain")
|
||||
response = client.post(reverse("documents:upload"), {"scenario_id": "knowledge_qa", "file": file})
|
||||
assert response.status_code == 302
|
||||
document = UploadedDocument.objects.get()
|
||||
assert document.status == "uploaded"
|
||||
assert document.file_type == "txt"
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Run test to verify it fails**
|
||||
|
||||
Run: `pytest tests/test_documents.py -q`
|
||||
Expected: FAIL because documents app is missing.
|
||||
|
||||
- [ ] **Step 3: Implement upload/list/index flow**
|
||||
|
||||
Support `.txt` and `.md`; index action calls `agent_core.rag.ingest.ingest_document()` and updates status.
|
||||
|
||||
- [ ] **Step 4: Run migrations and tests**
|
||||
|
||||
Run: `python manage.py makemigrations documents && pytest tests/test_documents.py -q`
|
||||
Expected: PASS.
|
||||
|
||||
## Task 6: Chat Module
|
||||
|
||||
**Files:**
|
||||
- Create: `apps/chat/forms.py`
|
||||
- Create: `apps/chat/views.py`
|
||||
- Create: `apps/chat/urls.py`
|
||||
- Create: `apps/chat/apps.py`
|
||||
- Create: `templates/chat/index.html`
|
||||
- Test: `tests/test_chat.py`
|
||||
|
||||
- [ ] **Step 1: Write failing chat tests**
|
||||
|
||||
```python
|
||||
from django.urls import reverse
|
||||
|
||||
from apps.audit.models import AgentAuditLog
|
||||
|
||||
|
||||
def test_chat_post_returns_agent_result_and_audit_log(client, db):
|
||||
response = client.post(reverse("chat:index", args=["knowledge_qa"]), {"message": "如何处理异常?"})
|
||||
assert response.status_code == 200
|
||||
assert "mock-model" in response.content.decode("utf-8")
|
||||
assert AgentAuditLog.objects.count() == 1
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Run test to verify it fails**
|
||||
|
||||
Run: `pytest tests/test_chat.py -q`
|
||||
Expected: FAIL because chat app is missing.
|
||||
|
||||
- [ ] **Step 3: Implement chat form and view**
|
||||
|
||||
Validate message, call `get_scenario()`, `run_agent()`, then `create_audit_log()`.
|
||||
|
||||
- [ ] **Step 4: Run tests**
|
||||
|
||||
Run: `pytest tests/test_chat.py tests/test_audit.py tests/test_agent_core.py -q`
|
||||
Expected: PASS.
|
||||
|
||||
## Task 7: Docker and Documentation Alignment
|
||||
|
||||
**Files:**
|
||||
- Create: `.env.example`
|
||||
- Create: `Dockerfile`
|
||||
- Create: `docker-compose.yml`
|
||||
- Modify: `README.md`
|
||||
- Test: all tests and Django checks.
|
||||
|
||||
- [ ] **Step 1: Add deployment files**
|
||||
|
||||
Use a single web service, install `requirements.txt`, run migrations, and serve `0.0.0.0:8000`.
|
||||
|
||||
- [ ] **Step 2: Verify Django and tests**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
python manage.py check
|
||||
pytest -q
|
||||
```
|
||||
|
||||
Expected: all checks pass.
|
||||
|
||||
- [ ] **Step 3: Verify docs path references**
|
||||
|
||||
Run:
|
||||
|
||||
```powershell
|
||||
$patterns = @('docs/需求分析', 'docs/设计文档', 'V1总需求文档', '智能体总体设计')
|
||||
Get-ChildItem -Recurse -File |
|
||||
Where-Object {
|
||||
$_.FullName -notlike '*\.git\*' -and
|
||||
$_.FullName -notlike '*\.idea\*' -and
|
||||
$_.FullName -notlike '*docs\superpowers\plans\2026-05-29-v1-django-baseline.md'
|
||||
} |
|
||||
Select-String -Pattern $patterns
|
||||
```
|
||||
|
||||
Expected: no matches.
|
||||
|
||||
## Self-Review
|
||||
|
||||
- Spec coverage: The plan covers Chinese docs, five scenario configs, Django startup, homepage, chat, audit, documents, Agent Core, and Docker baseline.
|
||||
- Placeholder scan: No implementation step relies on an undefined placeholder; mock LLM/RAG is intentionally scoped as the first runnable baseline.
|
||||
- Type consistency: Tests use `AgentResult`, `run_agent`, `list_scenarios`, `get_scenario`, `UploadedDocument`, and `AgentAuditLog` consistently.
|
||||
@@ -0,0 +1,376 @@
|
||||
# Registration Agent Prototype Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** Build a new high-fidelity, demo-ready prototype UI for the registration review agent platform across homepage, knowledge base, document processing, agent workspace, MCP, Skills, and leadership dashboard screens.
|
||||
|
||||
**Architecture:** Keep the existing Django monolith and template routing boundaries, but replace the current visual system with a unified prototype shell and add a dedicated platform app for new governance pages. Use shared presentation data in service/view code so the pages tell one coherent business story without coupling design code to the existing agent execution internals.
|
||||
|
||||
**Tech Stack:** Django templates, Django views/URLs, Python service helpers, shared inline CSS in base template, existing forms/models where useful.
|
||||
|
||||
---
|
||||
|
||||
## File Structure
|
||||
|
||||
- Modify: `F:\PyCharm\DEMO-AGENT\templates\base.html`
|
||||
- Modify: `F:\PyCharm\DEMO-AGENT\templates\scenarios\index.html`
|
||||
- Modify: `F:\PyCharm\DEMO-AGENT\templates\documents\document_list.html`
|
||||
- Modify: `F:\PyCharm\DEMO-AGENT\templates\documents\upload.html`
|
||||
- Modify: `F:\PyCharm\DEMO-AGENT\templates\chat\index.html`
|
||||
- Create: `F:\PyCharm\DEMO-AGENT\apps\platform_ui\__init__.py`
|
||||
- Create: `F:\PyCharm\DEMO-AGENT\apps\platform_ui\apps.py`
|
||||
- Create: `F:\PyCharm\DEMO-AGENT\apps\platform_ui\views.py`
|
||||
- Create: `F:\PyCharm\DEMO-AGENT\apps\platform_ui\urls.py`
|
||||
- Create: `F:\PyCharm\DEMO-AGENT\apps\platform_ui\services.py`
|
||||
- Create: `F:\PyCharm\DEMO-AGENT\templates\platform_ui\knowledge_base.html`
|
||||
- Create: `F:\PyCharm\DEMO-AGENT\templates\platform_ui\mcp_center.html`
|
||||
- Create: `F:\PyCharm\DEMO-AGENT\templates\platform_ui\skill_studio.html`
|
||||
- Create: `F:\PyCharm\DEMO-AGENT\templates\platform_ui\command_center.html`
|
||||
- Modify: `F:\PyCharm\DEMO-AGENT\config\settings.py`
|
||||
- Modify: `F:\PyCharm\DEMO-AGENT\config\urls.py`
|
||||
- Test: `F:\PyCharm\DEMO-AGENT\tests\`
|
||||
|
||||
### Task 1: Register the new platform prototype app
|
||||
|
||||
**Files:**
|
||||
- Create: `apps/platform_ui/__init__.py`
|
||||
- Create: `apps/platform_ui/apps.py`
|
||||
- Create: `apps/platform_ui/views.py`
|
||||
- Create: `apps/platform_ui/urls.py`
|
||||
- Modify: `config/settings.py`
|
||||
- Modify: `config/urls.py`
|
||||
|
||||
- [ ] **Step 1: Add the Django app module skeleton**
|
||||
|
||||
```python
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class PlatformUiConfig(AppConfig):
|
||||
default_auto_field = "django.db.models.BigAutoField"
|
||||
name = "apps.platform_ui"
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Register the app in settings**
|
||||
|
||||
```python
|
||||
INSTALLED_APPS = [
|
||||
# ...
|
||||
"apps.platform_ui",
|
||||
]
|
||||
```
|
||||
|
||||
- [ ] **Step 3: Add prototype page routes**
|
||||
|
||||
```python
|
||||
urlpatterns = [
|
||||
path("platform/", include("apps.platform_ui.urls")),
|
||||
]
|
||||
```
|
||||
|
||||
- [ ] **Step 4: Define view names for prototype pages**
|
||||
|
||||
```python
|
||||
urlpatterns = [
|
||||
path("knowledge-base/", views.knowledge_base, name="knowledge-base"),
|
||||
path("mcp-center/", views.mcp_center, name="mcp-center"),
|
||||
path("skills/", views.skill_studio, name="skills"),
|
||||
path("command-center/", views.command_center, name="command-center"),
|
||||
]
|
||||
```
|
||||
|
||||
- [ ] **Step 5: Run framework validation**
|
||||
|
||||
Run: `python manage.py check`
|
||||
Expected: PASS with no URL or app import errors
|
||||
|
||||
### Task 2: Create shared presentation data for the new prototype
|
||||
|
||||
**Files:**
|
||||
- Create: `apps/platform_ui/services.py`
|
||||
- Modify: `apps/platform_ui/views.py`
|
||||
|
||||
- [ ] **Step 1: Define one coherent demo dataset**
|
||||
|
||||
```python
|
||||
def get_platform_demo_context():
|
||||
return {
|
||||
"batch": {...},
|
||||
"knowledge_sources": [...],
|
||||
"mcp_connectors": [...],
|
||||
"skills": [...],
|
||||
"workflow_steps": [...],
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Keep each page view thin**
|
||||
|
||||
```python
|
||||
def knowledge_base(request):
|
||||
context = get_platform_demo_context()
|
||||
return render(request, "platform_ui/knowledge_base.html", context)
|
||||
```
|
||||
|
||||
- [ ] **Step 3: Run framework validation**
|
||||
|
||||
Run: `python manage.py check`
|
||||
Expected: PASS with importable views and service helpers
|
||||
|
||||
### Task 3: Replace the global visual system and navigation shell
|
||||
|
||||
**Files:**
|
||||
- Modify: `templates/base.html`
|
||||
|
||||
- [ ] **Step 1: Rewrite the global shell**
|
||||
|
||||
```html
|
||||
<body>
|
||||
<div class="app-shell">
|
||||
<aside class="sidebar">...</aside>
|
||||
<main class="main-shell">
|
||||
<header class="topbar">...</header>
|
||||
{% block content %}{% endblock %}
|
||||
</main>
|
||||
</div>
|
||||
</body>
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Define the new design tokens and shared components**
|
||||
|
||||
```css
|
||||
:root {
|
||||
--bg: #eef3f7;
|
||||
--surface: #f8fbfd;
|
||||
--panel: #ffffff;
|
||||
--ink: #102033;
|
||||
--accent: #1e5eff;
|
||||
--signal: #d77a2b;
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 3: Add global helpers for panels, metric cards, timelines, tables, pills, and section headers**
|
||||
|
||||
```css
|
||||
.panel { ... }
|
||||
.metric-card { ... }
|
||||
.section-heading { ... }
|
||||
.timeline-step { ... }
|
||||
.data-table { ... }
|
||||
```
|
||||
|
||||
- [ ] **Step 4: Render shared navigation links to all prototype surfaces**
|
||||
|
||||
```html
|
||||
<a href="{% url 'scenarios:index' %}">任务总览</a>
|
||||
<a href="{% url 'platform_ui:knowledge-base' %}">知识库配置</a>
|
||||
<a href="{% url 'documents:list' %}">文件中心</a>
|
||||
<a href="{% url 'platform_ui:command-center' %}">工作台大屏</a>
|
||||
```
|
||||
|
||||
- [ ] **Step 5: Open a few pages manually**
|
||||
|
||||
Run: `python manage.py runserver`
|
||||
Expected: the shell renders and every nav item resolves
|
||||
|
||||
### Task 4: Redesign the homepage as the business-closure entry point
|
||||
|
||||
**Files:**
|
||||
- Modify: `templates/scenarios/index.html`
|
||||
- Modify: `apps/scenarios/views.py` if extra presentation fields are needed
|
||||
|
||||
- [ ] **Step 1: Add a structured homepage context if needed**
|
||||
|
||||
```python
|
||||
return render(
|
||||
request,
|
||||
"scenarios/index.html",
|
||||
{
|
||||
"scenarios": list_scenarios(),
|
||||
"scenario_issues": list_scenario_issues(),
|
||||
"hero_metrics": [...],
|
||||
"workflow_overview": [...],
|
||||
},
|
||||
)
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Replace the page body with hero, metrics, workflow strip, risk board, and quick-entry modules**
|
||||
|
||||
```html
|
||||
<section class="hero-band">...</section>
|
||||
<section class="metrics-grid">...</section>
|
||||
<section class="workflow-strip">...</section>
|
||||
<section class="two-column-board">...</section>
|
||||
```
|
||||
|
||||
- [ ] **Step 3: Verify the homepage**
|
||||
|
||||
Run: `python manage.py runserver`
|
||||
Expected: `/` shows the new dashboard-like homepage
|
||||
|
||||
### Task 5: Redesign the document pages around parsing and slicing workflow
|
||||
|
||||
**Files:**
|
||||
- Modify: `templates/documents/document_list.html`
|
||||
- Modify: `templates/documents/upload.html`
|
||||
- Optionally modify: `apps/documents/views.py`
|
||||
|
||||
- [ ] **Step 1: Add any lightweight display-only summary fields in the view if needed**
|
||||
|
||||
```python
|
||||
return render(
|
||||
request,
|
||||
"documents/document_list.html",
|
||||
{
|
||||
"documents": documents,
|
||||
"processing_summary": {...},
|
||||
"exception_items": [...],
|
||||
},
|
||||
)
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Rebuild the list page into upload stats, pipeline board, anomaly box, and structured directory table**
|
||||
|
||||
```html
|
||||
<section class="metrics-grid">...</section>
|
||||
<section class="tri-column">...</section>
|
||||
<section class="panel">
|
||||
<table class="data-table">...</table>
|
||||
</section>
|
||||
```
|
||||
|
||||
- [ ] **Step 3: Rebuild the upload page into a guided import experience**
|
||||
|
||||
```html
|
||||
<section class="dropzone-panel">...</section>
|
||||
<section class="checklist-panel">...</section>
|
||||
```
|
||||
|
||||
- [ ] **Step 4: Verify both pages**
|
||||
|
||||
Run: `python manage.py runserver`
|
||||
Expected: `/documents/` and `/documents/upload/` match the new prototype style
|
||||
|
||||
### Task 6: Redesign the chat page as a controlled audit workspace
|
||||
|
||||
**Files:**
|
||||
- Modify: `templates/chat/index.html`
|
||||
- Optionally modify: `apps/chat/views.py`
|
||||
|
||||
- [ ] **Step 1: Add presentation-only helper blocks if the existing context is too sparse**
|
||||
|
||||
```python
|
||||
return render(
|
||||
request,
|
||||
"chat/index.html",
|
||||
{
|
||||
...
|
||||
"task_modes": [...],
|
||||
"result_highlights": [...],
|
||||
},
|
||||
)
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Replace the template with a three-zone workspace**
|
||||
|
||||
```html
|
||||
<section class="workspace-grid">
|
||||
<div class="left-rail">...</div>
|
||||
<div class="conversation-stage">...</div>
|
||||
<div class="result-rail">...</div>
|
||||
</section>
|
||||
```
|
||||
|
||||
- [ ] **Step 3: Preserve the real form submission path while upgrading the visual output areas**
|
||||
|
||||
```html
|
||||
<form method="post">...</form>
|
||||
{% if result %} ... {% endif %}
|
||||
```
|
||||
|
||||
- [ ] **Step 4: Verify one scenario page**
|
||||
|
||||
Run: `python manage.py runserver`
|
||||
Expected: `/chat/<scenario_id>/` still submits and now renders as a workbench
|
||||
|
||||
### Task 7: Implement the governance and platform pages
|
||||
|
||||
**Files:**
|
||||
- Create: `templates/platform_ui/knowledge_base.html`
|
||||
- Create: `templates/platform_ui/mcp_center.html`
|
||||
- Create: `templates/platform_ui/skill_studio.html`
|
||||
- Create: `templates/platform_ui/command_center.html`
|
||||
- Modify: `apps/platform_ui/views.py`
|
||||
- Modify: `apps/platform_ui/services.py`
|
||||
|
||||
- [ ] **Step 1: Build the knowledge base page**
|
||||
|
||||
```html
|
||||
<section class="three-column-board">...</section>
|
||||
<section class="panel">...</section>
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Build the MCP center page**
|
||||
|
||||
```html
|
||||
<section class="connector-grid">...</section>
|
||||
<section class="import-flow">...</section>
|
||||
```
|
||||
|
||||
- [ ] **Step 3: Build the Skill studio page**
|
||||
|
||||
```html
|
||||
<section class="editor-layout">...</section>
|
||||
<section class="version-board">...</section>
|
||||
```
|
||||
|
||||
- [ ] **Step 4: Build the leadership command center page**
|
||||
|
||||
```html
|
||||
<section class="command-stage">...</section>
|
||||
<section class="risk-heatmap">...</section>
|
||||
<section class="evidence-matrix">...</section>
|
||||
```
|
||||
|
||||
- [ ] **Step 5: Verify page routing**
|
||||
|
||||
Run: `python manage.py check`
|
||||
Expected: PASS and all `/platform/...` routes resolve
|
||||
|
||||
### Task 8: Regression, polish, and documentation sync
|
||||
|
||||
**Files:**
|
||||
- Modify: `README.md` if navigation or page descriptions need updating
|
||||
- Modify: `AGENTS.md` only if current implementation status needs sync
|
||||
|
||||
- [ ] **Step 1: Run core validation**
|
||||
|
||||
Run: `python manage.py check`
|
||||
Expected: PASS
|
||||
|
||||
- [ ] **Step 2: Run targeted tests if template/view assumptions changed**
|
||||
|
||||
Run: `pytest`
|
||||
Expected: PASS or clearly identified existing failures unrelated to the prototype
|
||||
|
||||
- [ ] **Step 3: Review the new screens for consistent terminology**
|
||||
|
||||
Check: page titles, batch name, product name, risk labels, and workflow terms all match the new design spec
|
||||
|
||||
- [ ] **Step 4: Update high-level documentation if needed**
|
||||
|
||||
```markdown
|
||||
## 当前原型页面
|
||||
- 任务总览
|
||||
- 知识库配置
|
||||
- 文件中心
|
||||
- 审核工作台
|
||||
- MCP 中心
|
||||
- Skill Studio
|
||||
- 工作台大屏
|
||||
```
|
||||
|
||||
## Self-Review
|
||||
|
||||
- Spec coverage: the plan covers homepage, knowledge base, document center, chat workspace, MCP, Skill studio, and leadership dashboard.
|
||||
- Placeholder scan: no TODO/TBD markers remain.
|
||||
- Type consistency: route names, app names, and page concepts are consistent across tasks.
|
||||
@@ -0,0 +1,185 @@
|
||||
# 注册审核智能体平台产品原型设计
|
||||
|
||||
## 目标
|
||||
|
||||
本次原型围绕“试剂盒临床注册文件准备与审核智能体平台”重新设计一套高保真、可点击、适合复试演示的 Web 产品界面。设计不沿用当前前端视觉,而是以新版需求分析为准,突出资料治理、法规知识底座、Agent 审核闭环、平台治理能力和可解释工作台。
|
||||
|
||||
## 设计范围
|
||||
|
||||
本次原型聚焦一条完整演示主线:
|
||||
|
||||
1. 首页进入批次级任务总览。
|
||||
2. 查看法规知识库与结构化规则配置。
|
||||
3. 上传并解析申报资料,查看切片、页数、章节点归类和异常状态。
|
||||
4. 进入 AI Agent 审核工作台执行完整性检查、字段抽取和一致性核查。
|
||||
5. 查看外部 MCP 能力接入情况。
|
||||
6. 查看和编辑 Skill 编排能力。
|
||||
7. 进入领导演示型工作台大屏查看 Agent 工作流程、解释依据和风险态势。
|
||||
|
||||
## 设计原则
|
||||
|
||||
### 1. 业务闭环优先
|
||||
|
||||
页面组织必须服务“资料准备到审核闭环”,而不是把系统包装成泛化 Agent 工具箱。
|
||||
|
||||
### 2. 高层能看懂,操作员也能讲清
|
||||
|
||||
首页与大屏承担讲故事职责;知识库、文件中心、Agent 工作台承担业务可信度职责;MCP 与 Skill 页面承担平台能力说明职责。
|
||||
|
||||
### 3. 可解释性强于炫技
|
||||
|
||||
任何页面都应尽量展示来源、阶段、规则命中、风险等级、人工复核状态,而不是堆叠模型术语。
|
||||
|
||||
### 4. 信息密度高但不压抑
|
||||
|
||||
整体风格走“专业监管科技工作台”,采用明亮底色、深色信息层、铜橙风险强调、清晰分栏和大面积结构化留白。
|
||||
|
||||
## 视觉方向
|
||||
|
||||
### 色彩
|
||||
|
||||
- 主背景采用浅米白与冷灰蓝混合渐变,强调专业与稳定。
|
||||
- 主强调色采用深青蓝,承担导航、激活态、关键信息。
|
||||
- 风险强调采用铜橙与深红,用于高风险、缺失、待处理。
|
||||
- 成功状态采用低饱和绿色,用于已完成、已入库、规则已生效。
|
||||
|
||||
### 排版
|
||||
|
||||
- 页级标题使用强对比的中文大标题,突出“阶段感”。
|
||||
- 模块级标题使用中等字号与清晰副标题。
|
||||
- 指标数字使用紧凑等宽风格,强调可视化汇报感。
|
||||
|
||||
### 组件风格
|
||||
|
||||
- 顶部为平台导航与当前批次状态条。
|
||||
- 页面内部以大面板、信息条、时间线、矩阵卡片、指标舱和结构树为主。
|
||||
- 尽量避免传统后台里大量相同卡片堆叠,强化带状布局、流程图感和分析板感。
|
||||
|
||||
## 页面设计
|
||||
|
||||
### 1. 首页 / 任务总览
|
||||
|
||||
**目标:**
|
||||
让评委在 10 秒内理解系统价值和当前批次进展。
|
||||
|
||||
**核心内容:**
|
||||
|
||||
- 批次概览 Hero:当前申报批次、产品名、流程阶段、批次状态。
|
||||
- 四个关键指标:资料齐套率、法规命中率、字段抽取完成度、高风险项数量。
|
||||
- 演示主流程带:资料进入、规则配置、解析入库、审核执行、结果输出。
|
||||
- 今日待办与高风险问题板。
|
||||
- 快速入口:知识库、文件中心、审核工作台、大屏。
|
||||
|
||||
### 2. 知识库搭建与配置页
|
||||
|
||||
**目标:**
|
||||
把“双层知识底座”讲透。
|
||||
|
||||
**核心内容:**
|
||||
|
||||
- 左侧法规规则树:按章、条、要求项、模板字段展示。
|
||||
- 中部知识源列表:法规依据、业务资料、模板库、公告附件包。
|
||||
- 右侧切片与生效配置:切片策略、召回阈值、适用流程、最近更新时间。
|
||||
- 底部人工校订记录与知识更新入口。
|
||||
|
||||
### 3. 文件上传、切片与解析中心
|
||||
|
||||
**目标:**
|
||||
展示 Documents 模块是“资料治理中心”。
|
||||
|
||||
**核心内容:**
|
||||
|
||||
- 顶部上传拖拽区与批次选择。
|
||||
- 左侧批量导入队列:文件名、类型、页数、识别状态。
|
||||
- 中部处理流水:保存原件、提取文本、识别表格、页数统计、章节点归类、切片入库。
|
||||
- 右侧异常箱:疑似扫描件、归类待确认、页数低可信度、切片失败。
|
||||
- 下方目录总览表:章节点、资料名称、状态、模板命中情况。
|
||||
|
||||
### 4. AI Agent 审核工作台
|
||||
|
||||
**目标:**
|
||||
把自由问答升级为受控审核任务工作台。
|
||||
|
||||
**核心内容:**
|
||||
|
||||
- 顶部任务切换:目录汇总、完整性检查、字段抽取、一致性核查、综合风险报告。
|
||||
- 左侧自然语言输入与资料范围选择。
|
||||
- 中间 Agent 对话流与执行阶段条。
|
||||
- 右侧结构化结果舱:结论摘要、字段表、缺失项、冲突项、风险建议。
|
||||
- 下方证据区:法规条款引用、文档片段、来源页码、人工复核提示。
|
||||
|
||||
### 5. 外部 MCP 导入页
|
||||
|
||||
**目标:**
|
||||
说明平台可扩展但不喧宾夺主。
|
||||
|
||||
**核心内容:**
|
||||
|
||||
- MCP 连接卡:法规源、飞书通知、模板服务、文档转换、企业数据源。
|
||||
- 接入状态、鉴权方式、最近同步时间。
|
||||
- 输入输出能力摘要。
|
||||
- 一个简单的导入向导区块。
|
||||
|
||||
### 6. Skill 编辑与使用页
|
||||
|
||||
**目标:**
|
||||
展示 Agent 可配置、可维护、可复用。
|
||||
|
||||
**核心内容:**
|
||||
|
||||
- Skill 列表:完整性检查、字段抽取、一致性核查、Word 回填、飞书通知。
|
||||
- 中部编辑区:角色说明、工具绑定、输入输出约束、启停配置。
|
||||
- 右侧运行预览:最近测试结果、命中工具、失败原因。
|
||||
- 底部版本历史和发布状态。
|
||||
|
||||
### 7. Agent 工作台大屏
|
||||
|
||||
**目标:**
|
||||
作为演示高潮页,向领导/评委解释“这一轮审核发生了什么”。
|
||||
|
||||
**核心内容:**
|
||||
|
||||
- 顶部大标题与批次状态。
|
||||
- 左侧流程总览:资料进入、规则装载、字段池建立、一致性比对、风险汇总。
|
||||
- 中央主舞台:Agent 工作流时间轴,展示每一步的输入、动作、输出和解释。
|
||||
- 右侧风险热力与关键告警。
|
||||
- 底部证据矩阵:法规依据、命中文档、责任人、待补动作。
|
||||
|
||||
## 跳转与演示动线
|
||||
|
||||
推荐演示顺序:
|
||||
|
||||
1. 首页说明平台定位。
|
||||
2. 进入知识库页说明法规与规则如何维护。
|
||||
3. 进入文件中心说明资料如何入库、切片、归类。
|
||||
4. 进入审核工作台发起一次完整性或一致性检查。
|
||||
5. 进入 Skill 页解释为何 Agent 行为可控。
|
||||
6. 进入 MCP 页说明可接飞书与外部能力。
|
||||
7. 最后切到大屏汇总整轮审核过程。
|
||||
|
||||
## 数据策略
|
||||
|
||||
本轮原型以高保真演示为优先,允许使用页面级演示数据,但必须满足:
|
||||
|
||||
- 术语与字段名称来自新版需求分析。
|
||||
- 状态设计贴近真实业务流程。
|
||||
- 页面间批次名称、产品名称、风险项和规则口径保持一致。
|
||||
|
||||
## 实现策略
|
||||
|
||||
基于当前 Django 模板工程直接重构前端:
|
||||
|
||||
1. 保留现有 Django 应用与路由边界。
|
||||
2. 新增平台页应用承接知识库、MCP、Skill、大屏页面。
|
||||
3. 重做 `base.html` 及所有主要模板的布局和样式。
|
||||
4. 使用共享演示数据构造页面内容,保证视觉统一和讲解一致。
|
||||
|
||||
## 测试与验证
|
||||
|
||||
原型完成后至少验证:
|
||||
|
||||
1. Django 路由可访问。
|
||||
2. 首页、知识库、文件中心、审核工作台、MCP、Skill、大屏页面均可打开。
|
||||
3. 页面导航互通。
|
||||
4. `python manage.py check` 通过。
|
||||
5. 如无模板语法问题,关键页面可在本地服务下正常渲染。
|
||||
142
docs/原型设计/1.1.资料包导入页原型设计.md
Normal file
142
docs/原型设计/1.1.资料包导入页原型设计.md
Normal file
@@ -0,0 +1,142 @@
|
||||
# 资料包导入页原型设计
|
||||
|
||||
## 1. 页面目标
|
||||
|
||||
把注册申报资料的导入、解包、扫描、目录汇总和章节点识别结果集中展示出来,让用户第一眼就明白本平台的输入对象是“资料包”,不是单篇文档。
|
||||
|
||||
## 2. 适用角色
|
||||
|
||||
- 注册资料专员
|
||||
- 文档整理人员
|
||||
- 演示讲解人
|
||||
|
||||
## 3. 页面布局分区
|
||||
|
||||
页面建议采用“三段式”:
|
||||
|
||||
1. 顶部导入条
|
||||
2. 中部处理看板
|
||||
3. 底部目录汇总区
|
||||
|
||||
建议分区:
|
||||
|
||||
- 顶部:批次信息、上传入口、导入方式切换
|
||||
- 左侧:文件 / 压缩包导入队列
|
||||
- 中部:处理流水线
|
||||
- 右侧:异常与待复核箱
|
||||
- 底部:目录树与目录汇总表
|
||||
|
||||
## 4. 核心卡片 / 表格 / 状态区
|
||||
|
||||
### 4.1 导入入口卡
|
||||
|
||||
展示:
|
||||
|
||||
- 批量文件上传
|
||||
- 文件夹导入
|
||||
- 压缩包导入
|
||||
- 支持格式标签:`pdf / docx / doc / zip / rar / 7z`
|
||||
|
||||
### 4.2 处理流水线
|
||||
|
||||
按步骤展示:
|
||||
|
||||
1. 创建批次
|
||||
2. 文件校验
|
||||
3. 解包
|
||||
4. 文件树扫描
|
||||
5. 页数统计
|
||||
6. 章节点识别
|
||||
7. 目录汇总
|
||||
|
||||
每一步显示:
|
||||
|
||||
- 当前状态
|
||||
- 处理数量
|
||||
- 成功 / 失败数
|
||||
|
||||
### 4.3 异常箱
|
||||
|
||||
展示以下异常类型:
|
||||
|
||||
- 页数待复核
|
||||
- 扩展名与 MIME 不一致
|
||||
- 扫描件待 OCR
|
||||
- 章节点识别失败
|
||||
- 解包失败
|
||||
|
||||
### 4.4 目录汇总表
|
||||
|
||||
表格列建议:
|
||||
|
||||
- 原始相对路径
|
||||
- 文件名
|
||||
- 文件类型
|
||||
- 页数
|
||||
- 页数可信度
|
||||
- 章节点
|
||||
- 资料名称
|
||||
- 处理状态
|
||||
- 是否命中法规目录
|
||||
|
||||
## 5. 关键字段定义
|
||||
|
||||
页面主要消费 `registration_overview_report`。
|
||||
|
||||
关键字段:
|
||||
|
||||
- `batch_id`
|
||||
- `file_count`
|
||||
- `supported_file_count`
|
||||
- `failed_file_count`
|
||||
- `total_page_count`
|
||||
- `page_count_status`
|
||||
- `chapter_summary`
|
||||
- `documents[]`
|
||||
|
||||
目录条目关键字段:
|
||||
|
||||
- `original_filename`
|
||||
- `relative_path`
|
||||
- `file_type`
|
||||
- `chapter_code`
|
||||
- `chapter_name`
|
||||
- `page_count`
|
||||
- `page_count_confidence`
|
||||
- `processing_status`
|
||||
- `needs_manual_review`
|
||||
|
||||
## 6. 关键交互
|
||||
|
||||
- 点击“上传压缩包”后,展示模拟导入进度。
|
||||
- 点击目录树节点,可在右侧高亮对应文件。
|
||||
- 点击异常项,可筛选下方表格。
|
||||
- 点击单个文件行,可打开“文档详情抽屉”,展示页数统计方式和章节点识别结果。
|
||||
- 点击“进入法规完整性检查”,跳转下一页。
|
||||
|
||||
## 7. 与上下游页面的数据关系
|
||||
|
||||
上游:无,属于演示主线起点。
|
||||
|
||||
下游:
|
||||
|
||||
- 法规完整性检查页直接消费目录汇总结果。
|
||||
- 字段抽取页复用文档主数据、文本状态和章节点结果。
|
||||
- 治理台中的 RAG 文档源管理可从该页二级入口进入。
|
||||
|
||||
## 8. 演示话术重点
|
||||
|
||||
- 强调本平台处理的是整套注册资料,不是单文档聊天。
|
||||
- 强调压缩包、目录层级、页数和章节点是后续审核的事实基础。
|
||||
- 强调异常箱的价值在于把“资料问题”前置,而不是等到审核后才发现。
|
||||
|
||||
## 9. 与知识库 / 治理台的关联入口
|
||||
|
||||
本页应提供以下治理入口:
|
||||
|
||||
- `查看 RAG 入库策略`
|
||||
- `查看支持文件类型配置`
|
||||
- `查看章节点识别规则`
|
||||
- `重跑切片任务`
|
||||
|
||||
这些入口统一打开治理台抽屉,不在本页直接展开 CRUD。
|
||||
120
docs/原型设计/1.2.审核任务工作台原型设计.md
Normal file
120
docs/原型设计/1.2.审核任务工作台原型设计.md
Normal file
@@ -0,0 +1,120 @@
|
||||
# 审核任务工作台原型设计
|
||||
|
||||
## 1. 页面目标
|
||||
|
||||
作为整套原型的首页,先把当前批次的审核进度、任务状态、关键风险和操作入口集中展示,让用户在 10 秒内理解平台价值和当前处理位置。
|
||||
|
||||
## 2. 适用角色
|
||||
|
||||
- 注册申报负责人
|
||||
- 项目经理
|
||||
- 复试演示讲解人
|
||||
|
||||
## 3. 页面布局分区
|
||||
|
||||
页面建议采用“总览头图 + 流程卡片 + 风险与待办双栏”。
|
||||
|
||||
分区如下:
|
||||
|
||||
- 顶部 Hero:批次、产品、流程、总体结论
|
||||
- 中部七卡任务区
|
||||
- 下方左侧:风险总览
|
||||
- 下方右侧:待办动作与推荐下一步
|
||||
|
||||
## 4. 核心卡片 / 表格 / 状态区
|
||||
|
||||
### 4.1 批次总览 Hero
|
||||
|
||||
展示:
|
||||
|
||||
- 批次编号
|
||||
- 产品名称
|
||||
- 当前流程类型
|
||||
- 当前审核阶段
|
||||
- 最高风险等级
|
||||
- 是否允许正式导出
|
||||
|
||||
### 4.2 七个流程任务卡片
|
||||
|
||||
固定七张卡片:
|
||||
|
||||
1. 资料包导入
|
||||
2. 目录汇总
|
||||
3. 法规完整性检查
|
||||
4. 字段抽取
|
||||
5. 一致性核查
|
||||
6. 风险预警
|
||||
7. Word 回填导出
|
||||
|
||||
每张卡片展示:
|
||||
|
||||
- 任务名称
|
||||
- 当前状态
|
||||
- 关键指标
|
||||
- 最近执行时间
|
||||
- 进入页面按钮
|
||||
|
||||
### 4.3 风险总览区
|
||||
|
||||
展示:
|
||||
|
||||
- 高 / 中 / 低风险数量
|
||||
- 当前阻断原因
|
||||
- 需要人工复核的字段数
|
||||
|
||||
### 4.4 待办动作区
|
||||
|
||||
展示:
|
||||
|
||||
- 缺失项补充建议
|
||||
- 字段冲突待确认项
|
||||
- 推荐下一步操作
|
||||
|
||||
## 5. 关键字段定义
|
||||
|
||||
建议聚合使用以下对象:
|
||||
|
||||
- `registration_overview_report`
|
||||
- `registration_completeness_report`
|
||||
- `registration_field_extraction_report`
|
||||
- `registration_consistency_report`
|
||||
- `registration_risk_report`
|
||||
- `registration_word_export_report`
|
||||
|
||||
工作台摘要字段:
|
||||
|
||||
- `task_name`
|
||||
- `task_status`
|
||||
- `last_run_at`
|
||||
- `summary_label`
|
||||
- `summary_value`
|
||||
- `entry_target`
|
||||
|
||||
## 6. 关键交互
|
||||
|
||||
- 点击任务卡片进入对应页面。
|
||||
- 点击“查看总体风险”滚动到风险区。
|
||||
- 点击“打开治理台”查看规则版本、字段 Schema、模板版本。
|
||||
- 鼠标悬浮卡片显示“本任务输入来自哪里,输出流向哪里”。
|
||||
|
||||
## 7. 与上下游页面的数据关系
|
||||
|
||||
上游:汇总所有页面结果。
|
||||
|
||||
下游:为各页面提供统一入口,不产生独立业务结果。
|
||||
|
||||
## 8. 演示话术重点
|
||||
|
||||
- 先讲“流程闭环”,再讲某个点上的智能能力。
|
||||
- 突出这不是自由问答,而是受控的任务执行工作台。
|
||||
- 强调每个任务卡片都有状态、有输入输出、有结构化结果。
|
||||
|
||||
## 9. 与知识库 / 治理台的关联入口
|
||||
|
||||
工作台页右上角提供:
|
||||
|
||||
- `规则版本总览`
|
||||
- `模板版本总览`
|
||||
- `责任人映射总览`
|
||||
|
||||
适合作为讲解治理能力的总入口。
|
||||
123
docs/原型设计/1.3.法规完整性检查页原型设计.md
Normal file
123
docs/原型设计/1.3.法规完整性检查页原型设计.md
Normal file
@@ -0,0 +1,123 @@
|
||||
# 法规完整性检查页原型设计
|
||||
|
||||
## 1. 页面目标
|
||||
|
||||
对照 NMPA 法规要求,展示当前资料包的齐套性、错放情况、法规依据、风险等级和处理建议,让用户知道“缺了什么、为什么缺、依据是什么”。
|
||||
|
||||
## 2. 适用角色
|
||||
|
||||
- 注册申报负责人
|
||||
- 法规专员
|
||||
- 质控复核人员
|
||||
|
||||
## 3. 页面布局分区
|
||||
|
||||
推荐采用“三栏 + 底部证据表”布局:
|
||||
|
||||
- 左栏:法规目录树与章节范围
|
||||
- 中栏:缺失项 / 错放项主列表
|
||||
- 右栏:法规依据和风险摘要
|
||||
- 底部:证据与建议表
|
||||
|
||||
## 4. 核心卡片 / 表格 / 状态区
|
||||
|
||||
### 4.1 法规目录树
|
||||
|
||||
展示:
|
||||
|
||||
- `CH1 ~ CH6`
|
||||
- 已匹配数量
|
||||
- 缺失数量
|
||||
- 待复核数量
|
||||
|
||||
### 4.2 问题列表
|
||||
|
||||
分标签展示:
|
||||
|
||||
- 缺失项
|
||||
- 错放项
|
||||
- 疑似提供
|
||||
- 待人工复核
|
||||
|
||||
每条记录展示:
|
||||
|
||||
- 章节
|
||||
- 资料名称
|
||||
- 当前状态
|
||||
- 风险等级
|
||||
- 命中文档或未命中说明
|
||||
|
||||
### 4.3 法规依据舱
|
||||
|
||||
展示:
|
||||
|
||||
- 规则包名称
|
||||
- 规则版本
|
||||
- 法规原文来源
|
||||
- 证据片段
|
||||
- 适用流程
|
||||
|
||||
### 4.4 处理建议表
|
||||
|
||||
列建议:
|
||||
|
||||
- 问题类型
|
||||
- 问题说明
|
||||
- 法规依据
|
||||
- 风险等级
|
||||
- 建议动作
|
||||
- 责任角色
|
||||
|
||||
## 5. 关键字段定义
|
||||
|
||||
页面主要消费 `registration_completeness_report`。
|
||||
|
||||
关键字段:
|
||||
|
||||
- `required_item_count`
|
||||
- `provided_item_count`
|
||||
- `missing_item_count`
|
||||
- `suspected_item_count`
|
||||
- `misplaced_item_count`
|
||||
- `manual_review_item_count`
|
||||
- `highest_risk_level`
|
||||
- `pass_status`
|
||||
- `missing_items[]`
|
||||
- `misplaced_items[]`
|
||||
- `manual_review_items[]`
|
||||
- `evidence_refs[]`
|
||||
- `suggestions[]`
|
||||
|
||||
## 6. 关键交互
|
||||
|
||||
- 点击目录树章节,筛选中部问题列表。
|
||||
- 点击缺失项,右侧法规依据自动切换。
|
||||
- 点击“查看证据片段”,展开 RAG 命中内容。
|
||||
- 点击“进入字段抽取”,继续主线。
|
||||
|
||||
## 7. 与上下游页面的数据关系
|
||||
|
||||
上游:消费 `registration_overview_report`。
|
||||
|
||||
下游:
|
||||
|
||||
- 风险预警页复用完整性结论。
|
||||
- 飞书通知页可引用完整性问题摘要。
|
||||
- 治理台中的法规规则包和 RAG 文档源由本页进入最自然。
|
||||
|
||||
## 8. 演示话术重点
|
||||
|
||||
- 强调完整性判断由结构化规则决定,不由大模型自由发挥。
|
||||
- 强调 RAG 的职责是给证据,不是当裁判。
|
||||
- 强调风险等级和责任角色已经提前结构化,便于协同。
|
||||
|
||||
## 9. 与知识库 / 治理台的关联入口
|
||||
|
||||
本页应提供:
|
||||
|
||||
- `查看规则包`
|
||||
- `查看法规原文切片`
|
||||
- `新增法规来源`
|
||||
- `编辑章节要求`
|
||||
|
||||
所有操作进入治理台对应 CRUD 视图。
|
||||
124
docs/原型设计/1.4.字段抽取与字段池页原型设计.md
Normal file
124
docs/原型设计/1.4.字段抽取与字段池页原型设计.md
Normal file
@@ -0,0 +1,124 @@
|
||||
# 字段抽取与字段池页原型设计
|
||||
|
||||
## 1. 页面目标
|
||||
|
||||
展示从说明书、申请表、产品列表等资料中抽取出的结构化字段,并把来源、置信度、标准值、待复核状态和是否可回填统一展示出来。
|
||||
|
||||
## 2. 适用角色
|
||||
|
||||
- 注册资料专员
|
||||
- 数据校对人员
|
||||
- 模板回填使用人
|
||||
|
||||
## 3. 页面布局分区
|
||||
|
||||
建议采用“顶部摘要 + 中部字段池表格 + 右侧来源证据抽屉”。
|
||||
|
||||
分区如下:
|
||||
|
||||
- 顶部:字段抽取统计
|
||||
- 中部:字段池主表
|
||||
- 下方:待复核字段区
|
||||
- 右侧:字段来源详情抽屉
|
||||
|
||||
## 4. 核心卡片 / 表格 / 状态区
|
||||
|
||||
### 4.1 抽取摘要卡
|
||||
|
||||
展示:
|
||||
|
||||
- 目标字段数量
|
||||
- 已抽取数量
|
||||
- 待复核字段数量
|
||||
- 冲突候选数量
|
||||
- 可回填字段数量
|
||||
|
||||
### 4.2 字段池主表
|
||||
|
||||
列建议:
|
||||
|
||||
- 字段编码
|
||||
- 中文字段名
|
||||
- 标准值
|
||||
- 原文值
|
||||
- 来源文档
|
||||
- 来源位置
|
||||
- 抽取方式
|
||||
- 置信度
|
||||
- 冲突状态
|
||||
- 待复核状态
|
||||
- 是否可回填
|
||||
|
||||
### 4.3 待复核区
|
||||
|
||||
重点突出:
|
||||
|
||||
- 低置信度字段
|
||||
- 长文本归纳字段
|
||||
- 来源不唯一字段
|
||||
|
||||
## 5. 关键字段定义
|
||||
|
||||
页面主要消费 `registration_field_extraction_report`。
|
||||
|
||||
关键字段:
|
||||
|
||||
- `target_field_count`
|
||||
- `extracted_field_count`
|
||||
- `manual_review_field_count`
|
||||
- `conflict_candidate_count`
|
||||
- `field_pool_status`
|
||||
- `field_pool_items[]`
|
||||
- `manual_review_fields[]`
|
||||
- `evidence_refs[]`
|
||||
|
||||
字段池条目关键字段:
|
||||
|
||||
- `field_key`
|
||||
- `field_label`
|
||||
- `standard_value`
|
||||
- `raw_value`
|
||||
- `source_document_name`
|
||||
- `source_location`
|
||||
- `extract_method`
|
||||
- `confidence`
|
||||
- `conflict_status`
|
||||
- `manual_review_required`
|
||||
- `fillable`
|
||||
|
||||
## 6. 关键交互
|
||||
|
||||
- 支持按“全部 / 可回填 / 待复核 / 高置信度”切换。
|
||||
- 点击字段行打开来源详情。
|
||||
- 点击“查看原文片段”展开证据区。
|
||||
- 点击“标记推荐值”模拟人工确认。
|
||||
- 点击“进入一致性核查”继续主线。
|
||||
|
||||
## 7. 与上下游页面的数据关系
|
||||
|
||||
上游:
|
||||
|
||||
- 来自资料导入页的文档主数据
|
||||
- 来自完整性检查页的前置校验状态
|
||||
|
||||
下游:
|
||||
|
||||
- 一致性核查页直接使用字段池
|
||||
- Word 回填导出页使用可回填字段集
|
||||
|
||||
## 8. 演示话术重点
|
||||
|
||||
- 强调统一字段池是后续一致性核查和回填导出的中间事实层。
|
||||
- 强调固定字段优先规则抽取,长文本才交给 LLM 辅助归纳。
|
||||
- 强调每个字段都有来源,不是“模型猜你要什么”。
|
||||
|
||||
## 9. 与知识库 / 治理台的关联入口
|
||||
|
||||
本页应提供:
|
||||
|
||||
- `维护字段 Schema`
|
||||
- `维护字段来源优先级`
|
||||
- `查看字段映射规则`
|
||||
- `重跑抽取策略`
|
||||
|
||||
这些入口接入治理台的字段 Schema 和模板映射 CRUD。
|
||||
113
docs/原型设计/1.5.一致性核查页原型设计.md
Normal file
113
docs/原型设计/1.5.一致性核查页原型设计.md
Normal file
@@ -0,0 +1,113 @@
|
||||
# 一致性核查页原型设计
|
||||
|
||||
## 1. 页面目标
|
||||
|
||||
基于统一字段池,对同一审核范围内不同文档的关键字段做完全一致比对,清楚展示冲突字段、来源对比和混档风险。
|
||||
|
||||
## 2. 适用角色
|
||||
|
||||
- 注册资料负责人
|
||||
- 复核人员
|
||||
- 项目经理
|
||||
|
||||
## 3. 页面布局分区
|
||||
|
||||
建议采用“范围确认条 + 冲突主表 + 对比视图 + 风险侧栏”。
|
||||
|
||||
分区如下:
|
||||
|
||||
- 顶部:审核范围确认条
|
||||
- 中部:冲突字段表
|
||||
- 下部:来源对比面板
|
||||
- 右侧:混档风险与建议
|
||||
|
||||
## 4. 核心卡片 / 表格 / 状态区
|
||||
|
||||
### 4.1 范围确认条
|
||||
|
||||
展示:
|
||||
|
||||
- 当前批次
|
||||
- 已纳入文档数量
|
||||
- 排除法规资料说明
|
||||
- 是否存在疑似跨产品文档
|
||||
|
||||
### 4.2 冲突字段主表
|
||||
|
||||
列建议:
|
||||
|
||||
- 字段名
|
||||
- 比对结果
|
||||
- 冲突值数量
|
||||
- 来源文档数
|
||||
- 最高风险等级
|
||||
- 是否疑似混档
|
||||
|
||||
### 4.3 来源对比面板
|
||||
|
||||
按选中字段展示:
|
||||
|
||||
- 文档 A 值
|
||||
- 文档 B 值
|
||||
- 来源章节
|
||||
- 来源页码
|
||||
- 标准化结果
|
||||
|
||||
### 4.4 风险侧栏
|
||||
|
||||
展示:
|
||||
|
||||
- 冲突字段总数
|
||||
- 混档告警数量
|
||||
- 待复核字段数
|
||||
- 建议处理动作
|
||||
|
||||
## 5. 关键字段定义
|
||||
|
||||
页面主要消费 `registration_consistency_report`。
|
||||
|
||||
关键字段:
|
||||
|
||||
- `checked_field_count`
|
||||
- `consistent_field_count`
|
||||
- `conflict_field_count`
|
||||
- `manual_review_field_count`
|
||||
- `mixed_package_warning_count`
|
||||
- `highest_risk_level`
|
||||
- `pass_status`
|
||||
- `conflict_fields[]`
|
||||
- `manual_review_fields[]`
|
||||
- `mixed_package_warnings[]`
|
||||
- `suggestions[]`
|
||||
|
||||
## 6. 关键交互
|
||||
|
||||
- 点击字段行,在下方切换来源对比视图。
|
||||
- 点击“仅看冲突字段”过滤表格。
|
||||
- 点击混档告警可跳到相关文档范围说明。
|
||||
- 点击“进入风险预警页”继续主线。
|
||||
|
||||
## 7. 与上下游页面的数据关系
|
||||
|
||||
上游:消费字段池。
|
||||
|
||||
下游:
|
||||
|
||||
- 风险预警页复用冲突结论
|
||||
- Word 回填导出页依据冲突状态做拦截
|
||||
|
||||
## 8. 演示话术重点
|
||||
|
||||
- 强调一致性核查不重新抽取字段,只对字段事实做比对。
|
||||
- 强调系统默认严格一致规则,避免模糊通过。
|
||||
- 强调混档风险是当前业务场景的关键价值点。
|
||||
|
||||
## 9. 与知识库 / 治理台的关联入口
|
||||
|
||||
本页应提供:
|
||||
|
||||
- `维护强一致字段规则`
|
||||
- `查看审核范围配置`
|
||||
- `查看混档识别规则`
|
||||
|
||||
这些入口进入治理台的规则包和字段规则维护视图。
|
||||
110
docs/原型设计/1.6.风险预警页原型设计.md
Normal file
110
docs/原型设计/1.6.风险预警页原型设计.md
Normal file
@@ -0,0 +1,110 @@
|
||||
# 风险预警页原型设计
|
||||
|
||||
## 1. 页面目标
|
||||
|
||||
把完整性、字段抽取和一致性核查的结果统一归并成综合风险清单,给出总风险等级、是否通过、整改建议和责任角色。
|
||||
|
||||
## 2. 适用角色
|
||||
|
||||
- 注册申报负责人
|
||||
- 项目经理
|
||||
- 业务主管
|
||||
|
||||
## 3. 页面布局分区
|
||||
|
||||
建议采用“总风险头图 + 风险矩阵 + 整改建议 + 责任分发区”。
|
||||
|
||||
分区如下:
|
||||
|
||||
- 顶部:总风险等级与通过结论
|
||||
- 左侧:风险分布矩阵
|
||||
- 中部:风险清单
|
||||
- 右侧:责任角色与建议动作
|
||||
|
||||
## 4. 核心卡片 / 表格 / 状态区
|
||||
|
||||
### 4.1 总风险头图
|
||||
|
||||
展示:
|
||||
|
||||
- 当前批次
|
||||
- 最高风险等级
|
||||
- 是否通过
|
||||
- 高 / 中 / 低风险数量
|
||||
- 待人工复核数量
|
||||
|
||||
### 4.2 风险清单表
|
||||
|
||||
列建议:
|
||||
|
||||
- 风险类型
|
||||
- 风险等级
|
||||
- 问题描述
|
||||
- 来源报告
|
||||
- 关联文档
|
||||
- 整改建议
|
||||
- 责任角色
|
||||
|
||||
### 4.3 责任分发区
|
||||
|
||||
展示:
|
||||
|
||||
- 注册资料负责人
|
||||
- 注册申报负责人
|
||||
- 临床注册负责人
|
||||
|
||||
并显示每个角色对应待处理风险数。
|
||||
|
||||
## 5. 关键字段定义
|
||||
|
||||
页面主要消费 `registration_risk_report`。
|
||||
|
||||
关键字段:
|
||||
|
||||
- `risk_item_count`
|
||||
- `high_risk_count`
|
||||
- `medium_risk_count`
|
||||
- `low_risk_count`
|
||||
- `manual_review_count`
|
||||
- `highest_risk_level`
|
||||
- `pass_status`
|
||||
- `risk_items[]`
|
||||
- `manual_review_items[]`
|
||||
- `suggestions[]`
|
||||
- `owner_notifications[]`
|
||||
|
||||
## 6. 关键交互
|
||||
|
||||
- 点击风险类型过滤清单。
|
||||
- 点击责任角色查看该角色负责的风险。
|
||||
- 点击“生成通知摘要”跳转飞书通知视图。
|
||||
- 点击“查看导出影响”跳转 Word 回填导出页。
|
||||
|
||||
## 7. 与上下游页面的数据关系
|
||||
|
||||
上游:
|
||||
|
||||
- 完整性报告
|
||||
- 字段抽取报告
|
||||
- 一致性报告
|
||||
|
||||
下游:
|
||||
|
||||
- Word 回填导出页引用是否通过和阻断项
|
||||
- 飞书通知视图引用责任人和风险摘要
|
||||
|
||||
## 8. 演示话术重点
|
||||
|
||||
- 强调整个系统不是只找问题,而是把问题归并成“可执行风险”。
|
||||
- 强调是否通过和责任角色已经直接结构化,可以进入实际协同。
|
||||
- 强调高风险会影响后续导出和通知动作。
|
||||
|
||||
## 9. 与知识库 / 治理台的关联入口
|
||||
|
||||
本页应提供:
|
||||
|
||||
- `维护风险规则`
|
||||
- `维护责任角色映射`
|
||||
- `查看准入判定规则`
|
||||
|
||||
这些入口进入治理台的风险规则和责任人映射 CRUD。
|
||||
118
docs/原型设计/1.7.Word回填导出页原型设计.md
Normal file
118
docs/原型设计/1.7.Word回填导出页原型设计.md
Normal file
@@ -0,0 +1,118 @@
|
||||
# Word回填导出页原型设计
|
||||
|
||||
## 1. 页面目标
|
||||
|
||||
展示字段如何回填到注册申报表格或对照清单中,并说明哪些字段已回填、哪些字段被风险或冲突拦截、当前导出状态如何以及用户从哪里下载文件。
|
||||
|
||||
## 2. 适用角色
|
||||
|
||||
- 注册资料专员
|
||||
- 表格整理人员
|
||||
- 审核结果使用人
|
||||
|
||||
## 3. 页面布局分区
|
||||
|
||||
建议采用“模板与导出状态头部 + 回填字段表 + 拦截项区 + 下载区”。
|
||||
|
||||
分区如下:
|
||||
|
||||
- 顶部:模板选择与导出结论
|
||||
- 中部:回填字段表
|
||||
- 右侧:拦截项和版式校验
|
||||
- 底部:导出记录与下载入口
|
||||
|
||||
## 4. 核心卡片 / 表格 / 状态区
|
||||
|
||||
### 4.1 导出头部
|
||||
|
||||
展示:
|
||||
|
||||
- 模板名称
|
||||
- 模板版本
|
||||
- 当前导出状态
|
||||
- 是否允许正式版
|
||||
- 是否允许草稿版
|
||||
|
||||
### 4.2 回填字段表
|
||||
|
||||
列建议:
|
||||
|
||||
- 占位符
|
||||
- 字段名
|
||||
- 字段值
|
||||
- 来源
|
||||
- 回填状态
|
||||
- 是否必填
|
||||
|
||||
### 4.3 拦截项区
|
||||
|
||||
展示:
|
||||
|
||||
- 冲突字段拦截
|
||||
- 高风险拦截
|
||||
- 待复核字段拦截
|
||||
- 缺失必填字段拦截
|
||||
|
||||
### 4.4 导出记录区
|
||||
|
||||
展示:
|
||||
|
||||
- 输出文件名
|
||||
- 输出版本
|
||||
- 导出时间
|
||||
- 版式校验结果
|
||||
- 下载入口
|
||||
|
||||
## 5. 关键字段定义
|
||||
|
||||
页面主要消费 `registration_word_export_report`。
|
||||
|
||||
关键字段:
|
||||
|
||||
- `template_id`
|
||||
- `export_status`
|
||||
- `fillable_field_count`
|
||||
- `filled_field_count`
|
||||
- `blocked_field_count`
|
||||
- `manual_review_field_count`
|
||||
- `layout_check_status`
|
||||
- `filled_fields[]`
|
||||
- `blocked_fields[]`
|
||||
- `output_file`
|
||||
|
||||
## 6. 关键交互
|
||||
|
||||
- 点击模板下拉模拟切换模板。
|
||||
- 点击“生成草稿”切换导出状态。
|
||||
- 点击“尝试生成正式版”时展示阻断提示。
|
||||
- 点击某个拦截项,可查看其来源风险。
|
||||
- 点击下载按钮,展示 mock 下载反馈。
|
||||
|
||||
## 7. 与上下游页面的数据关系
|
||||
|
||||
上游:
|
||||
|
||||
- 字段池
|
||||
- 一致性核查报告
|
||||
- 风险预警报告
|
||||
|
||||
下游:
|
||||
|
||||
- 飞书通知页可引用“已生成草稿”或“正式导出被阻断”的状态
|
||||
|
||||
## 8. 演示话术重点
|
||||
|
||||
- 强调平台不仅能抽取字段,还能进入真正的交付动作。
|
||||
- 强调高风险不会被忽略,系统会阻止直接生成正式报送文件。
|
||||
- 强调模板、字段映射、拦截条件都可治理,不写死在 Prompt 里。
|
||||
|
||||
## 9. 与知识库 / 治理台的关联入口
|
||||
|
||||
本页应提供:
|
||||
|
||||
- `维护 Word 模板`
|
||||
- `维护字段映射`
|
||||
- `查看导出版式校验规则`
|
||||
- `查看导出记录`
|
||||
|
||||
这些入口进入治理台的模板与映射 CRUD。
|
||||
104
docs/原型设计/1.8.飞书通知视图原型设计.md
Normal file
104
docs/原型设计/1.8.飞书通知视图原型设计.md
Normal file
@@ -0,0 +1,104 @@
|
||||
# 飞书通知视图原型设计
|
||||
|
||||
## 1. 页面目标
|
||||
|
||||
把风险预警和导出状态转成一张可发送的飞书消息卡片,展示责任人 `@`、消息摘要、Web 详情链接和发送回执,形成工作台外部协同闭环。
|
||||
|
||||
## 2. 适用角色
|
||||
|
||||
- 注册申报负责人
|
||||
- 协同群聊成员
|
||||
- 演示讲解人
|
||||
|
||||
## 3. 页面布局分区
|
||||
|
||||
建议采用“双栏布局”:
|
||||
|
||||
- 左侧:飞书消息卡片预览
|
||||
- 右侧:通知配置与发送回执
|
||||
|
||||
底部补一条 Web 详情页入口说明。
|
||||
|
||||
## 4. 核心卡片 / 表格 / 状态区
|
||||
|
||||
### 4.1 飞书消息卡片预览
|
||||
|
||||
展示:
|
||||
|
||||
- 批次编号
|
||||
- 风险摘要
|
||||
- 是否通过
|
||||
- 责任人 `@`
|
||||
- 关键风险条目
|
||||
- Web 详情按钮
|
||||
|
||||
### 4.2 通知配置区
|
||||
|
||||
展示:
|
||||
|
||||
- 触发来源
|
||||
- 飞书群聊 ID
|
||||
- 消息类型
|
||||
- 是否包含责任人通知
|
||||
- 是否附带 Web 链接
|
||||
|
||||
### 4.3 发送回执区
|
||||
|
||||
展示:
|
||||
|
||||
- 发送状态
|
||||
- 消息 ID
|
||||
- 发送时间
|
||||
- 失败原因
|
||||
|
||||
## 5. 关键字段定义
|
||||
|
||||
页面主要消费 `feishu_notification_report`。
|
||||
|
||||
关键字段:
|
||||
|
||||
- `send_status`
|
||||
- `message_type`
|
||||
- `mentioned_users[]`
|
||||
- `web_detail_url`
|
||||
- `receipt.message_id`
|
||||
- `receipt.sent_at`
|
||||
|
||||
同时复用风险页中的:
|
||||
|
||||
- `highest_risk_level`
|
||||
- `pass_status`
|
||||
- `owner_notifications[]`
|
||||
|
||||
## 6. 关键交互
|
||||
|
||||
- 点击“切换卡片样式”模拟不同消息模板。
|
||||
- 点击“发送通知”切换为已发送状态。
|
||||
- 点击责任人标签,查看角色映射详情。
|
||||
- 点击 Web 详情按钮,跳转到 mock 审计详情链接。
|
||||
|
||||
## 7. 与上下游页面的数据关系
|
||||
|
||||
上游:
|
||||
|
||||
- 风险预警页提供责任角色和风险摘要
|
||||
- Word 回填导出页提供导出状态
|
||||
|
||||
下游:无,属于主线收尾页。
|
||||
|
||||
## 8. 演示话术重点
|
||||
|
||||
- 强调平台不止有 Web 界面,还有飞书协同入口。
|
||||
- 强调系统可以把风险结果直接转换成责任人可执行的通知载荷。
|
||||
- 强调通知里保留 Web 详情链接,便于追溯。
|
||||
|
||||
## 9. 与知识库 / 治理台的关联入口
|
||||
|
||||
本页应提供:
|
||||
|
||||
- `维护责任人映射`
|
||||
- `维护飞书机器人配置`
|
||||
- `维护消息模板`
|
||||
- `查看发送日志`
|
||||
|
||||
这些入口进入治理台中的责任人映射和飞书通知配置 CRUD。
|
||||
222
docs/原型设计/1.9.知识库与治理台原型设计.md
Normal file
222
docs/原型设计/1.9.知识库与治理台原型设计.md
Normal file
@@ -0,0 +1,222 @@
|
||||
# 知识库与治理台原型设计
|
||||
|
||||
## 1. 页面目标
|
||||
|
||||
作为整套原型的治理能力承载层,统一展示法规知识、RAG 证据、字段标准、模板映射、责任人和飞书配置如何被维护,并明确支持完整 CRUD。
|
||||
|
||||
本页在 HTML 中不独立占据主导航,而是以“治理台抽屉 / 配置弹窗 / 详情侧栏”的形式从各业务页面打开。
|
||||
|
||||
## 2. 适用角色
|
||||
|
||||
- 规则维护人员
|
||||
- 平台管理员
|
||||
- 注册资料平台主管
|
||||
- 演示讲解人
|
||||
|
||||
## 3. 治理台布局分区
|
||||
|
||||
建议采用“左侧治理对象导航 + 中部列表 + 右侧详情 / 编辑抽屉”的结构。
|
||||
|
||||
左侧对象导航固定包含:
|
||||
|
||||
1. 法规规则包
|
||||
2. RAG 文档源
|
||||
3. RAG 切片
|
||||
4. 字段 Schema
|
||||
5. Word 模板与字段映射
|
||||
6. 责任人映射
|
||||
7. 飞书通知配置
|
||||
|
||||
## 4. 法规规则包 CRUD
|
||||
|
||||
### 4.1 列表字段
|
||||
|
||||
- 规则包名称
|
||||
- 适用流程
|
||||
- 版本号
|
||||
- 启用状态
|
||||
- 最近更新时间
|
||||
- 维护人
|
||||
|
||||
### 4.2 必备操作
|
||||
|
||||
- 新增规则包
|
||||
- 编辑规则包
|
||||
- 复制新版本
|
||||
- 启用 / 停用
|
||||
- 删除未生效草稿
|
||||
- 查看章节要求详情
|
||||
|
||||
### 4.3 原型交互要求
|
||||
|
||||
- 点击规则包行,右侧打开章节树与要求项详情。
|
||||
- 点击“新增规则包”,打开表单弹窗。
|
||||
|
||||
## 5. RAG 文档源 CRUD
|
||||
|
||||
### 5.1 列表字段
|
||||
|
||||
- 文档名称
|
||||
- 文档类型
|
||||
- 来源类别
|
||||
- 版本号
|
||||
- 入库状态
|
||||
- 切片数量
|
||||
- 最近同步时间
|
||||
|
||||
### 5.2 必备操作
|
||||
|
||||
- 上传新文档源
|
||||
- 替换版本
|
||||
- 编辑元数据
|
||||
- 停用文档源
|
||||
- 删除失效文档源
|
||||
- 重新入库
|
||||
|
||||
### 5.3 原型交互要求
|
||||
|
||||
- 支持按“法规 / 模板 / 业务资料”过滤。
|
||||
- 点击文档源查看切片预览和召回配置。
|
||||
|
||||
## 6. RAG 切片 CRUD
|
||||
|
||||
### 6.1 列表字段
|
||||
|
||||
- 切片 ID
|
||||
- 所属文档
|
||||
- 章节
|
||||
- 片段摘要
|
||||
- 切片长度
|
||||
- 召回状态
|
||||
- 最近更新时间
|
||||
|
||||
### 6.2 必备操作
|
||||
|
||||
- 新增手工切片
|
||||
- 编辑切片摘要
|
||||
- 合并切片
|
||||
- 拆分切片
|
||||
- 删除切片
|
||||
- 重建向量
|
||||
- 调整召回阈值
|
||||
|
||||
### 6.3 原型交互要求
|
||||
|
||||
- 点击切片行,右侧展示原文预览和命中场景。
|
||||
- 支持“查看证据命中历史”的详情抽屉。
|
||||
|
||||
## 7. 字段 Schema CRUD
|
||||
|
||||
### 7.1 列表字段
|
||||
|
||||
- 字段编码
|
||||
- 中文名
|
||||
- 字段类型
|
||||
- 是否可回填
|
||||
- 是否强一致
|
||||
- 启用状态
|
||||
- 版本号
|
||||
|
||||
### 7.2 必备操作
|
||||
|
||||
- 新增字段
|
||||
- 编辑字段
|
||||
- 启停字段
|
||||
- 删除草稿字段
|
||||
- 复制 schema 版本
|
||||
|
||||
### 7.3 原型交互要求
|
||||
|
||||
- 点击字段查看来源优先级和适用页面。
|
||||
- 支持切换“回填字段 / 强一致字段 / 全部字段”。
|
||||
|
||||
## 8. Word 模板与字段映射 CRUD
|
||||
|
||||
### 8.1 列表字段
|
||||
|
||||
- 模板名称
|
||||
- 输出类型
|
||||
- 版本号
|
||||
- 占位符数量
|
||||
- 启用状态
|
||||
- 最近更新时间
|
||||
|
||||
### 8.2 必备操作
|
||||
|
||||
- 上传模板
|
||||
- 编辑模板元数据
|
||||
- 编辑占位符映射
|
||||
- 启用 / 停用版本
|
||||
- 删除未发布版本
|
||||
- 预览模板
|
||||
|
||||
### 8.3 原型交互要求
|
||||
|
||||
- 点击模板打开占位符和字段映射详情。
|
||||
- 支持查看“阻断条件影响哪些占位符”。
|
||||
|
||||
## 9. 责任人映射 CRUD
|
||||
|
||||
### 9.1 列表字段
|
||||
|
||||
- 映射类型
|
||||
- 章节 / 风险类型
|
||||
- 责任角色
|
||||
- 飞书用户 ID
|
||||
- 启用状态
|
||||
- 备注
|
||||
|
||||
### 9.2 必备操作
|
||||
|
||||
- 新增映射
|
||||
- 编辑映射
|
||||
- 启停映射
|
||||
- 删除映射
|
||||
- 批量导入映射
|
||||
|
||||
### 9.3 原型交互要求
|
||||
|
||||
- 点击某条映射可联动查看受影响风险项或飞书卡片预览。
|
||||
|
||||
## 10. 飞书通知配置 CRUD
|
||||
|
||||
### 10.1 列表字段
|
||||
|
||||
- 配置名称
|
||||
- 群聊 / 机器人标识
|
||||
- 消息模板
|
||||
- Web 链接模板
|
||||
- 启用状态
|
||||
- 最近测试状态
|
||||
|
||||
### 10.2 必备操作
|
||||
|
||||
- 新增配置
|
||||
- 编辑配置
|
||||
- 切换消息模板
|
||||
- 启用 / 停用
|
||||
- 删除草稿配置
|
||||
- 发送测试消息
|
||||
|
||||
### 10.3 原型交互要求
|
||||
|
||||
- 支持查看 interactive card 模板预览。
|
||||
- 支持查看最近一次回执记录。
|
||||
|
||||
## 11. 与业务页面的入口关系
|
||||
|
||||
各主页面的治理入口分配如下:
|
||||
|
||||
- 资料包导入页:RAG 文档源、章节点规则
|
||||
- 法规完整性检查页:法规规则包、RAG 切片
|
||||
- 字段抽取页:字段 Schema、字段来源优先级
|
||||
- 一致性核查页:强一致规则
|
||||
- 风险预警页:风险规则、责任人映射
|
||||
- Word 回填页:模板与字段映射
|
||||
- 飞书通知视图:责任人映射、飞书通知配置
|
||||
|
||||
## 12. 演示话术重点
|
||||
|
||||
- 强调这套系统不是一次性写死,而是可以被维护和演进。
|
||||
- 强调法规判断、RAG 证据、字段标准、模板映射和飞书配置都能被可视化治理。
|
||||
- 强调 CRUD 的存在,说明平台具备从 Demo 走向实际业务平台的治理基础。
|
||||
231
docs/原型设计/1.整体原型设计.md
Normal file
231
docs/原型设计/1.整体原型设计.md
Normal file
@@ -0,0 +1,231 @@
|
||||
# 注册审核平台整体原型设计
|
||||
|
||||
## 1. 产品定位与演示目标
|
||||
|
||||
本轮原型面向:
|
||||
|
||||
```text
|
||||
试剂盒临床注册文件准备与审核智能体平台
|
||||
```
|
||||
|
||||
原型不强调“通用 Agent 工具箱”,而是围绕 NMPA 体外诊断试剂注册申报资料场景,展示一条可讲解、可追溯、可协同的审核闭环。
|
||||
|
||||
本轮演示目标:
|
||||
|
||||
1. 让评委在 1 分钟内理解平台解决什么问题。
|
||||
2. 让业务人员看到资料包导入、法规核查、字段抽取、一致性核查、风险预警、Word 回填、飞书协同的完整链路。
|
||||
3. 让技术评委看到系统具备规则优先、RAG 证据解释、结构化输出和治理后台能力。
|
||||
4. 为后续 Django 页面重构或前端实现提供可直接照做的页面规格。
|
||||
|
||||
## 2. 演示总动线
|
||||
|
||||
推荐演示顺序:
|
||||
|
||||
1. 从“审核任务工作台”进入,先看 7 个流程任务卡片和当前批次状态。
|
||||
2. 跳到“资料包导入页”,解释资料包、目录、页数和章节点识别。
|
||||
3. 进入“法规完整性检查页”,展示缺失项、错放项和法规依据。
|
||||
4. 进入“字段抽取与字段池页”,展示统一字段池、置信度和待复核字段。
|
||||
5. 进入“一致性核查页”,展示字段冲突和混档风险。
|
||||
6. 进入“风险预警页”,说明总风险等级、是否通过、整改建议和责任角色。
|
||||
7. 进入“Word 回填导出页”,说明自动回填、导出拦截和下载入口。
|
||||
8. 最后展示“飞书通知视图”,形成协同闭环。
|
||||
|
||||
知识库与治理台不作为独立主线页面插入,而是作为上述页面的配置入口、侧边抽屉或管理弹层出现,用来回答“规则从哪里来、谁来维护、如何增删改查”。
|
||||
|
||||
## 3. 统一视觉风格
|
||||
|
||||
### 3.1 视觉关键词
|
||||
|
||||
- 监管科技
|
||||
- 专业可信
|
||||
- 高信息密度
|
||||
- 可解释工作台
|
||||
- 演示友好
|
||||
|
||||
### 3.2 色彩建议
|
||||
|
||||
- 主背景:浅灰蓝与米白渐变,形成轻量但不空泛的工作台底色。
|
||||
- 主强调色:深青蓝,用于导航、主按钮、激活态和重点数值。
|
||||
- 风险色:铜橙、深红,用于缺失、冲突、高风险、阻断状态。
|
||||
- 成功色:低饱和绿色,用于完成、可通过、已同步状态。
|
||||
- 中性色:冷灰,用于说明文字、边框、标签和禁用态。
|
||||
|
||||
### 3.3 组件风格
|
||||
|
||||
- 使用“带状布局 + 信息舱 + 分析表格”的组合,不做普通后台卡片堆砌。
|
||||
- 表格、目录树、证据侧栏、步骤时间线是核心表达方式。
|
||||
- 高风险结论必须同时展示证据来源和责任角色,避免只有颜色没有解释。
|
||||
|
||||
## 4. 统一交互规范
|
||||
|
||||
### 4.1 全局导航
|
||||
|
||||
- 顶部固定展示:平台名称、当前批次、产品名称、流程类型、全局风险状态。
|
||||
- 左侧流程导航固定展示 8 个主页面入口。
|
||||
- 每个页面右上角保留“打开治理台”入口。
|
||||
|
||||
### 4.2 统一交互规则
|
||||
|
||||
- 所有结果页都支持“查看来源证据”。
|
||||
- 所有关键对象都支持“打开详情抽屉”。
|
||||
- 所有治理对象都遵循“列表 -> 详情 -> 新增 / 编辑 / 启停 / 删除”的统一 CRUD 结构。
|
||||
- 风险阻断项必须在 Word 导出页和飞书通知视图里继续可见,保证前后呼应。
|
||||
|
||||
### 4.3 状态规范
|
||||
|
||||
统一状态口径:
|
||||
|
||||
- `待导入`
|
||||
- `处理中`
|
||||
- `已完成`
|
||||
- `待复核`
|
||||
- `已阻断`
|
||||
- `已发送`
|
||||
- `失败`
|
||||
|
||||
统一风险口径:
|
||||
|
||||
- `高`
|
||||
- `中`
|
||||
- `低`
|
||||
- `待确认`
|
||||
|
||||
## 5. 统一 Mock 数据口径
|
||||
|
||||
本轮所有文档和 HTML 共用同一组演示数据,避免页面间口径冲突。
|
||||
|
||||
### 5.1 批次口径
|
||||
|
||||
- `batch_id`: `SUB-20260603-001`
|
||||
- `workflow_type`: `registration`
|
||||
- `product_name`: `新型冠状病毒 2019-nCoV 核酸检测试剂盒`
|
||||
- `applicant_name`: `示例生物科技(上海)有限公司`
|
||||
- `chapter_scope`: `CH1 ~ CH6`
|
||||
|
||||
### 5.2 主线风险口径
|
||||
|
||||
固定演示问题:
|
||||
|
||||
1. `CH1.11.4` 缺少一份必交声明类资料。
|
||||
2. 一份沟通记录疑似错放到 `CH1.9` 目录。
|
||||
3. 说明书与申请表中的产品名称存在文本不一致。
|
||||
4. 储存条件字段存在待人工复核状态。
|
||||
5. 风险等级为高,当前批次不允许正式导出,仅允许生成草稿。
|
||||
6. 飞书通知需要 `@注册资料负责人` 和 `@注册申报负责人`。
|
||||
|
||||
### 5.3 共用对象定义
|
||||
|
||||
文档和 HTML 共用以下结构化对象名称:
|
||||
|
||||
- `registration_overview_report`
|
||||
- `registration_completeness_report`
|
||||
- `registration_field_extraction_report`
|
||||
- `registration_consistency_report`
|
||||
- `registration_risk_report`
|
||||
- `registration_word_export_report`
|
||||
- `feishu_notification_report`
|
||||
|
||||
治理台对象:
|
||||
|
||||
- `knowledge_rule_package`
|
||||
- `rag_source_document`
|
||||
- `rag_chunk_item`
|
||||
- `field_schema_item`
|
||||
- `template_mapping_item`
|
||||
- `owner_mapping_item`
|
||||
- `feishu_channel_config`
|
||||
|
||||
## 6. 页面跳转关系
|
||||
|
||||
主页面跳转关系如下:
|
||||
|
||||
```text
|
||||
审核任务工作台
|
||||
-> 资料包导入页
|
||||
-> 法规完整性检查页
|
||||
-> 字段抽取与字段池页
|
||||
-> 一致性核查页
|
||||
-> 风险预警页
|
||||
-> Word 回填导出页
|
||||
-> 飞书通知视图
|
||||
```
|
||||
|
||||
跨页关系约束:
|
||||
|
||||
- 资料包导入页产出 `registration_overview_report`。
|
||||
- 法规完整性检查页消费 `registration_overview_report`,产出 `registration_completeness_report`。
|
||||
- 字段抽取与字段池页消费导入结果和完整性结果,产出 `registration_field_extraction_report`。
|
||||
- 一致性核查页消费字段池,产出 `registration_consistency_report`。
|
||||
- 风险预警页消费前三类报告,产出 `registration_risk_report`。
|
||||
- Word 回填导出页消费字段池、一致性和风险报告,产出 `registration_word_export_report`。
|
||||
- 飞书通知视图消费风险报告和导出报告,产出 `feishu_notification_report`。
|
||||
|
||||
## 7. HTML 演示站说明
|
||||
|
||||
### 7.1 交付方式
|
||||
|
||||
交付一个单文件 HTML:
|
||||
|
||||
`docs/原型设计/registration-prototype-demo.html`
|
||||
|
||||
该文件仅展示 mock 内容,不接真实 Django 路由,不调用真实接口。
|
||||
|
||||
### 7.2 HTML 结构要求
|
||||
|
||||
- 一个全局 App Shell
|
||||
- 八个主页面 section
|
||||
- 一个治理台抽屉层
|
||||
- 一份统一 mock 数据对象
|
||||
- 一组轻量 JavaScript 交互
|
||||
|
||||
### 7.3 必备交互
|
||||
|
||||
- 切换 8 个页面视图
|
||||
- 展开 / 收起目录树
|
||||
- 切换流程任务卡片选中态
|
||||
- 打开治理台抽屉
|
||||
- 切换治理对象 CRUD 子视图
|
||||
- 模拟 Word 导出状态切换
|
||||
- 模拟飞书消息卡片预览
|
||||
|
||||
## 8. 文档拆分说明
|
||||
|
||||
本轮分页文档如下:
|
||||
|
||||
1. [1.1.资料包导入页原型设计](F:\PyCharm\DEMO-AGENT\docs\原型设计\1.1.资料包导入页原型设计.md)
|
||||
2. [1.2.审核任务工作台原型设计](F:\PyCharm\DEMO-AGENT\docs\原型设计\1.2.审核任务工作台原型设计.md)
|
||||
3. [1.3.法规完整性检查页原型设计](F:\PyCharm\DEMO-AGENT\docs\原型设计\1.3.法规完整性检查页原型设计.md)
|
||||
4. [1.4.字段抽取与字段池页原型设计](F:\PyCharm\DEMO-AGENT\docs\原型设计\1.4.字段抽取与字段池页原型设计.md)
|
||||
5. [1.5.一致性核查页原型设计](F:\PyCharm\DEMO-AGENT\docs\原型设计\1.5.一致性核查页原型设计.md)
|
||||
6. [1.6.风险预警页原型设计](F:\PyCharm\DEMO-AGENT\docs\原型设计\1.6.风险预警页原型设计.md)
|
||||
7. [1.7.Word回填导出页原型设计](F:\PyCharm\DEMO-AGENT\docs\原型设计\1.7.Word回填导出页原型设计.md)
|
||||
8. [1.8.飞书通知视图原型设计](F:\PyCharm\DEMO-AGENT\docs\原型设计\1.8.飞书通知视图原型设计.md)
|
||||
9. [1.9.知识库与治理台原型设计](F:\PyCharm\DEMO-AGENT\docs\原型设计\1.9.知识库与治理台原型设计.md)
|
||||
|
||||
## 9. 实现边界
|
||||
|
||||
本轮原型只解决:
|
||||
|
||||
1. 演示表达
|
||||
2. 页面结构
|
||||
3. 模块关系
|
||||
4. 数据口径
|
||||
5. 治理台 CRUD 展示
|
||||
|
||||
本轮原型不直接承诺:
|
||||
|
||||
1. 后端真实接口联调
|
||||
2. Django 模板替换
|
||||
3. 真实 RAG 召回
|
||||
4. 真实 Word 文件生成
|
||||
5. 真实飞书 OpenAPI 调用
|
||||
|
||||
## 10. 结论
|
||||
|
||||
这套原型的核心讲法应统一为:
|
||||
|
||||
```text
|
||||
资料包治理 -> 法规完整性核查 -> 字段池沉淀 -> 一致性检查 -> 风险预警 -> Word 回填导出 -> 飞书协同闭环
|
||||
```
|
||||
|
||||
治理台负责回答“规则和知识如何维护”,工作台负责回答“这一批资料现在审核到了哪里、为什么这样判断、下一步谁来处理”。
|
||||
1803
docs/原型设计/registration-prototype-demo.html
Normal file
1803
docs/原型设计/registration-prototype-demo.html
Normal file
File diff suppressed because it is too large
Load Diff
BIN
docs/原始材料/【模拟题二】试剂盒临床注册文件准备与审核Agent.docx
Normal file
BIN
docs/原始材料/【模拟题二】试剂盒临床注册文件准备与审核Agent.docx
Normal file
Binary file not shown.
@@ -0,0 +1,62 @@
|
||||
**试剂盒临床注册文件准备与审核智能体搭建**
|
||||
|
||||
**一、背景**
|
||||
|
||||
卡尤迪生物研发团队在推进NMPA(国家药品监督管理局)注册申报时,需准备大量合规性文件,包括产品技术要求、说明书、检测报告、临床评估资料等。
|
||||
|
||||
公司计划组建AI Agent新团队,目标为"试剂盒NMPA注册文件准备与审核智能体",实现文件目录自动汇总、法规完整性检查、关键信息自动提取与填写、缺失文件预警、文档一致性核查,提升注册效率并降低合规风险。
|
||||
|
||||
**二、任务目标**
|
||||
|
||||
请你作为 AI Agent 工程师候选人,设计并实现(或详细描述)一个智能体,能够:
|
||||
|
||||
1. 自动汇总注册申报文件夹中的所有文件及页数
|
||||
2. 对照 NMPA 法规要求核查文件完整性并预警缺失
|
||||
3. 提取产品关键信息并自动填写至申报文件
|
||||
4. 核查文档结构与信息一致性
|
||||
5. 输出合规风险预警与处理建议
|
||||
|
||||
**三、具体要求如下**
|
||||
|
||||
**1. 自动汇总文件夹文件目录与页数。**
|
||||
|
||||
文件目录参考附件。
|
||||
|
||||
**2. 按照NMPA现行法规要求核查文件完整性。**
|
||||
|
||||
- 对照NMPA法规检查所需文件是否齐全(如注册申报资料基本要求、产品技术要求、注册检验报告等)
|
||||
- 自动识别缺失文件并通知责任人
|
||||
- 参考法规来源网站:
|
||||
|
||||
<https://www.cmde.org.cn/xwdt/zxyw/20210930163300622.html、>
|
||||
|
||||
<https://www.nmpa.gov.cn/>
|
||||
|
||||
**3. 从产品文件中提取关键信息并自动填写至目标文件。**
|
||||
|
||||
- 自动提取:产品名称、检测靶标、适用范围、储存条件、性能指标等核心信息
|
||||
- 将提取信息自动填入注册申报表格或对照清单
|
||||
|
||||
**4. 核查文档结构、信息一致性与章节规范性。**
|
||||
|
||||
- 检测章节是否完整(如分析灵敏度、特异性、重复性等必检项目)
|
||||
- 不同文档间同一信息是否一致(如产品名称、规格型号等)
|
||||
- 格式是否符合NMPA要求的规范章节结构
|
||||
|
||||
**5. 提供合规风险预警与处理建议。**
|
||||
|
||||
例如:"文件X:缺少临床评估报告,请补充"或"产品Y:说明书与检测报告中的适用范围描述不一致,请核对"
|
||||
|
||||
**附加要求【在复试时陈述,需结合 Demo 演示】**
|
||||
|
||||
**1. 架构搭建思路(基于 Demo 版)**
|
||||
|
||||
- 展示Demo运行结果(文件目录汇总表、法规完整性报告、信息提取对照表、异常预警列表)
|
||||
- 结合你实现的Demo,说明智能体的整体工作流(如:文件扫描 → 目录汇总 → 法规匹配 → 信息提取 → 一致性核查 → 风险预警)
|
||||
- 展示Demo中实际调用的关键工具/库(如 pdfplumber / PyMuPDF、正则表达式、规则引擎、向量检索等),并分析选用理由
|
||||
- 简述Demo中如何体现文件完整性检测、信息一致性核查、法规条款匹配等难点规则的处理
|
||||
|
||||
**2. 基于 Demo 版的迭代规划**
|
||||
|
||||
- 说明当前Demo实现了哪些核心功能,哪些是模拟数据/简化逻辑
|
||||
- 下一版本最想增加的一个功能以及需要投入的技术资源(如 NMPA 官网 API 对接、文件版本管理、多语言支持等),并说明为什么优先做它
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
docs/原始材料/关于公布体外诊断试剂注册申报资料要求和批准证明文件格式的公告/体外诊断试剂安全和性能基本原则清单.doc
Normal file
BIN
docs/原始材料/关于公布体外诊断试剂注册申报资料要求和批准证明文件格式的公告/体外诊断试剂安全和性能基本原则清单.doc
Normal file
Binary file not shown.
BIN
docs/原始材料/关于公布体外诊断试剂注册申报资料要求和批准证明文件格式的公告/体外诊断试剂延续注册申报资料要求及说明.doc
Normal file
BIN
docs/原始材料/关于公布体外诊断试剂注册申报资料要求和批准证明文件格式的公告/体外诊断试剂延续注册申报资料要求及说明.doc
Normal file
Binary file not shown.
BIN
docs/原始材料/关于公布体外诊断试剂注册申报资料要求和批准证明文件格式的公告/体外诊断试剂注册申报资料要求及说明.doc
Normal file
BIN
docs/原始材料/关于公布体外诊断试剂注册申报资料要求和批准证明文件格式的公告/体外诊断试剂注册申报资料要求及说明.doc
Normal file
Binary file not shown.
Binary file not shown.
BIN
docs/原始材料/目标产品说明书.docx
Normal file
BIN
docs/原始材料/目标产品说明书.docx
Normal file
Binary file not shown.
BIN
docs/原始材料/第1章 监管信息/CH1.11.1 符合标准的清单.docx
Normal file
BIN
docs/原始材料/第1章 监管信息/CH1.11.1 符合标准的清单.docx
Normal file
Binary file not shown.
BIN
docs/原始材料/第1章 监管信息/CH1.11.5 真实性声明.docx
Normal file
BIN
docs/原始材料/第1章 监管信息/CH1.11.5 真实性声明.docx
Normal file
Binary file not shown.
BIN
docs/原始材料/第1章 监管信息/CH1.11.6 符合性声明.docx
Normal file
BIN
docs/原始材料/第1章 监管信息/CH1.11.6 符合性声明.docx
Normal file
Binary file not shown.
BIN
docs/原始材料/第1章 监管信息/CH1.2 监管信息目录.docx
Normal file
BIN
docs/原始材料/第1章 监管信息/CH1.2 监管信息目录.docx
Normal file
Binary file not shown.
BIN
docs/原始材料/第1章 监管信息/CH1.4 申请表.docx
Normal file
BIN
docs/原始材料/第1章 监管信息/CH1.4 申请表.docx
Normal file
Binary file not shown.
BIN
docs/原始材料/第1章 监管信息/CH1.5 产品列表.docx
Normal file
BIN
docs/原始材料/第1章 监管信息/CH1.5 产品列表.docx
Normal file
Binary file not shown.
BIN
docs/原始材料/第1章 监管信息/CH1.9 产品申报前沟通的说明.doc
Normal file
BIN
docs/原始材料/第1章 监管信息/CH1.9 产品申报前沟通的说明.doc
Normal file
Binary file not shown.
BIN
docs/原始材料/附件 4 体外诊断试剂注册申报资料要求及说明.doc
Normal file
BIN
docs/原始材料/附件 4 体外诊断试剂注册申报资料要求及说明.doc
Normal file
Binary file not shown.
@@ -1,71 +0,0 @@
|
||||
# 模块详细设计文档索引
|
||||
|
||||
## 1. 设计文档说明
|
||||
|
||||
本目录存放 Universal Agent Demo Framework V1 的设计文档。需求文档回答“要做什么”,设计文档回答“怎么实现、边界在哪里、如何验证”。
|
||||
|
||||
文档命名统一使用中文编号,便于复试讲解和按顺序阅读。
|
||||
|
||||
## 2. 模块设计文档列表
|
||||
|
||||
| 顺序 | 文档 | 说明 |
|
||||
|---|---|---|
|
||||
| 0 | `0.设计文档索引.md` | 当前索引 |
|
||||
| 1 | `1.智能体总体设计.md` | 智能核心总体链路、配置、输出和 Adapter |
|
||||
| 2 | `2.功能流程设计.md` | 复试准备、演示、上传、入库、对话和审计流程 |
|
||||
| 3 | `3.数据库设计.md` | Django 数据模型、字段、索引和初始化策略 |
|
||||
| 4 | `4.页面与路由设计.md` | 页面结构、URL、跳转和异常状态 |
|
||||
| 5 | `5.部署设计.md` | 本地、Docker、环境变量和持久化 |
|
||||
|
||||
模块详细设计位于 `模块设计/`:
|
||||
|
||||
| 模块 | 文档 |
|
||||
|---|---|
|
||||
| 配置 | `模块设计/1.配置模块详细设计.md` |
|
||||
| 场景 | `模块设计/2.场景模块详细设计.md` |
|
||||
| 文档 | `模块设计/3.文档模块详细设计.md` |
|
||||
| 对话 | `模块设计/4.对话模块详细设计.md` |
|
||||
| 审计 | `模块设计/5.审计模块详细设计.md` |
|
||||
| 智能核心 | `模块设计/6.智能核心模块详细设计.md` |
|
||||
|
||||
## 3. 模块依赖关系
|
||||
|
||||
```text
|
||||
config
|
||||
|-- apps.scenarios
|
||||
|-- apps.documents
|
||||
|-- apps.chat
|
||||
|-- apps.audit
|
||||
|
||||
apps.scenarios
|
||||
|-- reads configs/*.yaml
|
||||
|
||||
apps.documents
|
||||
|-- depends on apps.scenarios
|
||||
|-- calls agent_core.rag.ingest
|
||||
|
||||
apps.chat
|
||||
|-- depends on apps.scenarios
|
||||
|-- calls agent_core.orchestrator
|
||||
|-- calls apps.audit.services
|
||||
|
||||
apps.audit
|
||||
|-- stores AgentResult snapshots
|
||||
|
||||
agent_core
|
||||
|-- consumes scenario config
|
||||
|-- uses RAG, tools, LLM provider and structured output parser
|
||||
```
|
||||
|
||||
## 4. 推荐阅读顺序
|
||||
|
||||
1. `docs/需求分析/1.V1总需求文档.md`
|
||||
2. `docs/需求分析/2.模块需求索引.md`
|
||||
3. `docs/设计文档/1.智能体总体设计.md`
|
||||
4. `docs/设计文档/2.功能流程设计.md`
|
||||
5. `docs/设计文档/3.数据库设计.md`
|
||||
6. `docs/设计文档/4.页面与路由设计.md`
|
||||
7. `docs/设计文档/5.部署设计.md`
|
||||
8. `docs/设计文档/模块设计/*.md`
|
||||
|
||||
后续编码时,每个模块应先对照对应需求文档和详细设计,再实现模型、服务、视图和测试。
|
||||
@@ -1,211 +0,0 @@
|
||||
# 智能体总体设计文档
|
||||
|
||||
## 1. 设计目标
|
||||
|
||||
Agent 设计的核心目标是支持未知复试题的快速适配。
|
||||
|
||||
系统不针对单一业务写死,而是通过场景配置、知识库、工具和输出模板组合出不同业务 Agent。
|
||||
|
||||
```text
|
||||
业务 Agent = 场景配置 + 知识库 + 工具集 + 输出模板 + 审计日志 + 模型适配器
|
||||
```
|
||||
|
||||
## 2. Agent 类型
|
||||
|
||||
V1 预置 5 类 Agent 场景:
|
||||
|
||||
| Agent ID | 名称 | 适用场景 |
|
||||
|---|---|---|
|
||||
| `knowledge_qa` | 知识库问答助手 | SOP、制度、客服知识库 |
|
||||
| `document_review` | 文档审核助手 | 合同、制度、SOP、材料审核 |
|
||||
| `ticket_assistant` | 工单处理助手 | 客服、售后、运维工单 |
|
||||
| `quality_analysis` | 质量异常分析助手 | 生产、质检、缺陷分析 |
|
||||
| `risk_audit` | 风险审核助手 | 财务、采购、报销、合同风险 |
|
||||
|
||||
## 3. Agent 执行链路
|
||||
|
||||
```text
|
||||
用户输入
|
||||
↓
|
||||
加载场景配置
|
||||
↓
|
||||
判断是否启用 RAG
|
||||
↓
|
||||
检索知识库片段
|
||||
↓
|
||||
加载可用工具
|
||||
↓
|
||||
构造 Prompt
|
||||
↓
|
||||
调用大模型
|
||||
↓
|
||||
解析工具调用和结构化输出
|
||||
↓
|
||||
生成 AgentResult
|
||||
↓
|
||||
写入审计日志
|
||||
↓
|
||||
页面展示
|
||||
```
|
||||
|
||||
## 4. 场景配置结构
|
||||
|
||||
场景配置使用 YAML,V1 以配置文件作为场景唯一事实来源,后台管理不作为场景配置入口。
|
||||
|
||||
```yaml
|
||||
id: quality_analysis
|
||||
name: 质量异常分析助手
|
||||
description: 用于分析生产质量异常、检索 SOP、生成处理建议
|
||||
|
||||
agent:
|
||||
role: 质量管理专家
|
||||
goal: 根据用户问题、知识库和工具结果,输出可执行的质量分析报告
|
||||
system_prompt: ""
|
||||
instructions:
|
||||
- 回答必须基于知识库或工具结果
|
||||
- 不确定时必须说明缺失信息
|
||||
- 涉及质量风险时给出风险等级
|
||||
|
||||
rag:
|
||||
enabled: true
|
||||
collection: quality_docs
|
||||
top_k: 5
|
||||
|
||||
tools:
|
||||
- query_demo_records
|
||||
- calculate_rate
|
||||
|
||||
output:
|
||||
type: quality_report
|
||||
|
||||
audit:
|
||||
enabled: true
|
||||
log_retrieval: true
|
||||
log_tool_calls: true
|
||||
```
|
||||
|
||||
## 5. Prompt 组成
|
||||
|
||||
Prompt 建议由以下部分组成:
|
||||
|
||||
```text
|
||||
系统角色
|
||||
任务目标
|
||||
行为约束
|
||||
输出格式要求
|
||||
知识库检索内容
|
||||
工具调用结果
|
||||
用户问题
|
||||
```
|
||||
|
||||
V1 不追求复杂 Prompt 框架,优先保证可读、可改、可解释。
|
||||
|
||||
## 6. RAG 策略
|
||||
|
||||
RAG 在 V1 中负责给 Agent 提供题目材料和业务知识。
|
||||
|
||||
入库流程:
|
||||
|
||||
```text
|
||||
上传文件
|
||||
↓
|
||||
抽取文本
|
||||
↓
|
||||
文本切分
|
||||
↓
|
||||
生成 embedding
|
||||
↓
|
||||
写入 Chroma
|
||||
```
|
||||
|
||||
检索流程:
|
||||
|
||||
```text
|
||||
用户问题
|
||||
↓
|
||||
按 scenario_id 和可选 document_ids 过滤
|
||||
↓
|
||||
向量检索 top_k
|
||||
↓
|
||||
返回片段内容、来源和分数
|
||||
```
|
||||
|
||||
## 7. 工具调用策略
|
||||
|
||||
工具用于补足大模型不能直接可靠完成的业务动作。
|
||||
|
||||
V1 内置工具:
|
||||
|
||||
| 工具 | 用途 |
|
||||
|---|---|
|
||||
| `calculate_rate` | 计算比例、缺陷率、通过率 |
|
||||
| `query_demo_records` | 查询模拟业务数据 |
|
||||
| `check_required_fields` | 检查必填项 |
|
||||
| `generate_action_items` | 生成行动项 |
|
||||
|
||||
工具返回格式:
|
||||
|
||||
```json
|
||||
{
|
||||
"tool_name": "calculate_rate",
|
||||
"success": true,
|
||||
"arguments": {},
|
||||
"result": {},
|
||||
"error": ""
|
||||
}
|
||||
```
|
||||
|
||||
## 8. 结构化输出
|
||||
|
||||
V1 支持以下输出类型:
|
||||
|
||||
- `general_answer`
|
||||
- `document_review_report`
|
||||
- `ticket_response`
|
||||
- `quality_report`
|
||||
- `risk_audit_report`
|
||||
|
||||
结构化输出优先使用 JSON。
|
||||
|
||||
解析失败时:
|
||||
|
||||
- 保留模型原始输出。
|
||||
- 返回解析错误。
|
||||
- 页面展示原始回答。
|
||||
- 审计日志记录失败原因。
|
||||
|
||||
## 9. AgentResult
|
||||
|
||||
Agent Core 统一返回:
|
||||
|
||||
```json
|
||||
{
|
||||
"answer": "",
|
||||
"structured_output": {},
|
||||
"references": [],
|
||||
"tool_calls": [],
|
||||
"raw_output": "",
|
||||
"model_name": "",
|
||||
"latency_ms": 0,
|
||||
"status": "success",
|
||||
"error": ""
|
||||
}
|
||||
```
|
||||
|
||||
## 10. Adapter 策略
|
||||
|
||||
V1 默认使用自研轻量 Orchestrator,通过 OpenAI 兼容接口接入 LLM 与 Embedding,可自主选择 OpenAI、硅基流动等兼容服务。
|
||||
|
||||
后续可以扩展:
|
||||
|
||||
- OpenAI Agents SDK Adapter。
|
||||
- Dify API Adapter。
|
||||
- LangGraph Adapter。
|
||||
|
||||
所有 Adapter 应保持统一接口:
|
||||
|
||||
```text
|
||||
run_agent(scenario_config, user_input, options=None) -> AgentResult
|
||||
```
|
||||
|
||||
这样可以保证 Django 业务层不受底层 Agent 编排实现影响。
|
||||
@@ -1,169 +0,0 @@
|
||||
# V1 功能设计文档
|
||||
|
||||
## 1. 功能设计目标
|
||||
|
||||
V1 的功能设计目标是让复试展示者在本地快速完成一个可讲解、可演示、可改题的 Agent Demo。系统不追求复杂平台能力,而是优先保证以下闭环稳定:
|
||||
|
||||
- 场景配置可选择。
|
||||
- 文档可上传并入库。
|
||||
- 用户可在场景下发起对话。
|
||||
- Agent 可返回结构化结果、引用来源和工具调用记录。
|
||||
- 每次成功或失败的对话都有审计记录。
|
||||
- 本地和 Docker 均可启动。
|
||||
|
||||
## 2. 用户角色
|
||||
|
||||
V1 仅设计一个用户角色:Demo 操作者。
|
||||
|
||||
该角色负责启动系统、选择场景、上传材料、触发入库、发起对话、查看输出和审计日志。系统不在 V1 中区分管理员、审核员、普通用户等权限角色。
|
||||
|
||||
## 3. 核心业务流程
|
||||
|
||||
```text
|
||||
启动系统
|
||||
↓
|
||||
查看 5 个预置场景
|
||||
↓
|
||||
选择场景
|
||||
↓
|
||||
上传题目材料
|
||||
↓
|
||||
触发知识库入库
|
||||
↓
|
||||
发起 Agent 对话
|
||||
↓
|
||||
查看结构化输出、引用和工具调用
|
||||
↓
|
||||
查看审计日志
|
||||
```
|
||||
|
||||
任一环节失败时,页面应给出明确提示,并尽量保留用户已完成的上下文。
|
||||
|
||||
## 4. 场景选择流程
|
||||
|
||||
1. 首页调用 `apps.scenarios.services.list_scenarios()`。
|
||||
2. 服务从 `configs/` 读取 YAML 场景配置。
|
||||
3. 校验必填字段、工具名称和输出类型。
|
||||
4. 页面展示场景名称、描述、适用题型、启用状态。
|
||||
5. 用户点击进入 `/chat/<scenario_id>/`。
|
||||
|
||||
异常处理:
|
||||
|
||||
- 配置目录不存在:展示空状态和配置目录提示。
|
||||
- 单个配置非法:不阻断其他配置,页面展示该配置错误。
|
||||
- 场景不存在:跳转或渲染错误页,提示检查场景 ID。
|
||||
|
||||
## 5. 文件上传流程
|
||||
|
||||
1. 用户进入 `/documents/upload/`。
|
||||
2. 页面加载可用场景下拉框。
|
||||
3. 用户选择场景并上传 `.txt`、`.md`、`.pdf` 或 `.docx` 文件。
|
||||
4. Documents 模块校验文件类型和大小。
|
||||
5. 保存文件到 `UPLOAD_ROOT/<scenario_id>/`。
|
||||
6. 写入 `UploadedDocument` 记录,状态为 `uploaded`。
|
||||
7. 返回文件列表页并展示上传结果。
|
||||
|
||||
V1 文件上传默认手动入库,避免上传大文件时页面阻塞过久。
|
||||
|
||||
## 6. 文档入库流程
|
||||
|
||||
1. 用户在文件列表点击“入库”。
|
||||
2. Documents 模块读取文件并抽取文本。
|
||||
3. 调用 `agent_core.rag.ingest.ingest_document()`。
|
||||
4. Agent Core 按固定长度切分文本。
|
||||
5. 写入本地 Chroma collection。
|
||||
6. 入库成功:更新状态为 `indexed`。
|
||||
7. 入库失败:更新状态为 `failed`,保存错误信息。
|
||||
|
||||
文本为空、文件丢失、向量库不可写都应进入失败状态,不能让页面报 500。
|
||||
|
||||
## 7. Agent 对话流程
|
||||
|
||||
```text
|
||||
用户提交问题
|
||||
↓
|
||||
Chat 表单校验
|
||||
↓
|
||||
Scenarios 加载场景配置
|
||||
↓
|
||||
Agent Core 执行 run_agent()
|
||||
↓
|
||||
RAG 按场景和可选文档范围检索知识片段
|
||||
↓
|
||||
工具系统执行可用工具
|
||||
↓
|
||||
LLM Provider 生成结果
|
||||
↓
|
||||
结构化输出解析
|
||||
↓
|
||||
Audit 写入日志
|
||||
↓
|
||||
Chat 页面展示结果
|
||||
```
|
||||
|
||||
Chat 模块只负责请求处理和页面展示,不直接写 RAG、工具和模型调用细节。
|
||||
|
||||
## 8. RAG 检索流程
|
||||
|
||||
1. Orchestrator 读取场景配置中的 `rag.enabled`、`collection`、`top_k`。
|
||||
2. 若启用 RAG,则调用 `agent_core.rag.retriever.retrieve()`。
|
||||
3. 检索必须按 `scenario_id` 过滤,避免跨场景污染。
|
||||
4. 如果用户在对话页选择了文档,则同时按 `document_ids` 过滤;未选择时使用当前场景全部已入库文档。
|
||||
5. 返回片段内容、来源文件、chunk ID、分数。
|
||||
6. 片段进入 Prompt,同时随 AgentResult 返回给页面和审计日志。
|
||||
|
||||
检索失败时,AgentResult 应记录错误或警告;若业务允许,可继续使用非 RAG 上下文回答。
|
||||
|
||||
## 9. 工具调用流程
|
||||
|
||||
1. 场景配置声明可用工具名称。
|
||||
2. Orchestrator 从 Tool Registry 查询工具。
|
||||
3. 对不可用工具记录失败,不中断整个流程。
|
||||
4. 内置工具按统一参数和返回结构执行。
|
||||
5. 工具结果进入 Prompt 或结构化输出上下文。
|
||||
6. 所有工具调用写入 AgentResult 和审计日志。
|
||||
|
||||
V1 先采用“配置声明 + Orchestrator 决策”的轻量策略,不实现复杂多轮工具调用协议。
|
||||
|
||||
## 10. 审计日志流程
|
||||
|
||||
1. Chat 模块在 Agent Core 返回后调用 `apps.audit.services.create_audit_log()`。
|
||||
2. 成功结果记录输入、输出、引用、工具调用、模型名和耗时。
|
||||
3. 失败结果也记录场景、输入、错误信息和已产生的中间结果。
|
||||
4. 日志中不得保存 `LLM_API_KEY`、环境变量完整内容或上传文件绝对敏感路径。
|
||||
5. 审计列表展示摘要,详情页展示完整 JSON 片段。
|
||||
|
||||
## 11. 复试改题流程
|
||||
|
||||
1. 判断题目最接近的模板。
|
||||
2. 复制 `configs/` 中相近 YAML。
|
||||
3. 修改场景名称、角色、目标、指令和输出类型。
|
||||
4. 上传题目文档并入库。
|
||||
5. 如题目需要计算或查询,新增一个内置工具并在场景中声明。
|
||||
6. 用 2 到 3 个问题验证输出和审计链路。
|
||||
7. 演示时重点展示配置、知识库、工具调用、结构化结果和审计日志。
|
||||
|
||||
## 12. 异常处理流程
|
||||
|
||||
| 异常 | 处理方式 |
|
||||
|---|---|
|
||||
| 场景配置缺失 | 页面展示错误,保留返回首页入口 |
|
||||
| 场景字段非法 | 标记非法配置,不影响其他场景 |
|
||||
| 上传文件类型不支持 | 表单错误提示 |
|
||||
| 文件读取失败 | 文档状态改为 `failed` |
|
||||
| RAG 入库失败 | 记录错误信息并允许重试 |
|
||||
| LLM 配置缺失 | AgentResult 返回失败,审计日志记录失败 |
|
||||
| 工具调用失败 | 记录工具失败,流程尽量继续 |
|
||||
| 结构化解析失败 | 展示原始输出并记录解析错误 |
|
||||
|
||||
## 13. V1 功能验收标准
|
||||
|
||||
- 首页可以展示 5 个预置场景。
|
||||
- 场景配置来自 YAML 文件。
|
||||
- 可以上传 `.txt`、`.md`、`.pdf` 和 `.docx` 文件。
|
||||
- 文件可触发入库,并显示 `uploaded`、`indexed`、`failed` 状态。
|
||||
- 可以进入任一场景对话页并提交问题。
|
||||
- AgentResult 至少包含回答、结构化输出、引用、工具调用、耗时和状态。
|
||||
- 成功和失败对话都能生成审计日志。
|
||||
- 审计详情可以解释一次 Agent 输出的输入、依据和过程。
|
||||
- 本地启动和 Docker 启动路径清晰可执行。
|
||||
@@ -1,144 +0,0 @@
|
||||
# V1 数据库设计文档
|
||||
|
||||
## 1. 数据库设计目标
|
||||
|
||||
V1 数据库设计优先服务本地演示、讲解清晰和快速改题。数据模型只覆盖文件、对话、审计和简单示例业务数据,不引入复杂权限、多租户或工作流状态机。
|
||||
|
||||
## 2. 数据库选型
|
||||
|
||||
默认使用 SQLite,数据库文件位于 `data/db.sqlite3`。SQLite 适合复试现场单机运行,便于 Docker 挂载和备份。
|
||||
|
||||
后续如需多人协作或更正式部署,可通过 Django settings 切换到 PostgreSQL,但 V1 不强制实现。
|
||||
|
||||
## 3. 表结构总览
|
||||
|
||||
| 表 | Django Model | 模块 | 说明 |
|
||||
|---|---|---|---|
|
||||
| uploaded_document | `UploadedDocument` | Documents | 上传文件元数据和入库状态 |
|
||||
| agent_audit_log | `AgentAuditLog` | Audit | Agent 执行审计快照 |
|
||||
| demo_business_record | `DemoBusinessRecord` | Agent Core / Tools | 内置工具可查询的模拟业务数据 |
|
||||
| chat_session | `ChatSession` | Chat | 可选,对话会话 |
|
||||
| chat_message | `ChatMessage` | Chat | 可选,对话消息 |
|
||||
|
||||
## 4. UploadedDocument 表设计
|
||||
|
||||
| 字段 | 类型 | 约束 | 说明 |
|
||||
|---|---|---|---|
|
||||
| id | BigAutoField | PK | 主键 |
|
||||
| scenario_id | CharField(100) | indexed | 关联场景 ID |
|
||||
| original_name | CharField(255) | required | 原始文件名 |
|
||||
| file | FileField | required | 文件相对路径 |
|
||||
| file_type | CharField(20) | required | `txt`、`md`、`pdf`、`docx` 等 |
|
||||
| size | PositiveIntegerField | default 0 | 字节数 |
|
||||
| status | CharField(20) | indexed | `uploaded`、`indexed`、`failed` |
|
||||
| error_message | TextField | blank | 入库失败原因 |
|
||||
| created_at | DateTimeField | auto_now_add | 上传时间 |
|
||||
| updated_at | DateTimeField | auto_now | 更新时间 |
|
||||
|
||||
状态流转:
|
||||
|
||||
```text
|
||||
uploaded -> indexed
|
||||
uploaded -> failed
|
||||
failed -> indexed
|
||||
failed -> failed
|
||||
```
|
||||
|
||||
重新入库时应按文档维度覆盖或清理旧 chunk,避免同一文件重复出现在向量检索结果中。文档选择范围由 Chat 表单本次提交的 `document_ids` 传入 Agent Core,V1 不需要为该选择单独建表。
|
||||
|
||||
## 5. AgentAuditLog 表设计
|
||||
|
||||
| 字段 | 类型 | 约束 | 说明 |
|
||||
|---|---|---|---|
|
||||
| id | BigAutoField | PK | 主键 |
|
||||
| scenario_id | CharField(100) | indexed | 场景 ID |
|
||||
| scenario_name | CharField(200) | blank | 场景名称快照 |
|
||||
| user_input | TextField | required | 用户输入 |
|
||||
| retrieved_chunks | JSONField | default list | RAG 引用片段 |
|
||||
| tool_calls | JSONField | default list | 工具调用记录 |
|
||||
| structured_output | JSONField | default dict | 结构化输出 |
|
||||
| final_answer | TextField | blank | 最终回答 |
|
||||
| raw_output | TextField | blank | 模型原始输出 |
|
||||
| model_name | CharField(100) | blank | 模型名称 |
|
||||
| latency_ms | PositiveIntegerField | default 0 | 执行耗时 |
|
||||
| status | CharField(20) | indexed | `success`、`failed` |
|
||||
| error_message | TextField | blank | 错误信息 |
|
||||
| created_at | DateTimeField | auto_now_add, indexed | 创建时间 |
|
||||
|
||||
审计日志保存的是执行快照,不依赖场景配置后续是否被修改。
|
||||
|
||||
## 6. DemoBusinessRecord 表设计
|
||||
|
||||
| 字段 | 类型 | 约束 | 说明 |
|
||||
|---|---|---|---|
|
||||
| id | BigAutoField | PK | 主键 |
|
||||
| scenario_id | CharField(100) | indexed | 适用场景 |
|
||||
| record_type | CharField(100) | indexed | 记录类型,如 defect、ticket、invoice |
|
||||
| title | CharField(255) | required | 标题 |
|
||||
| payload | JSONField | default dict | 模拟业务数据 |
|
||||
| created_at | DateTimeField | auto_now_add | 创建时间 |
|
||||
|
||||
该表为 V1 必需表,用于 `query_demo_records` 工具,避免工具只能返回硬编码数据。Django Admin 可以管理该表的数据,场景 YAML 仍不在 Admin 中编辑。
|
||||
|
||||
## 7. ChatSession 表设计
|
||||
|
||||
V1 可先不实现会话持久化。如果实现,字段建议如下:
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|---|---|---|
|
||||
| id | BigAutoField | 主键 |
|
||||
| scenario_id | CharField(100) | 场景 ID |
|
||||
| title | CharField(255) | 会话标题 |
|
||||
| created_at | DateTimeField | 创建时间 |
|
||||
| updated_at | DateTimeField | 更新时间 |
|
||||
|
||||
## 8. ChatMessage 表设计
|
||||
|
||||
V1 可通过审计日志满足演示追踪,不强制实现消息表。如果实现,字段建议如下:
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|---|---|---|
|
||||
| id | BigAutoField | 主键 |
|
||||
| session | ForeignKey(ChatSession) | 所属会话 |
|
||||
| role | CharField(20) | `user`、`assistant`、`system` |
|
||||
| content | TextField | 消息内容 |
|
||||
| audit_log | ForeignKey(AgentAuditLog, null=True) | 关联审计 |
|
||||
| created_at | DateTimeField | 创建时间 |
|
||||
|
||||
## 9. 表关系设计
|
||||
|
||||
```text
|
||||
Scenario YAML
|
||||
|-- scenario_id
|
||||
|-- UploadedDocument.scenario_id
|
||||
|-- AgentAuditLog.scenario_id
|
||||
|-- DemoBusinessRecord.scenario_id
|
||||
|-- ChatSession.scenario_id
|
||||
|
||||
ChatSession 1 -- N ChatMessage
|
||||
ChatMessage 0/1 -- 1 AgentAuditLog
|
||||
```
|
||||
|
||||
场景配置 V1 存在 YAML 中,不建 `Scenario` 数据表。这样更方便复试现场复制和修改配置文件。
|
||||
|
||||
## 10. 索引设计
|
||||
|
||||
- `UploadedDocument(scenario_id, status)`:用于按场景查看文件和入库状态。
|
||||
- `AgentAuditLog(scenario_id, created_at)`:用于按场景查看最近日志。
|
||||
- `AgentAuditLog(status, created_at)`:用于排查失败日志。
|
||||
- `DemoBusinessRecord(scenario_id, record_type)`:用于工具查询模拟数据。
|
||||
|
||||
## 11. 数据初始化策略
|
||||
|
||||
- 场景初始化:读取 `configs/*.yaml`,不写数据库。
|
||||
- 示例业务数据:可提供 Django management command 初始化 `DemoBusinessRecord`。
|
||||
- 超级用户:本地演示可手动创建,Docker 可通过说明引导创建。
|
||||
- 上传文件和 Chroma 数据:存放在 `data/` 下,通过 Docker volume 持久化。
|
||||
|
||||
## 12. 后续扩展方向
|
||||
|
||||
- 增加 `Scenario` 表,实现后台编辑场景。
|
||||
- 增加 `ToolCallLog` 独立表,用于复杂工具审计。
|
||||
- 使用 PostgreSQL JSONB 优化 JSON 查询。
|
||||
- 增加用户和权限模型。
|
||||
- 增加文档 chunk 元数据表,便于从数据库追踪向量库内容。
|
||||
@@ -1,179 +0,0 @@
|
||||
# V1 页面与路由设计文档
|
||||
|
||||
## 1. 页面设计目标
|
||||
|
||||
V1 页面使用 Django Templates,优先保证清晰、稳定、可讲解。页面应围绕复试演示的主路径组织:选择场景、上传文档、入库、对话、查看审计。
|
||||
|
||||
## 2. 页面列表
|
||||
|
||||
| 页面 | 路径 | 模块 | 说明 |
|
||||
|---|---|---|---|
|
||||
| 首页/场景列表 | `/` | Scenarios | 展示 5 个预置场景 |
|
||||
| Agent 对话页 | `/chat/<scenario_id>/` | Chat | 提交问题并展示结果 |
|
||||
| 文件列表页 | `/documents/` | Documents | 查看上传文件和入库状态 |
|
||||
| 文件上传页 | `/documents/upload/` | Documents | 上传题目材料 |
|
||||
| 文档入库动作 | `/documents/<id>/index/` | Documents | POST 触发入库 |
|
||||
| 审计日志列表 | `/audit/` | Audit | 查看对话记录 |
|
||||
| 审计日志详情 | `/audit/<log_id>/` | Audit | 查看单次执行详情 |
|
||||
| Django Admin | `/admin/` | Config | 后台管理 |
|
||||
|
||||
## 3. 路由总览
|
||||
|
||||
```text
|
||||
config.urls
|
||||
|-- "" -> apps.scenarios.urls
|
||||
|-- "chat/" -> apps.chat.urls
|
||||
|-- "documents/" -> apps.documents.urls
|
||||
|-- "audit/" -> apps.audit.urls
|
||||
|-- "admin/" -> django.contrib.admin
|
||||
```
|
||||
|
||||
各模块只暴露自己的 URL,避免把业务路由集中写在 `config.urls` 中。
|
||||
|
||||
## 4. 首页与场景列表页
|
||||
|
||||
路径:`/`
|
||||
|
||||
展示内容:
|
||||
|
||||
- 系统名称和简短定位。
|
||||
- 5 个场景卡片或列表。
|
||||
- 场景名称、描述、适用题型、启用状态。
|
||||
- “进入对话”按钮。
|
||||
- 文件管理和审计日志入口。
|
||||
|
||||
错误状态:
|
||||
|
||||
- 没有可用场景:展示配置目录提示。
|
||||
- 配置读取失败:展示失败原因和文件名。
|
||||
|
||||
## 5. Agent 对话页
|
||||
|
||||
路径:`/chat/<scenario_id>/`
|
||||
|
||||
页面区域:
|
||||
|
||||
- 场景摘要:名称、角色、目标、RAG 状态、工具列表。
|
||||
- 文档范围:当前场景下状态为 `indexed` 的文档多选框;未选择时默认使用全部已入库文档。
|
||||
- 输入区:一个 textarea 和提交按钮。
|
||||
- 结果区:自然语言回答和结构化输出。
|
||||
- 引用区:source、chunk_id、score、content。
|
||||
- 工具区:tool_name、success、arguments、result、error。
|
||||
- 审计入口:当前对话生成日志后展示详情链接。
|
||||
|
||||
POST 成功后仍渲染同一页面,保留用户问题和 AgentResult。
|
||||
|
||||
## 6. 文件上传页
|
||||
|
||||
路径:`/documents/upload/`
|
||||
|
||||
页面元素:
|
||||
|
||||
- 场景选择下拉框。
|
||||
- 文件选择控件。
|
||||
- 支持类型提示。
|
||||
- 上传按钮。
|
||||
- 错误或成功提示。
|
||||
|
||||
表单接受 `.txt`、`.md`、`.pdf`、`.docx`。PDF 仅要求纯文本抽取,DOCX 仅要求段落和普通文本抽取。
|
||||
|
||||
## 7. 文件列表页
|
||||
|
||||
路径:`/documents/`
|
||||
|
||||
展示字段:
|
||||
|
||||
- 原始文件名。
|
||||
- 所属场景。
|
||||
- 文件类型。
|
||||
- 文件大小。
|
||||
- 入库状态。
|
||||
- 上传时间。
|
||||
- 入库按钮。
|
||||
- 失败原因。
|
||||
|
||||
状态为 `indexed` 时可以显示“重新入库”,重新入库需要覆盖或清理该文档旧 chunk。
|
||||
|
||||
## 8. 审计日志列表页
|
||||
|
||||
路径:`/audit/`
|
||||
|
||||
展示字段:
|
||||
|
||||
- 日志 ID。
|
||||
- 场景名称。
|
||||
- 用户输入摘要。
|
||||
- 状态。
|
||||
- 模型名称。
|
||||
- 执行耗时。
|
||||
- 创建时间。
|
||||
- 详情入口。
|
||||
|
||||
默认按 `created_at desc` 排序。
|
||||
|
||||
## 9. 审计日志详情页
|
||||
|
||||
路径:`/audit/<log_id>/`
|
||||
|
||||
展示内容:
|
||||
|
||||
- 场景信息。
|
||||
- 用户输入。
|
||||
- 最终回答。
|
||||
- 结构化输出 JSON。
|
||||
- RAG 引用列表。
|
||||
- 工具调用列表。
|
||||
- 模型名称和耗时。
|
||||
- 错误信息。
|
||||
|
||||
JSON 内容可以先用 `<pre>` 展示,优先保证可读。
|
||||
|
||||
## 10. Django Admin 页面
|
||||
|
||||
Admin 注册:
|
||||
|
||||
- `UploadedDocument`
|
||||
- `AgentAuditLog`
|
||||
- `DemoBusinessRecord`
|
||||
|
||||
V1 不要求在 Admin 中编辑 YAML 场景,场景仍以配置文件为准。
|
||||
|
||||
## 11. 页面跳转关系
|
||||
|
||||
```text
|
||||
首页
|
||||
|-- 进入对话页
|
||||
|-- 文件列表页
|
||||
|-- 审计日志列表页
|
||||
|
||||
文件列表页
|
||||
|-- 文件上传页
|
||||
|-- 触发入库后回到文件列表页
|
||||
|
||||
对话页
|
||||
|-- 提交后留在当前对话页
|
||||
|-- 查看当前审计详情
|
||||
|
||||
审计列表页
|
||||
|-- 审计详情页
|
||||
```
|
||||
|
||||
## 12. 页面异常状态
|
||||
|
||||
| 页面 | 异常 | 展示方式 |
|
||||
|---|---|---|
|
||||
| 首页 | 场景配置为空 | 空状态和配置目录说明 |
|
||||
| 对话页 | 场景不存在 | 明确提示并提供返回首页 |
|
||||
| 对话页 | Agent 执行失败 | 展示错误、保留输入、写入失败审计 |
|
||||
| 上传页 | 文件类型错误 | 表单错误 |
|
||||
| 文件列表 | 入库失败 | 状态为 failed 并显示原因 |
|
||||
| 审计详情 | 日志不存在 | 404 或友好错误页 |
|
||||
|
||||
## 13. V1 页面验收标准
|
||||
|
||||
- 主要页面可通过浏览器访问。
|
||||
- 页面之间跳转路径完整。
|
||||
- POST 表单使用 CSRF 保护。
|
||||
- 所有用户可见错误都有中文提示。
|
||||
- Agent 对话结果可以同时看到回答、引用、工具和审计入口。
|
||||
- 页面不依赖 React/Vue。
|
||||
@@ -1,111 +0,0 @@
|
||||
# V1 部署设计文档
|
||||
|
||||
## 1. 部署设计目标
|
||||
|
||||
V1 部署目标是降低复试现场环境风险。系统应支持本地 Python 方式启动,也支持 Docker Compose 一键启动。默认不依赖外部数据库、Redis 或任务队列。
|
||||
|
||||
## 2. 本地运行方式
|
||||
|
||||
建议命令:
|
||||
|
||||
```bash
|
||||
python -m venv .venv
|
||||
.venv\Scripts\activate
|
||||
pip install -r requirements.txt
|
||||
python manage.py migrate
|
||||
python manage.py runserver
|
||||
```
|
||||
|
||||
本地运行使用 SQLite、`data/uploads` 和 `data/chroma`。
|
||||
|
||||
当前本地方式会在启动时自动读取根目录 `.env`,因此 `runserver`、`pytest` 和日常脚本可以共享同一套配置。
|
||||
|
||||
## 3. Docker 运行方式
|
||||
|
||||
建议命令:
|
||||
|
||||
```bash
|
||||
docker compose up --build
|
||||
```
|
||||
|
||||
V1 Docker Compose 只需要一个 Django Web 服务。Chroma 使用本地持久化目录,不额外启动独立服务。
|
||||
|
||||
## 4. 环境变量设计
|
||||
|
||||
| 变量 | 默认值 | 说明 |
|
||||
|---|---|---|
|
||||
| `DJANGO_SECRET_KEY` | `dev-secret-key` | 开发密钥 |
|
||||
| `DJANGO_DEBUG` | `true` | 是否开启调试 |
|
||||
| `DJANGO_ALLOWED_HOSTS` | `*` | 允许主机 |
|
||||
| `LLM_API_KEY` | 空 | 大模型 API Key |
|
||||
| `LLM_BASE_URL` | `https://api.openai.com/v1` | OpenAI 兼容接口地址,可接入 OpenAI、硅基流动等兼容服务 |
|
||||
| `LLM_MODEL` | `gpt-4.1-mini` | 默认模型 |
|
||||
| `EMBEDDING_API_KEY` | 空 | Embedding API Key;为空时可复用 `LLM_API_KEY` |
|
||||
| `EMBEDDING_BASE_URL` | 空 | Embedding OpenAI 兼容接口地址;为空时可复用 `LLM_BASE_URL` |
|
||||
| `EMBEDDING_MODEL` | `text-embedding-3-small` | 默认 Embedding 模型 |
|
||||
| `SCENARIO_CONFIG_DIR` | `configs` | 场景配置目录 |
|
||||
| `UPLOAD_ROOT` | `data/uploads` | 上传目录 |
|
||||
| `CHROMA_PATH` | `data/chroma` | 向量库目录 |
|
||||
|
||||
`.env.example` 应提供这些变量的样例,不写真实密钥。
|
||||
|
||||
当前实现说明:
|
||||
|
||||
- 本地 Python 方式启动时,会先加载根目录 `.env`,再读取进程环境中的覆盖值。
|
||||
- Docker Compose 方式可通过 `env_file` 向容器注入环境变量;当前仓库默认读取 `.env`。
|
||||
- 因此本地运行和容器运行可以默认共用一份 `.env`,但演示前仍应确认密钥和模型参数是否正确。
|
||||
|
||||
## 5. 目录挂载设计
|
||||
|
||||
Docker 需要持久化以下目录:
|
||||
|
||||
```text
|
||||
./data/db.sqlite3
|
||||
./data/uploads
|
||||
./data/chroma
|
||||
./configs
|
||||
```
|
||||
|
||||
`configs` 挂载后可以在不重建镜像的情况下修改场景配置。
|
||||
|
||||
## 6. SQLite 数据持久化
|
||||
|
||||
SQLite 文件放在 `data/db.sqlite3`。Docker 中应将 `data/` 作为 volume 挂载,避免容器重建后数据丢失。
|
||||
|
||||
## 7. Chroma 数据持久化
|
||||
|
||||
Chroma 数据放在 `data/chroma`。RAG 入库后,重启容器不应丢失向量数据。
|
||||
|
||||
## 8. 上传文件持久化
|
||||
|
||||
上传文件放在 `data/uploads/<scenario_id>/`。数据库只保存相对路径或 Django FileField 路径。
|
||||
|
||||
## 9. 启动命令设计
|
||||
|
||||
Docker 容器启动时建议执行:
|
||||
|
||||
```bash
|
||||
python manage.py migrate
|
||||
python manage.py runserver 0.0.0.0:8000
|
||||
```
|
||||
|
||||
V1 可以先用开发服务器满足演示。后续正式部署可切换到 Gunicorn。
|
||||
|
||||
## 10. 常见部署问题
|
||||
|
||||
| 问题 | 处理 |
|
||||
|---|---|
|
||||
| 端口 8000 被占用 | 修改 compose 端口映射 |
|
||||
| API Key 缺失 | 页面提示 LLM 或 Embedding 配置缺失 |
|
||||
| Chroma 目录无权限 | 检查 `data/chroma` 挂载权限 |
|
||||
| 上传目录不存在 | settings 或启动脚本创建目录 |
|
||||
| 场景配置读取失败 | 检查 `configs/*.yaml` 格式 |
|
||||
| Docker 构建慢 | 提前构建镜像或使用本地 Python 方式演示 |
|
||||
|
||||
## 11. 后续部署扩展
|
||||
|
||||
- 使用 Gunicorn + WhiteNoise。
|
||||
- 增加 PostgreSQL 服务。
|
||||
- 增加 Redis 和 Celery 做异步入库。
|
||||
- 增加 Nginx 反向代理。
|
||||
- 增加健康检查接口。
|
||||
@@ -1,112 +0,0 @@
|
||||
# 配置模块详细设计
|
||||
|
||||
## 1. 模块目标
|
||||
|
||||
Config 模块负责 Django 项目的启动配置和总装配。它不承载业务逻辑,只为其他模块提供稳定运行环境。
|
||||
|
||||
目标:
|
||||
|
||||
- 项目本地和 Docker 均可启动。
|
||||
- 环境变量可覆盖关键配置。
|
||||
- App、模板、静态资源、上传文件和数据库路径统一配置。
|
||||
- URL 总入口清晰,模块路由各自维护。
|
||||
|
||||
## 2. 职责边界
|
||||
|
||||
负责:
|
||||
|
||||
- `settings.py`、`urls.py`、`wsgi.py`、`asgi.py`。
|
||||
- 环境变量读取和默认值。
|
||||
- SQLite、静态文件、媒体文件、Chroma、场景配置目录。
|
||||
- Django Admin 和模块 URL 装配。
|
||||
|
||||
不负责:
|
||||
|
||||
- 不读取场景 YAML 业务内容。
|
||||
- 不调用 Agent Core。
|
||||
- 不处理上传文件文本抽取。
|
||||
- 不写审计日志。
|
||||
|
||||
## 3. 配置项设计
|
||||
|
||||
| 配置 | Django setting | 默认值 |
|
||||
|---|---|---|
|
||||
| `DJANGO_SECRET_KEY` | `SECRET_KEY` | `dev-secret-key` |
|
||||
| `DJANGO_DEBUG` | `DEBUG` | `true` |
|
||||
| `DJANGO_ALLOWED_HOSTS` | `ALLOWED_HOSTS` | `["*"]` |
|
||||
| `UPLOAD_ROOT` | `MEDIA_ROOT` | `BASE_DIR / "data" / "uploads"` |
|
||||
| `SCENARIO_CONFIG_DIR` | `SCENARIO_CONFIG_DIR` | `BASE_DIR / "configs"` |
|
||||
| `CHROMA_PATH` | `CHROMA_PATH` | `BASE_DIR / "data" / "chroma"` |
|
||||
| `LLM_API_KEY` | `LLM_API_KEY` | 空 |
|
||||
| `LLM_BASE_URL` | `LLM_BASE_URL` | `https://api.openai.com/v1` |
|
||||
| `LLM_MODEL` | `LLM_MODEL` | `gpt-4.1-mini` |
|
||||
| `EMBEDDING_API_KEY` | `EMBEDDING_API_KEY` | 空,默认可复用 `LLM_API_KEY` |
|
||||
| `EMBEDDING_BASE_URL` | `EMBEDDING_BASE_URL` | 空,默认可复用 `LLM_BASE_URL` |
|
||||
| `EMBEDDING_MODEL` | `EMBEDDING_MODEL` | `text-embedding-3-small` |
|
||||
|
||||
## 4. 目录路径设计
|
||||
|
||||
启动前或初始化时应确保:
|
||||
|
||||
```text
|
||||
data/
|
||||
uploads/
|
||||
chroma/
|
||||
configs/
|
||||
static/
|
||||
templates/
|
||||
```
|
||||
|
||||
V1 可以在 `settings.py` 中定义路径,在 management command 或启动脚本中创建目录。生产代码不应在每次请求中反复创建目录。
|
||||
|
||||
## 5. URL 总路由设计
|
||||
|
||||
`config.urls`:
|
||||
|
||||
```python
|
||||
urlpatterns = [
|
||||
path("admin/", admin.site.urls),
|
||||
path("", include("apps.scenarios.urls")),
|
||||
path("chat/", include("apps.chat.urls")),
|
||||
path("documents/", include("apps.documents.urls")),
|
||||
path("audit/", include("apps.audit.urls")),
|
||||
]
|
||||
```
|
||||
|
||||
开发模式下追加 `static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)`,用于访问上传文件。
|
||||
|
||||
## 6. 静态资源与上传文件设计
|
||||
|
||||
- `STATIC_URL = "static/"`
|
||||
- `STATICFILES_DIRS = [BASE_DIR / "static"]`
|
||||
- `MEDIA_URL = "media/"`
|
||||
- `MEDIA_ROOT = UPLOAD_ROOT`
|
||||
|
||||
上传文件路径由 Documents 模块按场景组织,Config 只提供根目录。
|
||||
|
||||
## 7. 环境变量读取设计
|
||||
|
||||
V1 可使用标准库 `os.environ.get()`,不强制引入复杂配置库。
|
||||
|
||||
布尔值规则:
|
||||
|
||||
```text
|
||||
"1", "true", "yes", "on" -> True
|
||||
其他 -> False
|
||||
```
|
||||
|
||||
`DJANGO_ALLOWED_HOSTS` 使用逗号分隔,空值时默认 `["*"]`。
|
||||
|
||||
当前实现约束:
|
||||
|
||||
- 本地直接运行 Django 命令时,会先尝试解析根目录 `.env` 文件,再读取进程环境中的覆盖值。
|
||||
- Docker Compose 方式可以通过 `env_file` 传入同一批变量;当前仓库默认读取 `.env`。
|
||||
- `.env.example` 只保留占位符示例,不保存真实 API Key。
|
||||
|
||||
## 8. 验收标准
|
||||
|
||||
- `python manage.py check` 通过。
|
||||
- `python manage.py migrate` 可执行。
|
||||
- `/`、`/admin/` 路由可访问。
|
||||
- `MEDIA_ROOT`、`CHROMA_PATH`、`SCENARIO_CONFIG_DIR` 在 settings 中可被其他模块引用。
|
||||
- LLM 与 Embedding 配置只从 settings 或环境变量读取,不散落在业务代码中。
|
||||
@@ -1,134 +0,0 @@
|
||||
# 场景模块详细设计
|
||||
|
||||
## 1. 模块目标
|
||||
|
||||
Scenarios 模块是业务 Agent 的入口,负责读取和展示场景配置,并向 Chat、Documents、Agent Core 提供场景上下文。
|
||||
|
||||
## 2. 职责边界
|
||||
|
||||
负责:
|
||||
|
||||
- 从 `configs/*.yaml` 读取场景。
|
||||
- 校验场景必填字段。
|
||||
- 展示场景列表和场景摘要。
|
||||
- 提供 `list_scenarios()`、`get_scenario()` 等服务。
|
||||
|
||||
不负责:
|
||||
|
||||
- 不执行 Agent。
|
||||
- 不做 RAG 检索。
|
||||
- 不调用工具和大模型。
|
||||
- 不保存审计日志。
|
||||
|
||||
## 3. 场景配置结构
|
||||
|
||||
必填结构:
|
||||
|
||||
```yaml
|
||||
id: knowledge_qa
|
||||
name: 知识库问答助手
|
||||
description: 用于 SOP、制度和内部知识库问答
|
||||
applicable_questions:
|
||||
- SOP 问答
|
||||
- 制度问答
|
||||
|
||||
agent:
|
||||
role: 知识库问答专家
|
||||
goal: 基于知识库回答用户问题
|
||||
system_prompt: ""
|
||||
instructions:
|
||||
- 回答必须基于检索内容
|
||||
|
||||
rag:
|
||||
enabled: true
|
||||
collection: knowledge_qa
|
||||
top_k: 5
|
||||
|
||||
tools:
|
||||
- generate_action_items
|
||||
|
||||
output:
|
||||
type: general_answer
|
||||
|
||||
audit:
|
||||
enabled: true
|
||||
```
|
||||
|
||||
`agent.system_prompt` 为可选字段。配置了非空值时,Agent Core 优先使用该字段作为系统提示词;为空或缺失时,由 `role`、`goal` 和 `instructions` 组合生成系统提示词。
|
||||
|
||||
`applicable_questions` 作为页面展示字段,若缺失可显示为空列表。
|
||||
|
||||
## 4. 场景加载流程
|
||||
|
||||
1. 读取 `settings.SCENARIO_CONFIG_DIR`。
|
||||
2. 遍历 `.yaml` 和 `.yml` 文件。
|
||||
3. 使用 YAML parser 转为 dict。
|
||||
4. 调用 `validate_scenario()`。
|
||||
5. 转换为 `ScenarioConfig` dataclass 或普通 dict。
|
||||
6. 按文件名或配置顺序返回。
|
||||
|
||||
为了便于复试修改,V1 不需要强缓存;若加缓存,应提供清理方式或在 DEBUG 下禁用缓存。
|
||||
|
||||
## 5. 场景校验规则
|
||||
|
||||
必填字段:
|
||||
|
||||
- `id`
|
||||
- `name`
|
||||
- `description`
|
||||
- `agent.role`
|
||||
- `agent.goal`
|
||||
- `agent.instructions`
|
||||
- `rag.enabled`
|
||||
- `tools`
|
||||
- `output.type`
|
||||
- `audit.enabled`
|
||||
|
||||
校验失败时返回包含文件名、字段路径、错误原因的结果。列表页可以跳过非法场景并展示错误摘要。
|
||||
|
||||
## 6. 页面设计
|
||||
|
||||
首页路径:`/`
|
||||
|
||||
展示:
|
||||
|
||||
- 场景名称。
|
||||
- 场景描述。
|
||||
- 适用题型。
|
||||
- RAG 是否启用。
|
||||
- 工具数量。
|
||||
- 进入对话按钮。
|
||||
|
||||
可选详情页:`/scenarios/<scenario_id>/`。V1 可以把详情合并到 Chat 页面。
|
||||
|
||||
## 7. 服务函数设计
|
||||
|
||||
```python
|
||||
def list_scenarios() -> list[ScenarioConfig]:
|
||||
"""读取配置目录中的合法场景,非法场景以错误摘要返回给页面。"""
|
||||
|
||||
def get_scenario(scenario_id: str) -> ScenarioConfig:
|
||||
"""按场景 ID 返回完整配置,找不到时抛出 ScenarioNotFound。"""
|
||||
|
||||
def validate_scenario(config: dict) -> ValidationResult:
|
||||
"""校验必填字段、字段类型、工具名称和输出类型。"""
|
||||
```
|
||||
|
||||
`get_scenario()` 找不到时抛出业务异常,例如 `ScenarioNotFound`,由 View 转成中文错误提示。
|
||||
|
||||
## 8. 异常处理
|
||||
|
||||
| 异常 | 处理 |
|
||||
|---|---|
|
||||
| 配置目录不存在 | 返回空列表和错误提示 |
|
||||
| YAML 语法错误 | 标记该文件无效 |
|
||||
| ID 重复 | 保留第一个,报告重复错误 |
|
||||
| 必填字段缺失 | 标记该场景无效 |
|
||||
| 工具不存在 | 场景仍可展示,但 Chat 执行时记录工具错误 |
|
||||
|
||||
## 9. 验收标准
|
||||
|
||||
- 首页至少展示 5 个场景。
|
||||
- 场景配置来自 `configs/` 文件。
|
||||
- 非法配置有明确错误,不导致首页 500。
|
||||
- Chat 可通过 `scenario_id` 获取完整配置。
|
||||
@@ -1,127 +0,0 @@
|
||||
# 文档模块详细设计
|
||||
|
||||
## 1. 模块目标
|
||||
|
||||
Documents 模块让用户把复试题材料快速变成 Agent 可检索的知识库。V1 必须支持 `.txt`、`.md`、`.pdf` 和 `.docx`,保证常见复试材料可以进入 RAG。
|
||||
|
||||
## 2. 职责边界
|
||||
|
||||
负责:
|
||||
|
||||
- 文件上传表单和页面。
|
||||
- 文件保存与元数据记录。
|
||||
- 读取文本内容。
|
||||
- 调用 Agent Core RAG 入库。
|
||||
- 更新入库状态。
|
||||
|
||||
不负责:
|
||||
|
||||
- 不实现向量检索算法。
|
||||
- 不生成模型回答。
|
||||
- 不直接写审计日志。
|
||||
|
||||
## 3. 数据模型设计
|
||||
|
||||
模型:`UploadedDocument`
|
||||
|
||||
字段见 `docs/设计文档/3.数据库设计.md`。
|
||||
|
||||
常量:
|
||||
|
||||
```python
|
||||
STATUS_UPLOADED = "uploaded"
|
||||
STATUS_INDEXED = "indexed"
|
||||
STATUS_FAILED = "failed"
|
||||
SUPPORTED_EXTENSIONS = {".txt", ".md", ".pdf", ".docx"}
|
||||
```
|
||||
|
||||
文件保存路径建议:
|
||||
|
||||
```text
|
||||
uploads/<scenario_id>/<YYYYMMDD>/<uuid>_<original_name>
|
||||
```
|
||||
|
||||
## 4. 文件上传流程
|
||||
|
||||
1. GET `/documents/upload/` 渲染上传表单。
|
||||
2. POST 校验 `scenario_id` 和文件。
|
||||
3. 调用 Scenarios 服务确认场景存在。
|
||||
4. 校验扩展名和文件大小。
|
||||
5. 保存文件。
|
||||
6. 创建 `UploadedDocument(status="uploaded")`。
|
||||
7. 跳转文件列表页并展示成功提示。
|
||||
|
||||
## 5. 文本抽取流程
|
||||
|
||||
抽取函数:
|
||||
|
||||
```python
|
||||
def extract_text(document: UploadedDocument) -> str:
|
||||
"""按文件类型抽取可入库纯文本,失败时抛出可展示的业务异常。"""
|
||||
```
|
||||
|
||||
规则:
|
||||
|
||||
- `.txt`:优先 UTF-8,失败时尝试系统默认编码。
|
||||
- `.md`:UTF-8 读取,保留标题、列表和正文。
|
||||
- `.pdf`:抽取纯文本,不要求 OCR、表格还原和复杂版式理解。
|
||||
- `.docx`:抽取段落、标题和普通表格文本,不要求完整保留 Word 样式。
|
||||
- 空文本视为失败。
|
||||
- 文件不存在视为失败。
|
||||
|
||||
XLSX 暂不作为 V1 必须项,可作为后续结构化业务数据导入能力。
|
||||
|
||||
## 6. RAG 入库触发流程
|
||||
|
||||
POST `/documents/<id>/index/`
|
||||
|
||||
1. 获取 `UploadedDocument`。
|
||||
2. 调用 `extract_text()`。
|
||||
3. 调用 `agent_core.rag.ingest.ingest_document()`,传入 `document_id`、`scenario_id`、文件名和抽取文本。
|
||||
4. 成功后更新 `status="indexed"`,清空 `error_message`。
|
||||
5. 失败后更新 `status="failed"`,写入 `error_message`。
|
||||
6. 重定向回文件列表页。
|
||||
|
||||
入库动作必须使用 POST,避免 GET 触发写操作。
|
||||
|
||||
已入库或失败文档允许重新入库。重新入库前需要按 `document_id` 清理或覆盖旧 chunk,避免重复检索。
|
||||
|
||||
## 7. 页面设计
|
||||
|
||||
文件列表页展示:
|
||||
|
||||
- 文件名。
|
||||
- 场景 ID。
|
||||
- 文件类型。
|
||||
- 文件大小。
|
||||
- 状态。
|
||||
- 上传时间。
|
||||
- 入库按钮。
|
||||
- 错误信息。
|
||||
|
||||
上传页展示:
|
||||
|
||||
- 场景下拉框。
|
||||
- 文件控件。
|
||||
- 支持类型提示。
|
||||
- 表单错误。
|
||||
|
||||
## 8. 异常处理
|
||||
|
||||
| 异常 | 处理 |
|
||||
|---|---|
|
||||
| 场景不存在 | 表单错误 |
|
||||
| 文件为空 | 表单错误 |
|
||||
| 扩展名不支持 | 表单错误 |
|
||||
| 文件保存失败 | 页面提示失败 |
|
||||
| 文本为空 | 状态 failed |
|
||||
| RAG 入库失败 | 状态 failed 并保存原因 |
|
||||
|
||||
## 9. 验收标准
|
||||
|
||||
- 可以上传 `.txt`、`.md`、`.pdf` 和 `.docx`。
|
||||
- 文件列表可看到记录。
|
||||
- 文件可按场景关联。
|
||||
- 入库成功状态变为 `indexed`。
|
||||
- 入库失败状态变为 `failed` 且可查看原因。
|
||||
- 入库失败或已入库文档可重新入库。
|
||||
@@ -1,118 +0,0 @@
|
||||
# 对话模块详细设计
|
||||
|
||||
## 1. 模块目标
|
||||
|
||||
Chat 模块负责复试演示中的主交互:用户选择场景后提交问题,系统展示 Agent 输出、引用、工具调用和审计入口。
|
||||
|
||||
## 2. 职责边界
|
||||
|
||||
负责:
|
||||
|
||||
- 对话页 GET/POST。
|
||||
- 用户输入表单校验。
|
||||
- 获取场景配置。
|
||||
- 调用 Agent Core。
|
||||
- 调用 Audit 服务写日志。
|
||||
- 渲染 AgentResult。
|
||||
|
||||
不负责:
|
||||
|
||||
- 不直接读取 YAML。
|
||||
- 不直接调用 LLM。
|
||||
- 不直接执行 RAG 和工具。
|
||||
- 不实现复杂多轮会话状态。
|
||||
|
||||
## 3. 页面设计
|
||||
|
||||
路径:`/chat/<scenario_id>/`
|
||||
|
||||
GET:
|
||||
|
||||
- 加载场景配置。
|
||||
- 展示场景摘要。
|
||||
- 加载当前场景下状态为 `indexed` 的文档列表。
|
||||
- 展示空表单。
|
||||
|
||||
POST:
|
||||
|
||||
- 校验输入。
|
||||
- 执行 Agent。
|
||||
- 写审计。
|
||||
- 展示结果和审计链接。
|
||||
|
||||
## 4. 表单设计
|
||||
|
||||
字段:
|
||||
|
||||
| 字段 | 类型 | 规则 |
|
||||
|---|---|---|
|
||||
| `message` | textarea | 必填,最大 4000 字 |
|
||||
| `document_ids` | 多选 | 可选,只能选择当前场景下已入库文档 |
|
||||
|
||||
错误提示:
|
||||
|
||||
- 空输入:`请输入要咨询的问题。`
|
||||
- 超长输入:`问题过长,请控制在 4000 字以内。`
|
||||
- 文档不属于当前场景或未入库:`请选择当前场景下已入库的文档。`
|
||||
|
||||
## 5. Agent Core 调用流程
|
||||
|
||||
```python
|
||||
scenario = get_scenario(scenario_id)
|
||||
result = run_agent(
|
||||
scenario_config=scenario,
|
||||
user_input=form.cleaned_data["message"],
|
||||
options={"document_ids": form.cleaned_data.get("document_ids", [])}
|
||||
)
|
||||
```
|
||||
|
||||
Chat 只依赖 Agent Core 的统一返回对象,不关心内部是否使用 RAG、工具或真实模型。
|
||||
|
||||
未选择文档时,`document_ids` 传空列表或不传,由 Agent Core 默认使用当前场景全部已入库文档。
|
||||
|
||||
## 6. 结果展示设计
|
||||
|
||||
优先级:
|
||||
|
||||
1. 如果 `structured_output` 不为空,展示结构化 JSON 或字段化结果。
|
||||
2. 展示 `answer`。
|
||||
3. 展示 `references`。
|
||||
4. 展示 `tool_calls`。
|
||||
5. 展示 `latency_ms`、`model_name`、`status`。
|
||||
6. 如果有 `error`,展示中文错误提示。
|
||||
|
||||
结构化解析失败时,页面仍展示 `raw_output` 或 `answer`。
|
||||
|
||||
## 7. 审计日志写入流程
|
||||
|
||||
Agent Core 返回后调用:
|
||||
|
||||
```python
|
||||
audit_log = create_audit_log(
|
||||
scenario_id=scenario.id,
|
||||
scenario_name=scenario.name,
|
||||
user_input=message,
|
||||
agent_result=result,
|
||||
)
|
||||
```
|
||||
|
||||
如果 Agent Core 抛异常,Chat 应构造失败结果并继续写失败审计。
|
||||
|
||||
## 8. 异常处理
|
||||
|
||||
| 异常 | 处理 |
|
||||
|---|---|
|
||||
| 场景不存在 | 显示错误并返回首页入口 |
|
||||
| 表单无效 | 留在页面并显示表单错误 |
|
||||
| Agent Core 抛异常 | 构造 failed AgentResult,写审计 |
|
||||
| 审计写入失败 | 页面提示审计失败,但展示 Agent 输出 |
|
||||
| LLM 配置缺失 | 展示模型配置缺失 |
|
||||
|
||||
## 9. 验收标准
|
||||
|
||||
- 从首页可进入对话页。
|
||||
- 可提交问题并渲染 AgentResult。
|
||||
- 可选择本次对话使用的文档范围;未选择时默认使用当前场景全部已入库文档。
|
||||
- 失败时有中文提示。
|
||||
- 成功和失败都尽量写入审计。
|
||||
- View 中没有 RAG、工具、LLM 的细节实现。
|
||||
@@ -1,121 +0,0 @@
|
||||
# 审计模块详细设计
|
||||
|
||||
## 1. 模块目标
|
||||
|
||||
Audit 模块记录 Agent 执行过程,使演示者能够解释一次输出的来源、工具调用和模型结果。它是系统从“普通问答页面”变成“可追踪业务 Agent”的关键。
|
||||
|
||||
## 2. 职责边界
|
||||
|
||||
负责:
|
||||
|
||||
- `AgentAuditLog` 模型。
|
||||
- 审计写入服务。
|
||||
- 审计列表页。
|
||||
- 审计详情页。
|
||||
- 敏感信息过滤。
|
||||
|
||||
不负责:
|
||||
|
||||
- 不执行 Agent。
|
||||
- 不执行 RAG。
|
||||
- 不执行工具。
|
||||
- 不调用模型。
|
||||
|
||||
## 3. 数据模型设计
|
||||
|
||||
模型:`AgentAuditLog`
|
||||
|
||||
字段见 `docs/设计文档/3.数据库设计.md`。
|
||||
|
||||
JSON 字段默认值必须使用函数,例如 `default=list`、`default=dict`,避免多实例共享同一对象。
|
||||
|
||||
## 4. 日志写入流程
|
||||
|
||||
服务函数:
|
||||
|
||||
```python
|
||||
def create_audit_log(
|
||||
scenario_id: str,
|
||||
scenario_name: str,
|
||||
user_input: str,
|
||||
agent_result: AgentResult,
|
||||
) -> AgentAuditLog:
|
||||
"""将 AgentResult 映射为 AgentAuditLog,并在保存前做敏感信息脱敏。"""
|
||||
```
|
||||
|
||||
写入映射:
|
||||
|
||||
- `agent_result.references` -> `retrieved_chunks`
|
||||
- `agent_result.tool_calls` -> `tool_calls`
|
||||
- `agent_result.structured_output` -> `structured_output`
|
||||
- `agent_result.answer` -> `final_answer`
|
||||
- `agent_result.raw_output` -> `raw_output`
|
||||
- `agent_result.model_name` -> `model_name`
|
||||
- `agent_result.latency_ms` -> `latency_ms`
|
||||
- `agent_result.status` -> `status`
|
||||
- `agent_result.error` -> `error_message`
|
||||
|
||||
## 5. 日志列表页设计
|
||||
|
||||
路径:`/audit/`
|
||||
|
||||
查询:
|
||||
|
||||
- 默认按创建时间倒序。
|
||||
- V1 可不做分页,若日志较多再加 Django Paginator。
|
||||
|
||||
展示:
|
||||
|
||||
- ID。
|
||||
- 场景名称。
|
||||
- 用户输入前 80 字。
|
||||
- 状态。
|
||||
- 模型名。
|
||||
- 耗时。
|
||||
- 创建时间。
|
||||
- 详情链接。
|
||||
|
||||
## 6. 日志详情页设计
|
||||
|
||||
路径:`/audit/<log_id>/`
|
||||
|
||||
展示:
|
||||
|
||||
- 基础信息。
|
||||
- 用户输入。
|
||||
- 最终回答。
|
||||
- 结构化输出。
|
||||
- RAG 检索片段。
|
||||
- 工具调用。
|
||||
- 原始输出。
|
||||
- 错误信息。
|
||||
|
||||
JSON 可用格式化后的 `<pre>` 展示。
|
||||
|
||||
## 7. 敏感信息处理
|
||||
|
||||
不得保存:
|
||||
|
||||
- `LLM_API_KEY`
|
||||
- 完整环境变量 dump
|
||||
- 用户机器上的敏感绝对路径
|
||||
- Docker secret 或 token
|
||||
|
||||
如错误信息来自异常对象,应在保存前做简单脱敏,至少替换 API Key 值。
|
||||
|
||||
## 8. 异常处理
|
||||
|
||||
| 异常 | 处理 |
|
||||
|---|---|
|
||||
| AgentResult 字段缺失 | 使用默认空值 |
|
||||
| JSON 不可序列化 | 转为字符串或空对象 |
|
||||
| 日志不存在 | 返回 404 |
|
||||
| 写入失败 | 抛给 Chat,由 Chat 展示审计失败提示 |
|
||||
|
||||
## 9. 验收标准
|
||||
|
||||
- 每次对话成功后有审计日志。
|
||||
- Agent 失败也有失败日志。
|
||||
- 列表页可查看日志摘要。
|
||||
- 详情页可查看输入、输出、引用和工具调用。
|
||||
- 日志不包含 API Key。
|
||||
@@ -1,259 +0,0 @@
|
||||
# 智能核心模块详细设计
|
||||
|
||||
## 1. 模块目标
|
||||
|
||||
Agent Core 提供独立于 Django View 的智能编排能力。它消费场景配置,执行 RAG、工具、模型调用和结构化解析,最终返回统一 AgentResult。
|
||||
|
||||
## 2. 职责边界
|
||||
|
||||
负责:
|
||||
|
||||
- Agent 编排。
|
||||
- 场景配置对象消费。
|
||||
- RAG 入库和检索。
|
||||
- 工具注册与执行。
|
||||
- LLM Provider 与 Embedding Provider。
|
||||
- 结构化输出解析。
|
||||
- AgentResult 定义。
|
||||
|
||||
不负责:
|
||||
|
||||
- 不渲染页面。
|
||||
- 不处理 Django 表单。
|
||||
- 不保存 Django Model。
|
||||
- 不管理登录权限。
|
||||
|
||||
## 3. 子模块划分
|
||||
|
||||
```text
|
||||
agent_core/
|
||||
orchestrator.py
|
||||
scenario_loader.py
|
||||
llm_provider.py
|
||||
tool_registry.py
|
||||
structured_output.py
|
||||
rag/
|
||||
ingest.py
|
||||
retriever.py
|
||||
tools/
|
||||
builtin_tools.py
|
||||
schemas/
|
||||
outputs.py
|
||||
```
|
||||
|
||||
`scenario_loader.py` 可作为非 Django 环境下加载配置的工具;Django 场景展示仍由 `apps.scenarios` 负责。
|
||||
|
||||
## 4. Orchestrator 设计
|
||||
|
||||
入口:
|
||||
|
||||
```python
|
||||
def run_agent(scenario_config, user_input: str, options: dict | None = None) -> AgentResult:
|
||||
"""执行一次 Agent 编排,options 可包含 document_ids 等运行期约束。"""
|
||||
```
|
||||
|
||||
流程:
|
||||
|
||||
1. 记录开始时间。
|
||||
2. 根据 `rag.enabled`、`scenario_id` 和可选 `document_ids` 检索引用。
|
||||
3. 根据 `tools` 执行或准备工具结果。
|
||||
4. 构造 messages。
|
||||
5. 调用 LLM Provider。
|
||||
6. 解析结构化输出。
|
||||
7. 计算耗时。
|
||||
8. 返回 `AgentResult(status="success")`。
|
||||
9. 捕获可恢复异常并返回 `status="failed"`。
|
||||
|
||||
V1 在缺少 LLM 或 Embedding 配置时必须返回清晰失败结果。测试代码可以使用 mock provider,但 V1 验收链路必须通过真实 OpenAI 兼容 LLM、Embedding 和 Chroma。
|
||||
|
||||
## 5. Scenario Loader 设计
|
||||
|
||||
Agent Core 的 Scenario Loader 用于脚本、测试或后续独立服务场景。它不依赖 Django View,可以复用 Scenarios 模块的字段规范。
|
||||
|
||||
接口:
|
||||
|
||||
```python
|
||||
load_scenario(path: str) -> dict
|
||||
load_scenarios(directory: str) -> list[dict]
|
||||
```
|
||||
|
||||
## 6. RAG 设计
|
||||
|
||||
入库接口:
|
||||
|
||||
```python
|
||||
def ingest_document(
|
||||
document_id: int,
|
||||
scenario_id: str,
|
||||
source_file: str,
|
||||
text: str,
|
||||
collection: str,
|
||||
) -> IngestResult:
|
||||
"""切分文档、生成 embedding,并写入 Chroma。重新入库时覆盖同一 document_id 的旧 chunk。"""
|
||||
```
|
||||
|
||||
检索接口:
|
||||
|
||||
```python
|
||||
def retrieve(
|
||||
scenario_id: str,
|
||||
query: str,
|
||||
collection: str,
|
||||
top_k: int = 5,
|
||||
document_ids: list[int] | None = None,
|
||||
) -> list[ReferenceChunk]:
|
||||
"""按场景和可选文档范围执行向量检索,返回可审计引用片段。"""
|
||||
```
|
||||
|
||||
切分策略:
|
||||
|
||||
- 默认 chunk size 800 到 1000 字。
|
||||
- overlap 100 到 150 字。
|
||||
- metadata 包含 `scenario_id`、`document_id`、`source_file`、`chunk_id`。
|
||||
|
||||
RAG 入库和检索必须使用 Embedding Provider 与 Chroma。单元测试桩或开发阶段临时验证方案不属于 V1 验收设计。
|
||||
|
||||
## 7. Tool Registry 设计
|
||||
|
||||
工具注册:
|
||||
|
||||
```python
|
||||
registry.register("calculate_rate", calculate_rate)
|
||||
registry.get("calculate_rate")
|
||||
registry.run("calculate_rate", **kwargs)
|
||||
```
|
||||
|
||||
工具结果统一:
|
||||
|
||||
```json
|
||||
{
|
||||
"tool_name": "calculate_rate",
|
||||
"success": true,
|
||||
"arguments": {},
|
||||
"result": {},
|
||||
"error": ""
|
||||
}
|
||||
```
|
||||
|
||||
内置工具:
|
||||
|
||||
- `calculate_rate`
|
||||
- `query_demo_records`
|
||||
- `check_required_fields`
|
||||
- `generate_action_items`
|
||||
|
||||
工具函数不得直接读取 API Key 或执行无审计的外部副作用。
|
||||
|
||||
## 8. LLM Provider 设计
|
||||
|
||||
接口:
|
||||
|
||||
```python
|
||||
class LLMProvider:
|
||||
def generate(self, messages: list[dict], response_format: dict | None = None) -> LLMResponse:
|
||||
"""调用 OpenAI 兼容 Chat Completions 接口并返回统一响应对象。"""
|
||||
```
|
||||
|
||||
配置来源:
|
||||
|
||||
- `LLM_API_KEY`
|
||||
- `LLM_BASE_URL`
|
||||
- `LLM_MODEL`
|
||||
|
||||
Provider 对外隐藏供应商差异,Orchestrator 只处理 `LLMResponse.content`、`LLMResponse.model_name` 和错误信息。供应商可自主选择 OpenAI、硅基流动等 OpenAI 兼容服务。
|
||||
|
||||
Embedding Provider 接口:
|
||||
|
||||
```python
|
||||
class EmbeddingProvider:
|
||||
def embed_texts(self, texts: list[str]) -> list[list[float]]:
|
||||
"""调用 OpenAI 兼容 Embeddings 接口,返回与输入文本一一对应的向量。"""
|
||||
```
|
||||
|
||||
配置来源:
|
||||
|
||||
- `EMBEDDING_API_KEY`
|
||||
- `EMBEDDING_BASE_URL`
|
||||
- `EMBEDDING_MODEL`
|
||||
|
||||
当 `EMBEDDING_API_KEY` 或 `EMBEDDING_BASE_URL` 为空时,可以复用 `LLM_API_KEY` 和 `LLM_BASE_URL`。
|
||||
|
||||
## 9. Structured Output 设计
|
||||
|
||||
接口:
|
||||
|
||||
```python
|
||||
def parse_structured_output(raw_output: str, output_type: str) -> ParseResult:
|
||||
"""优先解析 JSON,并根据输出类型返回结构化结果或解析错误。"""
|
||||
```
|
||||
|
||||
策略:
|
||||
|
||||
- 优先解析 JSON。
|
||||
- 根据 `output_type` 做字段补齐或轻校验。
|
||||
- 失败时返回 `success=False`,保留 `raw_output`。
|
||||
- 不因结构化解析失败导致整个 Agent 流程崩溃。
|
||||
|
||||
## 10. AgentResult 设计
|
||||
|
||||
建议 dataclass:
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class AgentResult:
|
||||
answer: str
|
||||
structured_output: dict
|
||||
references: list
|
||||
tool_calls: list
|
||||
raw_output: str
|
||||
model_name: str
|
||||
latency_ms: int
|
||||
status: str
|
||||
error: str = ""
|
||||
```
|
||||
|
||||
所有字段必须有默认值或构造时明确传入,保证 Audit 模块写入稳定。
|
||||
|
||||
## 11. Adapter 扩展设计
|
||||
|
||||
统一接口:
|
||||
|
||||
```python
|
||||
class AgentEngine:
|
||||
def run_agent(self, scenario_config, user_input: str, options: dict | None = None) -> AgentResult:
|
||||
"""保持与顶层 run_agent 函数一致的输入输出合约。"""
|
||||
```
|
||||
|
||||
V1 实现:
|
||||
|
||||
- `LightweightOrchestrator`
|
||||
|
||||
后续扩展:
|
||||
|
||||
- `DifyAdapter`
|
||||
- `OpenAIAgentsAdapter`
|
||||
- `LangGraphAdapter`
|
||||
|
||||
Adapter 只能替换编排实现,不能改变 Django 层依赖的 AgentResult 合约。
|
||||
|
||||
## 12. 异常处理
|
||||
|
||||
| 异常 | 处理 |
|
||||
|---|---|
|
||||
| RAG 检索失败 | 记录错误,允许继续或返回 failed |
|
||||
| 工具不存在 | 记录失败工具调用 |
|
||||
| 工具执行异常 | 捕获并返回失败工具结果 |
|
||||
| LLM 配置缺失 | 返回 failed AgentResult |
|
||||
| LLM 调用失败 | 返回 failed AgentResult |
|
||||
| JSON 解析失败 | 返回 success 但带解析错误,展示 raw output |
|
||||
|
||||
## 13. 验收标准
|
||||
|
||||
- Chat 可以调用 `run_agent()`。
|
||||
- 返回对象字段稳定完整。
|
||||
- RAG 按 `scenario_id` 隔离。
|
||||
- RAG 支持按 `document_ids` 限定本次对话的文档范围。
|
||||
- 工具调用结果格式统一。
|
||||
- LLM 与 Embedding 配置从环境变量读取。
|
||||
- 结构化解析失败不导致页面崩溃。
|
||||
- Agent Core 不依赖 Django View。
|
||||
600
docs/详细设计/1.资料包导入与目录汇总.md
Normal file
600
docs/详细设计/1.资料包导入与目录汇总.md
Normal file
@@ -0,0 +1,600 @@
|
||||
# 1. 资料包导入与目录汇总详细设计
|
||||
|
||||
## 1. 设计目标
|
||||
|
||||
本步骤是注册申报资料审核工作流的入口,目标是把用户上传的注册申报资料包转化为可供后续法规完整性核查、字段抽取、一致性检查和风险预警使用的结构化文档底座。
|
||||
|
||||
本步骤需要完成以下业务结果:
|
||||
|
||||
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`
|
||||
|
||||
后续 RAG 入库需要读取:
|
||||
|
||||
1. 文件路径。
|
||||
2. 文件类型。
|
||||
3. 章节点。
|
||||
4. 资料名称。
|
||||
5. 业务资料或法规资料角色。
|
||||
6. 文档处理状态。
|
||||
|
||||
## 11. 测试设计
|
||||
|
||||
### 11.1 单元测试
|
||||
|
||||
1. 上传文件校验。
|
||||
2. 路径安全校验。
|
||||
3. 压缩包解包。
|
||||
4. 文件扫描过滤。
|
||||
5. 页数统计。
|
||||
6. 章节点识别。
|
||||
7. 目录汇总聚合。
|
||||
|
||||
### 11.2 服务层测试
|
||||
|
||||
1. 单文件导入生成文档记录。
|
||||
2. 多文件导入生成同一批次。
|
||||
3. 压缩包导入保留相对路径。
|
||||
4. 解包失败时批次状态正确。
|
||||
5. DOC 无法统计页数时标记待复核。
|
||||
6. 目录汇总结果包含文件数量、页数、章节点和警告。
|
||||
|
||||
### 11.3 页面测试
|
||||
|
||||
1. 上传成功后跳转到目录汇总页。
|
||||
2. 页面展示页数可信度。
|
||||
3. 页面展示待人工复核提示。
|
||||
4. 不支持文件有清晰提示。
|
||||
|
||||
## 12. V1 实现建议
|
||||
|
||||
V1 建议先完成以下最小闭环:
|
||||
|
||||
1. 支持单文件和多文件上传。
|
||||
2. 支持 `zip` 解包,并预留 `rar`、`7z` 依赖接入点。
|
||||
3. 支持 `PDF`、`DOCX` 页数统计。
|
||||
4. `DOC` 文件先标记待人工复核。
|
||||
5. 基于文件名和路径识别 `CH1.*` 章节点。
|
||||
6. 生成目录汇总页面和结构化 `registration_overview_report`。
|
||||
|
||||
在 V1 后续增强中补齐:
|
||||
|
||||
1. `rar`、`7z` 纯 Python 解包。
|
||||
2. DOC 转换后精确统计。
|
||||
3. 目录类文档内容解析。
|
||||
4. 文件夹上传前端体验。
|
||||
5. 后台人工修正章节点和资料名称。
|
||||
610
docs/详细设计/2.法规完整性检查.md
Normal file
610
docs/详细设计/2.法规完整性检查.md
Normal file
@@ -0,0 +1,610 @@
|
||||
# 2. 法规完整性检查详细设计
|
||||
|
||||
## 1. 设计目标
|
||||
|
||||
本步骤承接“资料包导入与目录汇总”的输出,目标是对照 NMPA 体外诊断试剂注册申报资料要求,检查当前资料包是否齐套、章节点是否匹配、资料是否错放、是否存在需要人工复核的完整性问题。
|
||||
|
||||
本步骤需要完成以下业务结果:
|
||||
|
||||
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` 记录本次完整性检查的输入、规则版本、匹配结果、缺失项、证据和错误。
|
||||
|
||||
审计中必须保留:
|
||||
|
||||
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`
|
||||
|
||||
## 3. 输入输出
|
||||
|
||||
### 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
|
||||
}
|
||||
```
|
||||
|
||||
其中 `chapter_scope` 可为空。为空时默认检查当前批次已识别章节点及 V1 默认范围;演示首版建议优先检查 `CH1`,同时保留全六章规则结构。
|
||||
|
||||
### 3.2 输出
|
||||
|
||||
本步骤输出 `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. 主工作流
|
||||
|
||||
```text
|
||||
用户发起法规完整性检查
|
||||
-> 读取资料包目录汇总结果
|
||||
-> 确认法规流程类型
|
||||
-> 装载法规规则包
|
||||
-> 展开章节和必交项规则
|
||||
-> 将实际文档与规则项匹配
|
||||
-> 判定已提供/缺失/疑似/错放/待复核
|
||||
-> 映射风险等级与处理建议
|
||||
-> 检索法规原文证据
|
||||
-> 生成完整性检查报告
|
||||
-> 写入审计留痕
|
||||
-> 返回 Web/飞书可展示结果
|
||||
```
|
||||
|
||||
## 5. 节点详细设计
|
||||
|
||||
### 5.1 节点一:读取目录汇总结果
|
||||
|
||||
业务功能:
|
||||
|
||||
1. 根据 `batch_id` 读取第一步产出的 `registration_overview_report`。
|
||||
2. 校验资料包是否完成目录汇总。
|
||||
3. 过滤当前检查范围内的文档。
|
||||
4. 收集待人工复核文档,作为完整性检查的不确定性输入。
|
||||
|
||||
使用技术:
|
||||
|
||||
1. Django ORM
|
||||
2. JSONField
|
||||
3. Pydantic 或 dataclass schema 校验
|
||||
|
||||
产生方法:
|
||||
|
||||
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. 在线法规更新能力。
|
||||
|
||||
658
docs/详细设计/3.字段抽取与统一字段池.md
Normal file
658
docs/详细设计/3.字段抽取与统一字段池.md
Normal file
@@ -0,0 +1,658 @@
|
||||
# 3. 字段抽取与统一字段池详细设计
|
||||
|
||||
## 1. 设计目标
|
||||
|
||||
本步骤承接“资料包导入与目录汇总”和“法规完整性检查”的输出,目标是从说明书、申请表、产品列表、声明类文件等注册申报资料中抽取产品核心字段,形成可复用、可追溯、可回填、可一致性核查的统一字段池。
|
||||
|
||||
本步骤需要完成以下业务结果:
|
||||
|
||||
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 使用情况和失败原因。
|
||||
|
||||
审计中必须保留:
|
||||
|
||||
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`
|
||||
|
||||
## 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`
|
||||
4. `source_document_id`
|
||||
5. `source_location`
|
||||
6. `confidence`
|
||||
7. `conflict_status`
|
||||
8. `manual_review_required`
|
||||
|
||||
后续 Word 回填读取:
|
||||
|
||||
1. `field_key`
|
||||
2. `standard_value`
|
||||
3. `fillable`
|
||||
4. `manual_review_required`
|
||||
5. `conflict_status`
|
||||
6. `template_field_refs`
|
||||
|
||||
## 11. 测试设计
|
||||
|
||||
### 11.1 单元测试
|
||||
|
||||
1. 字段 schema 加载成功。
|
||||
2. 字段来源优先级排序正确。
|
||||
3. 标题字段抽取正确。
|
||||
4. 表格字段抽取正确。
|
||||
5. LLM 输出 schema 校验正确。
|
||||
6. 字段标准化正确。
|
||||
7. 推荐值选择正确。
|
||||
|
||||
### 11.2 服务层测试
|
||||
|
||||
1. 基于说明书抽取产品名称。
|
||||
2. 基于说明书抽取检测靶标。
|
||||
3. 基于申请表抽取申请人名称。
|
||||
4. 多来源候选写入字段池。
|
||||
5. LLM 不可用时任务仍能完成部分结果。
|
||||
6. 字段池报告写入审计。
|
||||
|
||||
### 11.3 页面测试
|
||||
|
||||
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. 字段池版本管理。
|
||||
|
||||
528
docs/详细设计/4.一致性核查.md
Normal file
528
docs/详细设计/4.一致性核查.md
Normal file
@@ -0,0 +1,528 @@
|
||||
# 4. 一致性核查详细设计
|
||||
|
||||
## 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` 记录一致性核查的审核范围、字段规则、冲突字段、来源文档、处理建议和最终状态。
|
||||
|
||||
审计中必须保留:
|
||||
|
||||
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`
|
||||
|
||||
## 3. 输入输出
|
||||
|
||||
### 3.1 输入
|
||||
|
||||
```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. 主工作流
|
||||
|
||||
```text
|
||||
用户发起一致性核查
|
||||
-> 读取统一字段池
|
||||
-> 确认审核范围
|
||||
-> 加载强一致字段规则
|
||||
-> 筛选目标字段
|
||||
-> 按字段分组候选值
|
||||
-> 按完全一致规则比对
|
||||
-> 识别字段冲突
|
||||
-> 识别疑似混档风险
|
||||
-> 生成处理建议
|
||||
-> 写入字段池冲突状态
|
||||
-> 生成一致性报告
|
||||
-> 写入审计留痕
|
||||
-> 返回 Web/飞书可展示结果
|
||||
```
|
||||
|
||||
## 5. 节点详细设计
|
||||
|
||||
### 5.1 节点一:读取统一字段池
|
||||
|
||||
业务功能:
|
||||
|
||||
1. 根据 `batch_id` 读取字段池。
|
||||
2. 过滤本次目标字段。
|
||||
3. 读取每个字段的所有候选值和推荐值。
|
||||
4. 加载字段来源文档信息。
|
||||
|
||||
使用技术:
|
||||
|
||||
1. Django ORM
|
||||
2. JSONField
|
||||
3. dataclass/Pydantic schema
|
||||
|
||||
产生方法:
|
||||
|
||||
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. 冲突字段修正建议。
|
||||
|
||||
477
docs/详细设计/5.风险预警.md
Normal file
477
docs/详细设计/5.风险预警.md
Normal file
@@ -0,0 +1,477 @@
|
||||
# 5. 风险预警详细设计
|
||||
|
||||
## 1. 设计目标
|
||||
|
||||
本步骤承接法规完整性检查、字段抽取与一致性核查结果,目标是把缺失项、错放项、字段冲突、混档风险、待人工复核项和交付风险统一汇总成可执行的合规风险清单,并给出是否通过、整改优先级和责任建议。
|
||||
|
||||
本步骤需要完成以下业务结果:
|
||||
|
||||
1. 汇总前序任务报告。
|
||||
2. 加载风险分级和准入规则。
|
||||
3. 将完整性、字段抽取、一致性等结果映射为风险项。
|
||||
4. 合并重复风险和关联风险。
|
||||
5. 计算最高风险等级和是否通过。
|
||||
6. 生成整改建议、处理优先级和责任角色。
|
||||
7. 输出结构化 `registration_risk_report`。
|
||||
8. 为飞书通知步骤生成风险摘要载荷。
|
||||
|
||||
本步骤不重新执行完整性检查、字段抽取或一致性核查。它只消费前序结构化报告,并在规则基础上生成综合风险预警。
|
||||
|
||||
## 2. 所属模块与边界
|
||||
|
||||
### 2.1 Agent Core
|
||||
|
||||
`agent_core` 是本步骤的执行主体,负责编排报告加载、风险规则加载、风险项生成、风险归并、准入判定、整改建议生成和报告输出。
|
||||
|
||||
本步骤建议产生以下中文 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` 风险项。
|
||||
4. `manual_review_items`
|
||||
5. 可回填风险拦截状态。
|
||||
|
||||
后续飞书通知读取:
|
||||
|
||||
1. 风险摘要。
|
||||
2. 高风险清单。
|
||||
3. 责任角色。
|
||||
4. 责任人通知载荷。
|
||||
5. Web 详情页链接。
|
||||
|
||||
## 11. 测试设计
|
||||
|
||||
### 11.1 单元测试
|
||||
|
||||
1. 风险规则加载成功。
|
||||
2. 完整性缺失项生成风险。
|
||||
3. 字段冲突生成高风险。
|
||||
4. 混档风险生成高风险。
|
||||
5. 风险归并正确。
|
||||
6. 任一高风险判不通过。
|
||||
|
||||
### 11.2 服务层测试
|
||||
|
||||
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. 后台风险规则维护。
|
||||
|
||||
456
docs/详细设计/6.Word回填导出.md
Normal file
456
docs/详细设计/6.Word回填导出.md
Normal file
@@ -0,0 +1,456 @@
|
||||
# 6. Word 回填导出详细设计
|
||||
|
||||
## 1. 设计目标
|
||||
|
||||
本步骤承接字段抽取、统一字段池、一致性核查和风险预警结果,目标是将可回填字段按模板映射写入注册申报表格或对照清单,并生成新的 Word 文件供用户下载、复核和归档。
|
||||
|
||||
本步骤需要完成以下业务结果:
|
||||
|
||||
1. 选择适用的 Word 模板。
|
||||
2. 加载模板字段映射。
|
||||
3. 从统一字段池读取可回填字段。
|
||||
4. 根据风险报告和冲突状态执行回填拦截。
|
||||
5. 生成回填数据集。
|
||||
6. 按模板写入 Word 文档。
|
||||
7. 校验输出文档版式、字段落位和导出状态。
|
||||
8. 生成导出记录和下载入口。
|
||||
9. 写入审计留痕。
|
||||
|
||||
本步骤不重新抽取字段,不修改法规判断和风险结论。若字段冲突或高风险未处理,应阻止自动生成可报送文件,或者生成“待复核草稿版”并明确标记。
|
||||
|
||||
## 2. 所属模块与边界
|
||||
|
||||
### 2.1 Documents
|
||||
|
||||
`apps.documents` 负责保存生成后的 Word 文件、记录导出文件元数据,并提供下载入口。
|
||||
|
||||
### 2.2 Agent Core
|
||||
|
||||
`agent_core` 负责模板选择、字段映射、回填数据集构建、Word 渲染、版式校验和导出报告生成。
|
||||
|
||||
本步骤建议产生以下中文 Skill:
|
||||
|
||||
1. `Word回填导出编排Skill`
|
||||
2. `模板选择Skill`
|
||||
3. `模板字段映射加载Skill`
|
||||
4. `回填字段集构建Skill`
|
||||
5. `回填拦截检查Skill`
|
||||
6. `Word模板渲染Skill`
|
||||
7. `导出版式校验Skill`
|
||||
8. `导出记录生成Skill`
|
||||
|
||||
### 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. 后台模板字段映射维护。
|
||||
|
||||
407
docs/详细设计/7.飞书通知.md
Normal file
407
docs/详细设计/7.飞书通知.md
Normal file
@@ -0,0 +1,407 @@
|
||||
# 7. 飞书通知详细设计
|
||||
|
||||
## 1. 设计目标
|
||||
|
||||
本步骤承接风险预警和 Word 回填导出结果,目标是在飞书群聊或应用会话中完成任务触发、结果摘要查看、责任人通知和 Web 详情跳转,让注册申报审核流程具备 Web 工作台以外的协同入口。
|
||||
|
||||
本步骤需要完成以下业务结果:
|
||||
|
||||
1. 支持飞书群聊机器人触发审核任务。
|
||||
2. 支持在飞书内选择任务或查看任务摘要。
|
||||
3. 根据风险项和章节点映射责任角色。
|
||||
4. 根据责任角色解析飞书账号。
|
||||
5. 生成飞书消息摘要和 @ 通知载荷。
|
||||
6. 调用飞书 OpenAPI 或 MCP 工具发送消息。
|
||||
7. 记录发送结果、失败原因和回传链接。
|
||||
8. 写入审计留痕。
|
||||
|
||||
本步骤不执行具体审核规则,不改变风险结论,不直接修改字段池或导出文件。它只负责飞书入口和通知协作。
|
||||
|
||||
## 2. 所属模块与边界
|
||||
|
||||
### 2.1 Chat
|
||||
|
||||
`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` 记录飞书触发来源、消息载荷、通知对象、发送状态和失败原因。
|
||||
|
||||
审计中必须保留:
|
||||
|
||||
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`
|
||||
|
||||
## 3. 输入输出
|
||||
|
||||
### 3.1 输入
|
||||
|
||||
```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
|
||||
}
|
||||
```
|
||||
|
||||
### 3.2 输出
|
||||
|
||||
本步骤输出 `feishu_notification_report`:
|
||||
|
||||
```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. 主工作流
|
||||
|
||||
```text
|
||||
飞书群聊或 Web 触发通知
|
||||
-> 解析飞书触发上下文
|
||||
-> 读取风险报告和导出报告
|
||||
-> 解析责任角色和飞书账号
|
||||
-> 生成飞书消息摘要
|
||||
-> 构建消息卡片和 @ 通知
|
||||
-> 调用飞书 OpenAPI / MCP 发送
|
||||
-> 记录发送回执
|
||||
-> 写入审计留痕
|
||||
-> 返回发送结果
|
||||
```
|
||||
|
||||
## 5. 节点详细设计
|
||||
|
||||
### 5.1 节点一:飞书任务入口解析
|
||||
|
||||
业务功能:
|
||||
|
||||
1. 解析飞书消息事件。
|
||||
2. 识别任务指令。
|
||||
3. 识别批次 ID 或项目上下文。
|
||||
4. 将飞书触发请求映射到系统场景。
|
||||
|
||||
支持指令示例:
|
||||
|
||||
1. `检查资料完整性`
|
||||
2. `生成风险报告`
|
||||
3. `查看导出结果`
|
||||
4. `通知责任人`
|
||||
|
||||
使用技术:
|
||||
|
||||
1. 飞书事件订阅
|
||||
2. 群聊机器人消息
|
||||
3. Django webhook view
|
||||
4. 场景配置 YAML
|
||||
|
||||
产生方法:
|
||||
|
||||
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. `飞书任务入口解析Skill`
|
||||
|
||||
### 5.2 节点二:通知上下文加载
|
||||
|
||||
业务功能:
|
||||
|
||||
1. 读取风险报告。
|
||||
2. 读取 Word 导出报告。
|
||||
3. 读取审计详情链接。
|
||||
4. 读取任务状态。
|
||||
|
||||
使用技术:
|
||||
|
||||
1. Django ORM
|
||||
2. JSONField
|
||||
3. URL reverse
|
||||
|
||||
产生方法:
|
||||
|
||||
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. `飞书通知编排Skill`
|
||||
|
||||
### 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. 消息卡片交互按钮。
|
||||
90
docs/详细设计/skill/Word回填导出编排Skill.md
Normal file
90
docs/详细设计/skill/Word回填导出编排Skill.md
Normal file
@@ -0,0 +1,90 @@
|
||||
# Word回填导出编排Skill 设计
|
||||
|
||||
## 1. Skill 定位
|
||||
|
||||
`Word回填导出编排Skill` 是第六步工作流的总入口 Skill,负责组织模板选择、字段映射加载、回填字段集构建、回填拦截检查、Word 渲染、版式校验和导出记录生成。
|
||||
|
||||
英文实现标识建议使用 `WordFillExportOrchestrateSkill`。
|
||||
|
||||
## 2. 输入
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class WordFillExportOrchestrateInput:
|
||||
batch_id: int
|
||||
template_id: str
|
||||
target_output_type: str
|
||||
selected_field_keys: list[str] = field(default_factory=list)
|
||||
allow_draft_when_blocked: bool = True
|
||||
```
|
||||
|
||||
## 3. 输出
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class WordFillExportOrchestrateOutput:
|
||||
report_type: str
|
||||
batch_id: int
|
||||
export_status: str
|
||||
output_file: dict | None
|
||||
filled_fields: list[dict]
|
||||
blocked_fields: list[dict]
|
||||
audit_id: int | None = None
|
||||
```
|
||||
|
||||
## 4. 依赖 Skill
|
||||
|
||||
1. `模板选择Skill`
|
||||
2. `模板字段映射加载Skill`
|
||||
3. `回填字段集构建Skill`
|
||||
4. `回填拦截检查Skill`
|
||||
5. `Word模板渲染Skill`
|
||||
6. `导出版式校验Skill`
|
||||
7. `导出记录生成Skill`
|
||||
|
||||
## 5. 核心方法
|
||||
|
||||
### 5.1 `run(input) -> WordFillExportOrchestrateOutput`
|
||||
|
||||
主入口方法。
|
||||
|
||||
### 5.2 `load_export_context(input) -> WordExportContext`
|
||||
|
||||
加载字段池、风险报告和一致性报告。
|
||||
|
||||
### 5.3 `resolve_export_mode(blockers) -> str`
|
||||
|
||||
确认正式、草稿或拦截模式。
|
||||
|
||||
## 6. 技术实现
|
||||
|
||||
使用技术:
|
||||
|
||||
1. Tool Registry
|
||||
2. Django ORM
|
||||
3. Django Storage
|
||||
4. dataclass/Pydantic
|
||||
|
||||
建议注册名:
|
||||
|
||||
```python
|
||||
tool_registry.register(
|
||||
name="word_fill_export_orchestrate",
|
||||
handler=WordFillExportOrchestrateSkill().run,
|
||||
)
|
||||
```
|
||||
|
||||
## 7. 异常处理
|
||||
|
||||
1. 模板缺失:任务失败。
|
||||
2. 字段池缺失:任务失败。
|
||||
3. 正式导出被拦截:按配置生成草稿或直接返回拦截。
|
||||
4. 渲染失败:写失败审计。
|
||||
|
||||
## 8. 测试要点
|
||||
|
||||
1. 能按顺序调用依赖 Skill。
|
||||
2. 冲突字段导致正式导出拦截。
|
||||
3. 草稿模式可生成文件。
|
||||
4. 输出报告稳定。
|
||||
|
||||
67
docs/详细设计/skill/Word模板渲染Skill.md
Normal file
67
docs/详细设计/skill/Word模板渲染Skill.md
Normal file
@@ -0,0 +1,67 @@
|
||||
# Word模板渲染Skill 设计
|
||||
|
||||
## 1. Skill 定位
|
||||
|
||||
`Word模板渲染Skill` 负责将回填字段集写入 Word 模板,生成新的 `.docx` 文件。
|
||||
|
||||
英文实现标识建议使用 `WordTemplateRenderSkill`。
|
||||
|
||||
## 2. 输入
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class WordTemplateRenderInput:
|
||||
template_file_path: Path
|
||||
fill_dataset: dict
|
||||
export_mode: str
|
||||
output_dir: Path
|
||||
```
|
||||
|
||||
## 3. 输出
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class WordTemplateRenderOutput:
|
||||
output_file_path: Path
|
||||
rendered_placeholders: list[str]
|
||||
render_warnings: list[dict]
|
||||
```
|
||||
|
||||
## 4. 核心方法
|
||||
|
||||
### 4.1 `run(input) -> WordTemplateRenderOutput`
|
||||
|
||||
主入口方法。
|
||||
|
||||
### 4.2 `replace_paragraph_placeholders(document, values) -> None`
|
||||
|
||||
替换段落占位符。
|
||||
|
||||
### 4.3 `replace_table_placeholders(document, values) -> None`
|
||||
|
||||
替换表格占位符。
|
||||
|
||||
### 4.4 `save_document(document, output_path) -> Path`
|
||||
|
||||
保存文档。
|
||||
|
||||
## 5. 技术实现
|
||||
|
||||
使用技术:
|
||||
|
||||
1. `python-docx`
|
||||
2. 可选 `docxtpl`
|
||||
3. Django Storage
|
||||
|
||||
## 6. 异常处理
|
||||
|
||||
1. 模板打不开:任务失败。
|
||||
2. 占位符替换失败:记录警告。
|
||||
3. 保存失败:任务失败。
|
||||
|
||||
## 7. 测试要点
|
||||
|
||||
1. 段落占位符可替换。
|
||||
2. 表格占位符可替换。
|
||||
3. 输出文件存在。
|
||||
|
||||
88
docs/详细设计/skill/一致性报告生成Skill.md
Normal file
88
docs/详细设计/skill/一致性报告生成Skill.md
Normal file
@@ -0,0 +1,88 @@
|
||||
# 一致性报告生成Skill 设计
|
||||
|
||||
## 1. Skill 定位
|
||||
|
||||
`一致性报告生成Skill` 负责将字段比对结果和混档风险组装成稳定的 `registration_consistency_report`,并生成页面展示、审计和飞书摘要载荷。
|
||||
|
||||
英文实现标识建议使用 `ConsistencyReportBuildSkill`。
|
||||
|
||||
## 2. 输入
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class ConsistencyReportBuildInput:
|
||||
context: ConsistencyReviewContext
|
||||
compare_results: list[FieldCompareResult]
|
||||
mixed_package_warnings: list[dict]
|
||||
```
|
||||
|
||||
## 3. 输出
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class ConsistencyReportBuildOutput:
|
||||
report: dict
|
||||
display_sections: list[dict]
|
||||
audit_payload: dict
|
||||
feishu_summary_payload: dict
|
||||
```
|
||||
|
||||
## 4. 报告结构
|
||||
|
||||
报告必须包含:
|
||||
|
||||
1. `report_type`
|
||||
2. `batch_id`
|
||||
3. `field_rule_id`
|
||||
4. `summary`
|
||||
5. `consistent_fields`
|
||||
6. `conflict_fields`
|
||||
7. `manual_review_fields`
|
||||
8. `mixed_package_warnings`
|
||||
9. `suggestions`
|
||||
|
||||
## 5. 核心方法
|
||||
|
||||
### 5.1 `run(input) -> ConsistencyReportBuildOutput`
|
||||
|
||||
主入口方法。
|
||||
|
||||
### 5.2 `build_summary(compare_results, warnings) -> dict`
|
||||
|
||||
生成汇总。
|
||||
|
||||
### 5.3 `split_compare_results(compare_results) -> dict`
|
||||
|
||||
拆分一致、冲突、待复核字段。
|
||||
|
||||
### 5.4 `build_suggestions(conflicts, warnings) -> list[dict]`
|
||||
|
||||
生成处理建议。
|
||||
|
||||
### 5.5 `build_audit_payload(report, context) -> dict`
|
||||
|
||||
生成审计载荷。
|
||||
|
||||
## 6. 技术实现
|
||||
|
||||
使用技术:
|
||||
|
||||
1. dataclass/Pydantic
|
||||
2. JSONField
|
||||
3. Audit 服务
|
||||
4. 页面展示 schema
|
||||
|
||||
## 7. 异常处理
|
||||
|
||||
1. 报告字段缺失:任务失败。
|
||||
2. 没有可比对字段:输出空报告。
|
||||
3. 飞书摘要构建失败:不影响 Web 报告。
|
||||
4. 审计写入失败:记录系统警告。
|
||||
|
||||
## 8. 测试要点
|
||||
|
||||
1. 冲突字段进入 `conflict_fields`。
|
||||
2. 混档风险进入 `mixed_package_warnings`。
|
||||
3. 汇总数量正确。
|
||||
4. 审计载荷包含审核范围。
|
||||
|
||||
103
docs/详细设计/skill/一致性核查编排Skill.md
Normal file
103
docs/详细设计/skill/一致性核查编排Skill.md
Normal file
@@ -0,0 +1,103 @@
|
||||
# 一致性核查编排Skill 设计
|
||||
|
||||
## 1. Skill 定位
|
||||
|
||||
`一致性核查编排Skill` 是第四步工作流的总入口 Skill,负责组织审核范围确认、强一致规则加载、字段分组、完全一致比对、混档风险识别、字段池状态回写和报告生成。
|
||||
|
||||
英文实现标识建议使用 `ConsistencyReviewOrchestrateSkill`。
|
||||
|
||||
## 2. 输入
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class ConsistencyReviewOrchestrateInput:
|
||||
batch_id: int
|
||||
scenario_id: str = "registration_consistency_review"
|
||||
selected_document_ids: list[int] = field(default_factory=list)
|
||||
field_rule_id: str = "ivd_strict_consistency_v1"
|
||||
target_field_keys: list[str] = field(default_factory=list)
|
||||
strict_mode: bool = True
|
||||
```
|
||||
|
||||
## 3. 输出
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class ConsistencyReviewOrchestrateOutput:
|
||||
report_type: str
|
||||
batch_id: int
|
||||
summary: dict
|
||||
consistent_fields: list[dict]
|
||||
conflict_fields: list[dict]
|
||||
manual_review_fields: list[dict]
|
||||
mixed_package_warnings: list[dict]
|
||||
audit_id: int | None = None
|
||||
```
|
||||
|
||||
## 4. 依赖 Skill
|
||||
|
||||
1. `审核范围确认Skill`
|
||||
2. `强一致规则加载Skill`
|
||||
3. `字段分组Skill`
|
||||
4. `字段完全一致比对Skill`
|
||||
5. `混档风险识别Skill`
|
||||
6. `一致性报告生成Skill`
|
||||
|
||||
## 5. 核心方法
|
||||
|
||||
### 5.1 `run(input) -> ConsistencyReviewOrchestrateOutput`
|
||||
|
||||
主入口方法。
|
||||
|
||||
执行顺序:
|
||||
|
||||
1. 读取统一字段池。
|
||||
2. 调用 `审核范围确认Skill`。
|
||||
3. 调用 `强一致规则加载Skill`。
|
||||
4. 调用 `字段分组Skill`。
|
||||
5. 调用 `字段完全一致比对Skill`。
|
||||
6. 调用 `混档风险识别Skill`。
|
||||
7. 回写字段池冲突状态。
|
||||
8. 调用 `一致性报告生成Skill`。
|
||||
9. 写入审计。
|
||||
|
||||
### 5.2 `load_field_pool(batch_id) -> list[FieldPoolItem]`
|
||||
|
||||
读取字段池主表和候选值。
|
||||
|
||||
### 5.3 `update_field_pool_status(compare_results) -> FieldPoolUpdateResult`
|
||||
|
||||
回写一致、冲突、待复核状态。
|
||||
|
||||
## 6. 技术实现
|
||||
|
||||
使用技术:
|
||||
|
||||
1. Django ORM
|
||||
2. Tool Registry
|
||||
3. dataclass/Pydantic
|
||||
4. Audit 服务
|
||||
|
||||
建议注册名:
|
||||
|
||||
```python
|
||||
tool_registry.register(
|
||||
name="consistency_review_orchestrate",
|
||||
handler=ConsistencyReviewOrchestrateSkill().run,
|
||||
)
|
||||
```
|
||||
|
||||
## 7. 异常处理
|
||||
|
||||
1. 字段池不存在:任务失败并提示先执行字段抽取。
|
||||
2. 审核范围为空:返回业务错误。
|
||||
3. 规则缺失:任务失败并写审计。
|
||||
4. 字段池回写失败:报告仍生成,但标记系统警告。
|
||||
|
||||
## 8. 测试要点
|
||||
|
||||
1. 能按顺序调用依赖 Skill。
|
||||
2. 字段池缺失时返回清晰错误。
|
||||
3. 冲突结果能回写字段池。
|
||||
4. 输出报告 schema 稳定。
|
||||
|
||||
70
docs/详细设计/skill/准入判定Skill.md
Normal file
70
docs/详细设计/skill/准入判定Skill.md
Normal file
@@ -0,0 +1,70 @@
|
||||
# 准入判定Skill 设计
|
||||
|
||||
## 1. Skill 定位
|
||||
|
||||
`准入判定Skill` 负责根据风险项、人工复核项和准入规则计算最终是否通过。
|
||||
|
||||
英文实现标识建议使用 `AdmissionDecisionSkill`。
|
||||
|
||||
## 2. 输入
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class AdmissionDecisionInput:
|
||||
risk_items: list[RiskItem]
|
||||
manual_review_items: list[dict]
|
||||
admission_rules: dict
|
||||
```
|
||||
|
||||
## 3. 输出
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class AdmissionDecisionOutput:
|
||||
pass_status: str
|
||||
highest_risk_level: str
|
||||
decision_reason: str
|
||||
score_detail: dict
|
||||
```
|
||||
|
||||
## 4. 判定规则
|
||||
|
||||
1. 任一高风险:不通过。
|
||||
2. 多个中风险:待整改后复核。
|
||||
3. 只有低风险:条件通过。
|
||||
4. 有人工复核项:待复核。
|
||||
5. 无风险:通过。
|
||||
|
||||
## 5. 核心方法
|
||||
|
||||
### 5.1 `run(input) -> AdmissionDecisionOutput`
|
||||
|
||||
主入口方法。
|
||||
|
||||
### 5.2 `calculate_highest_level(risk_items) -> str`
|
||||
|
||||
计算最高风险等级。
|
||||
|
||||
### 5.3 `calculate_status(risk_items, manual_review_items, rules) -> str`
|
||||
|
||||
计算准入状态。
|
||||
|
||||
### 5.4 `build_decision_reason(status, risk_items) -> str`
|
||||
|
||||
生成判定理由。
|
||||
|
||||
## 6. 技术实现
|
||||
|
||||
使用技术:
|
||||
|
||||
1. 风险等级枚举
|
||||
2. 准入规则 YAML
|
||||
3. Python 规则判断
|
||||
|
||||
## 7. 测试要点
|
||||
|
||||
1. 高风险导致失败。
|
||||
2. 中风险过多导致复核。
|
||||
3. 低风险条件通过。
|
||||
4. 无风险通过。
|
||||
|
||||
67
docs/详细设计/skill/前序报告汇总Skill.md
Normal file
67
docs/详细设计/skill/前序报告汇总Skill.md
Normal file
@@ -0,0 +1,67 @@
|
||||
# 前序报告汇总Skill 设计
|
||||
|
||||
## 1. Skill 定位
|
||||
|
||||
`前序报告汇总Skill` 负责读取当前批次已经生成的完整性、字段抽取和一致性核查报告,并统一转为风险评估上下文。
|
||||
|
||||
英文实现标识建议使用 `SourceReportCollectSkill`。
|
||||
|
||||
## 2. 输入
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class SourceReportCollectInput:
|
||||
batch_id: int
|
||||
include_reports: list[str]
|
||||
```
|
||||
|
||||
## 3. 输出
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class SourceReportCollectOutput:
|
||||
reports: dict[str, dict]
|
||||
missing_reports: list[str]
|
||||
stale_reports: list[str]
|
||||
validation_warnings: list[dict]
|
||||
```
|
||||
|
||||
## 4. 核心方法
|
||||
|
||||
### 4.1 `run(input) -> SourceReportCollectOutput`
|
||||
|
||||
主入口方法。
|
||||
|
||||
### 4.2 `load_report(batch_id, report_type) -> dict | None`
|
||||
|
||||
读取报告快照。
|
||||
|
||||
### 4.3 `validate_report_freshness(report) -> bool`
|
||||
|
||||
校验报告是否过期。
|
||||
|
||||
### 4.4 `build_report_bundle(reports) -> SourceReportBundle`
|
||||
|
||||
构建报告集合。
|
||||
|
||||
## 5. 技术实现
|
||||
|
||||
使用技术:
|
||||
|
||||
1. Django ORM
|
||||
2. JSONField
|
||||
3. 报告版本号
|
||||
|
||||
## 6. 异常处理
|
||||
|
||||
1. 报告不存在:加入 `missing_reports`。
|
||||
2. 报告 schema 不完整:加入警告。
|
||||
3. 报告过期:加入 `stale_reports`。
|
||||
|
||||
## 7. 测试要点
|
||||
|
||||
1. 能读取多个报告。
|
||||
2. 缺失报告能识别。
|
||||
3. 过期报告能识别。
|
||||
4. 输出 bundle 稳定。
|
||||
|
||||
137
docs/详细设计/skill/压缩包解包Skill.md
Normal file
137
docs/详细设计/skill/压缩包解包Skill.md
Normal file
@@ -0,0 +1,137 @@
|
||||
# 压缩包解包Skill 设计
|
||||
|
||||
## 1. Skill 定位
|
||||
|
||||
`压缩包解包Skill` 负责压缩包解包,是资料包导入链路中的文件展开能力。它需要支持 `zip`、`rar`、`7z`,并确保解包过程安全、可追踪、可复核。
|
||||
|
||||
本 Skill 的输出是“解包后的文件树”,不是文档审核结论。
|
||||
|
||||
英文实现标识建议使用 `ArchiveExtractionSkill`,用于 Python 类名和 Tool Registry 注册处理器。
|
||||
|
||||
## 2. 输入
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class ArchiveExtractionInput:
|
||||
archive_path: Path
|
||||
target_dir: Path
|
||||
source_archive_name: str
|
||||
max_file_count: int = 1000
|
||||
max_total_size: int | None = None
|
||||
```
|
||||
|
||||
## 3. 输出
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class ArchiveExtractionOutput:
|
||||
status: str
|
||||
archive_type: str
|
||||
extracted_files: list[ExtractedFile]
|
||||
skipped_items: list[SkippedArchiveItem]
|
||||
warnings: list[dict]
|
||||
```
|
||||
|
||||
`ExtractedFile` 字段:
|
||||
|
||||
1. `absolute_path`
|
||||
2. `relative_path`
|
||||
3. `file_size`
|
||||
4. `source_archive_name`
|
||||
5. `file_hash`
|
||||
|
||||
## 4. 支持格式与技术
|
||||
|
||||
| 格式 | 技术 |
|
||||
|---|---|
|
||||
| `zip` | Python 标准库 `zipfile` |
|
||||
| `rar` | 纯 Python rar 解析依赖,优先选择不依赖系统命令的库 |
|
||||
| `7z` | `py7zr` |
|
||||
|
||||
V1 可以先完成 `zip`,同时保留 `rar`、`7z` 的接口和失败提示。正式验收前需要补齐纯 Python 解包能力。
|
||||
|
||||
## 5. 核心方法
|
||||
|
||||
### 5.1 `run(input) -> ArchiveExtractionOutput`
|
||||
|
||||
主入口方法。
|
||||
|
||||
处理顺序:
|
||||
|
||||
1. 识别压缩包类型。
|
||||
2. 打开压缩包。
|
||||
3. 遍历成员文件。
|
||||
4. 校验成员路径安全性。
|
||||
5. 校验数量和大小限制。
|
||||
6. 解包到批次隔离目录。
|
||||
7. 生成解包结果。
|
||||
|
||||
### 5.2 `detect_archive_type(path) -> str`
|
||||
|
||||
根据扩展名和文件头识别压缩包类型。
|
||||
|
||||
返回:
|
||||
|
||||
1. `zip`
|
||||
2. `rar`
|
||||
3. `7z`
|
||||
4. `unsupported`
|
||||
|
||||
### 5.3 `validate_member_path(member_name) -> str`
|
||||
|
||||
路径安全校验。
|
||||
|
||||
拒绝:
|
||||
|
||||
1. 绝对路径。
|
||||
2. 包含 `..` 的路径。
|
||||
3. Windows 盘符路径。
|
||||
4. 空路径。
|
||||
5. 控制字符。
|
||||
|
||||
### 5.4 `extract_zip(input) -> list[ExtractedFile]`
|
||||
|
||||
使用 `zipfile` 解包。
|
||||
|
||||
### 5.5 `extract_rar(input) -> list[ExtractedFile]`
|
||||
|
||||
使用纯 Python rar 依赖解包。
|
||||
|
||||
如果当前环境依赖未安装,返回 `unsupported_archive`,并提示需要安装对应依赖。
|
||||
|
||||
### 5.6 `extract_7z(input) -> list[ExtractedFile]`
|
||||
|
||||
使用 `py7zr` 解包。
|
||||
|
||||
### 5.7 `build_file_hash(path) -> str`
|
||||
|
||||
使用 `sha256` 生成文件指纹,用于重复文件识别。
|
||||
|
||||
## 6. 状态设计
|
||||
|
||||
| 状态 | 含义 |
|
||||
|---|---|
|
||||
| `extracted` | 解包成功 |
|
||||
| `partial_extracted` | 部分成员解包失败 |
|
||||
| `empty_archive` | 压缩包为空 |
|
||||
| `encrypted_archive` | 加密压缩包 |
|
||||
| `unsupported_archive` | 格式不支持 |
|
||||
| `path_rejected` | 存在危险路径 |
|
||||
| `extract_failed` | 解包失败 |
|
||||
|
||||
## 7. 异常处理
|
||||
|
||||
1. 加密压缩包:不尝试暴力解析,标记为待人工处理。
|
||||
2. 路径穿越:拒绝危险成员并记录安全拦截。
|
||||
3. 超大压缩包:超过配置限制时停止处理。
|
||||
4. 成员数量过多:停止处理并提示资料包异常。
|
||||
5. 文件名乱码:保留原始名称,展示层提示人工复核。
|
||||
|
||||
## 8. 测试要点
|
||||
|
||||
1. 普通 zip 解包成功。
|
||||
2. 多层目录相对路径被保留。
|
||||
3. `../evil.docx` 被拒绝。
|
||||
4. 空压缩包返回 `empty_archive`。
|
||||
5. 不支持格式返回 `unsupported_archive`。
|
||||
6. 解包后文件哈希生成稳定。
|
||||
62
docs/详细设计/skill/回填字段集构建Skill.md
Normal file
62
docs/详细设计/skill/回填字段集构建Skill.md
Normal file
@@ -0,0 +1,62 @@
|
||||
# 回填字段集构建Skill 设计
|
||||
|
||||
## 1. Skill 定位
|
||||
|
||||
`回填字段集构建Skill` 负责根据模板字段映射和统一字段池构建实际要写入 Word 模板的字段值集合。
|
||||
|
||||
英文实现标识建议使用 `FillDatasetBuildSkill`。
|
||||
|
||||
## 2. 输入
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class FillDatasetBuildInput:
|
||||
field_pool_items: list[FieldPoolItem]
|
||||
template_mappings: list[dict]
|
||||
selected_field_keys: list[str] = field(default_factory=list)
|
||||
```
|
||||
|
||||
## 3. 输出
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class FillDatasetBuildOutput:
|
||||
fill_dataset: dict
|
||||
missing_required_fields: list[dict]
|
||||
manual_review_fields: list[dict]
|
||||
```
|
||||
|
||||
## 4. 核心方法
|
||||
|
||||
### 4.1 `run(input) -> FillDatasetBuildOutput`
|
||||
|
||||
主入口方法。
|
||||
|
||||
### 4.2 `resolve_field_value(mapping, field_pool) -> FillValue`
|
||||
|
||||
解析字段值。
|
||||
|
||||
### 4.3 `build_placeholder_values(mappings, field_pool) -> dict`
|
||||
|
||||
生成占位符和值。
|
||||
|
||||
## 5. 技术实现
|
||||
|
||||
使用技术:
|
||||
|
||||
1. 字段池数据
|
||||
2. 模板映射
|
||||
3. Python 字典构建
|
||||
|
||||
## 6. 异常处理
|
||||
|
||||
1. 必填字段缺失:进入缺失列表。
|
||||
2. 字段待复核:进入待复核列表。
|
||||
3. 字段不可回填:跳过。
|
||||
|
||||
## 7. 测试要点
|
||||
|
||||
1. 可回填字段进入 dataset。
|
||||
2. 必填缺失可识别。
|
||||
3. 待复核字段可识别。
|
||||
|
||||
70
docs/详细设计/skill/回填拦截检查Skill.md
Normal file
70
docs/详细设计/skill/回填拦截检查Skill.md
Normal file
@@ -0,0 +1,70 @@
|
||||
# 回填拦截检查Skill 设计
|
||||
|
||||
## 1. Skill 定位
|
||||
|
||||
`回填拦截检查Skill` 负责根据字段冲突、风险报告和必填字段缺失情况判断是否允许正式回填导出。
|
||||
|
||||
英文实现标识建议使用 `FillBlockerCheckSkill`。
|
||||
|
||||
## 2. 输入
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class FillBlockerCheckInput:
|
||||
fill_dataset: dict
|
||||
risk_report: dict
|
||||
consistency_report: dict
|
||||
missing_required_fields: list[dict]
|
||||
allow_draft_when_blocked: bool
|
||||
```
|
||||
|
||||
## 3. 输出
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class FillBlockerCheckOutput:
|
||||
export_mode: str
|
||||
blocked_fields: list[dict]
|
||||
blockers: list[dict]
|
||||
```
|
||||
|
||||
## 4. 拦截规则
|
||||
|
||||
1. 高风险未处理:拦截正式版。
|
||||
2. 字段冲突:拦截正式版。
|
||||
3. 必填字段缺失:拦截正式版。
|
||||
4. 待人工复核:允许草稿,不允许正式版。
|
||||
|
||||
## 5. 核心方法
|
||||
|
||||
### 5.1 `run(input) -> FillBlockerCheckOutput`
|
||||
|
||||
主入口方法。
|
||||
|
||||
### 5.2 `detect_high_risk_blocker(risk_report) -> list[dict]`
|
||||
|
||||
检测高风险。
|
||||
|
||||
### 5.3 `detect_conflict_blocker(consistency_report) -> list[dict]`
|
||||
|
||||
检测冲突字段。
|
||||
|
||||
### 5.4 `resolve_export_mode(blockers, allow_draft) -> str`
|
||||
|
||||
确定导出模式。
|
||||
|
||||
## 6. 技术实现
|
||||
|
||||
使用技术:
|
||||
|
||||
1. 风险报告
|
||||
2. 一致性报告
|
||||
3. 本地规则
|
||||
|
||||
## 7. 测试要点
|
||||
|
||||
1. 高风险拦截正式导出。
|
||||
2. 冲突字段拦截正式导出。
|
||||
3. 草稿模式可用。
|
||||
4. 无拦截时正式导出。
|
||||
|
||||
75
docs/详细设计/skill/字段Schema加载Skill.md
Normal file
75
docs/详细设计/skill/字段Schema加载Skill.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# 字段Schema加载Skill 设计
|
||||
|
||||
## 1. Skill 定位
|
||||
|
||||
`字段Schema加载Skill` 负责加载注册申报字段 schema,提供字段定义、来源优先级、抽取方式、回填属性和一致性要求。
|
||||
|
||||
英文实现标识建议使用 `FieldSchemaLoadSkill`。
|
||||
|
||||
## 2. 输入
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class FieldSchemaLoadInput:
|
||||
field_schema_id: str
|
||||
target_field_keys: list[str] = field(default_factory=list)
|
||||
```
|
||||
|
||||
## 3. 输出
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class FieldSchemaLoadOutput:
|
||||
field_schema_id: str
|
||||
version: str
|
||||
fields: list[FieldDefinition]
|
||||
source_priority: dict
|
||||
validation_warnings: list[dict]
|
||||
```
|
||||
|
||||
## 4. 核心方法
|
||||
|
||||
### 4.1 `run(input) -> FieldSchemaLoadOutput`
|
||||
|
||||
主入口方法。
|
||||
|
||||
### 4.2 `load_schema_file(field_schema_id) -> dict`
|
||||
|
||||
从 YAML 读取字段 schema。
|
||||
|
||||
### 4.3 `validate_field_schema(raw_schema) -> FieldSchemaValidationResult`
|
||||
|
||||
校验字段定义。
|
||||
|
||||
### 4.4 `select_target_fields(schema, target_field_keys) -> list[FieldDefinition]`
|
||||
|
||||
筛选目标字段。
|
||||
|
||||
## 5. 技术实现
|
||||
|
||||
使用技术:
|
||||
|
||||
1. `PyYAML`
|
||||
2. Pydantic
|
||||
3. Django cache
|
||||
|
||||
建议路径:
|
||||
|
||||
```text
|
||||
configs/registration/fields/ivd_registration_fields_v1.yaml
|
||||
```
|
||||
|
||||
## 6. 异常处理
|
||||
|
||||
1. schema 文件不存在:任务失败。
|
||||
2. 字段定义缺少 `field_key`:校验失败。
|
||||
3. 目标字段不存在:返回业务错误。
|
||||
4. 来源优先级缺失:允许执行,但记录警告。
|
||||
|
||||
## 7. 测试要点
|
||||
|
||||
1. schema 加载成功。
|
||||
2. 目标字段筛选正确。
|
||||
3. 缺少必填字段时报错。
|
||||
4. 来源优先级输出正确。
|
||||
|
||||
66
docs/详细设计/skill/字段分组Skill.md
Normal file
66
docs/详细设计/skill/字段分组Skill.md
Normal file
@@ -0,0 +1,66 @@
|
||||
# 字段分组Skill 设计
|
||||
|
||||
## 1. Skill 定位
|
||||
|
||||
`字段分组Skill` 负责将统一字段池中的字段候选按字段编码和来源文档分组,形成可比对的数据单元。
|
||||
|
||||
英文实现标识建议使用 `FieldGroupSkill`。
|
||||
|
||||
## 2. 输入
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class FieldGroupInput:
|
||||
field_pool_items: list[FieldPoolItem]
|
||||
field_candidates: list[FieldCandidateRecord]
|
||||
scope_documents: list[DocumentFact]
|
||||
```
|
||||
|
||||
## 3. 输出
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class FieldGroupOutput:
|
||||
compare_units: list[FieldCompareUnit]
|
||||
single_source_fields: list[dict]
|
||||
excluded_candidates: list[dict]
|
||||
```
|
||||
|
||||
## 4. 核心方法
|
||||
|
||||
### 4.1 `run(input) -> FieldGroupOutput`
|
||||
|
||||
主入口方法。
|
||||
|
||||
### 4.2 `group_by_field_key(candidates) -> dict`
|
||||
|
||||
按字段编码分组。
|
||||
|
||||
### 4.3 `filter_candidates_by_scope(candidates, scope_documents) -> list`
|
||||
|
||||
只保留审核范围内来源文档的候选。
|
||||
|
||||
### 4.4 `build_compare_unit(field_key, candidates) -> FieldCompareUnit`
|
||||
|
||||
构建字段比对单元。
|
||||
|
||||
## 5. 技术实现
|
||||
|
||||
使用技术:
|
||||
|
||||
1. Python 分组
|
||||
2. 字段池候选记录
|
||||
3. 文档范围过滤
|
||||
|
||||
## 6. 异常处理
|
||||
|
||||
1. 字段无候选:进入待复核。
|
||||
2. 来源文档不在范围内:排除候选。
|
||||
3. 单来源字段:标记 `single_source`。
|
||||
|
||||
## 7. 测试要点
|
||||
|
||||
1. 候选按字段分组正确。
|
||||
2. 范围外候选被排除。
|
||||
3. 单来源字段识别正确。
|
||||
|
||||
77
docs/详细设计/skill/字段完全一致比对Skill.md
Normal file
77
docs/详细设计/skill/字段完全一致比对Skill.md
Normal file
@@ -0,0 +1,77 @@
|
||||
# 字段完全一致比对Skill 设计
|
||||
|
||||
## 1. Skill 定位
|
||||
|
||||
`字段完全一致比对Skill` 负责按强一致规则对同一字段的不同来源值执行完全一致比对。
|
||||
|
||||
英文实现标识建议使用 `ExactFieldCompareSkill`。
|
||||
|
||||
本 Skill 不做语义相似判断。
|
||||
|
||||
## 2. 输入
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class ExactFieldCompareInput:
|
||||
compare_units: list[FieldCompareUnit]
|
||||
rules: list[ConsistencyFieldRule]
|
||||
```
|
||||
|
||||
## 3. 输出
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class ExactFieldCompareOutput:
|
||||
compare_results: list[FieldCompareResult]
|
||||
conflict_fields: list[dict]
|
||||
consistent_fields: list[dict]
|
||||
manual_review_fields: list[dict]
|
||||
```
|
||||
|
||||
## 4. 比对规则
|
||||
|
||||
1. 标准值完全相等才算一致。
|
||||
2. 空值不算一致证据。
|
||||
3. 待复核来源不算通过证据。
|
||||
4. 原始值明显差异但标准值相同,进入待复核。
|
||||
|
||||
## 5. 核心方法
|
||||
|
||||
### 5.1 `run(input) -> ExactFieldCompareOutput`
|
||||
|
||||
主入口方法。
|
||||
|
||||
### 5.2 `compare_exact(unit, rule) -> FieldCompareResult`
|
||||
|
||||
完全一致比对。
|
||||
|
||||
### 5.3 `build_conflict_result(unit, values, rule) -> FieldCompareResult`
|
||||
|
||||
构建冲突结果。
|
||||
|
||||
### 5.4 `build_consistent_result(unit, rule) -> FieldCompareResult`
|
||||
|
||||
构建一致结果。
|
||||
|
||||
## 6. 技术实现
|
||||
|
||||
使用技术:
|
||||
|
||||
1. Python 字符串比较
|
||||
2. 字段标准化值
|
||||
3. 风险规则
|
||||
|
||||
## 7. 异常处理
|
||||
|
||||
1. 无候选值:待人工复核。
|
||||
2. 单来源:不判冲突。
|
||||
3. 字段无规则:不检查。
|
||||
4. 候选来源待复核:结果待复核。
|
||||
|
||||
## 8. 测试要点
|
||||
|
||||
1. 相同标准值判一致。
|
||||
2. 不同标准值判冲突。
|
||||
3. 单来源不判冲突。
|
||||
4. 待复核来源进入人工复核。
|
||||
|
||||
89
docs/详细设计/skill/字段抽取报告生成Skill.md
Normal file
89
docs/详细设计/skill/字段抽取报告生成Skill.md
Normal file
@@ -0,0 +1,89 @@
|
||||
# 字段抽取报告生成Skill 设计
|
||||
|
||||
## 1. Skill 定位
|
||||
|
||||
`字段抽取报告生成Skill` 负责将字段池写入结果组装成稳定的 `registration_field_extraction_report`,并生成页面展示、审计和飞书摘要所需的数据结构。
|
||||
|
||||
英文实现标识建议使用 `FieldExtractionReportBuildSkill`。
|
||||
|
||||
## 2. 输入
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class FieldExtractionReportBuildInput:
|
||||
context: FieldExtractionContext
|
||||
field_pool_items: list[FieldPoolItem]
|
||||
manual_review_fields: list[dict]
|
||||
tool_calls: list[dict]
|
||||
```
|
||||
|
||||
## 3. 输出
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class FieldExtractionReportBuildOutput:
|
||||
report: dict
|
||||
display_sections: list[dict]
|
||||
audit_payload: dict
|
||||
feishu_summary_payload: dict
|
||||
```
|
||||
|
||||
## 4. 报告结构
|
||||
|
||||
报告必须包含:
|
||||
|
||||
1. `report_type`
|
||||
2. `batch_id`
|
||||
3. `field_schema_id`
|
||||
4. `field_schema_version`
|
||||
5. `summary`
|
||||
6. `field_pool_items`
|
||||
7. `manual_review_fields`
|
||||
8. `evidence_refs`
|
||||
9. `tool_calls`
|
||||
|
||||
## 5. 核心方法
|
||||
|
||||
### 5.1 `run(input) -> FieldExtractionReportBuildOutput`
|
||||
|
||||
主入口方法。
|
||||
|
||||
### 5.2 `build_summary(field_pool_items) -> dict`
|
||||
|
||||
汇总字段数量、已抽取数量、待复核数量和冲突候选数量。
|
||||
|
||||
### 5.3 `build_field_rows(field_pool_items) -> list[dict]`
|
||||
|
||||
生成字段池页面表格。
|
||||
|
||||
### 5.4 `build_audit_payload(report, context) -> dict`
|
||||
|
||||
生成审计载荷。
|
||||
|
||||
### 5.5 `build_feishu_summary_payload(report) -> dict`
|
||||
|
||||
生成飞书摘要载荷。
|
||||
|
||||
## 6. 技术实现
|
||||
|
||||
使用技术:
|
||||
|
||||
1. dataclass/Pydantic
|
||||
2. JSONField
|
||||
3. Audit 服务
|
||||
4. 页面展示 schema
|
||||
|
||||
## 7. 异常处理
|
||||
|
||||
1. 字段池为空:输出空报告并提示无可用字段。
|
||||
2. 报告字段缺失:任务失败。
|
||||
3. 审计写入失败:报告仍返回,但记录系统警告。
|
||||
4. 飞书摘要构建失败:不影响 Web 报告。
|
||||
|
||||
## 8. 测试要点
|
||||
|
||||
1. 输出 schema 稳定。
|
||||
2. 字段池行展示完整。
|
||||
3. 审计载荷包含字段 schema 版本。
|
||||
4. 飞书摘要不包含敏感信息。
|
||||
|
||||
114
docs/详细设计/skill/字段抽取编排Skill.md
Normal file
114
docs/详细设计/skill/字段抽取编排Skill.md
Normal file
@@ -0,0 +1,114 @@
|
||||
# 字段抽取编排Skill 设计
|
||||
|
||||
## 1. Skill 定位
|
||||
|
||||
`字段抽取编排Skill` 是第三步工作流的总入口 Skill,负责组织字段抽取范围确认、字段 schema 加载、规则抽取、表格抽取、长文本归纳、字段标准化、统一字段池写入和报告生成。
|
||||
|
||||
英文实现标识建议使用 `FieldExtractionOrchestrateSkill`。
|
||||
|
||||
本 Skill 不直接完成每一种抽取细节,而是负责执行顺序和结果合并。
|
||||
|
||||
## 2. 输入
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class FieldExtractionOrchestrateInput:
|
||||
batch_id: int
|
||||
scenario_id: str = "registration_field_extraction"
|
||||
field_schema_id: str = "ivd_registration_fields_v1"
|
||||
selected_document_ids: list[int] = field(default_factory=list)
|
||||
target_field_keys: list[str] = field(default_factory=list)
|
||||
enable_llm_fallback: bool = True
|
||||
enable_rag_context: bool = True
|
||||
```
|
||||
|
||||
## 3. 输出
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class FieldExtractionOrchestrateOutput:
|
||||
report_type: str
|
||||
batch_id: int
|
||||
field_schema_id: str
|
||||
summary: dict
|
||||
field_pool_items: list[dict]
|
||||
manual_review_fields: list[dict]
|
||||
evidence_refs: list[dict]
|
||||
audit_id: int | None = None
|
||||
```
|
||||
|
||||
## 4. 依赖 Skill
|
||||
|
||||
1. `字段抽取范围确认Skill`
|
||||
2. `字段Schema加载Skill`
|
||||
3. `规则字段抽取Skill`
|
||||
4. `表格字段抽取Skill`
|
||||
5. `长文本字段归纳Skill`
|
||||
6. `字段标准化Skill`
|
||||
7. `统一字段池写入Skill`
|
||||
8. `字段抽取报告生成Skill`
|
||||
|
||||
## 5. 核心方法
|
||||
|
||||
### 5.1 `run(input) -> FieldExtractionOrchestrateOutput`
|
||||
|
||||
主入口方法。
|
||||
|
||||
执行顺序:
|
||||
|
||||
1. 加载执行上下文。
|
||||
2. 调用 `字段抽取范围确认Skill`。
|
||||
3. 调用 `字段Schema加载Skill`。
|
||||
4. 调用 `规则字段抽取Skill`。
|
||||
5. 调用 `表格字段抽取Skill`。
|
||||
6. 按需调用 `长文本字段归纳Skill`。
|
||||
7. 调用 `字段标准化Skill`。
|
||||
8. 调用 `统一字段池写入Skill`。
|
||||
9. 调用 `字段抽取报告生成Skill`。
|
||||
10. 写入审计记录。
|
||||
|
||||
### 5.2 `load_execution_context(input) -> FieldExtractionContext`
|
||||
|
||||
加载批次、文档、完整性检查报告和已有字段池状态。
|
||||
|
||||
### 5.3 `merge_field_candidates(*candidate_groups) -> list[FieldCandidate]`
|
||||
|
||||
合并规则抽取、表格抽取和长文本归纳结果。
|
||||
|
||||
### 5.4 `filter_target_fields(schema, target_field_keys) -> list[FieldDefinition]`
|
||||
|
||||
筛选本次需要抽取的字段。
|
||||
|
||||
## 6. 技术实现
|
||||
|
||||
使用技术:
|
||||
|
||||
1. Python dataclass 或 Pydantic
|
||||
2. Tool Registry
|
||||
3. LLM Provider
|
||||
4. Django 服务层
|
||||
5. Audit 服务
|
||||
|
||||
建议注册名:
|
||||
|
||||
```python
|
||||
tool_registry.register(
|
||||
name="field_extraction_orchestrate",
|
||||
handler=FieldExtractionOrchestrateSkill().run,
|
||||
)
|
||||
```
|
||||
|
||||
## 7. 异常处理
|
||||
|
||||
1. 无可抽取文档:返回业务提示。
|
||||
2. 字段 schema 不存在:任务失败并写审计。
|
||||
3. LLM 不可用:跳过 LLM,保留规则和表格结果。
|
||||
4. 所有抽取方式均失败:返回待人工复核报告。
|
||||
|
||||
## 8. 测试要点
|
||||
|
||||
1. 能按顺序调用依赖 Skill。
|
||||
2. LLM 关闭时仍可执行规则抽取。
|
||||
3. 无文档时返回清晰错误。
|
||||
4. 输出报告结构稳定。
|
||||
|
||||
79
docs/详细设计/skill/字段抽取范围确认Skill.md
Normal file
79
docs/详细设计/skill/字段抽取范围确认Skill.md
Normal file
@@ -0,0 +1,79 @@
|
||||
# 字段抽取范围确认Skill 设计
|
||||
|
||||
## 1. Skill 定位
|
||||
|
||||
`字段抽取范围确认Skill` 负责确定本次字段抽取使用哪些文档,以及每个目标字段优先从哪些文档角色中抽取。
|
||||
|
||||
英文实现标识建议使用 `FieldExtractionScopeResolveSkill`。
|
||||
|
||||
## 2. 输入
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class FieldExtractionScopeResolveInput:
|
||||
documents: list[DocumentFact]
|
||||
selected_document_ids: list[int]
|
||||
target_field_keys: list[str]
|
||||
field_source_priority: dict
|
||||
```
|
||||
|
||||
## 3. 输出
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class FieldExtractionScopeResolveOutput:
|
||||
extractable_documents: list[DocumentFact]
|
||||
excluded_documents: list[dict]
|
||||
field_document_plan: dict[str, list[DocumentFact]]
|
||||
warnings: list[dict]
|
||||
```
|
||||
|
||||
## 4. 文档筛选规则
|
||||
|
||||
参与抽取的文档必须满足:
|
||||
|
||||
1. `source_role = submission`
|
||||
2. 文档处理状态可用。
|
||||
3. 文档存在文本或表格结构。
|
||||
4. 文档角色属于字段来源配置。
|
||||
|
||||
排除:
|
||||
|
||||
1. 法规依据资料。
|
||||
2. 不支持文件。
|
||||
3. 解析失败且无可用文本。
|
||||
4. 用户未选择且不在默认来源范围内的文档。
|
||||
|
||||
## 5. 核心方法
|
||||
|
||||
### 5.1 `run(input) -> FieldExtractionScopeResolveOutput`
|
||||
|
||||
主入口方法。
|
||||
|
||||
### 5.2 `filter_extractable_documents(documents) -> list[DocumentFact]`
|
||||
|
||||
筛选可抽取文档。
|
||||
|
||||
### 5.3 `build_field_document_plan(fields, documents, priority) -> dict`
|
||||
|
||||
为每个字段构建候选文档顺序。
|
||||
|
||||
### 5.4 `collect_scope_warnings(documents) -> list[dict]`
|
||||
|
||||
收集待复核、解析失败、文本缺失等警告。
|
||||
|
||||
## 6. 技术实现
|
||||
|
||||
使用技术:
|
||||
|
||||
1. 文档角色枚举
|
||||
2. YAML 来源优先级
|
||||
3. Python 排序规则
|
||||
|
||||
## 7. 测试要点
|
||||
|
||||
1. 法规资料被排除。
|
||||
2. 申请表、说明书、产品列表被纳入。
|
||||
3. 用户选择文档时只使用选中范围。
|
||||
4. 待复核文档会降低抽取可信度。
|
||||
|
||||
83
docs/详细设计/skill/字段标准化Skill.md
Normal file
83
docs/详细设计/skill/字段标准化Skill.md
Normal file
@@ -0,0 +1,83 @@
|
||||
# 字段标准化Skill 设计
|
||||
|
||||
## 1. Skill 定位
|
||||
|
||||
`字段标准化Skill` 负责对字段候选值进行清洗、标准化、置信度计算和冲突候选标记。
|
||||
|
||||
英文实现标识建议使用 `FieldNormalizeSkill`。
|
||||
|
||||
## 2. 输入
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class FieldNormalizeInput:
|
||||
candidates: list[FieldCandidate]
|
||||
field_definitions: list[FieldDefinition]
|
||||
source_priority: dict
|
||||
```
|
||||
|
||||
## 3. 输出
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class FieldNormalizeOutput:
|
||||
normalized_candidates: list[NormalizedFieldCandidate]
|
||||
conflict_candidates: list[dict]
|
||||
manual_review_candidates: list[dict]
|
||||
```
|
||||
|
||||
## 4. 标准化规则
|
||||
|
||||
1. 去除首尾空白。
|
||||
2. 合并连续空白。
|
||||
3. 全角半角标准化。
|
||||
4. 中文标点标准化。
|
||||
5. 日期格式标准化。
|
||||
6. 单位格式标准化。
|
||||
7. 空值和异常长值标记待复核。
|
||||
|
||||
## 5. 核心方法
|
||||
|
||||
### 5.1 `run(input) -> FieldNormalizeOutput`
|
||||
|
||||
主入口方法。
|
||||
|
||||
### 5.2 `normalize_text_value(value) -> str`
|
||||
|
||||
文本清洗。
|
||||
|
||||
### 5.3 `normalize_date_value(value) -> str`
|
||||
|
||||
日期标准化。
|
||||
|
||||
### 5.4 `calculate_confidence(candidate, field_definition) -> str`
|
||||
|
||||
计算置信度。
|
||||
|
||||
### 5.5 `detect_conflict_candidates(candidates) -> list[dict]`
|
||||
|
||||
检测同字段多候选值差异。
|
||||
|
||||
## 6. 技术实现
|
||||
|
||||
使用技术:
|
||||
|
||||
1. Python 字符串处理
|
||||
2. 正则表达式
|
||||
3. 日期解析
|
||||
4. 字段类型规则
|
||||
|
||||
## 7. 异常处理
|
||||
|
||||
1. 值为空:标记待复核。
|
||||
2. 值过长:标记待复核。
|
||||
3. 日期无法解析:保留原值并标记低可信。
|
||||
4. 多候选不一致:标记 `conflict_candidate`。
|
||||
|
||||
## 8. 测试要点
|
||||
|
||||
1. 空白和标点标准化正确。
|
||||
2. 日期标准化正确。
|
||||
3. 多候选冲突可识别。
|
||||
4. 低可信候选进入待复核。
|
||||
|
||||
115
docs/详细设计/skill/完整性报告生成Skill.md
Normal file
115
docs/详细设计/skill/完整性报告生成Skill.md
Normal file
@@ -0,0 +1,115 @@
|
||||
# 完整性报告生成Skill 设计
|
||||
|
||||
## 1. Skill 定位
|
||||
|
||||
`完整性报告生成Skill` 负责把完整性检查链路中的规则判定结果、风险映射结果和法规证据组装成稳定的 `registration_completeness_report`。
|
||||
|
||||
英文实现标识建议使用 `CompletenessReportBuildSkill`。
|
||||
|
||||
本 Skill 不重新判定缺失,不重新检索证据,只负责报告结构、展示摘要和审计载荷生成。
|
||||
|
||||
## 2. 输入
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class CompletenessReportBuildInput:
|
||||
execution_context: CompletenessExecutionContext
|
||||
item_results: list[CompletenessItemResult]
|
||||
evidence_refs: list[EvidenceRef]
|
||||
pass_status: str
|
||||
highest_risk_level: str
|
||||
```
|
||||
|
||||
## 3. 输出
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class CompletenessReportBuildOutput:
|
||||
report: dict
|
||||
display_sections: list[dict]
|
||||
audit_payload: dict
|
||||
feishu_summary_payload: dict
|
||||
```
|
||||
|
||||
## 4. 报告结构
|
||||
|
||||
报告必须包含:
|
||||
|
||||
1. `report_type`
|
||||
2. `batch_id`
|
||||
3. `workflow_type`
|
||||
4. `rule_package_id`
|
||||
5. `rule_version`
|
||||
6. `chapter_scope`
|
||||
7. `summary`
|
||||
8. `matched_items`
|
||||
9. `missing_items`
|
||||
10. `misplaced_items`
|
||||
11. `manual_review_items`
|
||||
12. `evidence_refs`
|
||||
13. `suggestions`
|
||||
|
||||
## 5. 核心方法
|
||||
|
||||
### 5.1 `run(input) -> CompletenessReportBuildOutput`
|
||||
|
||||
主入口方法。
|
||||
|
||||
### 5.2 `build_summary(item_results) -> dict`
|
||||
|
||||
汇总:
|
||||
|
||||
1. 要求项数量。
|
||||
2. 已提供数量。
|
||||
3. 缺失数量。
|
||||
4. 疑似提供数量。
|
||||
5. 错放数量。
|
||||
6. 待复核数量。
|
||||
7. 最高风险等级。
|
||||
8. 是否通过。
|
||||
|
||||
### 5.3 `split_item_results(item_results) -> dict`
|
||||
|
||||
按状态拆分明细。
|
||||
|
||||
### 5.4 `attach_evidence(item_results, evidence_refs) -> list[dict]`
|
||||
|
||||
把法规证据挂到对应要求项。
|
||||
|
||||
### 5.5 `build_display_sections(report) -> list[dict]`
|
||||
|
||||
生成页面展示区块。
|
||||
|
||||
### 5.6 `build_audit_payload(report, context) -> dict`
|
||||
|
||||
生成审计载荷。
|
||||
|
||||
### 5.7 `build_feishu_summary_payload(report) -> dict`
|
||||
|
||||
生成飞书摘要载荷,供后续飞书通知步骤复用。
|
||||
|
||||
## 6. 技术实现
|
||||
|
||||
使用技术:
|
||||
|
||||
1. Pydantic/dataclass
|
||||
2. JSONField
|
||||
3. Django Audit 服务层
|
||||
4. 结构化消息模板
|
||||
|
||||
## 7. 异常处理
|
||||
|
||||
1. 报告字段缺失:构建失败并写入失败审计。
|
||||
2. 证据为空:正常输出,标记证据缺失。
|
||||
3. 明细为空:输出空检查结果。
|
||||
4. 风险等级缺失:按 `low` 处理,并记录规则警告。
|
||||
|
||||
## 8. 测试要点
|
||||
|
||||
1. 输出 schema 字段稳定。
|
||||
2. 缺失项进入 `missing_items`。
|
||||
3. 错放项进入 `misplaced_items`。
|
||||
4. 待复核项进入 `manual_review_items`。
|
||||
5. 审计载荷包含规则版本和输入范围。
|
||||
6. 飞书摘要载荷不包含敏感信息。
|
||||
|
||||
77
docs/详细设计/skill/审核范围确认Skill.md
Normal file
77
docs/详细设计/skill/审核范围确认Skill.md
Normal file
@@ -0,0 +1,77 @@
|
||||
# 审核范围确认Skill 设计
|
||||
|
||||
## 1. Skill 定位
|
||||
|
||||
`审核范围确认Skill` 负责确认本次一致性核查的文档范围,避免把不同项目、不同产品或法规依据资料混入同一轮比对。
|
||||
|
||||
英文实现标识建议使用 `ReviewScopeResolveSkill`。
|
||||
|
||||
## 2. 输入
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class ReviewScopeResolveInput:
|
||||
batch_id: int
|
||||
documents: list[DocumentFact]
|
||||
selected_document_ids: list[int] = field(default_factory=list)
|
||||
```
|
||||
|
||||
## 3. 输出
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class ReviewScopeResolveOutput:
|
||||
scope_documents: list[DocumentFact]
|
||||
excluded_documents: list[dict]
|
||||
scope_warnings: list[dict]
|
||||
scope_status: str
|
||||
```
|
||||
|
||||
## 4. 范围规则
|
||||
|
||||
1. 必须同一批次。
|
||||
2. 必须是业务申报资料。
|
||||
3. 法规资料排除。
|
||||
4. 处理失败资料排除。
|
||||
5. 待人工复核资料保留但标记警告。
|
||||
6. 用户选中范围优先。
|
||||
|
||||
## 5. 核心方法
|
||||
|
||||
### 5.1 `run(input) -> ReviewScopeResolveOutput`
|
||||
|
||||
主入口方法。
|
||||
|
||||
### 5.2 `filter_by_selected_documents(documents, ids) -> list[DocumentFact]`
|
||||
|
||||
根据用户选择过滤文档。
|
||||
|
||||
### 5.3 `exclude_non_submission_documents(documents) -> list[dict]`
|
||||
|
||||
排除法规资料和非业务资料。
|
||||
|
||||
### 5.4 `build_scope_warnings(documents) -> list[dict]`
|
||||
|
||||
生成范围警告。
|
||||
|
||||
## 6. 技术实现
|
||||
|
||||
使用技术:
|
||||
|
||||
1. 文档主数据
|
||||
2. Django ORM
|
||||
3. 资料来源角色枚举
|
||||
|
||||
## 7. 异常处理
|
||||
|
||||
1. 范围为空:任务不可执行。
|
||||
2. 只有单个文档:允许执行,但只能输出单来源结果。
|
||||
3. 全部文档待复核:输出低可信警告。
|
||||
|
||||
## 8. 测试要点
|
||||
|
||||
1. 选中文档范围生效。
|
||||
2. 法规资料被排除。
|
||||
3. 待复核文档输出警告。
|
||||
4. 空范围返回错误。
|
||||
|
||||
65
docs/详细设计/skill/导出版式校验Skill.md
Normal file
65
docs/详细设计/skill/导出版式校验Skill.md
Normal file
@@ -0,0 +1,65 @@
|
||||
# 导出版式校验Skill 设计
|
||||
|
||||
## 1. Skill 定位
|
||||
|
||||
`导出版式校验Skill` 负责检查回填后的 Word 文件是否仍有未替换占位符、必填字段是否落位、基础版式是否完整。
|
||||
|
||||
英文实现标识建议使用 `ExportLayoutCheckSkill`。
|
||||
|
||||
## 2. 输入
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class ExportLayoutCheckInput:
|
||||
output_file_path: Path
|
||||
template_mappings: list[dict]
|
||||
```
|
||||
|
||||
## 3. 输出
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class ExportLayoutCheckOutput:
|
||||
layout_check_status: str
|
||||
unfilled_placeholders: list[str]
|
||||
layout_warnings: list[dict]
|
||||
```
|
||||
|
||||
## 4. 核心方法
|
||||
|
||||
### 4.1 `run(input) -> ExportLayoutCheckOutput`
|
||||
|
||||
主入口方法。
|
||||
|
||||
### 4.2 `detect_unfilled_placeholders(file) -> list[str]`
|
||||
|
||||
检查残留占位符。
|
||||
|
||||
### 4.3 `validate_required_fields(file, mappings) -> list[dict]`
|
||||
|
||||
校验必填字段。
|
||||
|
||||
### 4.4 `validate_basic_layout(file) -> list[dict]`
|
||||
|
||||
校验基础版式元素。
|
||||
|
||||
## 5. 技术实现
|
||||
|
||||
使用技术:
|
||||
|
||||
1. `python-docx`
|
||||
2. 可选 LibreOffice 转 PDF
|
||||
3. 占位符扫描规则
|
||||
|
||||
## 6. 异常处理
|
||||
|
||||
1. 文件不存在:校验失败。
|
||||
2. 残留占位符:标记待复核。
|
||||
3. 版式元素缺失:标记警告。
|
||||
|
||||
## 7. 测试要点
|
||||
|
||||
1. 残留占位符可识别。
|
||||
2. 必填字段缺失可识别。
|
||||
3. 正常文档通过校验。
|
||||
|
||||
75
docs/详细设计/skill/导出记录生成Skill.md
Normal file
75
docs/详细设计/skill/导出记录生成Skill.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# 导出记录生成Skill 设计
|
||||
|
||||
## 1. Skill 定位
|
||||
|
||||
`导出记录生成Skill` 负责保存导出文件元数据、生成下载入口、构建导出报告并写入审计。
|
||||
|
||||
英文实现标识建议使用 `ExportRecordBuildSkill`。
|
||||
|
||||
## 2. 输入
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class ExportRecordBuildInput:
|
||||
batch_id: int
|
||||
output_file_path: Path | None
|
||||
export_mode: str
|
||||
layout_check_result: dict
|
||||
filled_fields: list[dict]
|
||||
blocked_fields: list[dict]
|
||||
```
|
||||
|
||||
## 3. 输出
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class ExportRecordBuildOutput:
|
||||
report: dict
|
||||
output_file: dict | None
|
||||
audit_payload: dict
|
||||
```
|
||||
|
||||
## 4. 核心方法
|
||||
|
||||
### 4.1 `run(input) -> ExportRecordBuildOutput`
|
||||
|
||||
主入口方法。
|
||||
|
||||
### 4.2 `create_export_file_record(file_path) -> ExportedDocument`
|
||||
|
||||
创建导出文件记录。
|
||||
|
||||
### 4.3 `build_download_url(export_file) -> str`
|
||||
|
||||
生成下载 URL。
|
||||
|
||||
### 4.4 `build_report(input, output_file) -> dict`
|
||||
|
||||
生成导出报告。
|
||||
|
||||
### 4.5 `build_audit_payload(report) -> dict`
|
||||
|
||||
生成审计载荷。
|
||||
|
||||
## 5. 技术实现
|
||||
|
||||
使用技术:
|
||||
|
||||
1. Django ORM
|
||||
2. Django Storage
|
||||
3. JSONField
|
||||
4. Audit 服务
|
||||
|
||||
## 6. 异常处理
|
||||
|
||||
1. 文件不存在:只生成拦截报告。
|
||||
2. 下载链接生成失败:报告标记异常。
|
||||
3. 审计失败:记录系统警告。
|
||||
|
||||
## 7. 测试要点
|
||||
|
||||
1. 文件记录创建成功。
|
||||
2. 下载链接生成成功。
|
||||
3. 拦截模式不创建文件。
|
||||
4. 审计载荷完整。
|
||||
|
||||
74
docs/详细设计/skill/强一致规则加载Skill.md
Normal file
74
docs/详细设计/skill/强一致规则加载Skill.md
Normal file
@@ -0,0 +1,74 @@
|
||||
# 强一致规则加载Skill 设计
|
||||
|
||||
## 1. Skill 定位
|
||||
|
||||
`强一致规则加载Skill` 负责加载字段一致性核查规则,定义哪些字段必须完全一致、如何比对、冲突风险等级和是否参与回填拦截。
|
||||
|
||||
英文实现标识建议使用 `StrictConsistencyRuleLoadSkill`。
|
||||
|
||||
## 2. 输入
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class StrictConsistencyRuleLoadInput:
|
||||
field_rule_id: str
|
||||
target_field_keys: list[str] = field(default_factory=list)
|
||||
strict_mode: bool = True
|
||||
```
|
||||
|
||||
## 3. 输出
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class StrictConsistencyRuleLoadOutput:
|
||||
field_rule_id: str
|
||||
version: str
|
||||
rules: list[ConsistencyFieldRule]
|
||||
validation_warnings: list[dict]
|
||||
```
|
||||
|
||||
## 4. 核心方法
|
||||
|
||||
### 4.1 `run(input) -> StrictConsistencyRuleLoadOutput`
|
||||
|
||||
主入口方法。
|
||||
|
||||
### 4.2 `load_rule_file(field_rule_id) -> dict`
|
||||
|
||||
读取 YAML 规则。
|
||||
|
||||
### 4.3 `validate_rules(raw_rules) -> RuleValidationResult`
|
||||
|
||||
校验规则字段。
|
||||
|
||||
### 4.4 `select_target_rules(rules, target_field_keys) -> list[ConsistencyFieldRule]`
|
||||
|
||||
筛选本次目标字段规则。
|
||||
|
||||
## 5. 技术实现
|
||||
|
||||
使用技术:
|
||||
|
||||
1. YAML
|
||||
2. Pydantic
|
||||
3. Django cache
|
||||
|
||||
建议路径:
|
||||
|
||||
```text
|
||||
configs/registration/consistency/ivd_strict_consistency_v1.yaml
|
||||
```
|
||||
|
||||
## 6. 异常处理
|
||||
|
||||
1. 规则文件不存在:任务失败。
|
||||
2. 目标字段无规则:标记不检查。
|
||||
3. 风险等级缺失:默认中风险并记录警告。
|
||||
|
||||
## 7. 测试要点
|
||||
|
||||
1. 规则加载成功。
|
||||
2. 目标字段筛选正确。
|
||||
3. 缺少规则时报错。
|
||||
4. `strict_mode` 生效。
|
||||
|
||||
71
docs/详细设计/skill/整改建议生成Skill.md
Normal file
71
docs/详细设计/skill/整改建议生成Skill.md
Normal file
@@ -0,0 +1,71 @@
|
||||
# 整改建议生成Skill 设计
|
||||
|
||||
## 1. Skill 定位
|
||||
|
||||
`整改建议生成Skill` 负责根据风险项生成处理建议、整改优先级和责任角色。
|
||||
|
||||
英文实现标识建议使用 `RectificationSuggestionBuildSkill`。
|
||||
|
||||
## 2. 输入
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class RectificationSuggestionBuildInput:
|
||||
risk_items: list[RiskItem]
|
||||
suggestion_templates: dict
|
||||
owner_role_mapping: dict
|
||||
enable_llm_summary: bool = True
|
||||
```
|
||||
|
||||
## 3. 输出
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class RectificationSuggestionBuildOutput:
|
||||
suggestions: list[dict]
|
||||
owner_notifications: list[dict]
|
||||
summary_text: str
|
||||
```
|
||||
|
||||
## 4. 核心方法
|
||||
|
||||
### 4.1 `run(input) -> RectificationSuggestionBuildOutput`
|
||||
|
||||
主入口方法。
|
||||
|
||||
### 4.2 `build_suggestion(risk_item) -> dict`
|
||||
|
||||
生成单项建议。
|
||||
|
||||
### 4.3 `resolve_owner_role(risk_item) -> str`
|
||||
|
||||
映射责任角色。
|
||||
|
||||
### 4.4 `sort_by_priority(suggestions) -> list[dict]`
|
||||
|
||||
按风险等级和业务优先级排序。
|
||||
|
||||
### 4.5 `build_summary_text(suggestions) -> str`
|
||||
|
||||
生成摘要,可选使用 LLM Provider。
|
||||
|
||||
## 5. 技术实现
|
||||
|
||||
使用技术:
|
||||
|
||||
1. 建议模板
|
||||
2. 责任角色映射
|
||||
3. 可选 LLM Provider
|
||||
|
||||
## 6. 异常处理
|
||||
|
||||
1. 模板缺失:使用默认建议。
|
||||
2. 责任角色缺失:使用默认负责人。
|
||||
3. LLM 不可用:使用本地摘要。
|
||||
|
||||
## 7. 测试要点
|
||||
|
||||
1. 高风险建议优先。
|
||||
2. 责任角色映射正确。
|
||||
3. LLM 不可用时本地摘要可用。
|
||||
|
||||
126
docs/详细设计/skill/文档页数统计Skill.md
Normal file
126
docs/详细设计/skill/文档页数统计Skill.md
Normal file
@@ -0,0 +1,126 @@
|
||||
# 文档页数统计Skill 设计
|
||||
|
||||
## 1. Skill 定位
|
||||
|
||||
`文档页数统计Skill` 负责为注册申报资料文件生成页数统计结果。页数是题面明确要求的关键指标,因此本 Skill 必须把页数、统计方法和可信度分开记录。
|
||||
|
||||
本 Skill 不负责文档正文抽取,不负责 OCR,不负责合规判断。
|
||||
|
||||
英文实现标识建议使用 `DocumentPageCountSkill`,用于 Python 类名和 Tool Registry 注册处理器。
|
||||
|
||||
## 2. 输入
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class DocumentPageCountInput:
|
||||
document_id: int
|
||||
file_path: Path
|
||||
file_type: str
|
||||
options: dict = field(default_factory=dict)
|
||||
```
|
||||
|
||||
## 3. 输出
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class PageCountResult:
|
||||
document_id: int
|
||||
page_count: int | None
|
||||
method: str
|
||||
confidence: str
|
||||
status: str
|
||||
message: str = ""
|
||||
```
|
||||
|
||||
## 4. 页数统计策略
|
||||
|
||||
| 文件类型 | 策略 | 可信度 |
|
||||
|---|---|---|
|
||||
| `pdf` | 使用 `pypdf` 或 `PyMuPDF` 读取页数 | `exact` |
|
||||
| `docx` | 优先读取 Word 统计信息,必要时转换 PDF 后统计 | `exact` |
|
||||
| `doc` | 尝试转换后统计,失败则待复核 | `manual_review_required` |
|
||||
| `txt` | 页数不适用 | `not_applicable` |
|
||||
| `md` | 页数不适用 | `not_applicable` |
|
||||
|
||||
DOCX 是 V1 验收重点,不能用字数、段落数或估算分页代替精确页数。
|
||||
|
||||
## 5. 核心方法
|
||||
|
||||
### 5.1 `run(input) -> PageCountResult`
|
||||
|
||||
根据文件类型路由到具体统计方法。
|
||||
|
||||
### 5.2 `count_pdf_pages(path) -> PageCountResult`
|
||||
|
||||
推荐使用 `pypdf` 或 `PyMuPDF`。
|
||||
|
||||
失败处理:
|
||||
|
||||
1. 文件损坏:`failed`
|
||||
2. 加密 PDF:`manual_review_required`
|
||||
3. 无法读取:`failed`
|
||||
|
||||
### 5.3 `count_docx_pages(path) -> PageCountResult`
|
||||
|
||||
DOCX 精确页数建议采用两级策略:
|
||||
|
||||
1. 读取文档内部统计属性中的页数。
|
||||
2. 若统计属性不可用,使用 LibreOffice headless 转 PDF,再统计 PDF 页数。
|
||||
|
||||
如果两级策略均失败,输出 `manual_review_required`,并在页面突出显示。
|
||||
|
||||
### 5.4 `count_doc_pages(path) -> PageCountResult`
|
||||
|
||||
DOC 文件首版策略:
|
||||
|
||||
1. 尝试用兼容转换工具转 PDF。
|
||||
2. 转换成功后统计 PDF 页数。
|
||||
3. 转换失败则标记待人工复核。
|
||||
|
||||
### 5.5 `count_text_pages(path) -> PageCountResult`
|
||||
|
||||
TXT/MD 首版不做页数强制验收。
|
||||
|
||||
返回:
|
||||
|
||||
1. `page_count = None`
|
||||
2. `method = "not_applicable"`
|
||||
3. `confidence = "not_applicable"`
|
||||
|
||||
## 6. 技术实现
|
||||
|
||||
建议依赖:
|
||||
|
||||
1. `pypdf`
|
||||
2. `PyMuPDF`
|
||||
3. `python-docx`
|
||||
4. LibreOffice headless,可作为增强能力
|
||||
|
||||
如果 V1 Docker 环境暂不内置 LibreOffice,应在配置中显式标注 `DOCX_PAGE_COUNT_STRATEGY`,并保证演示样本能通过已实现策略得到精确页数。
|
||||
|
||||
## 7. 状态设计
|
||||
|
||||
| 状态 | 含义 |
|
||||
|---|---|
|
||||
| `success` | 页数统计成功 |
|
||||
| `not_applicable` | 文本类文件不适用 |
|
||||
| `manual_review_required` | 需要人工复核 |
|
||||
| `failed` | 统计失败 |
|
||||
|
||||
## 8. 落库字段
|
||||
|
||||
建议写入 `RegistrationDocument`:
|
||||
|
||||
1. `page_count`
|
||||
2. `page_count_method`
|
||||
3. `page_count_confidence`
|
||||
4. `page_count_status`
|
||||
5. `processing_message`
|
||||
|
||||
## 9. 测试要点
|
||||
|
||||
1. PDF 返回精确页数。
|
||||
2. DOCX 返回精确页数。
|
||||
3. DOC 无法统计时标记待人工复核。
|
||||
4. TXT/MD 返回不适用。
|
||||
5. 损坏文件返回失败状态。
|
||||
67
docs/详细设计/skill/模板字段映射加载Skill.md
Normal file
67
docs/详细设计/skill/模板字段映射加载Skill.md
Normal file
@@ -0,0 +1,67 @@
|
||||
# 模板字段映射加载Skill 设计
|
||||
|
||||
## 1. Skill 定位
|
||||
|
||||
`模板字段映射加载Skill` 负责加载 Word 模板占位符与统一字段池字段之间的映射关系。
|
||||
|
||||
英文实现标识建议使用 `TemplateFieldMappingLoadSkill`。
|
||||
|
||||
## 2. 输入
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class TemplateFieldMappingLoadInput:
|
||||
template_id: str
|
||||
template_file_path: Path
|
||||
```
|
||||
|
||||
## 3. 输出
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class TemplateFieldMappingLoadOutput:
|
||||
template_id: str
|
||||
mapping_version: str
|
||||
mappings: list[dict]
|
||||
missing_placeholders: list[str]
|
||||
extra_placeholders: list[str]
|
||||
```
|
||||
|
||||
## 4. 核心方法
|
||||
|
||||
### 4.1 `run(input) -> TemplateFieldMappingLoadOutput`
|
||||
|
||||
主入口方法。
|
||||
|
||||
### 4.2 `load_mapping(template_id) -> dict`
|
||||
|
||||
读取映射规则。
|
||||
|
||||
### 4.3 `scan_placeholders(template_file) -> list[str]`
|
||||
|
||||
扫描模板占位符。
|
||||
|
||||
### 4.4 `validate_mapping(mapping, placeholders) -> MappingValidationResult`
|
||||
|
||||
校验映射完整性。
|
||||
|
||||
## 5. 技术实现
|
||||
|
||||
使用技术:
|
||||
|
||||
1. YAML
|
||||
2. `python-docx`
|
||||
3. Pydantic
|
||||
|
||||
## 6. 异常处理
|
||||
|
||||
1. 映射不存在:任务失败。
|
||||
2. 必填占位符缺失:任务失败。
|
||||
3. 模板存在未映射占位符:标记警告。
|
||||
|
||||
## 7. 测试要点
|
||||
|
||||
1. 映射加载成功。
|
||||
2. 模板占位符能扫描。
|
||||
3. 缺失必填映射时报错。
|
||||
|
||||
65
docs/详细设计/skill/模板选择Skill.md
Normal file
65
docs/详细设计/skill/模板选择Skill.md
Normal file
@@ -0,0 +1,65 @@
|
||||
# 模板选择Skill 设计
|
||||
|
||||
## 1. Skill 定位
|
||||
|
||||
`模板选择Skill` 负责根据目标输出类型选择可用 Word 模板,并校验模板适用流程和版本状态。
|
||||
|
||||
英文实现标识建议使用 `WordTemplateSelectSkill`。
|
||||
|
||||
## 2. 输入
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class WordTemplateSelectInput:
|
||||
template_id: str
|
||||
target_output_type: str
|
||||
workflow_type: str = "registration"
|
||||
```
|
||||
|
||||
## 3. 输出
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class WordTemplateSelectOutput:
|
||||
template_id: str
|
||||
template_version: str
|
||||
template_file_path: Path
|
||||
template_type: str
|
||||
validation_warnings: list[dict]
|
||||
```
|
||||
|
||||
## 4. 核心方法
|
||||
|
||||
### 4.1 `run(input) -> WordTemplateSelectOutput`
|
||||
|
||||
主入口方法。
|
||||
|
||||
### 4.2 `load_template(template_id) -> WordTemplate`
|
||||
|
||||
读取模板记录。
|
||||
|
||||
### 4.3 `validate_template(template, workflow_type) -> TemplateValidationResult`
|
||||
|
||||
校验模板适用性。
|
||||
|
||||
## 5. 技术实现
|
||||
|
||||
使用技术:
|
||||
|
||||
1. Django ORM
|
||||
2. Django Storage
|
||||
3. 模板元数据 YAML
|
||||
|
||||
## 6. 异常处理
|
||||
|
||||
1. 模板不存在:任务失败。
|
||||
2. 模板文件丢失:任务失败。
|
||||
3. 模板未启用:任务失败。
|
||||
4. 流程不匹配:任务失败。
|
||||
|
||||
## 7. 测试要点
|
||||
|
||||
1. 能选择启用模板。
|
||||
2. 禁用模板不可用。
|
||||
3. 流程不匹配时报错。
|
||||
|
||||
136
docs/详细设计/skill/法规完整性检查Skill.md
Normal file
136
docs/详细设计/skill/法规完整性检查Skill.md
Normal file
@@ -0,0 +1,136 @@
|
||||
# 法规完整性检查Skill 设计
|
||||
|
||||
## 1. Skill 定位
|
||||
|
||||
`法规完整性检查Skill` 是第二步工作流的总编排 Skill,负责根据资料包目录汇总结果、法规流程类型和本地规则包,组织完整性检查链路并输出结构化完整性报告。
|
||||
|
||||
英文实现标识建议使用 `RegulationCompletenessCheckSkill`,用于 Python 类名和 Tool Registry 注册处理器。
|
||||
|
||||
本 Skill 不直接解析原始文件,不负责字段抽取,不负责综合风险报告。它消费第一步产生的文档事实。
|
||||
|
||||
## 2. 输入
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class RegulationCompletenessCheckInput:
|
||||
batch_id: int
|
||||
scenario_id: str = "registration_completeness_check"
|
||||
workflow_type: str = "registration"
|
||||
rule_package_id: str = "nmpa_ivd_registration_v1"
|
||||
chapter_scope: list[str] = field(default_factory=list)
|
||||
selected_document_ids: list[int] = field(default_factory=list)
|
||||
enable_rag_evidence: bool = True
|
||||
```
|
||||
|
||||
## 3. 输出
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class RegulationCompletenessCheckOutput:
|
||||
report_type: str
|
||||
batch_id: int
|
||||
rule_package_id: str
|
||||
rule_version: str
|
||||
summary: dict
|
||||
matched_items: list[dict]
|
||||
missing_items: list[dict]
|
||||
misplaced_items: list[dict]
|
||||
manual_review_items: list[dict]
|
||||
evidence_refs: list[dict]
|
||||
audit_id: int | None = None
|
||||
```
|
||||
|
||||
## 4. 依赖 Skill
|
||||
|
||||
1. `法规流程识别Skill`
|
||||
2. `法规规则包加载Skill`
|
||||
3. `资料要求匹配Skill`
|
||||
4. `缺失错放判定Skill`
|
||||
5. `法规证据检索Skill`
|
||||
6. `完整性报告生成Skill`
|
||||
|
||||
## 5. 核心方法
|
||||
|
||||
### 5.1 `run(input) -> RegulationCompletenessCheckOutput`
|
||||
|
||||
主入口方法。
|
||||
|
||||
执行顺序:
|
||||
|
||||
1. 读取资料包目录汇总。
|
||||
2. 调用 `法规流程识别Skill`。
|
||||
3. 调用 `法规规则包加载Skill`。
|
||||
4. 按章节范围展开法规要求项。
|
||||
5. 调用 `资料要求匹配Skill`。
|
||||
6. 调用 `缺失错放判定Skill`。
|
||||
7. 按需调用 `法规证据检索Skill`。
|
||||
8. 调用 `完整性报告生成Skill`。
|
||||
9. 写入审计记录。
|
||||
10. 返回完整性报告。
|
||||
|
||||
### 5.2 `load_execution_context(input) -> CompletenessExecutionContext`
|
||||
|
||||
加载执行上下文。
|
||||
|
||||
包含:
|
||||
|
||||
1. 批次信息。
|
||||
2. 目录汇总报告。
|
||||
3. 选中文档范围。
|
||||
4. 场景配置。
|
||||
5. 用户输入参数。
|
||||
|
||||
### 5.3 `select_document_facts(context) -> list[DocumentFact]`
|
||||
|
||||
从目录汇总中筛选参与完整性检查的文档。
|
||||
|
||||
如果 `selected_document_ids` 为空,则使用当前批次所有业务申报资料。
|
||||
|
||||
### 5.4 `build_requirement_scope(rule_package, chapter_scope) -> list[RequirementItem]`
|
||||
|
||||
根据章节点范围展开法规要求项。
|
||||
|
||||
V1 默认:
|
||||
|
||||
1. 有 `chapter_scope` 时按范围执行。
|
||||
2. 无 `chapter_scope` 时优先执行 `CH1`。
|
||||
3. 后续支持全六章。
|
||||
|
||||
## 6. 技术实现
|
||||
|
||||
使用技术:
|
||||
|
||||
1. Python dataclass 或 Pydantic
|
||||
2. Tool Registry
|
||||
3. Django 服务层调用
|
||||
4. JSONField 报告快照
|
||||
5. Audit 服务
|
||||
|
||||
建议注册名:
|
||||
|
||||
```python
|
||||
tool_registry.register(
|
||||
name="regulation_completeness_check",
|
||||
handler=RegulationCompletenessCheckSkill().run,
|
||||
)
|
||||
```
|
||||
|
||||
## 7. 异常处理
|
||||
|
||||
| 异常 | 处理 |
|
||||
|---|---|
|
||||
| 批次不存在 | 返回业务错误并写失败审计 |
|
||||
| 目录汇总不存在 | 提示先执行资料包导入与目录汇总 |
|
||||
| 规则包不存在 | 返回任务不可执行 |
|
||||
| 流程不支持 | 返回流程配置错误 |
|
||||
| RAG 不可用 | 保留规则判断,证据标记不可用 |
|
||||
| 所选文档为空 | 返回空范围报告 |
|
||||
|
||||
## 8. 测试要点
|
||||
|
||||
1. 能基于目录汇总生成完整性报告。
|
||||
2. 能调用依赖 Skill 并合并结果。
|
||||
3. 规则包缺失时写入失败审计。
|
||||
4. RAG 失败不阻断主链路。
|
||||
5. 输出 schema 稳定。
|
||||
|
||||
90
docs/详细设计/skill/法规流程识别Skill.md
Normal file
90
docs/详细设计/skill/法规流程识别Skill.md
Normal file
@@ -0,0 +1,90 @@
|
||||
# 法规流程识别Skill 设计
|
||||
|
||||
## 1. Skill 定位
|
||||
|
||||
`法规流程识别Skill` 负责确认当前完整性检查适用哪一类法规流程,避免把注册申报、变更备案、变更注册和延续注册混用。
|
||||
|
||||
英文实现标识建议使用 `RegulationWorkflowResolveSkill`。
|
||||
|
||||
V1 默认只执行 `registration`,但设计上保留扩展位。
|
||||
|
||||
## 2. 输入
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class RegulationWorkflowResolveInput:
|
||||
batch_workflow_type: str | None
|
||||
scenario_workflow_type: str | None
|
||||
user_workflow_type: str | None
|
||||
rule_package_supported_workflows: list[str]
|
||||
```
|
||||
|
||||
## 3. 输出
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class RegulationWorkflowResolveOutput:
|
||||
workflow_type: str
|
||||
confidence: str
|
||||
source: str
|
||||
supported: bool
|
||||
warnings: list[dict]
|
||||
```
|
||||
|
||||
## 4. 识别优先级
|
||||
|
||||
1. 用户显式选择。
|
||||
2. 场景配置。
|
||||
3. 资料包批次字段。
|
||||
4. 系统默认值 `registration`。
|
||||
|
||||
如果多个来源冲突,标记为 `manual_review_required`,并优先使用用户显式选择。
|
||||
|
||||
## 5. 核心方法
|
||||
|
||||
### 5.1 `run(input) -> RegulationWorkflowResolveOutput`
|
||||
|
||||
主入口方法。
|
||||
|
||||
### 5.2 `resolve_workflow_type(input) -> str`
|
||||
|
||||
按优先级解析流程类型。
|
||||
|
||||
### 5.3 `detect_workflow_conflict(input) -> list[dict]`
|
||||
|
||||
检测用户选择、场景配置和批次字段是否冲突。
|
||||
|
||||
### 5.4 `validate_supported(workflow_type, supported_workflows) -> bool`
|
||||
|
||||
校验规则包是否支持当前流程。
|
||||
|
||||
## 6. 技术实现
|
||||
|
||||
使用技术:
|
||||
|
||||
1. 场景 YAML
|
||||
2. 批次模型字段
|
||||
3. 规则包元数据
|
||||
4. Python 枚举
|
||||
|
||||
流程枚举:
|
||||
|
||||
1. `registration`
|
||||
2. `change_record`
|
||||
3. `change_registration`
|
||||
4. `renewal`
|
||||
|
||||
## 7. 异常处理
|
||||
|
||||
1. 流程为空:使用 `registration`。
|
||||
2. 流程冲突:标记警告。
|
||||
3. 流程不支持:阻断完整性检查。
|
||||
4. 用户输入非法:返回业务化错误。
|
||||
|
||||
## 8. 测试要点
|
||||
|
||||
1. 默认返回 `registration`。
|
||||
2. 用户显式选择优先。
|
||||
3. 场景和批次冲突时输出警告。
|
||||
4. 不支持流程返回 `supported = false`。
|
||||
|
||||
118
docs/详细设计/skill/法规规则包加载Skill.md
Normal file
118
docs/详细设计/skill/法规规则包加载Skill.md
Normal file
@@ -0,0 +1,118 @@
|
||||
# 法规规则包加载Skill 设计
|
||||
|
||||
## 1. Skill 定位
|
||||
|
||||
`法规规则包加载Skill` 负责加载、校验和展开本地结构化法规规则包,是完整性检查的规则来源入口。
|
||||
|
||||
英文实现标识建议使用 `RegulationRulePackageLoadSkill`。
|
||||
|
||||
本 Skill 不读取用户资料,不做匹配判断,只处理法规规则本身。
|
||||
|
||||
## 2. 输入
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class RegulationRulePackageLoadInput:
|
||||
rule_package_id: str
|
||||
workflow_type: str
|
||||
chapter_scope: list[str] = field(default_factory=list)
|
||||
```
|
||||
|
||||
## 3. 输出
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class RegulationRulePackageLoadOutput:
|
||||
rule_package_id: str
|
||||
version: str
|
||||
workflow_type: str
|
||||
source_documents: list[dict]
|
||||
requirements: list[dict]
|
||||
risk_rules: dict
|
||||
validation_warnings: list[dict]
|
||||
```
|
||||
|
||||
## 4. 规则包来源
|
||||
|
||||
V1 默认来源:
|
||||
|
||||
```text
|
||||
docs/原始材料/关于公布体外诊断试剂注册申报资料要求和批准证明文件格式的公告/
|
||||
```
|
||||
|
||||
结构化规则建议维护在:
|
||||
|
||||
```text
|
||||
configs/registration/rules/
|
||||
nmpa_ivd_registration_v1.yaml
|
||||
chapter_catalog.yaml
|
||||
risk_mapping.yaml
|
||||
```
|
||||
|
||||
## 5. 核心方法
|
||||
|
||||
### 5.1 `run(input) -> RegulationRulePackageLoadOutput`
|
||||
|
||||
主入口方法。
|
||||
|
||||
执行顺序:
|
||||
|
||||
1. 根据 `rule_package_id` 定位规则文件。
|
||||
2. 读取 YAML。
|
||||
3. 校验规则包元数据。
|
||||
4. 校验规则包是否支持当前 `workflow_type`。
|
||||
5. 展开章节范围。
|
||||
6. 返回要求项和风险规则。
|
||||
|
||||
### 5.2 `load_yaml_rule_file(path) -> dict`
|
||||
|
||||
读取 YAML 文件。
|
||||
|
||||
### 5.3 `validate_rule_package(raw_rules) -> RulePackageValidationResult`
|
||||
|
||||
校验:
|
||||
|
||||
1. 是否有规则包 ID。
|
||||
2. 是否有版本。
|
||||
3. 是否有适用流程。
|
||||
4. 是否有章节。
|
||||
5. 每个必交项是否有风险等级。
|
||||
6. 每个要求项是否有稳定 `requirement_id`。
|
||||
|
||||
### 5.4 `expand_requirements(rule_package, chapter_scope) -> list[RequirementItem]`
|
||||
|
||||
展开要求项。
|
||||
|
||||
如果 `chapter_scope = ["CH1"]`,只返回第 1 章要求项。
|
||||
|
||||
### 5.5 `load_risk_rules(rule_package) -> dict`
|
||||
|
||||
读取缺失、错放、待复核对应的风险映射规则。
|
||||
|
||||
## 6. 技术实现
|
||||
|
||||
使用技术:
|
||||
|
||||
1. `PyYAML`
|
||||
2. Pydantic schema
|
||||
3. Django cache
|
||||
4. 文件修改时间检测
|
||||
|
||||
## 7. 异常处理
|
||||
|
||||
| 异常 | 处理 |
|
||||
|---|---|
|
||||
| 规则文件不存在 | 返回 `rule_package_not_found` |
|
||||
| YAML 格式错误 | 返回 `rule_package_invalid` |
|
||||
| 流程不匹配 | 返回 `workflow_not_supported` |
|
||||
| 缺少风险配置 | 规则包校验失败 |
|
||||
| 章节范围为空 | 使用默认范围 |
|
||||
|
||||
## 8. 测试要点
|
||||
|
||||
1. 成功加载规则包。
|
||||
2. 规则包版本正确。
|
||||
3. `CH1` 范围展开正确。
|
||||
4. 不支持流程被拒绝。
|
||||
5. 缺少必填字段时报校验错误。
|
||||
|
||||
100
docs/详细设计/skill/法规证据检索Skill.md
Normal file
100
docs/详细设计/skill/法规证据检索Skill.md
Normal file
@@ -0,0 +1,100 @@
|
||||
# 法规证据检索Skill 设计
|
||||
|
||||
## 1. Skill 定位
|
||||
|
||||
`法规证据检索Skill` 负责为完整性检查结果补充法规原文证据,用于解释、页面展示和审计留痕。
|
||||
|
||||
英文实现标识建议使用 `RegulationEvidenceRetrieveSkill`。
|
||||
|
||||
本 Skill 不改变完整性判定结论。规则链路已经判定的缺失、错放和风险等级不能被 RAG 检索结果反向覆盖。
|
||||
|
||||
## 2. 输入
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class RegulationEvidenceRetrieveInput:
|
||||
requirement_results: list[CompletenessItemResult]
|
||||
rule_package_id: str
|
||||
workflow_type: str
|
||||
max_results_per_item: int = 3
|
||||
```
|
||||
|
||||
## 3. 输出
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class RegulationEvidenceRetrieveOutput:
|
||||
evidence_refs: list[EvidenceRef]
|
||||
unavailable_items: list[dict]
|
||||
warnings: list[dict]
|
||||
```
|
||||
|
||||
`EvidenceRef` 字段:
|
||||
|
||||
1. `requirement_id`
|
||||
2. `source_document`
|
||||
3. `source_type`
|
||||
4. `chapter_code`
|
||||
5. `section_title`
|
||||
6. `snippet`
|
||||
7. `page_no`
|
||||
8. `retrieval_score`
|
||||
9. `metadata`
|
||||
|
||||
## 4. 检索范围
|
||||
|
||||
只检索法规资料,不检索业务申报资料。
|
||||
|
||||
metadata 过滤:
|
||||
|
||||
1. `source_role = regulation`
|
||||
2. `workflow_type = registration`
|
||||
3. `rule_package_id = nmpa_ivd_registration_v1`
|
||||
4. `requirement_id` 或 `chapter_code`
|
||||
|
||||
## 5. 核心方法
|
||||
|
||||
### 5.1 `run(input) -> RegulationEvidenceRetrieveOutput`
|
||||
|
||||
主入口方法。
|
||||
|
||||
### 5.2 `build_evidence_query(item_result) -> str`
|
||||
|
||||
根据要求项名称、章节点和规则配置生成检索 query。
|
||||
|
||||
### 5.3 `retrieve_from_vector_store(query, metadata_filter) -> list[EvidenceRef]`
|
||||
|
||||
优先使用 Chroma。
|
||||
|
||||
### 5.4 `retrieve_from_fallback_index(query, metadata_filter) -> list[EvidenceRef]`
|
||||
|
||||
当 Chroma 不可用时,使用本地切片或关键词 fallback。
|
||||
|
||||
### 5.5 `normalize_evidence_results(results) -> list[EvidenceRef]`
|
||||
|
||||
统一证据格式。
|
||||
|
||||
## 6. 技术实现
|
||||
|
||||
使用技术:
|
||||
|
||||
1. Chroma
|
||||
2. 本地 fallback 检索
|
||||
3. 文本切片 metadata
|
||||
4. Python 关键词匹配
|
||||
|
||||
## 7. 异常处理
|
||||
|
||||
1. 向量库不可用:降级 fallback。
|
||||
2. fallback 也不可用:返回证据不可用警告。
|
||||
3. 找不到证据:不阻断完整性报告。
|
||||
4. 命中业务资料:过滤掉,避免把申报资料当法规依据。
|
||||
|
||||
## 8. 测试要点
|
||||
|
||||
1. 能根据要求项生成查询。
|
||||
2. Chroma 可用时返回证据。
|
||||
3. Chroma 不可用时 fallback 生效。
|
||||
4. 证据检索失败不改变缺失结论。
|
||||
5. 非法规资料被过滤。
|
||||
|
||||
73
docs/详细设计/skill/混档风险识别Skill.md
Normal file
73
docs/详细设计/skill/混档风险识别Skill.md
Normal file
@@ -0,0 +1,73 @@
|
||||
# 混档风险识别Skill 设计
|
||||
|
||||
## 1. Skill 定位
|
||||
|
||||
`混档风险识别Skill` 负责基于一致性核查结果识别疑似跨产品、跨批次或错误资料混入风险。
|
||||
|
||||
英文实现标识建议使用 `MixedPackageRiskDetectSkill`。
|
||||
|
||||
## 2. 输入
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class MixedPackageRiskDetectInput:
|
||||
compare_results: list[FieldCompareResult]
|
||||
scope_documents: list[DocumentFact]
|
||||
```
|
||||
|
||||
## 3. 输出
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class MixedPackageRiskDetectOutput:
|
||||
mixed_package_warnings: list[dict]
|
||||
highest_risk_level: str
|
||||
```
|
||||
|
||||
## 4. 识别规则
|
||||
|
||||
1. 产品名称冲突:高风险。
|
||||
2. 检测靶标冲突:高风险。
|
||||
3. 产品名称和检测靶标指向不同产品:高风险。
|
||||
4. 申请人名称冲突:高风险或待复核。
|
||||
5. 相同文档角色出现多份不同产品文件:中风险。
|
||||
|
||||
## 5. 核心方法
|
||||
|
||||
### 5.1 `run(input) -> MixedPackageRiskDetectOutput`
|
||||
|
||||
主入口方法。
|
||||
|
||||
### 5.2 `detect_product_name_conflict(results) -> dict | None`
|
||||
|
||||
识别产品名称冲突。
|
||||
|
||||
### 5.3 `detect_target_conflict(results) -> dict | None`
|
||||
|
||||
识别检测靶标冲突。
|
||||
|
||||
### 5.4 `classify_warning_risk(warning) -> str`
|
||||
|
||||
映射风险等级。
|
||||
|
||||
## 6. 技术实现
|
||||
|
||||
使用技术:
|
||||
|
||||
1. 字段比对结果
|
||||
2. 文档角色规则
|
||||
3. 风险映射 YAML
|
||||
|
||||
## 7. 异常处理
|
||||
|
||||
1. 缺少产品名称字段:不输出混档结论,标记待复核。
|
||||
2. 只有单来源:不输出混档结论。
|
||||
3. 字段已冲突但来源不明:标记待人工确认。
|
||||
|
||||
## 8. 测试要点
|
||||
|
||||
1. 产品名称冲突输出高风险。
|
||||
2. 检测靶标冲突输出高风险。
|
||||
3. 单来源不输出混档风险。
|
||||
4. 缺少核心字段时输出待复核。
|
||||
|
||||
185
docs/详细设计/skill/目录汇总Skill.md
Normal file
185
docs/详细设计/skill/目录汇总Skill.md
Normal file
@@ -0,0 +1,185 @@
|
||||
# 目录汇总Skill 设计
|
||||
|
||||
## 1. Skill 定位
|
||||
|
||||
`目录汇总Skill` 负责把一个资料包批次中的文档主数据聚合为目录汇总报告。它是第一步“资料包导入与目录汇总”的最终输出 Skill。
|
||||
|
||||
本 Skill 不重新扫描文件,不重新统计页数,只消费已经落库或已处理的文档事实。
|
||||
|
||||
英文实现标识建议使用 `DirectorySummarySkill`,用于 Python 类名和 Tool Registry 注册处理器。
|
||||
|
||||
## 2. 输入
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class DirectorySummaryInput:
|
||||
batch_id: int
|
||||
include_unsupported: bool = true
|
||||
include_warnings: bool = true
|
||||
```
|
||||
|
||||
## 3. 输出
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class RegistrationOverviewReport:
|
||||
batch_id: int
|
||||
batch_no: str
|
||||
workflow_type: str
|
||||
source_role: str
|
||||
file_count: int
|
||||
supported_file_count: int
|
||||
unsupported_file_count: int
|
||||
failed_file_count: int
|
||||
manual_review_count: int
|
||||
total_page_count: int
|
||||
page_count_status: str
|
||||
chapter_summary: list[dict]
|
||||
documents: list[dict]
|
||||
warnings: list[dict]
|
||||
```
|
||||
|
||||
## 4. 核心方法
|
||||
|
||||
### 4.1 `run(input) -> RegistrationOverviewReport`
|
||||
|
||||
主入口方法。
|
||||
|
||||
执行顺序:
|
||||
|
||||
1. 读取批次信息。
|
||||
2. 读取该批次所有文档记录。
|
||||
3. 计算总文件数。
|
||||
4. 计算支持文件、不支持文件、失败文件和待复核文件数量。
|
||||
5. 汇总页数。
|
||||
6. 按章节点聚合。
|
||||
7. 生成文档明细。
|
||||
8. 生成导入警告。
|
||||
9. 返回结构化报告。
|
||||
|
||||
### 4.2 `summarize_counts(documents) -> dict`
|
||||
|
||||
计算:
|
||||
|
||||
1. `file_count`
|
||||
2. `supported_file_count`
|
||||
3. `unsupported_file_count`
|
||||
4. `failed_file_count`
|
||||
5. `manual_review_count`
|
||||
|
||||
### 4.3 `summarize_pages(documents) -> dict`
|
||||
|
||||
计算:
|
||||
|
||||
1. `total_page_count`
|
||||
2. `exact_page_count`
|
||||
3. `manual_review_page_count`
|
||||
4. `page_count_status`
|
||||
|
||||
`page_count_status` 规则:
|
||||
|
||||
1. 全部精确:`exact`
|
||||
2. 部分待复核:`partial_review_required`
|
||||
3. 全部无法统计:`manual_review_required`
|
||||
|
||||
### 4.4 `summarize_chapters(documents) -> list[dict]`
|
||||
|
||||
按 `chapter_code` 聚合:
|
||||
|
||||
1. 文件数。
|
||||
2. 页数。
|
||||
3. 待复核数。
|
||||
4. 主要资料角色。
|
||||
|
||||
无章节点的文件归入 `unclassified`。
|
||||
|
||||
### 4.5 `build_document_rows(documents) -> list[dict]`
|
||||
|
||||
生成页面明细。
|
||||
|
||||
字段:
|
||||
|
||||
1. `document_id`
|
||||
2. `relative_path`
|
||||
3. `original_filename`
|
||||
4. `file_type`
|
||||
5. `page_count`
|
||||
6. `page_count_confidence`
|
||||
7. `chapter_code`
|
||||
8. `chapter_name`
|
||||
9. `document_role`
|
||||
10. `processing_status`
|
||||
11. `needs_manual_review`
|
||||
|
||||
### 4.6 `build_warnings(documents) -> list[dict]`
|
||||
|
||||
生成业务化提示。
|
||||
|
||||
提示类型:
|
||||
|
||||
1. `unsupported_file`
|
||||
2. `page_count_review_required`
|
||||
3. `chapter_unclassified`
|
||||
4. `file_type_mismatch`
|
||||
5. `duplicate_file`
|
||||
6. `archive_extract_warning`
|
||||
|
||||
## 5. 技术实现
|
||||
|
||||
使用技术:
|
||||
|
||||
1. Django ORM 聚合查询
|
||||
2. Python dataclass 或 Pydantic
|
||||
3. JSONField 存储报告快照
|
||||
|
||||
建议注册名:
|
||||
|
||||
```python
|
||||
tool_registry.register(
|
||||
name="build_directory_summary",
|
||||
handler=DirectorySummarySkill().run,
|
||||
)
|
||||
```
|
||||
|
||||
## 6. 报告存储
|
||||
|
||||
建议将目录汇总报告快照写入批次模型或独立模型:
|
||||
|
||||
```python
|
||||
class SubmissionBatchSummary(models.Model):
|
||||
batch = models.OneToOneField(SubmissionBatch, on_delete=models.CASCADE)
|
||||
report_type = models.CharField(max_length=64, default="registration_overview_report")
|
||||
report_json = models.JSONField(default=dict)
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
updated_at = models.DateTimeField(auto_now=True)
|
||||
```
|
||||
|
||||
## 7. 与页面接口
|
||||
|
||||
Documents 页面直接消费 `RegistrationOverviewReport`:
|
||||
|
||||
1. 顶部显示统计卡片。
|
||||
2. 中部显示按章节点聚合表。
|
||||
3. 底部显示文件明细。
|
||||
4. 侧边显示待人工复核提示。
|
||||
|
||||
## 8. 与后续 Agent Core 接口
|
||||
|
||||
法规完整性核查从本报告读取:
|
||||
|
||||
1. `batch_id`
|
||||
2. `documents`
|
||||
3. `chapter_summary`
|
||||
4. `manual_review_count`
|
||||
5. `warnings`
|
||||
|
||||
如果 `manual_review_count > 0`,后续完整性核查仍可执行,但最终报告应标记“存在资料处理不确定性”。
|
||||
|
||||
## 9. 测试要点
|
||||
|
||||
1. 空批次返回合理空报告。
|
||||
2. 多章节点文件能正确聚合。
|
||||
3. 页数合计只统计有明确页数的文档。
|
||||
4. 待复核文件数量正确。
|
||||
5. 不支持文件可选展示。
|
||||
6. 输出 schema 字段稳定。
|
||||
158
docs/详细设计/skill/章节点识别Skill.md
Normal file
158
docs/详细设计/skill/章节点识别Skill.md
Normal file
@@ -0,0 +1,158 @@
|
||||
# 章节点识别Skill 设计
|
||||
|
||||
## 1. Skill 定位
|
||||
|
||||
`章节点识别Skill` 负责对已登记文档进行章节点和资料角色的初步识别,为目录汇总和后续法规完整性核查提供结构化字段。
|
||||
|
||||
本 Skill 使用规则优先,不依赖 LLM。后续可以在人工复核或复杂标题解析中引入模型辅助,但不作为 V1 必需能力。
|
||||
|
||||
英文实现标识建议使用 `ChapterClassificationSkill`,用于 Python 类名和 Tool Registry 注册处理器。
|
||||
|
||||
## 2. 输入
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class ChapterClassificationInput:
|
||||
document_id: int
|
||||
original_filename: str
|
||||
relative_path: str
|
||||
file_type: str
|
||||
title_text: str | None = None
|
||||
manual_hint: dict = field(default_factory=dict)
|
||||
```
|
||||
|
||||
## 3. 输出
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class ChapterClassificationResult:
|
||||
document_id: int
|
||||
chapter_code: str | None
|
||||
chapter_name: str | None
|
||||
document_role: str | None
|
||||
declared_document_name: str | None
|
||||
confidence: str
|
||||
status: str
|
||||
evidence: list[dict]
|
||||
```
|
||||
|
||||
## 4. 识别规则
|
||||
|
||||
### 4.1 章节点编码识别
|
||||
|
||||
从文件名和相对路径中识别:
|
||||
|
||||
1. `CH1.2`
|
||||
2. `CH1.4`
|
||||
3. `CH1.5`
|
||||
4. `CH1.9`
|
||||
5. `CH1.11.1`
|
||||
6. `CH1.11.5`
|
||||
7. `CH1.11.6`
|
||||
|
||||
正则示例:
|
||||
|
||||
```python
|
||||
r"CH\s*(\d+(?:\.\d+)*)"
|
||||
```
|
||||
|
||||
### 4.2 章节名称识别
|
||||
|
||||
从相对路径中识别:
|
||||
|
||||
1. `第1章 监管信息`
|
||||
2. `第2章 综述资料`
|
||||
3. `第3章 非临床资料`
|
||||
4. `第4章 临床评价资料`
|
||||
5. `第5章 产品说明书和标签样稿`
|
||||
6. `第6章 质量管理体系文件`
|
||||
|
||||
### 4.3 文档角色识别
|
||||
|
||||
| 关键词 | document_role |
|
||||
|---|---|
|
||||
| `监管信息目录` | `regulatory_information_catalog` |
|
||||
| `申请表` | `application_form` |
|
||||
| `产品列表` | `product_list` |
|
||||
| `符合标准的清单` | `standard_compliance_list` |
|
||||
| `真实性声明` | `authenticity_statement` |
|
||||
| `符合性声明` | `conformity_statement` |
|
||||
| `沟通的说明` | `pre_submission_communication` |
|
||||
| `说明书` | `product_instruction` |
|
||||
|
||||
## 5. 核心方法
|
||||
|
||||
### 5.1 `run(input) -> ChapterClassificationResult`
|
||||
|
||||
主入口方法。
|
||||
|
||||
执行顺序:
|
||||
|
||||
1. 从相对路径识别章名称。
|
||||
2. 从文件名识别章节点编码。
|
||||
3. 从文件名识别文档角色。
|
||||
4. 如有标题文本,则用标题补充识别。
|
||||
5. 计算置信度。
|
||||
6. 返回识别结果。
|
||||
|
||||
### 5.2 `extract_chapter_code(text) -> str | None`
|
||||
|
||||
从路径或文件名提取 `CHx.x`。
|
||||
|
||||
### 5.3 `extract_chapter_name(relative_path) -> str | None`
|
||||
|
||||
从目录层级识别章节名称。
|
||||
|
||||
### 5.4 `detect_document_role(text) -> str | None`
|
||||
|
||||
基于关键词和规则表识别文档角色。
|
||||
|
||||
### 5.5 `calculate_confidence(matches) -> str`
|
||||
|
||||
置信度规则:
|
||||
|
||||
1. 路径、文件名和标题一致:`high`
|
||||
2. 文件名命中但路径缺失:`medium`
|
||||
3. 只有关键词命中:`low`
|
||||
4. 无法识别:`manual_review_required`
|
||||
|
||||
## 6. 技术实现
|
||||
|
||||
使用技术:
|
||||
|
||||
1. `re`
|
||||
2. YAML 规则表
|
||||
3. 可选 `python-docx` 首页标题抽取
|
||||
4. Django 管理后台人工修正
|
||||
|
||||
建议规则文件:
|
||||
|
||||
```text
|
||||
configs/registration/chapter_classification.yaml
|
||||
```
|
||||
|
||||
## 7. 落库字段
|
||||
|
||||
建议写入 `RegistrationDocument`:
|
||||
|
||||
1. `chapter_code`
|
||||
2. `chapter_name`
|
||||
3. `document_role`
|
||||
4. `declared_document_name`
|
||||
5. `classification_confidence`
|
||||
6. `classification_status`
|
||||
7. `needs_manual_review`
|
||||
|
||||
## 8. 异常处理
|
||||
|
||||
1. 文件名无章节点:尝试路径识别。
|
||||
2. 路径与文件名冲突:标记待人工复核。
|
||||
3. 识别为法规资料但批次为业务资料:标记潜在混入风险。
|
||||
4. 同一文件命中多个角色:保留最高优先级角色,记录警告。
|
||||
|
||||
## 9. 测试要点
|
||||
|
||||
1. `CH1.4 申请表.docx` 识别为 `CH1.4` 和 `application_form`。
|
||||
2. `第1章 监管信息/CH1.2 监管信息目录.docx` 识别章节和目录角色。
|
||||
3. 无章节点文件标记待人工复核。
|
||||
4. 路径与文件名冲突时输出警告。
|
||||
83
docs/详细设计/skill/统一字段池写入Skill.md
Normal file
83
docs/详细设计/skill/统一字段池写入Skill.md
Normal file
@@ -0,0 +1,83 @@
|
||||
# 统一字段池写入Skill 设计
|
||||
|
||||
## 1. Skill 定位
|
||||
|
||||
`统一字段池写入Skill` 负责将标准化后的字段候选写入统一字段池,并为每个字段选择推荐值、保留候选值和来源证据。
|
||||
|
||||
英文实现标识建议使用 `UnifiedFieldPoolWriteSkill`。
|
||||
|
||||
## 2. 输入
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class UnifiedFieldPoolWriteInput:
|
||||
batch_id: int
|
||||
normalized_candidates: list[NormalizedFieldCandidate]
|
||||
field_definitions: list[FieldDefinition]
|
||||
source_priority: dict
|
||||
```
|
||||
|
||||
## 3. 输出
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class UnifiedFieldPoolWriteOutput:
|
||||
field_pool_items: list[FieldPoolItem]
|
||||
candidate_records: list[dict]
|
||||
manual_review_fields: list[dict]
|
||||
write_status: str
|
||||
```
|
||||
|
||||
## 4. 推荐值选择规则
|
||||
|
||||
1. 优先选择高置信候选。
|
||||
2. 同置信度时按来源优先级选择。
|
||||
3. 来源优先级一致时选择规则抽取结果。
|
||||
4. 多候选值明显不同则标记 `conflict_candidate`。
|
||||
5. 待人工复核字段不作为无条件回填值。
|
||||
|
||||
## 5. 核心方法
|
||||
|
||||
### 5.1 `run(input) -> UnifiedFieldPoolWriteOutput`
|
||||
|
||||
主入口方法。
|
||||
|
||||
### 5.2 `group_candidates_by_field(candidates) -> dict`
|
||||
|
||||
按 `field_key` 分组。
|
||||
|
||||
### 5.3 `select_recommended_value(field_key, candidates, priority) -> FieldPoolItem`
|
||||
|
||||
选择推荐值。
|
||||
|
||||
### 5.4 `persist_field_pool_item(item) -> RegistrationFieldPoolItem`
|
||||
|
||||
写入字段池。
|
||||
|
||||
### 5.5 `persist_field_candidates(item, candidates) -> None`
|
||||
|
||||
保留所有候选值。
|
||||
|
||||
## 6. 技术实现
|
||||
|
||||
使用技术:
|
||||
|
||||
1. Django ORM
|
||||
2. JSONField
|
||||
3. 批量写入
|
||||
4. 唯一约束:`batch + field_key`
|
||||
|
||||
## 7. 异常处理
|
||||
|
||||
1. 没有候选值:写入空字段并标记待复核。
|
||||
2. 数据库写入失败:任务失败并写审计。
|
||||
3. 字段重复写入:更新字段池版本或覆盖当前批次结果。
|
||||
4. 候选冲突:保留候选并标记冲突候选。
|
||||
|
||||
## 8. 测试要点
|
||||
|
||||
1. 高置信候选被选为推荐值。
|
||||
2. 来源优先级生效。
|
||||
3. 冲突候选被保留。
|
||||
4. 可回填字段标记正确。
|
||||
|
||||
118
docs/详细设计/skill/缺失错放判定Skill.md
Normal file
118
docs/详细设计/skill/缺失错放判定Skill.md
Normal file
@@ -0,0 +1,118 @@
|
||||
# 缺失错放判定Skill 设计
|
||||
|
||||
## 1. Skill 定位
|
||||
|
||||
`缺失错放判定Skill` 负责根据法规要求项和资料匹配结果,判定每个要求项的完整性状态,并映射完整性维度的风险等级和基础处理建议。
|
||||
|
||||
英文实现标识建议使用 `MissingMisplacementEvaluateSkill`。
|
||||
|
||||
本 Skill 是完整性检查中真正产生“缺失、错放、待复核”结论的规则执行单元。
|
||||
|
||||
## 2. 输入
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class MissingMisplacementEvaluateInput:
|
||||
requirements: list[RequirementItem]
|
||||
matches: list[RequirementDocumentMatch]
|
||||
document_uncertainties: list[DocumentUncertainty]
|
||||
risk_rules: dict
|
||||
```
|
||||
|
||||
## 3. 输出
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class MissingMisplacementEvaluateOutput:
|
||||
item_results: list[CompletenessItemResult]
|
||||
missing_items: list[dict]
|
||||
misplaced_items: list[dict]
|
||||
suspected_items: list[dict]
|
||||
manual_review_items: list[dict]
|
||||
pass_status: str
|
||||
highest_risk_level: str
|
||||
```
|
||||
|
||||
## 4. 判定规则
|
||||
|
||||
| 条件 | 状态 |
|
||||
|---|---|
|
||||
| 必交要求项有高置信匹配 | `provided` |
|
||||
| 必交要求项没有匹配 | `missing` |
|
||||
| 有低置信匹配 | `suspected` |
|
||||
| 文档角色匹配但章节点不匹配 | `misplaced` |
|
||||
| 命中文档待人工复核 | `manual_review_required` |
|
||||
| 当前流程不适用 | `not_applicable` |
|
||||
|
||||
## 5. 风险映射
|
||||
|
||||
风险来源:
|
||||
|
||||
1. 规则项自身的 `risk_level_if_missing`。
|
||||
2. 错放风险映射。
|
||||
3. 待复核不确定性。
|
||||
4. 资料处理失败状态。
|
||||
|
||||
准入结论:
|
||||
|
||||
1. 存在高风险缺失:`failed`
|
||||
2. 存在中风险缺失或错放:`review_required`
|
||||
3. 只有低风险或待复核:`conditional_pass`
|
||||
4. 全部已提供:`passed`
|
||||
|
||||
## 6. 核心方法
|
||||
|
||||
### 6.1 `run(input) -> MissingMisplacementEvaluateOutput`
|
||||
|
||||
主入口方法。
|
||||
|
||||
### 6.2 `evaluate_requirement_status(requirement, matches) -> CompletenessItemResult`
|
||||
|
||||
对单个要求项判定状态。
|
||||
|
||||
### 6.3 `detect_misplacement(requirement, matches) -> bool`
|
||||
|
||||
判断文档是否存在但归错章节点。
|
||||
|
||||
### 6.4 `detect_suspected_provided(requirement, matches) -> bool`
|
||||
|
||||
判断是否疑似提供。
|
||||
|
||||
### 6.5 `map_risk_level(requirement, status, risk_rules) -> str`
|
||||
|
||||
映射风险等级。
|
||||
|
||||
### 6.6 `build_suggestion(requirement, status, risk_level) -> str`
|
||||
|
||||
生成基础处理建议。
|
||||
|
||||
建议示例:
|
||||
|
||||
1. `补充 CH1.4 申请表,并由注册申报负责人复核。`
|
||||
2. `核对该文件是否应归入 CH1.5 产品列表。`
|
||||
3. `当前资料疑似提供但命名不规范,建议人工确认后修正章节点。`
|
||||
|
||||
## 7. 技术实现
|
||||
|
||||
使用技术:
|
||||
|
||||
1. Python 规则引擎
|
||||
2. YAML 风险映射
|
||||
3. Pydantic/dataclass
|
||||
4. 本地建议模板
|
||||
|
||||
## 8. 异常处理
|
||||
|
||||
1. 要求项缺少风险配置:默认中风险,并记录规则警告。
|
||||
2. 匹配结果为空:按必交状态判缺失或不适用。
|
||||
3. 匹配冲突:标记待人工复核。
|
||||
4. 文档处理失败:不作为已提供,进入待复核。
|
||||
|
||||
## 9. 测试要点
|
||||
|
||||
1. 必交项无匹配时判缺失。
|
||||
2. 高风险缺失导致 `failed`。
|
||||
3. 低置信匹配进入 `suspected`。
|
||||
4. 章节点不一致进入 `misplaced`。
|
||||
5. 待复核文档不会直接判为通过。
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user