NER阶段实现方案.md 9.8 KB

NER阶段完整实现方案

一、当前架构分析

1.1 数据流概览

附件上传 → 文档解析 → 文本存储 → NER提取 → 图数据库存储 → 前端展示

1.2 现有组件

后端服务

  • lingyue-ai: NER服务调用层
  • lingyue-project: 项目、附件、规则管理
  • lingyue-file: 文件存储
  • lingyue-task: 异步任务管理

Python服务

  • ner-service: NER实体提取服务(支持rule/ollama/deepseek模式)

数据存储

  • 图数据库:graph_nodes(节点)、graph_edges(边)、graph_properties(属性)
  • 节点类型:PROJECT, ELEMENT, VALUE, ATTACHMENT, ENTITY, RULE

1.3 Mock数据要素分类

A. 用户输入类(6个):

  • 项目编号、申请级别、申请日期、获证日期、证书编号、通过评审日期

B. 附件提取类-基础信息(7个):

  • 评审对象、简称、开始日期、结束日期、复审范围、工作过程、自评过程等

C. 附件提取类-评审内容(18个):

  • 目标、职责、全员参与、安全投入、安全文化、体系化管理等

D. 表格数据类(7个):

  • 复审项目列表、复审人员列表、整改建议、评审详情等

E. 计算类(2个):

  • 评审得分、评审级别(基于表格数据计算)

二、NER要素提取策略

2.1 提取模式设计

采用三层提取策略

层1:规则提取(Rule-based)

适用于格式固定的字段:

  • 日期:2024年7月13日
  • 数值:93.33分
  • 级别:一级二级
  • 证书编号:ZGDIDBOY-083
  • 评审代码:5.1.1.1

层2:LLM智能提取(DeepSeek/Qwen)

适用于需要语义理解的字段:

  • 评审对象简称提取
  • 复审范围总结
  • 各类管理描述(目标、职责等)
  • 工作过程描述

层3:表格结构化提取

适用于表格数据:

  • 使用文档解析器识别表格结构
  • 按行列提取数据
  • 映射到实体节点

2.2 实体类型扩展

新增智报专用实体类型

ENTITY_TYPES = {
    # 基础类型(已有)
    "DATE": "日期",
    "NUMBER": "数值", 
    "ORG": "机构",
    "LOC": "地点",
    "PERSON": "人名",
    
    # 智报专用类型(新增)
    "SCORE": "评审得分",
    "LEVEL": "级别",
    "CERTIFICATE_CODE": "证书编号",
    "REVIEW_CODE": "评审代码",
    "COMPANY_ALIAS": "公司简称",
    "PROJECT_NAME": "项目名称",
    "REVIEW_ITEM": "评审项",
    "SUGGESTION": "整改建议",
}

2.3 分阶段提取流程

阶段1: 工作方案(001008)
  ↓ 提取:评审对象、简称、日期、范围、人员
  
阶段2: 核心要素评审记录表(001001)
  ↓ 提取:得分、各项评审内容、问题描述
  
阶段3: 复审问题建议表(001010)
  ↓ 提取:整改建议
  
阶段4: 其他附件(001003等)
  ↓ 提取:自评过程、工作依据等

三、存储结构设计

3.1 图数据库节点设计

节点类型扩展

-- 新增节点类型
NODE_NER_ENTITY = "NER_ENTITY"  -- NER提取的实体
NODE_NER_RELATION = "NER_RELATION"  -- 实体间关系

实体节点属性

{
  "id": 1001,
  "node_type": "NER_ENTITY",
  "node_key": "entity_20240101_001",
  "node_name": "中国电建集团成都勘测设计研究院有限公司",
  "properties": {
    "entity_type": "ORG",           // 实体类型
    "entity_value": "成都院",        // 实体值(简称)
    "confidence": 0.95,             // 置信度
    "char_start": 100,              // 文本起始位置
    "char_end": 125,                // 文本结束位置
    "line": 5,                      // 所在行号
    "context": "...评审对象:中国电建...",  // 上下文
    "source_attachment_id": 408,    // 来源附件
    "extract_method": "llm",        // 提取方法
    "extract_time": "2024-03-04 14:00:00"
  }
}

3.2 边关系设计

-- 新增边类型
EDGE_HAS_NER_ENTITY = "HAS_NER_ENTITY"  -- 附件→实体
EDGE_ENTITY_RELATION = "ENTITY_RELATION"  -- 实体→实体关系
EDGE_ENTITY_TO_VALUE = "ENTITY_TO_VALUE"  -- 实体→要素值(映射)

关系示例

附件[408:工作方案] --[HAS_NER_ENTITY]--> 实体[成都院]
实体[成都院] --[ENTITY_RELATION:简称]--> 实体[中国电建集团成都院]
实体[成都院] --[ENTITY_TO_VALUE]--> 要素值[project.reviewObjectAlias]

3.3 与现有要素系统的映射

NER实体 → 规则处理 → 要素值填充

示例:
NER提取: "2024年7月13日" (DATE)
  ↓
规则匹配: project.workStartAt
  ↓
创建VALUE节点: "2024年7月13日"
  ↓
关联到ELEMENT: workStartAt

四、前端展示方案

4.1 NER结果展示页面

