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