Completed: - Unifuncs DeepSearch API site coverage test (18 medical sites, 9 tier-1 available) - ClinicalTrials.gov dedicated test (4 strategies, English query + depth>=10 works best) - Deep Research V2.0 development plan (5-day phased delivery) - DeepResearch engine capability guide (docs/02-common-capability/) - Test scripts: test-unifuncs-site-coverage.ts, test-unifuncs-clinicaltrials.ts Key findings: - Tier-1 sites: PubMed(28), ClinicalTrials(38), NCBI(18), Scholar(10), Cochrane(4), CNKI(7), SinoMed(9), GeenMedical(5), VIP(1) - Paid databases (WoS/Embase/Scopus/Ovid) cannot be accessed (no credential support) - ClinicalTrials.gov requires English queries with max_depth>=10 Updated: ASL module status doc, system status doc, common capability list Co-authored-by: Cursor <cursoragent@cursor.com>
41 KiB
AI智能文献模块 - 当前状态与开发指南
文档版本: v1.6
创建日期: 2025-11-21
维护者: AI智能文献开发团队
最后更新: 2026-02-22 🆕 Deep Research V2.0 开发计划确认 + Unifuncs API 网站覆盖测试完成
重大进展:
- 🆕 2026-02-22:V2.0 开发计划确认!四步瀑布流 + 异步模式 + HITL 需求确认 + 务实结果展示
- 🆕 2026-02-22:Unifuncs API 网站覆盖测试完成!18 站点实测,9 个一级可用,ClinicalTrials.gov 专项验证通过
- 2026-01-18:智能文献检索(DeepSearch)MVP完成 - unifuncs API 集成
文档目的: 反映模块真实状态,帮助新开发人员快速上手
📋 文档说明
本文档是AI智能文献(ASL)模块的真实状态快照,记录实际的代码结构、已实现功能、技术栈和开发规范。
与其他文档的关系:
- 本文档(00-模块当前状态):What is(真实状态)
- 开发计划文档:What to do(计划)
- 开发记录文档:What done(历史)
- 技术设计文档:How to do(设计)
🎯 模块概述
核心功能
AI智能文献模块是一个基于大语言模型(LLM)的文献筛选系统,用于帮助研究人员根据PICOS标准自动筛选文献。
当前状态
- 开发阶段:🚧 V1.x 完成,V2.0 Deep Research 开发计划已确认,即将启动
- 已完成功能:
- ✅ 标题摘要初筛(Title & Abstract Screening)- 完整流程
- ✅ 全文复筛后端(Day 2-5)- LLM服务 + API + Excel导出
- ✅ 智能文献检索(DeepSearch)V1.x MVP - unifuncs API 集成,SSE 实时流式
- ✅ Unifuncs API 网站覆盖测试 - 18 站点实测,9 个一级可用
- ✅ Deep Research V2.0 开发计划 - 完整技术方案、API 契约、5 天分阶段计划
- V2.0 开发中:
- 🚧 Deep Research V2.0 — 四步瀑布流(Landing→配置→HITL→终端→结果)
- 🚧 异步模式改造(SSE → Unifuncs create_task/query_task)
- 🚧 需求扩写 + HITL 确认 + Agent 终端 + 简洁结果展示 + Word 导出
- 模型支持:DeepSeek-V3(需求扩写) + unifuncs s2(深度搜索) + Qwen-Max(筛选)
- 部署状态:✅ 本地开发环境运行正常
🆕 Deep Research V2.0(2026-02-22 开发计划确认)
V2.0 核心升级:
- 四步瀑布流:Landing → 配置 → HITL 策略确认 → Agent 终端 → 结果展示
- LLM 需求扩写(DeepSeek-V3):粗略输入 → 结构化自然语言检索指令书
- Human-in-the-Loop:用户可编辑修改 AI 生成的检索需求
- 异步模式:SSE → Unifuncs create_task/query_task + pg-boss 队列(离开页面不中断)
- Agent 终端:暗色主题 + 分类结构化日志(每 3-5s 弹出一条)
- 简洁结果展示:AI 综合报告(Markdown)+ 文献清单表格 + Word 导出
- 多站点搜索:9 个一级可用站点,用户可在前端选择数据源
V2.0 确认可用数据源(2026-02-22 实测):
| 站点 | 站内链接数 | 说明 |
|---|---|---|
| PubMed | 28 | 核心数据源,效果最佳 |
| ClinicalTrials.gov | 38 | 必须英文查询,max_depth≥10 |
| NCBI/PMC | 18 | 含 PMC 全文链接 |
| Google Scholar | 10 | 跨库聚合 |
| CBM/SinoMed | 9 | 中文生物医学 |
| CNKI | 7 | 中文核心期刊 |
| GeenMedical | 5 | 医学搜索引擎 |
| Cochrane Library | 4 | 系统综述金标准 |
| 维普 | 1 | 中文库 |
开发计划:5 天分阶段交付,详见 04-开发计划/07-Deep Research V2.0 开发计划.md
通用能力指南:docs/02-通用能力层/04-DeepResearch引擎/01-Unifuncs DeepSearch API 使用指南.md
智能文献检索 DeepSearch V1.x(2026-01-18 MVP完成)
功能概述:
- AI 驱动的自动化 PubMed 文献检索
- 自然语言输入研究问题,AI 自动生成检索策略
- 实时显示 AI 思考过程和检索进展
- 提取并展示 PubMed 文献链接
技术实现:
- 集成 unifuncs DeepSearch API(OpenAI 兼容协议)
- Server-Sent Events (SSE) 实时流式通信
- 数据库存储:
asl_schema.asl_research_tasks
API 端点(V1.x,保留兼容):
POST /api/v1/asl/research/stream- SSE 流式检索POST /api/v1/asl/research/tasks- 异步任务创建GET /api/v1/asl/research/tasks/:taskId/status- 任务状态查询
已知限制(V2.0 将解决):
- ⚠️ SSE 模式,离开页面任务中断 → V2.0 用异步模式解决
- ⚠️ 仅搜索 PubMed → V2.0 支持 9 个数据源
- ⏳ 无需求扩写、无 HITL → V2.0 新增
🏆 Postgres-Only 架构改造(2025-12-13完成)
改造目标:
- 支持2-24小时的长时间任务(1000篇文献筛选)
- 实例重启后任务可恢复(断点续传)
- 零额外成本(使用 Postgres,不需要 Redis)
核心实现:
-
智能双模式处理 🎯
- 阈值:50篇文献
- 小任务(<50篇):直接处理,快速响应(<1分钟)
- 大任务(≥50篇):队列处理,可靠性高(支持断点续传)
-
任务拆分机制 📦
- 100篇 → 2个批次(每批50篇)
- 1000篇 → 20个批次(每批50篇)
- 自动推荐批次大小
-
断点续传机制 🔄
- 每10篇文献保存一次断点
- 断点数据存储在
platform_schema.job.data(pg-boss) - 实例重启后自动从上次位置继续
-
Platform层统一管理 🏗️
- 任务管理信息不存储在
asl_schema.screening_tasks - 统一存储在
platform_schema.job.data(JSONB) - 使用
CheckpointService操作 job.data(所有模块通用)
- 任务管理信息不存储在
改造文件:
screeningService.ts:添加智能阈值判断,推送批次任务到 pg-bossscreeningWorker.ts:批次处理逻辑,断点续传实现CheckpointService.ts:操作 job.data,不依赖业务表
测试验证:
- ✅ 小任务(7篇)- 直接模式测试通过
- ✅ 大任务(100篇)- 队列模式测试通过
- ✅ 任务拆分逻辑验证通过
- ✅ Platform-Only 架构验证通过
技术债务:
- ⚠️ Phase 8 全面测试(断点续传压力测试、1000篇文献完整流程)
- ⚠️ Phase 9 SAE 部署验证
关键里程碑
标题摘要初筛(已完成):
- ✅ 2025-11-18:Prompt v1.0.0-MVP完成,准确率60%
- ✅ 2025-11-18:LLM集成与测试框架完成
- ✅ 2025-11-19:前端MVP(设置与启动、审核工作台)完成
- ✅ 2025-11-21:真实LLM集成完成(替换Mock数据)
- ✅ 2025-11-21:用户体验优化(进度显示、列表排序)
- ✅ 2025-11-21:Week 4完成(结果展示与导出功能)
- 统计概览与PRISMA排除分析
- 初筛结果页面(混合方案)
- Excel批量导出(云原生)
全文复筛(后端已完成,待前端开发):
- ✅ 2025-11-22:Day 2-3完成(LLM服务与验证系统)
- 提示词工程体系(System/User Prompt + JSON Schema)
- PromptBuilder服务(动态Prompt组装)
- LLM12FieldsService(Nougat优先 + 双模型 + 3层JSON解析)
- 医学逻辑验证器(5条规则)
- 证据链验证器(引用完整性)
- 冲突检测服务(双模型对比)
- 集成测试与容错优化
- ✅ 2025-11-23:Day 4上午完成(数据库设计与迁移)
- 数据库Schema设计(云原生架构)
- 修改 literatures 表(+13个全文字段)
- 创建 fulltext_screening_tasks 表
- 创建 fulltext_screening_results 表
- 手动SQL迁移脚本(安全执行,不影响其他模块)
- 数据库迁移状态文档(详细记录Schema隔离情况)
- ✅ 2025-11-23:Day 4下午完成(批处理服务)
- FulltextScreeningService(批量处理逻辑,716行)
- 异步任务管理(后台处理LLM调用)
- 并发控制(p-queue)
- 进度跟踪和错误处理
- ✅ 2025-11-23:Day 5完成(后端API开发)
- FulltextScreeningController(5个核心API,652行)
- ExcelExporter服务(4-Sheet报告生成,352行)
- Zod参数验证
- 路由注册(/api/v1/asl/fulltext-screening)
- 31个REST Client测试用例
- API文档更新到v3.0
- PDF提取fallback机制
- 🚧 2025-11-24:Day 6-8待开发(前端UI)
- 4个核心页面(设置、进度、工作台、结果)
- PDF上传和预览功能
- 双模型判断对比UI
- 实时进度监控(轮询机制)
- 详细前端开发计划已制定
🏗️ 技术架构
技术栈
前端
框架: React 18 + TypeScript 5
路由: React Router DOM v6
状态管理: @tanstack/react-query (React Query v5)
UI组件: Ant Design v5
样式: TailwindCSS v3
构建工具: Vite v5
后端
框架: Fastify v4 (Node.js 22)
数据库: PostgreSQL 16 + Prisma 5
LLM SDK: 自研 LLMFactory (统一适配层)
模型: DeepSeek-V3, Qwen-Max, GPT-4o, Claude-4.5
日志: Winston
基础设施
数据库: PostgreSQL 16 with Schema isolation
Schema: asl_schema (独立隔离)
用户表: platform_schema.users (共享)
📂 真实代码结构
前端代码结构
frontend-v2/src/modules/asl/
├── api/
│ └── index.ts # API客户端(所有后端调用)
├── components/
│ ├── ASLLayout.tsx # 左侧导航布局
│ ├── JudgmentBadge.tsx # PICOS判断Badge
│ ├── ConclusionTag.tsx # 结论Tag(纳入/排除)
│ └── DetailReviewDrawer.tsx # 详情+复核统一Drawer
├── hooks/
│ ├── useScreeningTask.ts # 任务进度轮询Hook
│ └── useScreeningResults.ts # 筛选结果查询Hook
├── pages/
│ ├── TitleScreeningSettings.tsx # 设置与启动页面
│ ├── ScreeningWorkbench.tsx # 审核工作台页面
│ └── ScreeningResults.tsx # 初筛结果页面(占位)
├── types/
│ └── index.ts # TypeScript类型定义
├── utils/
│ ├── excelUtils.ts # Excel导入/导出工具
│ └── tableTransform.ts # 表格数据转换(双行)
└── index.tsx # 模块入口(路由配置)
后端代码结构
backend/src/modules/asl/
├── controllers/
│ ├── projectController.ts # 项目管理API
│ ├── literatureController.ts # 文献管理API
│ └── screeningController.ts # 筛选相关API(标题摘要初筛)
├── services/
│ ├── screeningService.ts # 筛选任务服务(核心)
│ └── llmScreeningService.ts # LLM调用服务(标题摘要初筛)
├── schemas/
│ └── screening.schema.ts # Prompt生成与JSON Schema(标题摘要初筛)
├── types/
│ └── index.ts # TypeScript类型定义
├── routes/
│ └── index.ts # 路由注册
│
├── common/ # ✅ 全文复筛通用能力层(NEW)
│ ├── pdf/ # PDF存储与提取
│ │ ├── types.ts
│ │ ├── PDFStorageService.ts
│ │ ├── PDFStorageFactory.ts
│ │ ├── adapters/
│ │ │ ├── DifyPDFStorageAdapter.ts
│ │ │ └── OSSPDFStorageAdapter.ts
│ │ └── __tests__/
│ ├── llm/ # LLM 12字段服务(核心)
│ │ ├── types.ts
│ │ ├── PromptBuilder.ts # 动态Prompt组装
│ │ ├── LLM12FieldsService.ts # Nougat+双模型+3层JSON解析
│ │ ├── index.ts
│ │ └── __tests__/
│ │ ├── integration-test.ts # 完整集成测试
│ │ ├── quick-test.ts # 快速测试(1篇PDF)
│ │ └── cached-result-test.ts # 容错验证测试
│ ├── validation/ # 验证服务
│ │ ├── MedicalLogicValidator.ts # 医学逻辑验证(5条规则)
│ │ ├── EvidenceChainValidator.ts # 证据链验证
│ │ ├── ConflictDetectionService.ts # 冲突检测
│ │ ├── index.ts
│ │ └── __tests__/
│ │ └── validation-test.ts
│ ├── utils/
│ │ └── tokenCalculator.ts # Token计算与成本估算
│ └── index.ts
│
└── fulltext-screening/ # ✅ 全文复筛模块(NEW)
├── controllers/
│ └── FulltextScreeningController.ts # 5个核心API(652行)
├── services/
│ ├── FulltextScreeningService.ts # 批处理服务(716行)
│ └── ExcelExporter.ts # Excel导出服务(352行)
├── routes/
│ └── fulltext-screening.ts # 路由注册(73行)
├── prompts/ # 提示词体系
│ ├── system_prompt.md # System Prompt(6601字符)
│ ├── user_prompt_template.md # User Prompt模板(199行)
│ ├── json_schema.json # JSON Schema(12字段约束)
│ └── cochrane_standards/ # Cochrane标准(MVP暂不加载)
│ ├── 随机化方法.md
│ ├── 盲法.md
│ └── 结果完整性.md
└── __tests__/ # 测试文件
├── fulltext-screening-api.http # REST Client测试(31个用例)
├── api-integration-test.ts # 自动化集成测试
├── e2e-real-test.ts # 端到端测试(真实PDF)
└── e2e-real-test-v2.ts # 端到端测试(简化版)
backend/prisma/
└── schema.prisma # 数据库Schema定义
backend/prompts/asl/screening/
├── v1.0.0-mvp.txt # 标准Prompt(标题摘要初筛)
├── v1.1.0-lenient.txt # 宽松模式
└── v1.1.0-strict.txt # 严格模式
backend/scripts/
└── test-llm-screening.ts # LLM测试脚本(标题摘要初筛)
🔌 API端点(真实)
基础URL
开发环境: http://localhost:3001/api/v1/asl
项目管理
POST /projects # 创建项目
GET /projects # 获取项目列表
GET /projects/:projectId # 获取项目详情
文献管理
POST /literatures/import # 导入文献(JSON格式)
POST /literatures/import/excel # 导入Excel文献
GET /projects/:projectId/literatures # 获取文献列表
DELETE /literatures/:literatureId # 删除文献
筛选相关(标题摘要初筛)
GET /projects/:projectId/screening-task # 获取任务进度
GET /projects/:projectId/screening-results # 获取筛选结果
GET /screening-results/:resultId # 获取结果详情
POST /screening-results/:resultId/review # 提交人工复核
全文复筛(NEW - Day 5)
POST /fulltext-screening/tasks # 创建全文复筛任务
GET /fulltext-screening/tasks/:taskId/progress # 获取任务进度
GET /fulltext-screening/tasks/:taskId/results # 获取任务结果
PUT /fulltext-screening/results/:resultId/decision # 更新人工决策
GET /fulltext-screening/tasks/:taskId/export # 导出Excel报告
关键参数说明
创建项目
{
projectName: string;
picoCriteria: {
P: string; // 人群
I: string; // 干预
C: string; // 对照
O: string; // 结局
S: string; // 研究设计
};
inclusionCriteria: string;
exclusionCriteria: string;
screeningConfig?: {
models: ['DeepSeek-V3', 'Qwen-Max'];
style: 'standard' | 'lenient' | 'strict';
};
}
获取筛选结果
Query参数:
- page: 页码(默认1)
- pageSize: 每页数量(默认50)
- filter: all | conflict | included | excluded | reviewed
🗄️ 数据库结构(真实)
Schema: asl_schema
1. screening_projects(筛选项目)
主键: id (UUID)
外键: user_id → platform_schema.users(id)
关键字段:
- project_name: 项目名称
- pico_criteria: JSONB(格式:{P, I, C, O, S})
- inclusion_criteria: TEXT
- exclusion_criteria: TEXT
- screening_config: JSONB(格式:{models, style})
- status: 'draft' | 'screening' | 'completed'
索引: user_id, status
2. literatures(文献)✨ 已扩展
主键: id (UUID)
外键: project_id → screening_projects(id) CASCADE
标题摘要字段:
- title: TEXT(必需)
- abstract: TEXT(必需)
- authors, journal, publication_year, pmid, doi
全文复筛字段(2025-11-23新增):
- stage: TEXT(生命周期:imported/title_screened/fulltext_pending/fulltext_screened)
- has_pdf: BOOLEAN(是否有PDF)
- pdf_storage_type, pdf_storage_ref, pdf_status, pdf_uploaded_at(PDF管理)
- full_text_storage_type, full_text_storage_ref, full_text_url(云原生存储)
- full_text_format, full_text_source, full_text_token_count(全文元数据)
索引: project_id, pmid, doi, stage, has_pdf, pdf_status
唯一约束: (project_id, pmid), (project_id, doi)
3. screening_tasks(标题摘要筛选任务)
主键: id (UUID)
外键: project_id → screening_projects(id) CASCADE
关键字段:
- status: 'pending' | 'running' | 'completed' | 'failed'
- total_items, processed_items, success_items, conflict_items
- started_at, completed_at
索引: project_id, status
4. screening_results(标题摘要筛选结果)
主键: id (UUID)
外键:
- project_id → screening_projects(id) CASCADE
- literature_id → literatures(id) CASCADE
关键字段:
DeepSeek结果:
- ds_*_judgment: 'match' | 'partial' | 'mismatch'
- ds_*_evidence: TEXT(P/I/C/S的证据)
- ds_conclusion: 'include' | 'exclude' | 'uncertain'
- ds_confidence: FLOAT(0-1)
- ds_reason: TEXT
Qwen结果: 同上(qwen_*)
冲突检测:
- conflict_status: 'none' | 'conflict' | 'resolved'
- conflict_fields: JSONB
人工复核:
- final_decision: 'include' | 'exclude' | NULL
- final_decision_by: 用户ID
- final_decision_at: TIMESTAMP
- exclusion_reason: TEXT
索引: project_id, literature_id, conflict_status, final_decision
唯一约束: (project_id, literature_id)
5. fulltext_screening_tasks(全文复筛任务)✨ 新建
主键: id (UUID)
外键: project_id → screening_projects(id) CASCADE
关键字段:
- model_a, model_b: TEXT(双模型名称)
- prompt_version: TEXT(Prompt版本)
- status: 'pending' | 'running' | 'completed' | 'failed'
- total_count, processed_count, success_count, failed_count, degraded_count
- total_tokens, total_cost: 成本统计
- started_at, completed_at, estimated_end_at
- error_message, error_stack
索引: project_id, status, created_at
6. fulltext_screening_results(全文复筛结果)✨ 新建
主键: id (UUID)
外键:
- task_id → fulltext_screening_tasks(id) CASCADE
- project_id → screening_projects(id) CASCADE
- literature_id → literatures(id) CASCADE
关键字段:
Model A (DeepSeek-V3) 结果:
- model_a_name, model_a_status, model_a_fields (JSONB)
- model_a_overall, model_a_processing_log, model_a_verification (JSONB)
- model_a_tokens, model_a_cost, model_a_error
Model B (Qwen-Max) 结果: 同上(model_b_*)
验证结果:
- medical_logic_issues (JSONB): 医学逻辑验证
- evidence_chain_issues (JSONB): 证据链验证
冲突检测:
- is_conflict, conflict_severity, conflict_fields, conflict_details (JSONB)
- review_priority (0-100), review_deadline
人工复核:
- final_decision: 'include' | 'exclude' | NULL
- final_decision_by, final_decision_at
- exclusion_reason, review_notes
处理状态:
- processing_status, is_degraded, degraded_model
可追溯性:
- raw_output_a (JSONB), raw_output_b (JSONB), prompt_version
索引: task_id, project_id, literature_id, is_conflict, final_decision, review_priority
唯一约束: (project_id, literature_id)
数据库Schema隔离状态
✅ 完全正确:
- 所有ASL表都在
asl_schema中 - 无数据泄漏到
publicschema - Schema隔离策略执行严格
- 详见:数据库迁移状态说明
📊 数据流程(真实)
标题摘要初筛流程
用户上传Excel
↓
解析并导入到 literatures 表
↓
创建 screening_task
↓
后台异步处理:
- 双模型并行调用(DeepSeek + Qwen)
- 保存到 screening_results
- 冲突检测
- 更新任务进度
↓
前端轮询任务状态
↓
用户审阅结果,提交人工复核
↓
导出Excel(前端生成或后端OSS)
全文复筛流程(设计中)
用户上传PDF(批量)
↓
PDF提取服务(Nougat优先,PyMuPDF降级)
↓
更新 literatures 表(全文引用字段)
↓
创建 fulltext_screening_task
↓
后台异步批处理:
- 双模型并行调用(DeepSeek + Qwen)
- 12字段结构化提取
- 医学逻辑验证 + 证据链验证
- 冲突检测(字段级对比)
- 保存到 fulltext_screening_results
- 更新任务进度
↓
前端展示结果(双视图审阅)
↓
用户复核冲突项,提交最终决策
↓
导出Excel(12字段详细报告)
- total_items: INT
- processed_items: INT
- success_items: INT
- conflict_items: INT
- failed_items: INT
- started_at, completed_at: TIMESTAMP
索引: project_id, status
🤖 LLM集成(真实实现)
LLM调用流程
前端: 点击"开始AI初筛"
↓
后端: literatureController.importLiteratures()
↓
后端: screeningService.startScreeningTask()
↓
后端: screeningService.processLiteraturesInBackground()
↓ (for each literature)
后端: llmScreeningService.dualModelScreening()
↓
后端: LLMFactory.getAdapter(model).chat()
↓
真实API: DeepSeek API / Qwen API
↓
后端: JSON解析 + Schema验证
↓
后端: 保存到 screening_results 表
↓
后端: 更新 screening_tasks 进度
↓
前端: useScreeningTask 轮询(1秒/次)
↓
前端: 显示进度条和结果
字段映射关系
PICOS字段
// 前端/数据库格式
picoCriteria: { P, I, C, O, S }
// LLM服务兼容格式
picoCriteria: {
P || population,
I || intervention,
C || comparison,
O || outcome,
S || studyDesign
}
// 映射位置: screeningService.ts (Line 82-92)
模型名称
// 前端展示名 → API名称
const MODEL_NAME_MAP = {
'DeepSeek-V3': 'deepseek-chat',
'Qwen-Max': 'qwen-max',
'GPT-4o': 'gpt-4o',
'Claude-4.5': 'claude-sonnet-4.5',
};
// 映射位置: screeningService.ts (Line 97-110)
LLM配置
模型参数
{
temperature: 0, // 固定,确保结果一致性
top_p: 1.0,
max_tokens: 2048,
}
Prompt版本
当前使用: v1.0.0-mvp.txt
位置: backend/prompts/asl/screening/v1.0.0-mvp.txt
准确率: 60%(首次测试)
一致率: 70-100%
处理性能
单篇文献耗时: 10-20秒(DeepSeek + Qwen并行)
5篇文献: 约50-100秒
199篇文献: 约33-66分钟(串行处理)
进度更新: 每1条更新数据库
前端轮询: 1秒/次
✅ 已完成功能
1. 标题摘要初筛 - 设置与启动 ⭐
功能清单
- ✅ PICOS标准录入(P/I/C/O/S两栏布局)
- ✅ 纳入/排除标准录入(侧边对称布局)
- ✅ Excel模板下载(包含字段说明)
- ✅ Excel文件上传
- ✅ Excel解析(内存中,支持中英文表头)
- ✅ 文献去重(DOI优先,标题辅助)
- ✅ 文献预览表格(固定列宽,Tooltip显示全文)
- ✅ 启动AI初筛按钮
- ✅ 自动跳转到审核工作台
关键代码
// 文件: frontend-v2/src/modules/asl/pages/TitleScreeningSettings.tsx
// 核心功能: PICOS表单 + Excel上传 + 文献预览 + 提交
// Excel处理
import { downloadExcelTemplate, processExcelFile } from '../utils/excelUtils';
// API调用
const projectResponse = await aslApi.createProject({ ... });
const importResponse = await aslApi.importLiteratures({ ... });
navigate('/literature/screening/title/workbench', { state: { projectId } });
2. 标题摘要初筛 - 审核工作台 ⭐
功能清单
- ✅ 任务进度显示(轮询,1秒/次)
- ✅ 进度条实时更新(平滑增长)
- ✅ 模型处理数量显示(DeepSeek + Qwen)
- ✅ 双行表格(DeepSeek上行,Qwen下行)
- ✅ PICOS判断Badge(匹配/部分/不匹配)
- ✅ 结论Tag(纳入/排除/不确定)
- ✅ 冲突文献高亮(红色背景)
- ✅ 点击标题展开证据(双模型对比)
- ✅ 统一复核Drawer(左侧详情+右侧复核)
- ✅ 人工复核提交
- ✅ 筛选Tab(全部/冲突/已纳入/已排除/已复核)
- ✅ 分页(后端分页,20条/页)
关键代码
// 文件: frontend-v2/src/modules/asl/pages/ScreeningWorkbench.tsx
// 核心功能: 双行表格 + 进度轮询 + 展开行 + 复核Drawer
// 轮询进度
const { task, progress, isRunning } = useScreeningTask({ projectId, pollingInterval: 1000 });
// 查询结果
const { results } = useScreeningResults({ projectId, page, pageSize, filter });
// 双行转换
const tableData = transformToDoubleRows(results);
// 展开行
expandable={{
expandedRowRender: (record) => { /* 双模型证据对比 */ },
expandedRowKeys,
onExpandedRowsChange: (keys) => setExpandedRowKeys([...keys]),
}}
3. 后端LLM集成 ⭐
功能清单
- ✅ 双模型并行筛选(DeepSeek + Qwen)
- ✅ JSON结构化输出(带Schema验证)
- ✅ 冲突检测(结论不一致)
- ✅ 串行处理(避免API限流)
- ✅ 进度实时更新(每1条)
- ✅ 错误处理与重试
- ✅ 字段映射(PICOS, 模型名)
- ✅ 文献验证(标题+摘要必需)
- ✅ 详细日志输出
关键代码
// 文件: backend/src/modules/asl/services/screeningService.ts
// 核心功能: 任务管理 + 字段映射 + LLM调用
// 字段映射
const picoCriteria = {
P: rawPicoCriteria?.P || rawPicoCriteria?.population || '',
I: rawPicoCriteria?.I || rawPicoCriteria?.intervention || '',
// ... C, O, S
};
const MODEL_NAME_MAP = {
'DeepSeek-V3': 'deepseek-chat',
'Qwen-Max': 'qwen-max',
// ...
};
// LLM调用
const screeningResult = await llmScreeningService.dualModelScreening(
literature.id,
literature.title,
literature.abstract,
picoCriteria,
inclusionCriteria,
exclusionCriteria,
[models[0], models[1]],
screeningConfig?.style || 'standard'
);
4. LLM服务层 ⭐
功能清单
- ✅ 统一LLM适配器(LLMFactory)
- ✅ 支持4个模型(DeepSeek, Qwen, GPT, Claude)
- ✅ Prompt生成(基于模板)
- ✅ JSON解析(容错,支持中文引号)
- ✅ Schema验证(AJV)
- ✅ 双模型并行调用
- ✅ 批量筛选(并发控制)
关键代码
// 文件: backend/src/modules/asl/services/llmScreeningService.ts
// 核心功能: LLM调用 + JSON解析 + Schema验证
async dualModelScreening(...) {
const [result1, result2] = await Promise.all([
this.screenWithModel(model1, ...),
this.screenWithModel(model2, ...),
]);
// 冲突检测(只检测conclusion)
const hasConflict = result1.conclusion !== result2.conclusion;
// 最终决策
let finalDecision = hasConflict ? 'pending' : result1.conclusion;
return { deepseek: result1, qwen: result2, hasConflict, finalDecision };
}
5. 标题摘要初筛 - 初筛结果 ⭐ Week 4 新增
功能清单
- ✅ 统计概览卡片(总数、已纳入、已排除、待复核)
- ✅ 待复核提示(当有冲突时显示)
- ✅ PRISMA排除原因统计(柱状图展示)
- ✅ 结果列表Tab(全部/已纳入/已排除/待复核)
- ✅ 混合方案表格(AI共识 + 人工最终决策)
- ✅ 点击标题展开详细判断(双模型证据对比)
- ✅ 批量选择与导出(3种导出方式)
- ✅ Excel导出(前端生成,云原生)
混合方案设计
核心特点:
- 明确区分AI决策和人工决策
- 排除原因逻辑清晰(纳入不显示原因)
- 状态标签准确(4种状态)
- 无逻辑矛盾
表格列设计:
| 列名 | 宽度 | 说明 |
|---|---|---|
| # | 50px | 序号 |
| 文献标题 | 300px | 可点击展开 |
| AI共识 | 100px | DS+QW是否一致 |
| 排除原因 | 140px | 智能显示 |
| 人工最终决策 | 120px | 标注推翻AI/与AI一致 |
| 状态 | 90px | 4种状态 |
| 操作 | 70px | 展开/收起 |
总宽度:870px(无需横向滚动)
关键代码
// 文件: frontend-v2/src/modules/asl/pages/ScreeningResults.tsx
// 核心功能: 统计展示 + 混合方案表格 + Excel导出
// 统计数据获取(云原生:后端聚合)
const { data: statsData } = useQuery({
queryKey: ['projectStatistics', projectId],
queryFn: () => aslApi.getProjectStatistics(projectId),
});
// Excel导出(云原生:前端生成,零文件落盘)
exportScreeningResults(data.items, {
filter,
projectName: `项目${projectId.slice(0, 8)}`,
});
6. 统计API ⭐ Week 4 新增
功能清单
- ✅ 后端聚合统计(Prisma并行查询)
- ✅ 统计总数、已纳入、已排除、待复核、冲突、已复核
- ✅ 分析排除原因(从AI判断中提取)
- ✅ 计算各类百分比
- ✅ 云原生:后端聚合,减少网络传输
关键代码
// 文件: backend/src/modules/asl/controllers/screeningController.ts
// 核心功能: 统计聚合 + 排除原因分析
// ⭐ 云原生:使用Prisma聚合查询(并行执行)
const [total, included, excluded, pending, conflict, reviewed] =
await Promise.all([
prisma.aslScreeningResult.count({ where: { projectId } }),
prisma.aslScreeningResult.count({ where: { projectId, finalDecision: 'include' } }),
// ... 更多并行查询
]);
// 返回统计数据(从MB级降到KB级)
return {
total, included, excluded, pending, conflict, reviewed,
exclusionReasons,
includedRate, excludedRate, pendingRate,
};
⚠️ 已知问题与限制
1. 功能限制
- ⚠️ 仅实现标题摘要初筛(全文复筛未开发)
- ⚠️ 串行处理,处理时间较长(199篇约30-60分钟)
- ⚠️ 无任务暂停/取消功能
- ⚠️ 无断点续传(中断后需重新开始)
- ⚠️ 准确率60%(需要Prompt优化)
2. 技术债务
- ⚠️ 浏览器警告:
setTimeout handler took >50ms(性能优化) - ⚠️ 前端轮询(建议改为WebSocket)
- ⚠️ 缺少单元测试(E2E测试)
- ⚠️ Excel后端导出优化(当数据量>5000条时)
3. 用户体验
- ⚠️ 无估计剩余时间
- ⚠️ 无当前处理文献标题显示
- ⚠️ 批量修改决策功能未实现
4. 生产环境未就绪
- ⚠️ 使用默认测试用户(无真实认证)
- ⚠️ 无消息队列(异步任务)
- ⚠️ 无错误重试机制
- ⚠️ 无成本控制(API调用)
- ⚠️ 无监控和告警
详细技术债务清单:技术债务清单
🚀 快速上手指南
环境要求
Node.js: v22.18.0+
PostgreSQL: 16+
npm: 10+
1. 初始化数据库
cd backend
npm install
npx prisma generate
npx prisma migrate dev
2. 配置环境变量
创建 backend/.env:
# 数据库
DATABASE_URL="postgresql://user:password@localhost:5432/dbname?schema=asl_schema"
# LLM API密钥
DEEPSEEK_API_KEY=sk-xxxxxxxxxxxxxx
QWEN_API_KEY=sk-xxxxxxxxxxxxxx
# 可选
GPT_API_KEY=sk-xxxxxxxxxxxxxx
CLAUDE_API_KEY=sk-xxxxxxxxxxxxxx
3. 启动后端
cd backend
npm run dev
应该看到:
✅ Fastify server listening on http://0.0.0.0:3001
✅ Database connected
✅ ASL module routes registered at /api/v1/asl
4. 启动前端
cd frontend-v2
npm install
npm run dev
应该看到:
VITE v5.x.x ready in xxx ms
➜ Local: http://localhost:3000
5. 测试流程
- 访问
http://localhost:3001 - 点击顶部 "AI智能文献"
- 自动跳转到 "设置与启动"
- 填写PICOS标准(复制测试数据)
- 下载Excel模板(或使用现有)
- 上传Excel(建议先测试5篇)
- 点击 "开始AI初筛"
- 等待10-100秒(取决于文献数)
- 查看 "审核工作台"
- 点击标题展开查看证据
- 点击"复核"提交人工决策
6. 查看后端日志
🚀 开始真实LLM筛选:
任务ID: xxx
文献数: 5
模型(映射后): [ 'deepseek-chat', 'qwen-max' ]
PICOS-P: 2型糖尿病患者...
✅ 文献 1/5 处理成功
DS: include / Qwen: exclude
冲突: 是
🧪 测试指南
1. LLM质量测试
cd backend
# 方式1: 使用测试脚本
npm run test:llm
# 方式2: 直接运行
npx ts-node scripts/test-llm-screening.ts
测试数据:
- 位置:
backend/scripts/test-samples/asl-test-literatures.json - 数量:10篇(6篇应排除,3篇应纳入,1篇边界)
- PICOS:SGLT2抑制剂系统综述
预期输出:
准确率: 60%
一致率: 70-100%
JSON验证率: 100%
平均耗时: 10-15秒/篇
2. API测试
# 创建项目
curl -X POST http://localhost:3001/api/v1/asl/projects \
-H "Content-Type: application/json" \
-d '{
"projectName": "测试项目",
"picoCriteria": {"P":"成人","I":"药物A","C":"安慰剂","O":"结局","S":"RCT"},
"inclusionCriteria": "英文",
"exclusionCriteria": "综述"
}'
# 获取项目列表
curl http://localhost:3001/api/v1/asl/projects
3. 前端E2E测试
手动测试清单:
- PICOS表单提交
- Excel模板下载
- Excel文件上传(正常)
- Excel文件上传(错误格式)
- 文献预览显示
- 去重逻辑(相同DOI)
- 启动AI初筛
- 进度条更新
- 自动跳转
- 表格显示
- 列排序
- 筛选Tab切换
- 展开行
- 复核Drawer
- 提交复核
4. 数据库验证
-- 查看最新项目
SELECT * FROM asl_schema.screening_projects
ORDER BY created_at DESC LIMIT 1;
-- 查看筛选任务
SELECT * FROM asl_schema.screening_tasks
WHERE project_id = 'xxx';
-- 查看筛选结果
SELECT
id,
ds_conclusion,
qwen_conclusion,
conflict_status,
SUBSTRING(ds_p_evidence, 1, 50) as ds_evidence
FROM asl_schema.screening_results
WHERE project_id = 'xxx'
LIMIT 5;
📚 开发规范
1. 代码风格
TypeScript
// 使用接口而非类型别名(对外API)
export interface ScreeningResult { ... }
// 严格类型检查
const picoCriteria: PicoCriteria = { ... };
// 使用可选链和空值合并
const models = config?.models ?? ['deepseek-chat', 'qwen-max'];
React
// 使用函数组件
export function ScreeningWorkbench() { ... }
// 自定义Hook命名以use开头
export function useScreeningTask() { ... }
// Props接口命名以Props结尾
interface ScreeningWorkbenchProps { ... }
2. 命名约定
文件名: PascalCase (组件) 或 camelCase (工具)
✅ ScreeningWorkbench.tsx
✅ excelUtils.ts
组件名: PascalCase
✅ function DetailReviewDrawer()
变量/函数: camelCase
✅ const screeningResult = ...
✅ function processLiteratures()
常量: UPPER_SNAKE_CASE
✅ const MODEL_NAME_MAP = ...
类型/接口: PascalCase
✅ interface ScreeningResult
3. 注释规范
/**
* 筛选任务轮询Hook
*
* @param projectId - 项目ID
* @param pollingInterval - 轮询间隔(毫秒),默认1000
* @returns 任务状态和进度信息
*/
export function useScreeningTask() { ... }
// 🔧 修复:字段名映射(前端格式 → LLM格式)
const picoCriteria = { ... };
// ⚠️ 注意:双模型是并行处理
await Promise.all([...]);
4. 错误处理
// 后端
try {
const result = await llmScreeningService.dualModelScreening(...);
} catch (error) {
logger.error('Failed to process literature', {
literatureId: literature.id,
error: error instanceof Error ? error.message : 'Unknown error',
stack: error instanceof Error ? error.stack : undefined,
});
// 输出到控制台
console.error('\n❌ 文献处理失败:', error);
}
// 前端
try {
await aslApi.createProject(...);
} catch (error) {
message.error(`操作失败: ${(error as Error).message}`);
}
5. Git提交规范
遵循 Git提交规范:
feat: 添加审核工作台进度显示优化
fix: 修复列表显示顺序反向问题
refactor: 重构字段映射逻辑
docs: 更新模块状态文档
test: 添加LLM筛选质量测试
chore: 更新依赖版本
🔗 相关文档
核心文档
开发记录
全文复筛:
标题摘要初筛:
- 2025-11-21 真实LLM集成
- 2025-11-21 字段映射修复
- 2025-11-21 用户体验优化
- 2025-11-19 Week2-Day2完成
- 2025-11-18 Prompt设计与测试
测试文档
- 测试数据:PICOS示例、Excel模板
💡 开发建议
对新开发人员
- 先了解业务:阅读 开发计划
- 再看代码:按照本文档的代码结构阅读
- 动手测试:跑一遍完整流程
- 查看日志:理解后端处理逻辑
- 阅读Prompt:理解LLM如何工作
对AI助手
- 优先阅读本文档:了解真实状态
- 参考开发记录:了解历史问题和解决方案
- 查看测试数据:了解实际使用场景
- 检查字段映射:注意前后端格式差异
- 理解限制:不要承诺未实现的功能
常见陷阱
- ❌ PICOS格式混淆:前端用P/I/C/O/S,不是population/intervention
- ❌ 模型名称错误:前端用DeepSeek-V3,API用deepseek-chat
- ❌ 结果查询时机:任务未完成时查询结果为空
- ❌ 轮询间隔过长:用户体验差
- ❌ 文献缺少摘要:LLM调用会失败
📊 性能指标(实测)
处理速度
单篇文献: 10-20秒(DeepSeek + Qwen并行)
5篇文献: 50-100秒
20篇文献: 200-400秒(3-7分钟)
199篇文献: 2000-4000秒(33-66分钟)
准确率(v1.0.0-MVP)
准确率: 60%
一致率: 70-100%
JSON验证率: 100%
需人工复核率: 20-30%(冲突)
前端性能
轮询间隔: 1秒
数据更新延迟: <1秒
表格渲染: <100ms(20条记录)
Drawer打开: <50ms
数据库性能
项目创建: <50ms
文献导入(199篇): <500ms
筛选结果查询(分页): <100ms
进度更新: <50ms
🎯 下一步开发计划
当前Sprint(全文复筛MVP)
- 🚧 全文复筛 Day 4:批处理任务服务(进行中)
- ⏳ 全文复筛 Day 5:前端UI开发(待开始)
- ⏳ 全文复筛 Day 6:API集成与联调(待开始)
短期优化(标题摘要初筛)
- ⏳ Prompt优化(提升准确率到85%+)
- ⏳ 添加任务暂停/取消功能
- ⏳ 实现并发处理(3-5个并发)
- ⏳ 添加估计剩余时间显示
中期(Month 2)
- 🚧 全文复筛功能(开发中)
- ⏳ 全文数据提取功能
- ⏳ 用户自定义边界情况
- ⏳ WebSocket实时推送
长期(Month 3+)
- ⏳ 多用户支持(真实认证)
- ⏳ 消息队列(Bull/RabbitMQ)
- ⏳ 分布式处理
- ⏳ 成本控制和监控
文档维护者:AI智能文献开发团队
更新周期:每个重要功能完成后更新
反馈方式:提交Issue或Pull Request
最后更新:2025-11-22(全文复筛 Day 2-3完成)
文档状态:✅ 反映真实状态
下次更新时机:全文复筛MVP完成 或 标题摘要Prompt优化完成
本次更新内容(v1.1):
- ✅ 更新当前状态(新增全文复筛开发进度)
- ✅ 更新关键里程碑(Day 2-3完成)
- ✅ 新增后端代码结构(common层 + fulltext-screening层)
- ✅ 新增开发记录链接(Day 2-3工作总结)
- ✅ 更新下一步开发计划(当前Sprint)