位置:项目详情 → 附件管理 → NER分析

功能模块

  1. 实体列表视图

    • 按类型分组展示(ORG/DATE/PERSON等)
    • 显示置信度、来源位置
    • 支持筛选、搜索
  2. 文本标注视图

    • 在原文中高亮显示实体
    • 不同颜色标识不同类型
    • 鼠标悬停显示详情
  3. 关系图谱视图

    • 可视化实体间关系
    • 支持交互式探索
  4. 要素映射视图

    • 显示NER实体→要素值的映射关系
    • 支持手动调整映射

4.2 UI组件设计

<template>
  <div class="ner-analysis">
    <!-- 顶部统计 -->
    <div class="stats-bar">
      <el-statistic title="实体总数" :value="entityCount" />
      <el-statistic title="关系数" :value="relationCount" />
      <el-statistic title="已映射" :value="mappedCount" />
    </div>
    
    <!-- 实体列表 -->
    <el-tabs v-model="activeTab">
      <el-tab-pane label="实体列表" name="entities">
        <entity-list :entities="entities" />
      </el-tab-pane>
      
      <el-tab-pane label="文本标注" name="annotation">
        <text-annotation :text="sourceText" :entities="entities" />
      </el-tab-pane>
      
      <el-tab-pane label="关系图谱" name="graph">
        <relation-graph :entities="entities" :relations="relations" />
      </el-tab-pane>
      
      <el-tab-pane label="要素映射" name="mapping">
        <entity-mapping :entities="entities" :elements="elements" />
      </el-tab-pane>
    </el-tabs>
  </div>
</template>

五、实施路线图

阶段1:基础设施搭建(1-2天)

任务

  • 扩展Constants常量(新增节点/边类型)
  • 创建NER实体相关的DTO/VO类
  • 扩展图数据库Service(支持NER节点操作)
  • 配置DeepSeek API(如使用LLM模式)

产出

  • NER基础数据结构就绪
  • API配置完成

阶段2:NER服务增强(2-3天)

任务

  • 扩展Python NER服务的实体类型规则
  • 实现智报专用实体提取逻辑
  • 添加表格数据提取功能
  • 实现分阶段提取策略

产出

  • 增强版NER服务
  • 单元测试通过

阶段3:后端集成(2-3天)

任务

  • 在AttachmentService中添加NER触发逻辑
  • 实现NER结果存储到图数据库
  • 实现实体→要素值的自动映射
  • 添加NER结果查询API

产出

  • 完整的NER数据流
  • API接口文档

阶段4:前端展示(3-4天)

任务

  • 创建NER分析页面组件
  • 实现实体列表视图
  • 实现文本标注视图
  • 实现要素映射视图
  • (可选)实现关系图谱视图

产出

  • NER可视化界面
  • 用户操作手册

阶段5:测试与优化(2-3天)

任务

  • 端到端测试(上传附件→NER→展示)
  • 准确率评估与规则优化
  • 性能测试与优化
  • 用户体验优化

产出

  • 测试报告
  • 优化方案

六、技术实现细节

6.1 NER触发时机

方案A:附件上传后自动触发

// AttachmentService.uploadAttachment()
@Transactional
public AttachmentUploadVO uploadAttachment(...) {
    // ... 创建附件节点
    
    // 触发NER提取(异步)
    taskService.createNerTask(attachmentId);
    
    return vo;
}

方案B:用户手动触发

// 新增API
@PostMapping("/{attachmentId}/ner")
public Result<?> triggerNer(@PathVariable Long attachmentId) {
    nerService.extractEntities(attachmentId);
    return Result.ok();
}

6.2 实体映射策略

自动映射规则

// 基于实体类型和上下文自动映射
if (entity.getType().equals("ORG") && 
    entity.getContext().contains("评审对象")) {
    mapToElement(entity, "project.reviewObject");
}

if (entity.getType().equals("DATE") && 
    entity.getContext().contains("评审开始")) {
    mapToElement(entity, "project.workStartAt");
}

手动映射接口

@PostMapping("/entities/{entityId}/map")
public Result<?> mapEntityToElement(
    @PathVariable Long entityId,
    @RequestBody MapRequest request) {
    
    nerService.mapEntity(entityId, request.getElementKey());
    return Result.ok();
}

6.3 性能优化

批量处理

  • 多个附件并行NER提取
  • 批量插入图数据库

缓存策略

  • 缓存NER结果(避免重复提取)
  • 缓存实体映射规则

增量更新

  • 仅对新上传/修改的附件执行NER
  • 支持部分重新提取

七、风险与应对

7.1 准确率问题

风险:规则模式准确率不足,LLM成本高

应对

  • 混合模式:规则+LLM
  • 人工校验机制
  • 持续优化规则库

7.2 性能问题

风险:大文档NER耗时长

应对

  • 异步处理
  • 分块提取
  • 进度反馈

7.3 数据一致性

风险:NER结果与要素值不一致

应对

  • 版本控制
  • 审计日志
  • 回滚机制

八、后续扩展

  • 支持自定义实体类型
  • 实体去重与合并
  • 跨附件实体关联
  • 知识图谱构建
  • 智能问答(基于NER结果)

文档版本:v1.0
创建时间:2024-03-04
维护者:开发团队