更新提示配置和AI服务内容,增强信息提取助手的描述,明确提取要求,添加后处理逻辑以推断缺失字段,改进字段提取方法以提高数据提取的准确性和完整性。
This commit is contained in:
parent
b8d89c28ec
commit
eaa384cf7e
@ -1,15 +1,15 @@
|
|||||||
{
|
{
|
||||||
"prompt_template": {
|
"prompt_template": {
|
||||||
"intro": "请从以下输入文本中提取结构化信息。仔细分析文本内容,准确提取每个字段的值。",
|
"intro": "请从以下输入文本中提取结构化信息。仔细分析文本内容,准确提取每个字段的值。\n\n⚠️ 重要提醒:请逐字逐句仔细阅读输入文本,不要遗漏任何信息。对于性别、年龄、职务、单位、文化程度等字段,请特别仔细查找,这些信息可能以各种形式出现在文本中。",
|
||||||
"input_text_label": "输入文本:",
|
"input_text_label": "输入文本:",
|
||||||
"output_fields_label": "需要提取的字段(请仔细分析每个字段,确保提取完整):",
|
"output_fields_label": "需要提取的字段(请仔细分析每个字段,确保提取完整):",
|
||||||
"json_format_label": "请严格按照以下JSON格式返回结果,只返回JSON对象,不要包含任何其他文字说明或markdown代码块标记:",
|
"json_format_label": "请严格按照以下JSON格式返回结果,只返回JSON对象,不要包含任何其他文字说明或markdown代码块标记:",
|
||||||
"requirements_label": "重要要求(请严格遵守):",
|
"requirements_label": "重要要求(请严格遵守):",
|
||||||
"requirements": [
|
"requirements": [
|
||||||
"逐字逐句仔细分析输入文本,不要遗漏任何信息",
|
"⚠️ 逐字逐句仔细分析输入文本,不要遗漏任何信息。请特别关注性别、年龄、职务、单位、文化程度等字段",
|
||||||
"对于每个字段,请从多个角度思考:直接提及、同义词、隐含信息、可推断信息",
|
"对于每个字段,请从多个角度思考:直接提及、同义词、隐含信息、可推断信息。例如:性别可能以\"男\"、\"女\"、\"男性\"、\"女性\"、\"先生\"、\"女士\"等形式出现",
|
||||||
"如果文本中明确提到某个信息,必须提取出来,不能设为空",
|
"如果文本中明确提到某个信息(如\"30岁\"、\"男\"、\"总经理\"、\"某公司\"等),必须提取出来,不能设为空",
|
||||||
"如果可以通过已有信息合理推断(如根据出生年月推算年龄),请进行推断并填写",
|
"如果可以通过已有信息合理推断,请进行推断并填写:\n - 根据出生年月(如1980年05月)和当前年份(2024年)计算年龄(44岁)\n - 从单位及职务(如\"某公司总经理\")中拆分单位(\"某公司\")和职务(\"总经理\")\n - 从工作基本情况中提取性别、文化程度等信息",
|
||||||
"如果某个字段在输入文本中确实找不到任何相关信息,该字段值才设为空字符串\"\"",
|
"如果某个字段在输入文本中确实找不到任何相关信息,该字段值才设为空字符串\"\"",
|
||||||
"日期格式统一为中文格式:YYYY年MM月(如:1980年05月表示1980年5月),如果包含日期信息则格式为YYYY年MM月DD日(如:1985年05月17日)。注意:年份必须是4位数字,月份和日期必须是2位数字(如1980年5月应格式化为1980年05月,不是1980年5月)",
|
"日期格式统一为中文格式:YYYY年MM月(如:1980年05月表示1980年5月),如果包含日期信息则格式为YYYY年MM月DD日(如:1985年05月17日)。注意:年份必须是4位数字,月份和日期必须是2位数字(如1980年5月应格式化为1980年05月,不是1980年5月)",
|
||||||
"性别统一为\"男\"或\"女\",不要使用\"男性\"或\"女性\"。如果文本中提到\"男性\"、\"男\"、\"先生\"等,统一转换为\"男\";如果提到\"女性\"、\"女\"、\"女士\"等,统一转换为\"女\"",
|
"性别统一为\"男\"或\"女\",不要使用\"男性\"或\"女性\"。如果文本中提到\"男性\"、\"男\"、\"先生\"等,统一转换为\"男\";如果提到\"女性\"、\"女\"、\"女士\"等,统一转换为\"女\"",
|
||||||
@ -47,8 +47,11 @@
|
|||||||
"description": "被核查人员性别",
|
"description": "被核查人员性别",
|
||||||
"rules": [
|
"rules": [
|
||||||
"只能返回\"男\"或\"女\"",
|
"只能返回\"男\"或\"女\"",
|
||||||
"如果文本中提到\"男性\"、\"男性公民\"等,统一转换为\"男\"",
|
"如果文本中提到\"男性\"、\"男性公民\"、\"男\"、\"先生\"等,统一转换为\"男\"",
|
||||||
"如果文本中提到\"女性\"、\"女性公民\"等,统一转换为\"女\""
|
"如果文本中提到\"女性\"、\"女性公民\"、\"女\"、\"女士\"等,统一转换为\"女\"",
|
||||||
|
"请仔细查找文本中所有可能表示性别的词汇,不要遗漏",
|
||||||
|
"如果文本中提到\"XXX,男,...\"或\"XXX,女,...\",必须提取性别",
|
||||||
|
"如果工作基本情况中提到性别信息,必须提取"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"target_date_of_birth": {
|
"target_date_of_birth": {
|
||||||
@ -122,9 +125,10 @@
|
|||||||
"target_age": {
|
"target_age": {
|
||||||
"description": "被核查人员年龄",
|
"description": "被核查人员年龄",
|
||||||
"rules": [
|
"rules": [
|
||||||
"如果文本中直接提到年龄(如\"30岁\"、\"30周岁\"、\"年龄30\"),直接提取数字部分",
|
"如果文本中直接提到年龄(如\"30岁\"、\"30周岁\"、\"年龄30\"、\"现年30\"),直接提取数字部分",
|
||||||
"如果只有出生年月(如\"1980年5月出生\"、\"198005\"),可以根据当前年份(2024年)计算年龄",
|
"如果只有出生年月(如\"1980年5月出生\"、\"1980年05月\"),必须根据当前年份(2024年)计算年龄(如1980年出生,2024-1980=44岁)",
|
||||||
"年龄格式:纯数字,单位为岁,如\"44\"表示44岁",
|
"年龄格式:纯数字,单位为岁,如\"44\"表示44岁",
|
||||||
|
"⚠️ 如果已有出生年月信息,必须计算年龄,不能设为空字符串",
|
||||||
"如果文本中既没有直接提到年龄,也没有出生年月信息,则设为空字符串"
|
"如果文本中既没有直接提到年龄,也没有出生年月信息,则设为空字符串"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -144,8 +148,9 @@
|
|||||||
"从单位及职务信息中提取单位名称部分",
|
"从单位及职务信息中提取单位名称部分",
|
||||||
"单位名称包括:公司、企业、机关、事业单位、部门等(如\"XX公司\"、\"XX局\"、\"XX部门\"、\"XX委员会\"等)",
|
"单位名称包括:公司、企业、机关、事业单位、部门等(如\"XX公司\"、\"XX局\"、\"XX部门\"、\"XX委员会\"等)",
|
||||||
"如果文本中只提到单位名称,直接提取",
|
"如果文本中只提到单位名称,直接提取",
|
||||||
"如果文本中提到\"XX公司总经理\",提取\"XX公司\"部分",
|
"⚠️ 如果文本中提到\"XX公司总经理\",必须提取\"XX公司\"部分,不能设为空",
|
||||||
"如果文本中提到\"XX单位XX职务\",提取\"XX单位\"部分",
|
"如果文本中提到\"XX单位XX职务\",提取\"XX单位\"部分",
|
||||||
|
"如果已有单位及职务字段(target_organization_and_position),必须从中拆分出单位名称",
|
||||||
"保持单位名称的完整性,不要遗漏"
|
"保持单位名称的完整性,不要遗漏"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -155,8 +160,9 @@
|
|||||||
"从单位及职务信息中提取职务名称部分",
|
"从单位及职务信息中提取职务名称部分",
|
||||||
"职务名称包括:总经理、经理、局长、处长、科长、主任、书记、部长等",
|
"职务名称包括:总经理、经理、局长、处长、科长、主任、书记、部长等",
|
||||||
"如果文本中只提到职务名称,直接提取",
|
"如果文本中只提到职务名称,直接提取",
|
||||||
"如果文本中提到\"XX公司总经理\",提取\"总经理\"部分",
|
"⚠️ 如果文本中提到\"XX公司总经理\",必须提取\"总经理\"部分,不能设为空",
|
||||||
"如果文本中提到\"XX单位XX职务\",提取\"XX职务\"部分",
|
"如果文本中提到\"XX单位XX职务\",提取\"XX职务\"部分",
|
||||||
|
"如果已有单位及职务字段(target_organization_and_position),必须从中拆分出职务名称",
|
||||||
"如果文本中提到多个职务,需要全部提取,用\"、\"连接",
|
"如果文本中提到多个职务,需要全部提取,用\"、\"连接",
|
||||||
"保持职务名称的准确性"
|
"保持职务名称的准确性"
|
||||||
]
|
]
|
||||||
|
|||||||
@ -204,7 +204,7 @@ class AIService:
|
|||||||
"messages": [
|
"messages": [
|
||||||
{
|
{
|
||||||
"role": "system",
|
"role": "system",
|
||||||
"content": "你是一个专业的数据提取助手。请仔细分析用户提供的输入文本,提取所有相关信息,并严格按照指定的JSON格式返回结果。只返回JSON对象,不要包含任何其他文字说明、思考过程或markdown代码块标记。"
|
"content": "你是一个专业的数据提取助手。请仔细分析用户提供的输入文本,提取所有相关信息,并严格按照指定的JSON格式返回结果。\n\n重要要求:\n1. 必须仔细阅读输入文本的每一个字,不要遗漏任何信息\n2. 对于每个字段,请从多个角度思考:直接提及、同义词、隐含信息、可推断信息\n3. 如果文本中明确提到某个信息(如性别、年龄、职务等),必须提取出来,不能设为空\n4. 如果可以通过已有信息合理推断(如根据出生年月推算年龄,从单位及职务中拆分单位和职务),请进行推断并填写\n5. 只返回JSON对象,不要包含任何其他文字说明、思考过程或markdown代码块标记"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"role": "user",
|
"role": "user",
|
||||||
@ -212,12 +212,12 @@ class AIService:
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"stream": False,
|
"stream": False,
|
||||||
"presence_penalty": 1.03,
|
"presence_penalty": 1.05, # 提高presence_penalty,鼓励模型提取更多不同字段
|
||||||
"frequency_penalty": 1.0,
|
"frequency_penalty": 1.02, # 提高frequency_penalty,减少重复
|
||||||
"repetition_penalty": 1.0,
|
"repetition_penalty": 1.05, # 提高repetition_penalty,避免重复
|
||||||
"temperature": 0.3,
|
"temperature": 0.2, # 降低temperature,提高确定性
|
||||||
"top_p": 0.95,
|
"top_p": 0.9, # 降低top_p,更聚焦
|
||||||
"top_k": 1,
|
"top_k": 40, # 增加top_k,允许更多选择
|
||||||
"seed": 1,
|
"seed": 1,
|
||||||
"max_tokens": self.api_max_tokens,
|
"max_tokens": self.api_max_tokens,
|
||||||
"n": 1,
|
"n": 1,
|
||||||
@ -305,6 +305,12 @@ class AIService:
|
|||||||
for key in ['target_name', 'target_gender', 'target_age', 'target_date_of_birth']:
|
for key in ['target_name', 'target_gender', 'target_age', 'target_date_of_birth']:
|
||||||
if key in normalized_data:
|
if key in normalized_data:
|
||||||
print(f"[AI服务] 日期格式化后 {key} = '{normalized_data[key]}'")
|
print(f"[AI服务] 日期格式化后 {key} = '{normalized_data[key]}'")
|
||||||
|
# 后处理:从已有信息推断缺失字段
|
||||||
|
normalized_data = self._post_process_inferred_fields(normalized_data, output_fields)
|
||||||
|
# 打印后处理后的关键字段
|
||||||
|
for key in ['target_name', 'target_gender', 'target_age', 'target_date_of_birth', 'target_organization', 'target_position']:
|
||||||
|
if key in normalized_data:
|
||||||
|
print(f"[AI服务] 后处理后 {key} = '{normalized_data[key]}'")
|
||||||
return normalized_data
|
return normalized_data
|
||||||
|
|
||||||
# 如果无法提取JSON,记录错误
|
# 如果无法提取JSON,记录错误
|
||||||
@ -840,6 +846,156 @@ class AIService:
|
|||||||
# 如果无法解析,返回原值
|
# 如果无法解析,返回原值
|
||||||
return date_str
|
return date_str
|
||||||
|
|
||||||
|
def _post_process_inferred_fields(self, data: Dict, output_fields: List[Dict]) -> Dict:
|
||||||
|
"""
|
||||||
|
后处理:从已有信息推断缺失字段
|
||||||
|
|
||||||
|
Args:
|
||||||
|
data: 提取的数据字典
|
||||||
|
output_fields: 输出字段列表
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
后处理后的数据字典
|
||||||
|
"""
|
||||||
|
# 创建字段编码到字段信息的映射
|
||||||
|
field_code_map = {field['field_code']: field for field in output_fields}
|
||||||
|
|
||||||
|
# 1. 从出生年月计算年龄
|
||||||
|
if 'target_age' in field_code_map and (not data.get('target_age') or data.get('target_age') == ''):
|
||||||
|
if 'target_date_of_birth' in data and data.get('target_date_of_birth'):
|
||||||
|
age = self._calculate_age_from_birth_date(data['target_date_of_birth'])
|
||||||
|
if age:
|
||||||
|
data['target_age'] = str(age)
|
||||||
|
print(f"[AI服务] 后处理:从出生年月 '{data['target_date_of_birth']}' 计算年龄: {age}岁")
|
||||||
|
|
||||||
|
# 2. 从单位及职务中拆分单位和职务
|
||||||
|
if 'target_organization_and_position' in data and data.get('target_organization_and_position'):
|
||||||
|
org_pos = data['target_organization_and_position']
|
||||||
|
|
||||||
|
# 拆分单位
|
||||||
|
if 'target_organization' in field_code_map and (not data.get('target_organization') or data.get('target_organization') == ''):
|
||||||
|
org = self._extract_organization_from_org_pos(org_pos)
|
||||||
|
if org:
|
||||||
|
data['target_organization'] = org
|
||||||
|
print(f"[AI服务] 后处理:从单位及职务 '{org_pos}' 提取单位: {org}")
|
||||||
|
|
||||||
|
# 拆分职务
|
||||||
|
if 'target_position' in field_code_map and (not data.get('target_position') or data.get('target_position') == ''):
|
||||||
|
pos = self._extract_position_from_org_pos(org_pos)
|
||||||
|
if pos:
|
||||||
|
data['target_position'] = pos
|
||||||
|
print(f"[AI服务] 后处理:从单位及职务 '{org_pos}' 提取职务: {pos}")
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
def _calculate_age_from_birth_date(self, birth_date: str) -> Optional[int]:
|
||||||
|
"""
|
||||||
|
从出生年月计算年龄
|
||||||
|
|
||||||
|
Args:
|
||||||
|
birth_date: 出生年月,格式如 "1980年05月" 或 "198005"
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
年龄(整数),如果无法计算则返回None
|
||||||
|
"""
|
||||||
|
if not birth_date:
|
||||||
|
return None
|
||||||
|
|
||||||
|
birth_date = str(birth_date).strip()
|
||||||
|
|
||||||
|
# 提取年份
|
||||||
|
year_match = re.search(r'(\d{4})', birth_date)
|
||||||
|
if not year_match:
|
||||||
|
return None
|
||||||
|
|
||||||
|
birth_year = int(year_match.group(1))
|
||||||
|
current_year = 2024 # 当前年份
|
||||||
|
|
||||||
|
# 计算年龄
|
||||||
|
age = current_year - birth_year
|
||||||
|
|
||||||
|
# 验证年龄合理性(0-150岁)
|
||||||
|
if 0 <= age <= 150:
|
||||||
|
return age
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
def _extract_organization_from_org_pos(self, org_pos: str) -> Optional[str]:
|
||||||
|
"""
|
||||||
|
从单位及职务中提取单位名称
|
||||||
|
|
||||||
|
Args:
|
||||||
|
org_pos: 单位及职务,如 "某公司总经理"
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
单位名称,如 "某公司"
|
||||||
|
"""
|
||||||
|
if not org_pos:
|
||||||
|
return None
|
||||||
|
|
||||||
|
org_pos = str(org_pos).strip()
|
||||||
|
|
||||||
|
# 常见职务关键词
|
||||||
|
position_keywords = [
|
||||||
|
'总经理', '经理', '局长', '处长', '科长', '主任', '书记', '部长',
|
||||||
|
'副部长', '副经理', '副局长', '副处长', '副科长', '副主任', '副书记',
|
||||||
|
'董事长', '副董事长', '总裁', '副总裁', '总监', '副总监',
|
||||||
|
'部长', '副部长', '司长', '副司长', '厅长', '副厅长',
|
||||||
|
'市长', '副市长', '县长', '副县长', '乡长', '副乡长',
|
||||||
|
'镇长', '副镇长', '村长', '副村长'
|
||||||
|
]
|
||||||
|
|
||||||
|
# 尝试匹配:单位 + 职务
|
||||||
|
for pos_keyword in position_keywords:
|
||||||
|
if pos_keyword in org_pos:
|
||||||
|
# 找到职务位置,提取前面的单位部分
|
||||||
|
pos_index = org_pos.find(pos_keyword)
|
||||||
|
if pos_index > 0:
|
||||||
|
org = org_pos[:pos_index].strip()
|
||||||
|
if org:
|
||||||
|
return org
|
||||||
|
|
||||||
|
# 如果没有找到明确的职务关键词,尝试其他模式
|
||||||
|
# 例如:"XX公司XX部门XX职务"
|
||||||
|
# 这里简单返回,可能需要更复杂的逻辑
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
def _extract_position_from_org_pos(self, org_pos: str) -> Optional[str]:
|
||||||
|
"""
|
||||||
|
从单位及职务中提取职务名称
|
||||||
|
|
||||||
|
Args:
|
||||||
|
org_pos: 单位及职务,如 "某公司总经理"
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
职务名称,如 "总经理"
|
||||||
|
"""
|
||||||
|
if not org_pos:
|
||||||
|
return None
|
||||||
|
|
||||||
|
org_pos = str(org_pos).strip()
|
||||||
|
|
||||||
|
# 常见职务关键词
|
||||||
|
position_keywords = [
|
||||||
|
'总经理', '经理', '局长', '处长', '科长', '主任', '书记', '部长',
|
||||||
|
'副部长', '副经理', '副局长', '副处长', '副科长', '副主任', '副书记',
|
||||||
|
'董事长', '副董事长', '总裁', '副总裁', '总监', '副总监',
|
||||||
|
'部长', '副部长', '司长', '副司长', '厅长', '副厅长',
|
||||||
|
'市长', '副市长', '县长', '副县长', '乡长', '副乡长',
|
||||||
|
'镇长', '副镇长', '村长', '副村长'
|
||||||
|
]
|
||||||
|
|
||||||
|
# 按长度从长到短排序,优先匹配长关键词(如"副经理"优先于"经理")
|
||||||
|
position_keywords.sort(key=len, reverse=True)
|
||||||
|
|
||||||
|
# 尝试匹配职务关键词
|
||||||
|
for pos_keyword in position_keywords:
|
||||||
|
if pos_keyword in org_pos:
|
||||||
|
return pos_keyword
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
def _parse_text_response(self, text: str, output_fields: List[Dict]) -> Dict:
|
def _parse_text_response(self, text: str, output_fields: List[Dict]) -> Dict:
|
||||||
"""
|
"""
|
||||||
从文本响应中解析字段值(备用方案)
|
从文本响应中解析字段值(备用方案)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user