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

5.5 KiB
Raw Permalink Blame History

性别和年龄字段缺失问题深度修复

问题描述

测试数据中明明有"男性"、"男"、"年龄44岁"等明确信息,但解析结果中target_gendertarget_age都是空。

根本原因分析

问题1后处理逻辑无法访问原始输入文本

问题

  • 后处理函数_post_process_inferred_fields只能访问模型返回的JSON解析结果data
  • 如果模型根本没有提取这些字段,后处理也无法从原始输入文本中提取
  • 后处理逻辑只能从已提取的数据中推断无法访问原始prompt

影响

  • 即使原始输入文本中明确有"男性"、"年龄44岁"等信息
  • 如果模型没有提取,后处理也无法补充

问题2模型可能没有正确提取

虽然我们强化了system prompt但模型可能仍然

  • 忽略了某些字段
  • 返回了空值
  • 字段名错误导致规范化失败

修复方案

1. 增强后处理逻辑,支持从原始输入文本提取

修改位置services/ai_service.py 第1236-1350行

改进内容

  1. 修改函数签名,增加prompt参数:
def _post_process_inferred_fields(self, data: Dict, output_fields: List[Dict], prompt: str = None) -> Dict:
  1. 从原始输入文本中提取性别
# 如果仍然没有尝试从原始输入文本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)
  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)
  1. 更新所有调用点,传入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

  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即使模型没有正确提取字段也能从原始输入中补充。这提供了多层保障确保关键字段不会为空。