# 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. 字段池版本管理。