- Implement 5 core API endpoints (create task, get progress, get results, update decision, export Excel) - Add FulltextScreeningController with Zod validation (652 lines) - Implement ExcelExporter service with 4-sheet report generation (352 lines) - Register routes under /api/v1/asl/fulltext-screening - Create 31 REST Client test cases - Add automated integration test script - Fix PDF extraction fallback mechanism in LLM12FieldsService - Update API design documentation to v3.0 - Update development plan to v1.2 - Create Day 5 development record - Clean up temporary test files
16 KiB
ASL模块开发 - 新AI交接文档
日期: 2025-11-18
当前阶段: Week 2 - 前端UI开发
阅读时间: 5分钟
🎯 项目概述
这是什么项目?
AIclinicalresearch - 医学临床研究AI平台
一个覆盖医学研究全生命周期的AI辅助平台,包括7大业务模块。当前正在开发ASL模块(AI智能文献筛选)。
系统架构(三层)
┌─────────────────────────────────────────┐
│ 业务模块层 (Business Layer) │
│ - ASL (AI智能文献) ← 当前开发中 │
│ - AIA, PKB, DC, SSA, ST, RVW │
└─────────────────────────────────────────┘
↓ 依赖
┌─────────────────────────────────────────┐
│ 能力层 (Capability Layer) │
│ - LLM Gateway (5个模型已集成) ✅ │
│ - Document Processing Engine │
│ - RAG Engine, ETL, Medical NLP │
└─────────────────────────────────────────┘
↓ 依赖
┌─────────────────────────────────────────┐
│ 平台基础设施层 (Platform Layer) │
│ 8个核心模块 - 已完成 ✅ │
│ Storage, Logging, Caching, Jobs, etc. │
└─────────────────────────────────────────┘
关键特性:
- Schema隔离: 10个独立PostgreSQL Schema
- 模块化: 每个业务模块独立开发、部署、销售
- 云原生: 优化Alibaba Cloud SAE部署
📍 当前状态(2025-11-18)
✅ Week 1 已完成(提前4天)
后端开发 (100%):
- ✅ 数据库Schema设计(4个表,asl_schema)
- ✅ 后端API框架(10个接口)
- ✅ LLM双模型筛选服务
- ✅ 三种筛选风格(宽松/标准/严格)
- ✅ JSON解析器修复(支持中文引号)
- ✅ API测试完成(7/7通过)
核心成果:
- 双模型筛选: DeepSeek-V3 + Qwen-Max并行
- 三种Prompt: 宽松/标准/严格模式
- 理由展示: 保存两个模型的完整判断理由
- 冲突检测: 只检测conclusion冲突,不检测PICO差异
⬜ Week 2 待开始(当前任务)
前端UI开发 (0%):
- ⬜ Day 1-2: 项目管理界面
- ⬜ Day 3-4: 文献导入界面
- ⬜ Day 5: 筛选结果展示
🔧 技术栈
前端
- 框架: React 18 + TypeScript
- UI库: Ant Design 5
- 路由: React Router v6
- 状态: React Query + Zustand
- 架构: Frontend-v2(模块化注册)
后端
- 框架: Fastify + TypeScript
- ORM: Prisma
- 数据库: PostgreSQL (asl_schema)
- LLM: DeepSeek-V3, Qwen-Max, GPT-4o, Claude-4.5
已完成的平台服务(可直接使用)
import { logger } from '@/common/logging'; // 日志
import { storage } from '@/common/storage'; // 存储
import { cache } from '@/common/cache'; // 缓存
import { jobQueue } from '@/common/jobs'; // 异步任务
import { prisma } from '@/config/database'; // 数据库
📂 关键目录结构
前端(待开发)
frontend-v2/src/modules/asl/
├── pages/ # 页面组件
│ ├── ProjectList/ # 项目列表页 ← Week 2 Day 1
│ ├── ProjectDetail/ # 项目详情页 ← Week 2 Day 2
│ ├── LiteratureImport/ # 文献导入页 ← Week 2 Day 3-4
│ └── ScreeningResults/ # 筛选结果页 ← Week 2 Day 5
├── components/ # 通用组件
├── hooks/ # 自定义Hooks
├── services/ # API调用
├── types/ # TypeScript类型
└── index.tsx # 模块入口
后端(已完成)✅
backend/src/modules/asl/
├── controllers/ # 控制器 ✅
├── services/ # 业务逻辑 ✅
│ └── llmScreeningService.ts # 核心筛选服务
├── routes/ # 路由 ✅
├── schemas/ # JSON Schema + Prompt生成 ✅
├── types/ # 类型定义 ✅
└── prompts/ # 三种Prompt模板 ✅
├── v1.1.0-lenient.txt # 宽松模式
├── v1.1.0-standard.txt # 标准模式
└── v1.1.0-strict.txt # 严格模式
🌟 核心功能说明
1. 双模型筛选机制
工作流程:
1. 用户上传文献(Excel)
2. 系统解析文献(标题+摘要)
3. 并行调用两个LLM模型:
- DeepSeek-V3
- Qwen-Max
4. 两个模型独立判断(include/exclude)
5. 系统检测冲突(conclusion是否一致)
6. 返回结果:
- 一致 → finalDecision = 模型结论
- 冲突 → finalDecision = pending(需人工复核)
重要: 保存两个模型的完整理由供用户查看
2. 三种筛选风格
| 风格 | 特点 | 使用场景 |
|---|---|---|
| 宽松模式 | 宁可多纳入,不错过 | 初筛阶段 |
| 标准模式 | 平衡准确率和召回率 | 常规使用 |
| 严格模式 | 宁可错杀,保证质量 | 精筛阶段 |
实现: 已在后端实现,前端需添加选择器
3. 数据模型(asl_schema)
4个核心表:
screening_projects -- 筛选项目(存PICOS、纳排标准)
literatures -- 文献条目(标题、摘要、PDF链接)
screening_results -- 筛选结果(两个模型的判断+理由)
screening_tasks -- 筛选任务(批量任务进度跟踪)
🎨 UI原型参考
位置: docs/03-业务模块/ASL-AI智能文献/03-UI设计/AI智能文献-标题摘要初筛原型.html
核心页面:
- 项目列表 - 显示所有筛选项目
- 项目详情 - PICOS标准、纳排标准、文献列表
- 文献导入 - Excel上传、预览、导入
- 筛选结果 - 显示筛选结果、两个模型的理由、冲突标记
📋 Week 2 开发任务(详细清单)
Day 1-2: 项目管理界面
任务:
- 创建项目列表页(
/asl/projects) - 创建项目按钮 + 创建项目表单
- 项目名称
- PICOS标准(5个字段)
- 纳入标准(文本域)
- 排除标准(文本域)
- 筛选风格选择(Radio: 宽松/标准/严格)⭐
- 项目列表展示(Table)
- 项目详情页(
/asl/projects/:id)
API接口(已完成):
POST /api/v1/asl/projects- 创建项目GET /api/v1/asl/projects- 获取项目列表GET /api/v1/asl/projects/:id- 获取项目详情
Day 3-4: 文献导入界面
任务:
- 文献导入页(
/asl/projects/:id/import) - Excel文件上传(Dragger)
- 文献预览(Table)
- 格式验证提示
- 确认导入按钮
- 导入进度提示
API接口(已完成):
POST /api/v1/asl/projects/:id/literatures/import-json- 导入文献GET /api/v1/asl/projects/:id/literatures- 获取文献列表
Excel格式:
必须字段: title, abstract
可选字段: pmid, authors, journal, publicationYear, doi
Day 5: 筛选结果展示 ⭐ 重点
任务:
- 筛选结果列表页(
/asl/projects/:id/results) - 结果筛选(全部/纳入/排除/待复核)
- 结果详情弹窗 ⭐ 关键
- 文献信息(标题、摘要)
- 最终决策(include/exclude/pending)
- 两个模型的完整结果:
- DeepSeek-V3:结论 + 理由 + 置信度
- Qwen-Max:结论 + 理由 + 置信度
- 冲突提示(如果两个模型不一致)
- 人工复核按钮
API接口(已完成):
GET /api/v1/asl/projects/:id/results- 获取筛选结果
响应格式:
{
literatureId: string;
title: string;
abstract: string;
finalDecision: 'include' | 'exclude' | 'pending';
// ⭐ 两个模型的详细结果
model1Result: {
modelName: 'DeepSeek-V3';
conclusion: 'exclude';
confidence: 0.92;
reason: '完整的排除理由...'; // ← 前端需显示
judgment: { P: 'match', I: 'match', C: 'mismatch', S: 'match' };
},
model2Result: {
modelName: 'Qwen-Max';
conclusion: 'include';
confidence: 0.85;
reason: '完整的纳入理由...'; // ← 前端需显示
judgment: { ... };
},
hasConflict: true; // 两个模型不一致
conflictFields: ['conclusion'];
}
🔥 Week 2 开发重点
1. 筛选风格选择器 ⭐
位置: 创建项目表单
<Form.Item label="筛选风格" name="screeningStyle">
<Radio.Group defaultValue="standard">
<Radio.Button value="lenient">
🔓 宽松模式
<Tooltip title="初筛推荐,宁可多纳入">
<QuestionCircleOutlined />
</Tooltip>
</Radio.Button>
<Radio.Button value="standard">
⚖️ 标准模式
</Radio.Button>
<Radio.Button value="strict">
🔒 严格模式
</Radio.Button>
</Radio.Group>
</Form.Item>
2. 两个模型理由展示 ⭐⭐⭐ 最重要
位置: 筛选结果详情弹窗
<Modal title="筛选详情" width={1000}>
{/* 最终决策 */}
<Alert type={finalDecision === 'pending' ? 'warning' : 'success'}>
<strong>最终决策:</strong> {finalDecision}
</Alert>
{/* 冲突提示 */}
{hasConflict && (
<Alert type="warning" showIcon style={{marginTop: 16}}>
⚠️ 两个模型判断不一致,建议人工复核
</Alert>
)}
<Divider />
{/* ⭐ 两个模型的详细结果(并排显示)*/}
<Row gutter={16}>
<Col span={12}>
<Card title="🤖 DeepSeek-V3" size="small">
<Descriptions column={1} size="small">
<Descriptions.Item label="结论">
<Tag color={model1.conclusion === 'include' ? 'green' : 'red'}>
{model1.conclusion}
</Tag>
</Descriptions.Item>
<Descriptions.Item label="置信度">
{(model1.confidence * 100).toFixed(0)}%
</Descriptions.Item>
</Descriptions>
<Divider style={{margin: '12px 0'}} />
<div>
<strong>判断理由:</strong>
<p style={{marginTop: 8, whiteSpace: 'pre-wrap'}}>
{model1.reason} {/* ⭐ 显示完整理由 */}
</p>
</div>
<Divider style={{margin: '12px 0'}} />
<Collapse ghost size="small">
<Panel header="PICO维度详情" key="1">
<Descriptions column={2} size="small">
<Descriptions.Item label="P">{model1.judgment.P}</Descriptions.Item>
<Descriptions.Item label="I">{model1.judgment.I}</Descriptions.Item>
<Descriptions.Item label="C">{model1.judgment.C}</Descriptions.Item>
<Descriptions.Item label="S">{model1.judgment.S}</Descriptions.Item>
</Descriptions>
</Panel>
</Collapse>
</Card>
</Col>
<Col span={12}>
<Card title="🤖 Qwen-Max" size="small">
{/* 同上,显示model2的结果 */}
</Card>
</Col>
</Row>
{/* 人工复核按钮 */}
<div style={{marginTop: 16, textAlign: 'center'}}>
<Button type="primary" onClick={handleManualReview}>
人工复核此文献
</Button>
</div>
</Modal>
为什么这么重要?
- 用户需要看到AI的思考过程
- 当两个模型冲突时,用户需要对比理由来做决策
- 即使人类专家也可能犯错,理由帮助验证
📚 重要文档索引
必读文档(开发前)
-
任务分解:
docs/03-业务模块/ASL-AI智能文献/04-开发计划/03-任务分解.md- Week 2详细任务清单
-
UI原型:
docs/03-业务模块/ASL-AI智能文献/03-UI设计/AI智能文献-标题摘要初筛原型.html- 界面参考
-
API设计:
docs/03-业务模块/ASL-AI智能文献/02-技术设计/02-API设计规范.md- API接口文档
参考文档(需要时查阅)
- 系统架构:
docs/00-系统总体设计/00-系统当前状态与开发指南.md - 前端模块化:
docs/00-系统总体设计/前后端模块化架构设计-V2.md - 数据库设计:
docs/03-业务模块/ASL-AI智能文献/02-技术设计/01-数据库设计.md
🚀 快速启动
1. 启动后端(已完成)
cd backend
npm run dev
# 后端运行在 http://localhost:3001
# API前缀: /api/v1/asl
2. 启动前端(待开发)
cd frontend-v2
npm run dev
# 前端运行在 http://localhost:5173
3. 测试API
# 健康检查
curl http://localhost:3001/api/v1/asl/health
# 获取项目列表
curl http://localhost:3001/api/v1/asl/projects
⚠️ 重要注意事项
1. 临时测试模式
JWT认证暂时绕过,使用默认测试用户:
const userId = requestBody.userId || 'asl-test-user-001';
生产环境需要: 实现真实的JWT认证
2. 筛选风格参数
创建项目时,记得传递筛选风格:
const projectData = {
projectName: '...',
picoCriteria: { ... },
inclusionCriteria: '...',
exclusionCriteria: '...',
screeningConfig: {
style: 'lenient', // ← 筛选风格
models: ['deepseek-chat', 'qwen-max']
}
};
3. 两个模型理由是核心功能
必须在前端显示,不能省略!
这是用户最重要的需求,帮助他们理解AI的判断逻辑。
🎯 Week 2 成功标准
功能完整性
- 用户可以创建项目(包含PICOS和筛选风格选择)
- 用户可以上传Excel文件导入文献
- 用户可以查看筛选结果列表
- 用户可以查看两个模型的详细理由 ⭐
- 用户可以识别冲突的文献
界面质量
- UI符合Ant Design规范
- 响应式布局(适配不同屏幕)
- 加载状态提示
- 错误处理友好
代码质量
- TypeScript类型完整
- 组件职责清晰
- API调用封装好
- 代码符合ESLint规范
💡 开发建议
1. 先做框架,再填内容
Day 1: 搭建页面框架 + 路由
Day 2: 实现表单和列表
Day 3-4: 文献导入功能
Day 5: 筛选结果展示(重点)
2. 组件复用
- ProjectForm.tsx(创建/编辑项目表单)
- LiteratureTable.tsx(文献列表表格)
- ScreeningResultCard.tsx(筛选结果卡片)
- ModelComparisonPanel.tsx(模型对比面板)⭐
3. 状态管理
// 使用React Query管理服务端状态
const { data: projects } = useQuery(['projects'], fetchProjects);
// 使用Zustand管理客户端状态
const useAslStore = create((set) => ({
currentProject: null,
setCurrentProject: (project) => set({ currentProject: project }),
}));
🔄 后续计划
Week 3-4: MVP完成
- 批量筛选
- 结果导出
- 测试上线
Week 5-7: Phase 2(可选)
- 智能Prompt生成模块
- 用户自定义PICOS
- AI分析边界情况
详见: docs/03-业务模块/ASL-AI智能文献/02-技术设计/07-智能Prompt生成模块开发计划.md
📞 关键联系信息
- 项目文档:
AIclinicalresearch/docs/ - 代码仓库:
AIclinicalresearch/ - 前端代码:
frontend-v2/src/modules/asl/ - 后端代码:
backend/src/modules/asl/
✅ 交接检查清单
新AI应该确认理解:
- 项目是什么(医学文献AI筛选)
- 当前状态(Week 1完成,Week 2待开始)
- 技术栈(React + Ant Design + Fastify + Prisma)
- Week 2任务(3个页面:项目管理、文献导入、结果展示)
- 核心功能(双模型筛选、三种风格、显示理由)
- 重点任务(显示两个模型的完整理由)⭐
祝新AI开发顺利! 🚀
文档版本: v1.0
创建日期: 2025-11-18
维护人: Previous AI Assistant
用途: 新AI快速上手指南