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

285 lines
6.1 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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.
# 字段映射问题修å¤<C3A5>报åŠ
**日期**: 2025-11-21
**问题**: 真实LLMç­é€‰å¤±è´¥ï¼ˆæˆ<C3A6>功ï¼?/20ï¼?
**原因**: 字段å<C2B5><C3A5>ä¸<C3A4>匹é…<C3A9>
**状�*: �已修�
---
## ðŸ”<C5B8> 问题诊断
### 症状
```
任务状� completed
进度: 20/20
æˆ<EFBFBD>功: 0 â<>?
筛选结果数: 0
```
**表现**�
- 任务瞬间完æˆ<C3A6>ï¼?秒)
- 所有æ‡çŒ®å¤„ç<E2809E>†å¤±è´?
- 没有ä¿<C3A4>存任何ç­é€‰ç»“æž?
---
## 🎯 根本原因
### 问题1: PICOS字段å<C2B5><C3A5>ä¸<C3A4>匹é…<C3A9>
**å‰<C3A5>端/æ•°æ<C2B0>®åº“æ ¼å¼?* (`TitleScreeningSettings.tsx`):
```typescript
picoCriteria: {
P: '2åžç³å°¿ç—…æ£è€?..',
I: 'SGLT2æŠåˆ¶å‰?..',
C: '安慰剂或常规治疗...',
O: '心血管结局...',
S: 'RCT'
}
```
**LLMæœ<C3A6>åŠ¡æœŸæœæ ¼å¼<C3A5>** (`llmScreeningService.ts`):
```typescript
// 实际上支æŒ<C3A6>两ç§<C3A7>æ ¼å¼<C3A5>,但优先使用短格å¼<C3A5>
picoCriteria: {
P: '...', // �
I: '...', // �
C: '...', // �
O: '...', // �
S: '...' // �
}
```
**诊断**:å‰<C3A5>端使ç”?P/I/C/O/S æ ¼å¼<C3A5>,但 `screeningService.ts` ç´æŽ¥ä¼ é€äº†æ•°æ<C2B0>®åº“çš„åŽŸå§æ ¼å¼<C3A5>,未å<C2AA>šæ˜ å°„ã€?
---
### 问题2: 模åžå<E280B9><C3A5>æ ¼å¼<C3A5>ä¸<C3A4>匹é…<C3A9>
**å‰<C3A5>端格å¼<C3A5>** (`TitleScreeningSettings.tsx`):
```typescript
models: ['DeepSeek-V3', 'Qwen-Max']
```
**LLMæœ<C3A6>åŠ¡æœŸæœæ ¼å¼<C3A5>** (`llmScreeningService.ts`):
```typescript
models: ['deepseek-chat', 'qwen-max']
```
**原因**:å‰<C3A5>端使用展示å<C2BA><C3A5>称,å<C592>Žç«¯éœ€è¦<C3A8>APIå<49><C3A5>ç§°ã€?
---
### 问题3: 缺å°å­—段验è¯<C3A8>
æ‡çŒ®å<EFBFBD>¯èƒ½ç¼ºå° `title` æˆ?`abstract`,导致LLM调用失败ã€?
---
## âœ?ä¿®å¤<C3A5>æ¹æ¡ˆ
### ä¿®å¤<C3A5>1: 添加PICOS字段映射
**文件**: `backend/src/modules/asl/services/screeningService.ts`
```typescript
// 🔧 ä¿®å¤<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
---
### ä¿®å¤<C3A5>2: 添加模åžå<E280B9><C3A5>映å°?
```typescript
// 🔧 ä¿®å¤<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);
```
**映射�*�
| å‰<C3A5>端展示å<C2BA>?| APIå<49><C3A5>ç§° |
|-----------|---------|
| DeepSeek-V3 | deepseek-chat |
| Qwen-Max | qwen-max |
| GPT-4o | gpt-4o |
| Claude-4.5 | claude-sonnet-4.5 |
---
### ä¿®å¤<C3A5>3: 添加æ‡çŒ®éªŒè¯<C3A8>
```typescript
// 🔧 验è¯<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(`âš ï¸<EFBFBD> 跳过文献 ${processedCount + 1}: ç¼ºå°æ ‡é¢˜æˆæ˜è¦<C3A8>`);
processedCount++;
continue;
}
```
---
### ä¿®å¤<C3A5>4: 增强调试日志
```typescript
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>ï¼?
```bash
# å<>œæ­¢å½“å‰<C3A5>å<EFBFBD>Žç«¯ï¼ˆCtrl+Cï¼?
cd D:\MyCursor\AIclinicalresearch\backend
npm run dev
```
### 2. æµè¯•(å°<C3A5>规模ï¼?
1. 访问å‰<C3A5>端
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>: å<>?
...
```
---
## 📊 预期效果
### ä¿®å¤<C3A5>å‰?
- â<>±ï¸<C3AF> 1ç§å®Œæˆ?0ç¯?
- â<>ˆ<C3A6>功ï¼?
- â<>?筛选结果数ï¼?
### ä¿®å¤<C3A5>å<EFBFBD>?
- â<>±ï¸<C3AF> 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字段映射
- 添加模åžå<E280B9><C3A5>映å°?
- 添加æ‡çŒ®éªŒè¯<C3A8>
- 增强调试日志
---
## 💡 ç»<C3A7>验教训
### 1. å‰<C3A5>å<EFBFBD>Žç«¯æ•°æ<C2B0>®æ ¼å¼<C3A5>一致æ€?
- å‰<C3A5>端使用的展示格å¼?â‰?å<>Žç«¯APIæ ¼å¼<C3A5>
- 需è¦<C3A8>åœ¨é†æˆ<C3A6>å±å<E2809A>šæ˜ å°„
### 2. 防御性编�
- 使用 `||` æ<><C3A6>ä¾é»˜è®¤å€?
- 验è¯<C3A8>必需字段
- 兼容多ç§<C3A7>æ ¼å¼<C3A5>
### 3. 调试日志的é‡<C3A9>è¦<C3A8>æ€?
- 显示映射å<E2809E>Žçš„值(ä¸<C3A4>是原å§å€¼ï¼‰
- 输出所有关键å<C2AE>æ•?
- 帮助快速定ä½<C3A4>é—®é¢?
---
## 🎯 å<>Žç»­ä¼˜åŒ
### 短期
1. âœ?字段映射(已完æˆ<C3A6>ï¼?
2. âœ?模åžå<E280B9><C3A5>映射(已完æˆ<C3A6>)
3. âœ?验è¯<C3A8>必需字段(已完æˆ<C3A6>ï¼?
### 中期
1. 统一å‰<C3A5>å<EFBFBD>Žç«¯æ•°æ<C2B0>®æ ¼å¼<C3A5>(使用 TypeScript 接å<C2A5>£ï¼?
2. 添加数æ<C2B0>®æ ¼å¼<C3A5>验è¯<C3A8>中间ä»?
3. 改è¿é”™è¯¯æ<C2AF><C3A6>示
### 长期
1. 使用 tRPC æˆ?GraphQL ç¡®ä¿<C3A4>ç±»åžå®‰å…¨
2. 自动化测试覆�
3. Schema验è¯<C3A8>
---
**报告�*: AI Assistant
**日期**: 2025-11-21
**版本**: v1.0.0