5.5 KiB
5.5 KiB
性别和年龄字段缺失问题深度修复
问题描述
测试数据中明明有"男性"、"男"、"年龄44岁"等明确信息,但解析结果中target_gender和target_age都是空。
根本原因分析
问题1:后处理逻辑无法访问原始输入文本
问题:
- 后处理函数
_post_process_inferred_fields只能访问模型返回的JSON解析结果(data) - 如果模型根本没有提取这些字段,后处理也无法从原始输入文本中提取
- 后处理逻辑只能从已提取的数据中推断,无法访问原始prompt
影响:
- 即使原始输入文本中明确有"男性"、"年龄44岁"等信息
- 如果模型没有提取,后处理也无法补充
问题2:模型可能没有正确提取
虽然我们强化了system prompt,但模型可能仍然:
- 忽略了某些字段
- 返回了空值
- 字段名错误导致规范化失败
修复方案
1. 增强后处理逻辑,支持从原始输入文本提取 ✅
修改位置:services/ai_service.py 第1236-1350行
改进内容:
- 修改函数签名,增加
prompt参数:
def _post_process_inferred_fields(self, data: Dict, output_fields: List[Dict], prompt: str = None) -> Dict:
- 从原始输入文本中提取性别:
# 如果仍然没有,尝试从原始输入文本(prompt)中提取
if (not data.get('target_gender') or data.get('target_gender') == '') and prompt:
# 从prompt中提取输入文本部分(通常在"输入文本:"之后)
input_text_match = re.search(r'输入文本[::]\s*\n(.*?)(?:\n\n需要提取的字段|$)', prompt, re.DOTALL)
if input_text_match:
input_text = input_text_match.group(1)
# 匹配性别关键词:男性、女性、男、女等
if re.search(r'\b男性\b|\b男\b', input_text) and not re.search(r'\b女性\b|\b女\b', input_text):
data['target_gender'] = '男'
elif re.search(r'\b女性\b|\b女\b', input_text) and not re.search(r'\b男性\b|\b男\b', input_text):
data['target_gender'] = '女'
elif re.search(r'[,,]\s*([男女])\s*[,,]', input_text):
gender_match = re.search(r'[,,]\s*([男女])\s*[,,]', input_text)
if gender_match:
data['target_gender'] = gender_match.group(1)
- 从原始输入文本中提取年龄:
# 如果还没有,尝试从原始输入文本中直接提取年龄
if (not data.get('target_age') or data.get('target_age') == '') and prompt:
input_text_match = re.search(r'输入文本[::]\s*\n(.*?)(?:\n\n需要提取的字段|$)', prompt, re.DOTALL)
if input_text_match:
input_text = input_text_match.group(1)
# 匹配年龄模式:年龄44岁、44岁、年龄44等
age_match = re.search(r'年龄\s*(\d+)\s*岁|(\d+)\s*岁|年龄\s*(\d+)', input_text)
if age_match:
age = age_match.group(1) or age_match.group(2) or age_match.group(3)
if age:
data['target_age'] = str(age)
- 更新所有调用点,传入
prompt参数:
# 修改前
normalized_data = self._post_process_inferred_fields(normalized_data, output_fields)
# 修改后
normalized_data = self._post_process_inferred_fields(normalized_data, output_fields, prompt)
2. 提取逻辑的优先级
后处理逻辑按以下优先级提取字段:
对于性别(target_gender):
- 从
target_work_basic_info中提取(匹配XXX,男,...模式) - 从所有已提取的文本字段中查找(使用正则表达式)
- 从原始输入文本中提取(新增)
对于年龄(target_age):
- 从
target_date_of_birth计算(根据出生年月和当前年份) - 从原始输入文本中直接提取(新增,匹配"年龄44岁"等模式)
预期效果
-
提高字段提取成功率
- 即使模型没有提取,后处理也能从原始输入文本中提取
- 多层保障确保关键字段不会为空
-
增强容错能力
- 不依赖模型的提取准确性
- 即使模型返回空值,也能从原始输入中补充
-
提高数据完整性
- 确保性别、年龄等关键字段有值
- 减少空值的情况
测试建议
-
功能测试
- 使用包含"男性"、"年龄44岁"的测试数据
- 验证后处理是否能从原始输入文本中提取
- 检查日志输出,确认提取来源
-
边界测试
- 测试性别信息在不同位置的情况
- 测试年龄的不同表述方式("44岁"、"年龄44"、"年龄44岁"等)
- 测试模型返回空值的情况
-
日志检查
- 查看日志中的"后处理"信息
- 确认是从哪个来源提取的字段
- 验证提取逻辑是否正确执行
调试建议
如果问题仍然存在,可以:
-
检查日志输出
- 查看
[AI服务] 后处理:从原始输入文本中提取...的日志 - 确认prompt是否正确传入
- 确认正则表达式是否匹配成功
- 查看
-
手动测试正则表达式
- 测试
r'输入文本[::]\s*\n(.*?)(?:\n\n需要提取的字段|$)'是否能正确提取输入文本 - 测试性别和年龄的正则表达式是否能匹配
- 测试
-
检查prompt格式
- 确认prompt中确实包含"输入文本:"标签
- 确认输入文本的格式是否符合预期
总结
通过增强后处理逻辑,让它能够访问原始输入文本(prompt),即使模型没有正确提取字段,也能从原始输入中补充。这提供了多层保障,确保关键字段不会为空。