Просмотр исходного кода

optimize: 优化 NER 提取 Prompt,提高实体识别质量

主要改进:
1. 完善 Prompt 中各实体类型的详细定义和示例
2. 明确排除规则:
   - NUMBER 不包括章节编号、序号
   - PROJECT 不包括文件编号
   - METHOD 不包括标准编号
3. 增加重要规则提示:
   - 只提取有实际意义的实体
   - 实体边界要准确
   - 去除重复实体
   - 位置信息要准确

解决问题:
- 之前大量章节编号(16、17、1.1等)被误识别为 NUMBER
- 文件编号(SQE.01C0213)被误识别为 METHOD
- 标准编号被误识别为 PROJECT
何文松 1 месяц назад
Родитель
Сommit
96cd0f9e9a

+ 9 - 8
python-services/ner-service/app/config.py

@@ -47,15 +47,16 @@ class Settings(BaseSettings):
     deepseek_max_retries: int = 3
     
     # 实体类型配置
+    # 注意:这些类型名需要与 prompt 中的定义一致
     entity_types: List[str] = [
-        "PERSON",   # 人名
-        "ORG",      # 机构/组织
-        "LOC",      # 地点
-        "DATE",     # 日期
-        "NUMBER",   # 数值
-        "DEVICE",   # 设备
-        "PROJECT",  # 项目
-        "METHOD",   # 方法/标准
+        "PERSON",   # 人名(包含职务+姓名)
+        "ORG",      # 机构/组织(完整名称)
+        "LOC",      # 地点/位置
+        "DATE",     # 日期/时间
+        "NUMBER",   # 有意义的数值(带单位,非章节号)
+        "DEVICE",   # 设备/系统
+        "PROJECT",  # 项目/工程名称(非编号)
+        "METHOD",   # 方法/标准/规范名称
     ]
     
     # 日志配置

+ 59 - 8
python-services/ner-service/app/services/deepseek_service.py

@@ -67,18 +67,69 @@ class DeepSeekService:
         构建 NER 提取的 Prompt
         """
         types = entity_types or settings.entity_types
-        types_desc = ", ".join(types)
         
-        example = '{"entities": [{"name": "成都市", "type": "LOC", "charStart": 10, "charEnd": 13}, {"name": "2024年5月", "type": "DATE", "charStart": 0, "charEnd": 7}]}'
-        
-        prompt = f"""请从以下文本中提取命名实体,直接输出JSON,不要解释。
+        prompt = f"""你是专业的命名实体识别(NER)专家。请从以下文本中提取有意义的命名实体。
+
+## 实体类型定义
+
+1. **PERSON** - 人名
+   - 包括:姓名、职务+姓名(如"张总"、"李工程师")
+   - 不包括:职位本身(如"经理"、"主任")
+
+2. **ORG** - 机构/组织
+   - 包括:公司、政府机关、协会、院校等完整名称
+   - 例如:"中国电建集团成都勘测设计研究院有限公司"、"国家能源局"
+   - 不包括:简称(如"公司"、"集团"),除非是特定缩写(如"成都院")
+
+3. **LOC** - 地点/位置
+   - 包括:省市区县、具体地址、工程位置
+   - 例如:"四川省成都市"、"龙滩水电站"
+
+4. **DATE** - 日期/时间
+   - 包括:具体日期、时间段、年份
+   - 例如:"2024年7月13日"、"2019年版"
+   - 不包括:单独的年份数字
+
+5. **NUMBER** - 有意义的数值
+   - 包括:带单位的数量、金额、评分、比例
+   - 例如:"93.33分"、"7000名"、"70多年"、"5个"
+   - **不包括**:章节编号(如"1.1"、"第3章")、纯序号(如"16"、"17")、表格序号
+
+6. **PROJECT** - 项目/工程名称
+   - 包括:具体项目名称、工程名称
+   - 例如:"白鹤滩水电站工程"、"安全生产标准化建设项目"
+   - **不包括**:文件编号(如"AY-BZ-0092-2024")、标准编号
+
+7. **METHOD** - 方法/标准/规范
+   - 包括:技术标准、管理办法、评价标准的完整名称
+   - 例如:"电力建设企业安全生产标准化评价标准"、"安全生产风险抵押金管理办法"
+   - **不包括**:编号(如"SQE.01C0213"、"中电建协〔2014〕24号文")
+
+8. **DEVICE** - 设备/系统
+   - 包括:设备名称、信息系统名称
+   - 例如:"OA系统"、"QHSE系统"、"造槽机"
+
+## 重要规则
+
+1. **只提取有实际意义的实体**,忽略:
+   - 章节编号(如"1"、"1.1"、"第一章")
+   - 表格序号
+   - 单独的数字(如"16"、"17")
+   - 文件编号和标准编号(归类为无意义数据,不要提取)
+
+2. **实体边界要准确**,提取完整的名称而非片段
+
+3. **去除重复实体**,相同的实体只返回一次
+
+4. **charStart和charEnd必须准确**,对应实体在原文中的字符位置(从0开始)
+
+## 输出格式
 
-实体类型: {types_desc}
+直接输出JSON,格式如下:
+{{"entities": [{{"name": "实体名称", "type": "实体类型", "charStart": 起始位置, "charEnd": 结束位置}}]}}
 
-输出格式示例:
-{example}
+## 待处理文本
 
-文本:
 {text}
 
 请直接输出JSON:"""