Files
AIclinicalresearch/docs/03-业务模块/DC-数据清洗整理/07-技术债务/Tool-B技术债务清单.md
HaHafeng 06028c6952 feat(pkb): implement complete batch processing workflow and frontend optimization
- Frontend V3 architecture migration to modules/pkb
- Implement three work modes: full-text reading, deep reading, batch processing
- Complete batch processing: template selection, progress display, result export (CSV)
- Integrate Ant Design X Chat component with streaming support
- Add document upload modal with drag-and-drop support
- Optimize UI: multi-line table display, citation formatting, auto-scroll
- Fix 10+ technical issues: API mapping, state sync, form clearing
- Update documentation: development records and module status

Performance: 3 docs batch processing ~17-28s
Status: PKB module now production-ready (90% complete)
2026-01-07 18:23:43 +08:00

481 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
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.
# Tool B - 病历结构化机器人 技术债务清单
> **创建日期:** 2025-12-03
> **状态:** 待处理
> **优先级:** P1=高优先级, P2=中优先级, P3=低优先级
---
## 📋 技术债务列表
### **[P1] #1 - Excel导出与前端显示结果不一致**
**问题描述:**
- 用户在步骤4交叉验证页面看到的提取结果与导出的Excel文件内容不一致
- 列顺序混乱,部分字段缺失或数据错位
**重现步骤:**
1. 完成双模型提取并进入步骤4
2. 点击"导出当前结果"或在步骤5点击"下载结果Excel"
3. 打开Excel对比前端显示的结果
**根本原因:**
- JavaScript对象展开`...extractedData`时顺序不固定
- 未按模板定义的字段顺序构建Excel列
**当前状态:**
- ✅ 已部分修复按targetFields顺序导出
- ❌ 仍需验证:多次导出结果是否稳定一致
**解决方案:**
1. 严格按照`task.targetFields`定义的字段顺序导出
2. 添加表头样式(加粗、冻结首行)
3. 添加数据验证(确保所有字段都存在)
4. 添加导出测试用例
**预计工时:** 2小时
**影响范围:** 后端 ExtractionController.exportResults方法
---
### **[P2] #2 - 步骤3进度条显示不够细腻**
**问题描述:**
- 当前进度条直接从0%跳到100%,缺少中间过程
- 用户无法感知大模型正在处理第几条记录
- 没有实时反馈当前处理状态(如"正在处理第3/9条"
**期望效果:**
```
提取进度: 33% (3/9条已完成)
日志输出:
[13:43:12] 正在创建提取任务...
[13:43:12] 任务创建成功 (ID: xxx)
[13:43:12] 初始化双模型引擎 (DeepSeek-V3 & Qwen-Max)...
[13:43:13] [1/9] 正在提取: 【右肺下叶】浸润性腺癌...
[13:43:18] [1/9] ✅ 提取完成 (DeepSeek: 549 tokens, Qwen: 627 tokens)
[13:43:19] [2/9] 正在提取: 【右肺上叶】浸润性腺癌...
[13:43:24] [2/9] ✅ 提取完成 (DeepSeek: 486 tokens, Qwen: 551 tokens)
...
[13:43:30] PII 脱敏完成
[13:43:30] ✅ 所有记录提取完成!
```
**解决方案:**
**后端改动:**
1.`DualModelExtractionService.batchExtract`的for循环中每处理完一条记录就更新进度
2. 添加`currentItem`字段到Task表可选用于实时显示当前处理的记录
3. 或者使用Redis存储实时进度信息更云原生
**前端改动:**
1. 轮询API时解析`processedCount``totalCount`
2. 动态生成日志:`[${processedCount}/${totalCount}] 正在提取...`
3. 进度条平滑过渡CSS transition
**预计工时:** 3小时
**影响范围:**
- 后端DualModelExtractionService.batchExtract
- 前端Step3Processing.tsx
---
### **[P1] #3 - Excel文件预处理与脏数据清洗**
**问题描述:**
医疗科研场景下Excel文件质量参差不齐存在大量脏数据导致解析失败或结果错误。
#### **子问题1表头特殊字符**
- **现象:** 列名包含换行符`\n`、空格、制表符等,导致列名匹配失败
- **示例:** `"病人ID\n(Patient ID)"` → 前端下拉框显示异常
- **影响:** 用户无法选择正确的列
#### **子问题2公式 (Formulas)**
- **现象:** 单元格包含公式`=A1+B1`xlsx库读取时返回公式文本而非计算结果
- **示例:**
- 原始值:`=SUM(A1:A10)`
- 读取结果:字符串`"=SUM(A1:A10)"`(而非数字)
- 外部引用:`=[外部文件]Sheet1!A1``#REF!`
- **影响:** 数值型字段(如年龄、血糖值)变成文本,无法统计
#### **子问题3合并单元格 (Merged Cells)**
- **现象:** 医生习惯合并"住院号"列,对应多行化验记录
- **示例:**
```
住院号 检查项目 结果
H001 血常规 正常 ← 只有这行有住院号
(合并) 肝功能 异常 ← 这行住院号为null
(合并) 肾功能 正常 ← 这行住院号为null
```
- **影响:** 后续行的关联字段丢失,无法追溯到患者
#### **子问题4日期地狱 (Date Parsing Hell)**
- **现象:** Excel日期存储为数字Serial Number或多种文本格式
- **示例:**
- `44927` → 应该解析为 `2023-01-01`
- `2023.1.1`(文本)
- `2023年1月1日`(中文)
- `Jan 1, 2023`(英文)
- **影响:** 日期字段无法排序、筛选、统计
#### **子问题5不可见字符与脏文本 (Ghost Characters)**
- **现象:** 看起来是"男",实际包含不可见字符
- **示例:**
- `"男 "` (尾部空格)
- `"男\u200b"` (零宽空格 Zero-Width Space)
- `"男\ufeff"` (BOM字符)
- **影响:** 条件判断失败:`if (sex === '男')` → false
- **医学场景特例:**
- 化验单复制粘贴时带入富文本格式
- 不同医院HIS系统导出编码不统一
**解决方案:**
#### **架构设计独立的Excel预处理服务**
```typescript
// backend/src/modules/dc/services/ExcelPreprocessor.ts
export class ExcelPreprocessor {
/**
* 清洗表头
*/
cleanHeaders(headers: string[]): string[] {
return headers.map(h => h
.replace(/[\n\r\t]/g, ' ') // 移除换行、制表符
.trim() // 去除首尾空格
.replace(/\s+/g, ' ') // 多个空格合并为一个
);
}
/**
* 处理公式单元格
*/
processFormulas(worksheet: xlsx.WorkSheet): void {
// 使用 xlsx 的 { cellFormula: false } 选项
// 或手动遍历单元格,计算公式结果
}
/**
* 展开合并单元格
*/
unflattenMergedCells(worksheet: xlsx.WorkSheet): void {
// 1. 找到所有合并区域 worksheet['!merges']
// 2. 将主单元格的值填充到所有子单元格
}
/**
* 统一日期格式
*/
normalizeDates(value: any): string | null {
if (typeof value === 'number') {
// Excel Serial Number → ISO Date
return this.excelSerialToDate(value);
}
if (typeof value === 'string') {
// 尝试多种格式解析
return this.parseChineseDate(value) ||
this.parseSlashDate(value) ||
this.parseDotDate(value);
}
return null;
}
/**
* 清除不可见字符
*/
cleanInvisibleChars(text: string): string {
return text
.replace(/\u200b/g, '') // 零宽空格
.replace(/\ufeff/g, '') // BOM
.replace(/\u00a0/g, ' ') // 不间断空格 → 普通空格
.trim();
}
}
```
#### **使用位置:**
1. **uploadFile API** - 上传后立即预处理,返回清洗后的列名
2. **healthCheck API** - 使用清洗后的数据进行检查
3. **createTask API** - 使用清洗后的数据创建items
**预计工时:** 16小时复杂度高需要大量测试
**影响范围:**
- 新增:`ExcelPreprocessor.ts` (~400行)
- 修改:`ExtractionController.ts` 的文件处理逻辑
- 测试:覆盖各种脏数据场景
**依赖:**
- xlsx库的高级功能cellFormula、!merges等
- dayjs或date-fns日期解析
---
### **[P2] #4 - 支持用户自定义提取模板**
**问题描述:**
当前系统只支持3个预设模板肺癌病理、糖尿病入院、高血压门诊无法满足用户的多样化需求。
**需求场景:**
1. 科研人员研究罕见病(如:系统性红斑狼疮、重症肌无力)
2. 需要提取的字段与预设模板不同
3. 每个研究项目的数据规范可能不同
**期望功能:**
#### **1. 前端:自定义模板编辑器**
```
步骤2.1:选择模板来源
- [ ] 使用系统预设模板
- [x] 创建自定义模板
步骤2.2:定义模板信息
- 模板名称:[我的肺癌研究模板]
- 疾病类型:[自定义:系统性红斑狼疮]
- 报告类型:[自定义:实验室检查]
步骤2.3:定义提取字段(可视化编辑)
┌─────────────────────────────────────┐
│ 字段1: [抗核抗体滴度] │
│ 描述: [如 1:320, 1:640] │
│ 宽度: [w-32] ▼ │
│ [ 删除 ] │
├─────────────────────────────────────┤
│ 字段2: [补体C3] │
│ 描述: [单位g/L] │
│ [ 删除 ] │
└─────────────────────────────────────┘
[+ 添加字段]
步骤2.4AI生成Prompt自动化
[ 🤖 让AI帮我生成提示词 ]
后台自动生成:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
你是一名风湿免疫科专家。请从以下系统性红斑狼疮
患者的实验室检查报告中提取关键信息。
提取字段(必须返回以下所有字段):
- 抗核抗体滴度:如 1:320, 1:640
- 补体C3单位g/L
**输出格式严格的JSON格式**
```json
{
"抗核抗体滴度": "...",
"补体C3": "..."
}
```
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[ 编辑Prompt ] [ 预览效果 ] [ 保存模板 ]
```
#### **2. 后端模板管理API**
```typescript
// 新增API端点
POST /api/v1/dc/tool-b/templates // 创建自定义模板
PUT /api/v1/dc/tool-b/templates/:id // 更新模板
DELETE /api/v1/dc/tool-b/templates/:id // 删除模板
GET /api/v1/dc/tool-b/templates/:id // 获取模板详情
// Prompt自动生成服务
POST /api/v1/dc/tool-b/templates/generate-prompt
Request:
{
"diseaseType": "系统性红斑狼疮",
"reportType": "实验室检查",
"fields": [
{ "name": "抗核抗体滴度", "desc": "如 1:320, 1:640" },
{ "name": "补体C3", "desc": "单位g/L" }
]
}
Response:
{
"promptTemplate": "你是一名风湿免疫科专家...",
"estimatedTokens": 450
}
```
#### **3. AI Prompt生成逻辑**
```typescript
// 使用元PromptMeta-Prompt
async generatePrompt(
diseaseType: string,
reportType: string,
fields: { name: string; desc: string }[]
): Promise<string> {
const metaPrompt = `
你是一名医学AI Prompt工程师。请为病历结构化提取任务生成专业的提示词。
任务背景:
- 疾病类型:${diseaseType}
- 报告类型:${reportType}
提取字段:
${fields.map((f, i) => `${i + 1}. ${f.name}${f.desc}`).join('\n')}
要求:
1. 模拟该疾病领域的专家角色
2. 清晰说明每个字段的提取规则
3. 要求输出严格的JSON格式
4. 处理"未提及"的情况
请生成完整的Prompt。`;
// 调用GPT-5或Claude生成Prompt
const llm = LLMFactory.getAdapter('gpt-5');
const response = await llm.chat([
{ role: 'user', content: metaPrompt }
]);
return response.content;
}
```
**技术亮点:**
- ✨ **Prompt即代码Prompt-as-Code**模板可版本控制、A/B测试
- ✨ **AI生成AI的PromptMeta-Prompt**:降低用户门槛
- ✨ **模板市场(未来)**:用户可分享、下载优质模板
**预计工时:** 12小时
**影响范围:**
- 新增:`CustomTemplateService.ts` (~300行)
- 新增:`PromptGeneratorService.ts` (~200行)
- 前端Step2Schema.tsx 新增自定义模板编辑UI
- 数据库DCTemplate表已支持无需改动
---
## 📊 优先级评估
| 债务ID | 问题 | 优先级 | 工时 | 影响用户 | 技术风险 |
|--------|------|--------|------|----------|----------|
| #1 | Excel导出不一致 | P1 | 2h | 高(核心功能) | 低 |
| #2 | 进度条显示优化 | P2 | 3h | 中(体验优化) | 低 |
| #3 | Excel预处理 | P1 | 16h | 高(数据质量) | 中 |
| #4 | 自定义模板 | P2 | 12h | 中(扩展性) | 中 |
**总计:** 33小时约4个工作日
---
## 🎯 建议处理顺序
### **Sprint 1核心功能修复P1优先**
1. ✅ #1 - Excel导出修复2小时→ **立即处理**
2. #3 - Excel预处理16小时→ **分阶段实现**
- Phase 1表头清洗2小时
- Phase 2合并单元格展开4小时
- Phase 3公式处理3小时
- Phase 4日期统一3小时
- Phase 5不可见字符清理2小时
- Phase 6集成测试2小时
### **Sprint 2体验优化P2**
1. #2 - 进度条优化3小时
2. #4 - 自定义模板12小时
- Phase 1后端模板CRUD4小时
- Phase 2Prompt自动生成4小时
- Phase 3前端模板编辑器4小时
---
## 💡 长期优化建议
### **1. 数据质量评分系统**
为上传的Excel文件打分0-100分
- ✅ 90-100优质数据直接处理
- ⚠️ 60-89一般质量提示可能问题
- ❌ 0-59低质量强制要求用户清洗后再上传
### **2. Excel模板标准化**
提供标准Excel模板下载用户按模板填写减少脏数据
```
病历结构化标准模板 v1.0.xlsx
- 表头行冻结
- 数据验证(下拉框)
- 字段说明(批注)
- 示例数据
```
### **3. 智能修复建议**
检测到问题时AI给出修复建议
```
⚠️ 检测到22个合并单元格可能导致数据丢失
建议操作:
[ 自动展开合并单元格 ] [ 忽略并继续 ]
```
---
## 📝 开发记录
| 日期 | 处理内容 | 状态 | 备注 |
|------|---------|------|------|
| 2025-12-03 | 创建技术债务文档 | ✅ | 初始记录4个问题 |
| 2025-12-03 | #1 Excel导出顺序修复 | 🔄 | 已修改代码,待验证 |
| - | #2 进度条优化 | ⏸️ | 待开发 |
| - | #3 Excel预处理 | ⏸️ | 待开发 |
| - | #4 自定义模板 | ⏸️ | 待开发 |
---
## 🔗 相关文档
- [技术设计文档:工具 B](../02-技术设计/技术设计文档:工具%20B%20-%20病历结构化机器人%20(The%20AI%20Structurer).md)
- [API设计文档](../02-技术设计/API设计文档-DC模块完整版.md)
- [开发计划](../04-开发计划/DC模块Tool-B开发计划.md)
- [云原生开发规范](../../../04-开发规范/08-云原生开发规范.md)
---
**文档维护:** 每次处理技术债务时更新此文档