# 性别字段缺失问题分析与修复 ## 问题描述 模型在思考过程中正确识别了性别信息("性别方面,无论是在哪里,都明确指出是男性或者男,所以统一转换为'男'即可"),但在最终的JSON输出中,`target_gender`字段却是空字符串。同时,`target_professional_rank`和`clue_source`字段也存在类似问题。 ## 问题分析 ### 1. 根本原因 **问题1:System Prompt不够强调** - 虽然system prompt提到了性别字段,但可能不够强调 - 模型在生成JSON时可能因为某些原因跳过了某些字段 - 需要更明确地在提示词中强调每个字段都必须填写,不能为空 **问题2:字段名错误** - 模型返回了错误的字段名:`_professional_rank`和`_source` - 说明模型没有严格遵循system prompt中的字段名要求 - 需要更明确地禁止使用下划线前缀 **问题3:后处理机制不完善** - 虽然代码中有后处理逻辑,但对于性别、职级等关键字段的推断不够完善 - 需要增强后处理机制,从已有数据中推断缺失字段 ### 2. 具体表现 从用户提供的返回结果来看: ```json { "target_name": "张三", "target_political_status": "中共党员", "target_date_of_birth": "1980年05月", "target_organization_and_position": "某公司总经理", "target_issue_description": "违反国家计划生育有关政策规定,于2010年10月生育二胎。", "target_gender": "", // ❌ 应该是"男" "_professional_rank": "", // ❌ 字段名错误,应该是"target_professional_rank",值应该是"正处级" "_source": "", // ❌ 字段名错误,应该是"clue_source",值应该是"群众举报" } ``` **问题点**: 1. `target_gender`为空,但思考过程中明确识别了性别 2. 字段名错误:`_professional_rank`应该是`target_professional_rank` 3. 字段名错误:`_source`应该是`clue_source` 4. 值缺失:职级和线索来源的值都是空的 ## 修复方案 ### 1. 强化System Prompt ✅ **修改位置**:`services/ai_service.py` 第237行 **改进内容**: - 使用⚠️标记强调核心要求 - 明确列出关键字段(性别、职级、线索来源)的提取要求 - 明确禁止使用下划线前缀的字段名 - 强调如果文本中明确提到信息,必须提取,不能为空 **新的System Prompt**: ``` 你是一个专业的数据提取助手。请从输入文本中提取结构化信息,并严格按照JSON格式返回结果。 ⚠️ 核心要求(必须严格遵守): 1. 字段提取要求: - 如果文本中明确提到信息(如性别、年龄、职务、职级、线索来源等),必须提取,绝对不能设为空字符串 - 性别字段(target_gender):如果文本中出现"男"、"女"、"男性"、"女性"、"先生"、"女士"等任何表示性别的词汇,必须提取并转换为"男"或"女",不能为空 - 职级字段(target_professional_rank):如果文本中提到"正处级"、"副处级"、"正科级"等,必须提取,不能为空 - 线索来源字段(clue_source):如果文本中提到"举报"、"群众举报"、"来信"等,必须提取,不能为空 2. 字段名格式要求(严格禁止错误): - 必须使用"target_professional_rank",禁止使用"_professional_rank"或任何下划线前缀 - 必须使用"clue_source",禁止使用"_source"、"source"或任何下划线前缀 - 必须使用"target_organization",禁止使用"target_organisation"(英式拼写) - 所有字段名必须严格按照JSON示例中的字段编码,不能随意修改 3. JSON格式要求: - 只返回JSON对象,不要包含任何其他文字、思考过程、markdown代码块标记或```json标记 - 所有字段名必须使用双引号 - 必须返回所有要求的字段,即使值为空字符串也要包含在JSON中 - JSON格式必须完整且有效,不能有语法错误 4. 提取逻辑: - 逐字逐句仔细阅读输入文本,不要遗漏任何信息 - 对于性别、职级、线索来源等关键字段,请特别仔细查找 - 如果文本中明确提到某个信息,必须提取出来,不能设为空 ``` ### 2. 增强后处理机制 ✅ **修改位置**:`services/ai_service.py` 第1233-1320行 **新增功能**: 1. **从工作基本情况中提取性别** - 匹配模式:`XXX,男,...` 或 `XXX,女,...` - 如果`target_gender`为空,从`target_work_basic_info`中提取 2. **从所有文本字段中推断性别** - 如果工作基本情况中没有,检查所有文本字段 - 使用正则表达式匹配"男"或"女" 3. **从工作基本情况中提取职级** - 匹配模式:`正处级`、`副处级`、`正科级`等 - 如果`target_professional_rank`为空,从文本中提取 4. **从文本中推断线索来源** - 检查所有文本字段中是否包含"举报"、"群众举报"等关键词 - 根据关键词推断线索来源类型 **后处理逻辑**: ```python # 3. 从工作基本情况中提取性别(如果target_gender为空) if 'target_gender' in field_code_map and (not data.get('target_gender') or data.get('target_gender') == ''): # 尝试从工作基本情况中提取性别 work_info = data.get('target_work_basic_info', '') if work_info: gender_match = re.search(r'[,,]\s*([男女])\s*[,,]', work_info) if gender_match: gender = gender_match.group(1) data['target_gender'] = gender # 如果还没有,尝试从其他字段中查找 if not data.get('target_gender'): for key, value in data.items(): if isinstance(value, str) and value: if re.search(r'\b男\b', value) and not re.search(r'\b女\b', value): data['target_gender'] = '男' break elif re.search(r'\b女\b', value) and not re.search(r'\b男\b', value): data['target_gender'] = '女' break ``` ## 预期效果 1. **提高字段提取准确性** - 强化后的system prompt明确要求提取关键字段 - 模型更可能正确提取性别、职级、线索来源等信息 2. **修复字段名错误** - 明确禁止使用下划线前缀 - JSON修复机制可以处理字段名错误 3. **增强容错能力** - 即使模型没有正确提取,后处理机制可以从已有数据中推断 - 多层保障确保关键字段不会为空 ## 测试建议 1. **功能测试** - 使用相同的输入数据测试修复后的代码 - 验证性别、职级、线索来源字段是否正确提取 - 检查字段名是否正确 2. **边界测试** - 测试性别信息在不同位置的情况(工作基本情况、问题线索等) - 测试职级信息的不同表述方式 - 测试线索来源的不同表述方式 3. **错误处理测试** - 测试模型返回错误字段名的情况 - 验证JSON修复机制是否能正确处理 ## 后续优化建议 1. **如果问题持续存在** - 考虑进一步降低temperature参数(当前0.2,可以尝试0.1) - 考虑调整其他参数(top_p, top_k等) - 联系模型服务提供商寻求支持 2. **监控和日志** - 记录修复前后的字段提取准确率 - 分析仍然存在的错误模式 - 持续优化提示词和后处理机制 3. **考虑使用Few-shot示例** - 在system prompt中添加正确的JSON示例 - 展示如何正确提取性别、职级等字段 ## 总结 通过强化system prompt和增强后处理机制,应该能够解决性别字段缺失的问题。如果问题仍然存在,可能需要进一步调整模型参数或联系服务提供商。