ai-business-write/性别和年龄字段缺失问题深度修复.md

148 lines
5.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 性别和年龄字段缺失问题深度修复
## 问题描述
测试数据中明明有"男性"、"男"、"年龄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即使模型没有正确提取字段也能从原始输入中补充。这提供了多层保障确保关键字段不会为空。