diff --git a/docs/详细设计/2.法规完整性检查.md b/docs/详细设计/2.法规完整性检查.md new file mode 100644 index 0000000..d34bbe8 --- /dev/null +++ b/docs/详细设计/2.法规完整性检查.md @@ -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. 在线法规更新能力。 + diff --git a/docs/详细设计/skill/完整性报告生成Skill.md b/docs/详细设计/skill/完整性报告生成Skill.md new file mode 100644 index 0000000..41dd15d --- /dev/null +++ b/docs/详细设计/skill/完整性报告生成Skill.md @@ -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. 飞书摘要载荷不包含敏感信息。 + diff --git a/docs/详细设计/skill/法规完整性检查Skill.md b/docs/详细设计/skill/法规完整性检查Skill.md new file mode 100644 index 0000000..8cbad67 --- /dev/null +++ b/docs/详细设计/skill/法规完整性检查Skill.md @@ -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 稳定。 + diff --git a/docs/详细设计/skill/法规流程识别Skill.md b/docs/详细设计/skill/法规流程识别Skill.md new file mode 100644 index 0000000..121f32a --- /dev/null +++ b/docs/详细设计/skill/法规流程识别Skill.md @@ -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`。 + diff --git a/docs/详细设计/skill/法规规则包加载Skill.md b/docs/详细设计/skill/法规规则包加载Skill.md new file mode 100644 index 0000000..790b917 --- /dev/null +++ b/docs/详细设计/skill/法规规则包加载Skill.md @@ -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. 缺少必填字段时报校验错误。 + diff --git a/docs/详细设计/skill/法规证据检索Skill.md b/docs/详细设计/skill/法规证据检索Skill.md new file mode 100644 index 0000000..17e6417 --- /dev/null +++ b/docs/详细设计/skill/法规证据检索Skill.md @@ -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. 非法规资料被过滤。 + diff --git a/docs/详细设计/skill/缺失错放判定Skill.md b/docs/详细设计/skill/缺失错放判定Skill.md new file mode 100644 index 0000000..bdbdc57 --- /dev/null +++ b/docs/详细设计/skill/缺失错放判定Skill.md @@ -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. 待复核文档不会直接判为通过。 + diff --git a/docs/详细设计/skill/资料要求匹配Skill.md b/docs/详细设计/skill/资料要求匹配Skill.md new file mode 100644 index 0000000..5fc830b --- /dev/null +++ b/docs/详细设计/skill/资料要求匹配Skill.md @@ -0,0 +1,112 @@ +# 资料要求匹配Skill 设计 + +## 1. Skill 定位 + +`资料要求匹配Skill` 负责把当前资料包中的文档事实与法规要求项进行匹配,生成每个要求项的候选命中文档和匹配证据。 + +英文实现标识建议使用 `RequirementDocumentMatchSkill`。 + +本 Skill 只判断“是否可能命中”,不负责最终缺失或风险判定。 + +## 2. 输入 + +```python +@dataclass +class RequirementDocumentMatchInput: + documents: list[DocumentFact] + requirements: list[RequirementItem] +``` + +## 3. 输出 + +```python +@dataclass +class RequirementDocumentMatchOutput: + matches: list[RequirementDocumentMatch] + unmatched_documents: list[DocumentFact] + warnings: list[dict] +``` + +## 4. 匹配策略 + +### 4.1 章节点编码匹配 + +最高优先级。 + +示例: + +1. 文档 `CH1.4 申请表.docx` +2. 要求项 `CH1.4 申请表` +3. 结果:高置信命中 + +### 4.2 文档角色匹配 + +使用第一步产生的 `document_role`。 + +示例: + +1. `application_form` +2. `product_list` +3. `regulatory_information_catalog` + +### 4.3 关键词匹配 + +使用法规要求项中的关键词表匹配文件名和相对路径。 + +### 4.4 人工修正字段匹配 + +如果用户在后台修正了章节点或资料名称,应优先使用修正结果。 + +## 5. 核心方法 + +### 5.1 `run(input) -> RequirementDocumentMatchOutput` + +主入口方法。 + +### 5.2 `match_by_chapter_code(document, requirement) -> MatchEvidence | None` + +章节点编码完全相等时返回高置信证据。 + +### 5.3 `match_by_document_role(document, requirement) -> MatchEvidence | None` + +文档角色命中期望角色时返回证据。 + +### 5.4 `match_by_keywords(document, requirement) -> MatchEvidence | None` + +文件名、资料名称或相对路径命中关键词时返回证据。 + +### 5.5 `calculate_match_confidence(evidences) -> str` + +置信度: + +1. `high` +2. `medium` +3. `low` +4. `none` + +## 6. 技术实现 + +使用技术: + +1. Python 字符串规则 +2. `re` +3. 中文空白和标点标准化 +4. 可选 `rapidfuzz` + +V1 中不建议过度依赖模糊匹配,避免把相似但不等价的资料误判为已提供。 + +## 7. 异常处理 + +1. 一个要求项命中多个文档:保留全部候选,交给判定 Skill 处理。 +2. 一个文档命中多个要求项:标记潜在错放或重复。 +3. 文档待人工复核:仍可参与匹配,但置信度不超过 `medium`。 +4. 章节点冲突:输出警告。 + +## 8. 测试要点 + +1. 章节点完全匹配返回高置信。 +2. 文档角色匹配返回中高置信。 +3. 只有关键词匹配返回低或中置信。 +4. 待复核文档不会被高置信命中。 +5. 多重命中输出警告。 +