# 字段映射问题修复报告 **日期**: 2025-11-21 **问题**: 真实LLM筛选失败(成功:0/20) **原因**: 字段名不匹配 **状态**: ✅ 已修复 --- ## 🔍 问题诊断 ### 症状 ``` 任务状态: completed 进度: 20/20 成功: 0 ❌ 筛选结果数: 0 ``` **表现**: - 任务瞬间完成(1秒) - 所有文献处理失败 - 没有保存任何筛选结果 --- ## 🎯 根本原因 ### 问题1: PICOS字段名不匹配 **前端/数据库格式** (`TitleScreeningSettings.tsx`): ```typescript picoCriteria: { P: '2型糖尿病患者...', I: 'SGLT2抑制剂...', C: '安慰剂或常规治疗...', O: '心血管结局...', S: 'RCT' } ``` **LLM服务期望格式** (`llmScreeningService.ts`): ```typescript // 实际上支持两种格式,但优先使用短格式 picoCriteria: { P: '...', // ✅ I: '...', // ✅ C: '...', // ✅ O: '...', // ✅ S: '...' // ✅ } ``` **诊断**:前端使用 P/I/C/O/S 格式,但 `screeningService.ts` 直接传递了数据库的原始格式,未做映射。 --- ### 问题2: 模型名格式不匹配 **前端格式** (`TitleScreeningSettings.tsx`): ```typescript models: ['DeepSeek-V3', 'Qwen-Max'] ``` **LLM服务期望格式** (`llmScreeningService.ts`): ```typescript models: ['deepseek-chat', 'qwen-max'] ``` **原因**:前端使用展示名称,后端需要API名称。 --- ### 问题3: 缺少字段验证 文献可能缺少 `title` 或 `abstract`,导致LLM调用失败。 --- ## ✅ 修复方案 ### 修复1: 添加PICOS字段映射 **文件**: `backend/src/modules/asl/services/screeningService.ts` ```typescript // 🔧 修复:字段名映射(数据库格式 → LLM服务格式) const rawPicoCriteria = project.picoCriteria as any; const picoCriteria = { P: rawPicoCriteria?.P || rawPicoCriteria?.population || '', I: rawPicoCriteria?.I || rawPicoCriteria?.intervention || '', C: rawPicoCriteria?.C || rawPicoCriteria?.comparison || '', O: rawPicoCriteria?.O || rawPicoCriteria?.outcome || '', S: rawPicoCriteria?.S || rawPicoCriteria?.studyDesign || '', }; ``` **优势**: - ✅ 兼容两种格式(P/I/C/O/S 或 population/intervention/...) - ✅ 防御性编程,避免undefined --- ### 修复2: 添加模型名映射 ```typescript // 🔧 修复:模型名映射(前端格式 → API格式) const MODEL_NAME_MAP: Record = { 'DeepSeek-V3': 'deepseek-chat', 'Qwen-Max': 'qwen-max', 'GPT-4o': 'gpt-4o', 'Claude-4.5': 'claude-sonnet-4.5', 'deepseek-chat': 'deepseek-chat', // 兼容直接使用API名 'qwen-max': 'qwen-max', // ... 更多映射 }; const rawModels = screeningConfig?.models || ['deepseek-chat', 'qwen-max']; const models = rawModels.map((m: string) => MODEL_NAME_MAP[m] || m); ``` **映射表**: | 前端展示名 | API名称 | |-----------|---------| | DeepSeek-V3 | deepseek-chat | | Qwen-Max | qwen-max | | GPT-4o | gpt-4o | | Claude-4.5 | claude-sonnet-4.5 | --- ### 修复3: 添加文献验证 ```typescript // 🔧 验证:必须有标题和摘要 if (!literature.title || !literature.abstract) { logger.warn('Skipping literature without title or abstract', { literatureId: literature.id, hasTitle: !!literature.title, hasAbstract: !!literature.abstract, }); console.log(`⚠️ 跳过文献 ${processedCount + 1}: 缺少标题或摘要`); processedCount++; continue; } ``` --- ### 修复4: 增强调试日志 ```typescript console.log('\n🚀 开始真实LLM筛选:'); console.log(' 任务ID:', taskId); console.log(' 项目ID:', projectId); console.log(' 文献数:', literatures.length); console.log(' 模型(映射后):', models); // ⭐ 显示映射后的值 console.log(' PICOS-P:', picoCriteria.P?.substring(0, 50) || '(空)'); console.log(' PICOS-I:', picoCriteria.I?.substring(0, 50) || '(空)'); console.log(' PICOS-C:', picoCriteria.C?.substring(0, 50) || '(空)'); console.log(' 纳入标准:', inclusionCriteria?.substring(0, 50) || '(空)'); console.log(' 排除标准:', exclusionCriteria?.substring(0, 50) || '(空)'); ``` --- ## 🧪 测试步骤 ### 1. 重启后端(必须!) ```bash # 停止当前后端(Ctrl+C) cd D:\MyCursor\AIclinicalresearch\backend npm run dev ``` ### 2. 测试(小规模) 1. 访问前端 2. 填写PICOS 3. **上传5篇文献**(先测试小规模) 4. 点击"开始AI初筛" ### 3. 查看后端控制台 **应该看到**: ``` 🚀 开始真实LLM筛选: 任务ID: xxx 文献数: 5 模型(映射后): [ 'deepseek-chat', 'qwen-max' ] PICOS-P: 2型糖尿病患者... PICOS-I: SGLT2抑制剂... PICOS-C: 安慰剂... 纳入标准: 成人2型糖尿病... 排除标准: 综述、系统评价... [等待10-20秒] ✅ 文献 1/5 处理成功 DS: include / Qwen: include 冲突: 否 [等待10-20秒] ✅ 文献 2/5 处理成功 DS: exclude / Qwen: exclude 冲突: 否 ... ``` --- ## 📊 预期效果 ### 修复前 - ⏱️ 1秒完成20篇 - ❌ 成功:0 - ❌ 筛选结果数:0 ### 修复后 - ⏱️ 50-100秒完成5篇(每篇10-20秒) - ✅ 成功:5 - ✅ 筛选结果数:5 - ✅ 证据包含真实的AI分析 - ✅ 证据不包含"模拟证据" --- ## 🔧 修改文件 - ✅ `backend/src/modules/asl/services/screeningService.ts` - 添加PICOS字段映射 - 添加模型名映射 - 添加文献验证 - 增强调试日志 --- ## 💡 经验教训 ### 1. 前后端数据格式一致性 - 前端使用的展示格式 ≠ 后端API格式 - 需要在集成层做映射 ### 2. 防御性编程 - 使用 `||` 提供默认值 - 验证必需字段 - 兼容多种格式 ### 3. 调试日志的重要性 - 显示映射后的值(不是原始值) - 输出所有关键参数 - 帮助快速定位问题 --- ## 🎯 后续优化 ### 短期 1. ✅ 字段映射(已完成) 2. ✅ 模型名映射(已完成) 3. ✅ 验证必需字段(已完成) ### 中期 1. 统一前后端数据格式(使用 TypeScript 接口) 2. 添加数据格式验证中间件 3. 改进错误提示 ### 长期 1. 使用 tRPC 或 GraphQL 确保类型安全 2. 自动化测试覆盖 3. Schema验证 --- **报告人**: AI Assistant **日期**: 2025-11-21 **版本**: v1.0.0