Files
AIclinicalresearch/docs/03-业务模块/ASL-AI智能文献/05-开发记录/2025-11-21-字段映射问题修复.md
HaHafeng 1b53ab9d52 feat(aia): Complete AIA V2.0 with universal streaming capabilities
Major Changes:
- Add StreamingService with OpenAI Compatible format
- Upgrade Chat component V2 with Ant Design X integration
- Implement AIA module with 12 intelligent agents
- Update API routes to unified /api/v1 prefix
- Update system documentation

Backend (~1300 lines):
- common/streaming: OpenAI Compatible adapter
- modules/aia: 12 agents, conversation service, streaming integration
- Update route versions (RVW, PKB to v1)

Frontend (~3500 lines):
- modules/aia: AgentHub + ChatWorkspace (100% prototype restoration)
- shared/Chat: AIStreamChat, ThinkingBlock, useAIStream Hook
- Update API endpoints to v1

Documentation:
- AIA module status guide
- Universal capabilities catalog
- System overview updates
- All module documentation sync

Tested: Stream response verified, authentication working
Status: AIA V2.0 core completed (85%)
2026-01-14 19:15:01 +08:00

6.1 KiB
Raw Blame History

字段映射问题修å¤<EFBFBD>报åŠ

日期: 2025-11-21
问题: 真实LLMç­é€‰å¤±è´¥ï¼ˆæˆ<C3A6>功ï¼?/20ï¼? **原因**: 字段å<C2B5><C3A5>ä¸<C3A4>匹é…<C3A9>
**状�*: �已修�


ðŸ”<EFBFBD> 问题诊断

症状

任务状� completed
进度: 20/20
æˆ<C3A6>功: 0 â<>?
筛选结果数: 0

**表现**�

  • 任务瞬间完æˆ<EFBFBD>ï¼?秒)
  • 所有æ‡çŒ®å¤„ç<EFBFBD>†å¤±è´?
  • 没有ä¿<EFBFBD>存任何ç­é€‰ç»“æž?

🎯 根本原因

问题1: PICOS字段å<C2B5><C3A5>ä¸<C3A4>匹é…<C3A9>

*å‰<EFBFBD>端/æ•°æ<C2B0>®åº“æ ¼å¼? (TitleScreeningSettings.tsx):

picoCriteria: {
  P: '2åžç³å°¿ç—…æ£è€?..',
  I: 'SGLT2æŠåˆ¶å‰?..',
  C: '安慰剂或常规治疗...',
  O: '心血管结局...',
  S: 'RCT'
}

LLMæœ<EFBFBD>åŠ¡æœŸæœæ ¼å¼<EFBFBD> (llmScreeningService.ts):

// 实际上支æŒ<C3A6>两ç§<C3A7>æ ¼å¼<C3A5>,但优先使用短格å¼<C3A5>
picoCriteria: {
  P: '...',  // �
  I: '...',  // �
  C: '...',  // �
  O: '...',  // �
  S: '...'   // �
}

诊断:å‰<EFBFBD>端使ç”?P/I/C/O/S æ ¼å¼<C3A5>,但 screeningService.ts ç´æŽ¥ä¼ é€äº†æ•°æ<C2B0>®åº“çš„åŽŸå§æ ¼å¼<C3A5>,未å<C2AA>šæ˜ å°„ã€?


问题2: 模åžå<E280B9><C3A5>æ ¼å¼<C3A5>ä¸<C3A4>匹é…<C3A9>

å‰<EFBFBD>端格å¼<EFBFBD> (TitleScreeningSettings.tsx):

models: ['DeepSeek-V3', 'Qwen-Max']

LLMæœ<EFBFBD>åŠ¡æœŸæœæ ¼å¼<EFBFBD> (llmScreeningService.ts):

models: ['deepseek-chat', 'qwen-max']

**原因**:å‰<C3A5>端使用展示å<C2BA><C3A5>称,å<C592>Žç«¯éœ€è¦<C3A8>APIå<49><C3A5>ç§°ã€?


问题3: 缺å°å­—段验è¯<C3A8>

æ‡çŒ®å<EFBFBD>¯èƒ½ç¼ºå° title æˆ?abstract,导致LLM调用失败ã€?


âœ?ä¿®å¤<C3A5>æ¹æ¡ˆ

ä¿®å¤<EFBFBD>1: 添加PICOS字段映射

文件: backend/src/modules/asl/services/screeningService.ts

// 🔧 ä¿®å¤<C3A5>:字段å<C2B5><C3A5>映射(数æ<C2B0>®åº“æ ¼å¼<C3A5> â†?LLMæœ<C3A6>务格å¼<C3A5>ï¼?
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 || '',
};

**优势**�

  • âœ?兼容两ç§<C3A7>æ ¼å¼<C3A5>(P/I/C/O/S æˆ?population/intervention/...ï¼?
  • âœ?防御性ç¼ç¨ï¼Œé<C592>¿å…<C3A5>undefined

ä¿®å¤<EFBFBD>2: 添加模åžå<E280B9><C3A5>映å°?

// 🔧 ä¿®å¤<C3A5>:模åžå<E280B9><C3A5>映射(å‰<C3A5>端格å¼?â†?APIæ ¼å¼<C3A5>ï¼?
const MODEL_NAME_MAP: Record<string, string> = {
  'DeepSeek-V3': 'deepseek-chat',
  'Qwen-Max': 'qwen-max',
  'GPT-4o': 'gpt-4o',
  'Claude-4.5': 'claude-sonnet-4.5',
  'deepseek-chat': 'deepseek-chat',  // å…¼å®¹ç´æŽ¥ä½¿ç”¨APIå<49>?
  'qwen-max': 'qwen-max',
  // ... 更多映射
};

const rawModels = screeningConfig?.models || ['deepseek-chat', 'qwen-max'];
const models = rawModels.map((m: string) => MODEL_NAME_MAP[m] || m);

**映射�*�

å‰<EFBFBD>端展示å<EFBFBD>? APIå<EFBFBD><EFBFBD>ç§°
DeepSeek-V3 deepseek-chat
Qwen-Max qwen-max
GPT-4o gpt-4o
Claude-4.5 claude-sonnet-4.5

ä¿®å¤<EFBFBD>3: 添加æ‡çŒ®éªŒè¯<C3A8>

// 🔧 验è¯<C3A8>ï¼šå¿…é¡»æœ‰æ ‡é¢˜åŒæ˜è¦?
if (!literature.title || !literature.abstract) {
  logger.warn('Skipping literature without title or abstract', {
    literatureId: literature.id,
    hasTitle: !!literature.title,
    hasAbstract: !!literature.abstract,
  });
  console.log(`âš ï¸<C3AF>  跳过文献 ${processedCount + 1}: ç¼ºå°æ ‡é¢˜æˆæ˜è¦<C3A8>`);
  processedCount++;
  continue;
}

ä¿®å¤<EFBFBD>4: 增强调试日志

console.log('\n🚀 å¼€å§çœŸå®žLLMç­é€?');
console.log('  任务ID:', taskId);
console.log('  项ç®ID:', projectId);
console.log('  文献�', literatures.length);
console.log('  模åžï¼ˆæ˜ å°„å<E2809E>Žï¼?', models);  // â­?显示映射å<E2809E>Žçš„å€?
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. é‡<C3A9>å<EFBFBD>¯å<C2AF>Žç«¯ï¼ˆå¿…é¡»ï¼<C3AF>ï¼?

# å<>œæ­¢å½“å‰<C3A5>å<EFBFBD>Žç«¯ï¼ˆCtrl+Cï¼?
cd D:\MyCursor\AIclinicalresearch\backend
npm run dev

2. æµè¯•(å°<C3A5>规模ï¼?

  1. 访问å‰<EFBFBD>端
  2. 填写PICOS
  3. **上传5篇æ‡çŒ?*(先æµè¯•å°<C3A5>规模)
  4. 点击"å¼€å§AIåˆ<C3A5>ç­"

3. 查çœå<E280B9>Žç«¯æŽ§åˆ¶å<C2B6>?

**应该看到**�

🚀 å¼€å§çœŸå®žLLMç­é€?
  任务ID: xxx
  文献� 5
  模åžï¼ˆæ˜ å°„å<E2809E>Žï¼? [ 'deepseek-chat', 'qwen-max' ]
  PICOS-P: 2åžç³å°¿ç—…æ£è€?..
  PICOS-I: SGLT2æŠåˆ¶å‰?..
  PICOS-C: 安慰�..
  纳入标准: æˆ<C3A6>人2åžç³å°¿ç—…...
  排除标准: 综述ã€<C3A3>系统评ä»?..

[等待10-20ç§]

âœ?文献 1/5 处ç<E2809E>†æˆ<C3A6>功
  DS: include / Qwen: include
  冲çª<C3A7>: å<>?

[等待10-20ç§]

âœ?文献 2/5 处ç<E2809E>†æˆ<C3A6>功
  DS: exclude / Qwen: exclude
  冲çª<C3A7>: å<>?
...

📊 预期效果

ä¿®å¤<EFBFBD>å‰?

  • â<EFBFBD>±ï¸<EFBFBD> 1ç§å®Œæˆ?0ç¯?
  • â<EFBFBD>ˆ<C3A6>功ï¼?
  • â<EFBFBD>?筛选结果数ï¼?

ä¿®å¤<EFBFBD>å<EFBFBD>?

  • â<EFBFBD>±ï¸<EFBFBD> 50-100ç§å®Œæˆ?篇(æ¯<C3A6>篇10-20ç§ï¼‰
  • âœ?æˆ<C3A6>功ï¼?
  • âœ?筛选结果数ï¼?
  • âœ?è¯<C3A8>æ<EFBFBD>®åŒ…å<E280A6>«çœŸå®žçš„AI分æž<C3A6>
  • âœ?è¯<C3A8>æ<EFBFBD>®ä¸<C3A4>包å<E280A6>?模æŸè¯<C3A8>æ<EFBFBD>®"

🔧 修改文件

  • âœ?backend/src/modules/asl/services/screeningService.ts
    • 添加PICOS字段映射
    • 添加模åžå<EFBFBD><EFBFBD>映å°?
    • 添加æ‡çŒ®éªŒè¯<EFBFBD>
    • 增强调试日志

💡 ç»<C3A7>验教训

1. å‰<C3A5>å<EFBFBD>Žç«¯æ•°æ<C2B0>®æ ¼å¼<C3A5>一致æ€?

  • å‰<EFBFBD>端使用的展示格å¼?â‰?å<>Žç«¯APIæ ¼å¼<C3A5>
  • 需è¦<EFBFBD>åœ¨é†æˆ<EFBFBD>å±å<EFBFBD>šæ˜ å°„

2. 防御性编�

  • 使用 || æ<><C3A6>ä¾é»˜è®¤å€?
  • 验è¯<EFBFBD>必需字段
  • 兼容多ç§<EFBFBD>æ ¼å¼<EFBFBD>

3. 调试日志的é‡<C3A9>è¦<C3A8>æ€?

  • 显示映射å<EFBFBD>Žçš„值(ä¸<EFBFBD>是原å§å€¼ï¼‰
  • 输出所有关键å<EFBFBD>æ•?
  • 帮助快速定ä½<EFBFBD>é—®é¢?

🎯 å<>Žç»­ä¼˜åŒ

短期

  1. âœ?字段映射(已完æˆ<C3A6>ï¼?
  2. âœ?模åžå<E280B9><C3A5>映射(已完æˆ<C3A6>)
  3. âœ?验è¯<C3A8>必需字段(已完æˆ<C3A6>ï¼?

中期

  1. 统一å‰<EFBFBD>å<EFBFBD>Žç«¯æ•°æ<EFBFBD>®æ ¼å¼<EFBFBD>(使用 TypeScript 接å<C2A5>£ï¼?
  2. 添加数æ<EFBFBD>®æ ¼å¼<EFBFBD>验è¯<EFBFBD>中间ä»?
  3. 改è¿é”™è¯¯æ<EFBFBD><EFBFBD>示

长期

  1. 使用 tRPC æˆ?GraphQL ç¡®ä¿<C3A4>ç±»åžå®‰å…¨
  2. 自动化测试覆�
  3. Schema验è¯<EFBFBD>

**报告�*: AI Assistant
日期: 2025-11-21
版本: v1.0.0