# AI智能文献模块 - 当前状态与开发指? > **文档版本?* v1.4 > **创建日期?* 2025-11-21 > **维护者:** AI智能文献开发团? > **最后更新:** 2025-12-13 🏆 **Postgres-Only 架构改造完?* > **重大进展?* Platform-Only 架构改?- 智能双模式处理、任务拆分、断点续? > **文档目的?* 反映模块真实状态,帮助新开发人员快速上? --- ## 📋 文档说明 本文档是AI智能文献(ASL)模块的**真实状态快?*,记录实际的代码结构、已实现功能、技术栈和开发规范? **与其他文档的关系**?- **本文档(00-模块当前状态)**:What is(真实状态) - **开发计划文?*:What to do(计划) - **开发记录文?*:What done(历史) - **技术设计文?*:How to do(设计) --- ## 🎯 模块概述 ### 核心功能 AI智能文献模块是一个基于大语言模型(LLM)的文献筛选系统,用于帮助研究人员根据PICOS标准自动筛选文献? ### 当前状?- **开发阶?*:?标题摘要初筛MVP已完成,全文复筛后端已完成,待前端开?- **已完成功?*? - ?标题摘要初筛(Title & Abstract Screening? 完整流程 - ?全文复筛后端(Day 2-5? LLM服务 + API + Excel导出 - **开发中功能**? - 🚧 全文复筛前端UI(Day 6-8,预?.5天) - **模型支持**:DeepSeek-V3 + Qwen-Max 双模型筛?- **部署状?*:✅ 本地开发环境运行正? ### 🏆 Postgres-Only 架构改造(2025-12-13完成? **改造目标:** - 支持2-24小时的长时间任务?000篇文献筛选) - 实例重启后任务可恢复(断点续传) - 零额外成本(使用 Postgres,不需?Redis? **核心实现?* 1. **智能双模式处?* 🎯 - 阈值:50篇文? - 小任务(<50篇):直接处理,快速响应(<1分钟? - 大任务(?0篇):队列处理,可靠性高(支持断点续传) 2. **任务拆分机制** 📦 - 100??2个批次(每批50篇) - 1000??20个批次(每批50篇) - 自动推荐批次大小 3. **断点续传机制** 🔄 - ?0篇文献保存一次断? - 断点数据存储?`platform_schema.job.data`(pg-boss? - 实例重启后自动从上次位置继续 4. **Platform层统一管理** 🏗? - 任务管理信息不存储在 `asl_schema.screening_tasks` - 统一存储?`platform_schema.job.data`(JSONB? - 使用 `CheckpointService` 操作 job.data(所有模块通用? **改造文件:** - `screeningService.ts`:添加智能阈值判断,推送批次任务到 pg-boss - `screeningWorker.ts`:批次处理逻辑,断点续传实?- `CheckpointService.ts`:操?job.data,不依赖业务? **测试验证?* - ?小任务(7篇)- 直接模式测试通过 - ?大任务(100篇)- 队列模式测试通过 - ?任务拆分逻辑验证通过 - ?Platform-Only 架构验证通过 **技术债务?* - ⚠️ Phase 8 全面测试(断点续传压力测试?000篇文献完整流程) - ⚠️ 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(批量处理逻辑?16行) - 异步任务管理(后台处理LLM调用? - 并发控制(p-queue? - 进度跟踪和错误处?- ?2025-11-23?*Day 5完成(后端API开发)** - FulltextScreeningController?个核心API?52行) - ExcelExporter服务?-Sheet报告生成?52行) - 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 # 医学逻辑验证?条规则) ? ? ├── EvidenceChainValidator.ts # 证据链验?? ? ├── ConflictDetectionService.ts # 冲突检?? ? ├── index.ts ? ? └── __tests__/ ? ? └── validation-test.ts ? ├── utils/ ? ? └── tokenCalculator.ts # Token计算与成本估?? └── index.ts ?└── fulltext-screening/ # ?全文复筛模块(NEW? ├── controllers/ ? └── FulltextScreeningController.ts # 5个核心API?52行) ├── services/ ? ├── FulltextScreeningService.ts # 批处理服务(716行) ? └── ExcelExporter.ts # Excel导出服务?52行) ├── routes/ ? └── fulltext-screening.ts # 路由注册?3行) ├── prompts/ # 提示词体? ? ├── system_prompt.md # System Prompt?601字符? ? ├── user_prompt_template.md # User Prompt模板?99行) ? ├── json_schema.json # JSON Schema?2字段约束? ? └── cochrane_standards/ # Cochrane标准(MVP暂不加载? ? ├── 随机化方?md ? ├── 盲法.md ? └── 结果完整?md └── __tests__/ # 测试文件 ├── fulltext-screening-api.http # REST Client测试?1个用例) ├── 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 ``` ### 项目管理 ```http POST /projects # 创建项目 GET /projects # 获取项目列表 GET /projects/:projectId # 获取项目详情 ``` ### 文献管理 ```http POST /literatures/import # 导入文献(JSON格式?POST /literatures/import/excel # 导入Excel文献 GET /projects/:projectId/literatures # 获取文献列表 DELETE /literatures/:literatureId # 删除文献 ``` ### 筛选相关(标题摘要初筛?```http GET /projects/:projectId/screening-task # 获取任务进度 GET /projects/:projectId/screening-results # 获取筛选结?GET /screening-results/:resultId # 获取结果详情 POST /screening-results/:resultId/review # 提交人工复核 ``` ### 全文复筛(NEW - Day 5?```http 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报告 ``` ### 关键参数说明 #### 创建项目 ```typescript { 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: 页码(默??- pageSize: 每页数量(默?0?- filter: all | conflict | included | excluded | reviewed ``` --- ## 🗄?数据库结构(真实? ### Schema: asl_schema #### 1. screening_projects(筛选项目) ```sql 主键: 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(文献)?已扩?```sql 主键: id (UUID) 外键: project_id ?screening_projects(id) CASCADE 标题摘要字段: - title: TEXT(必需? - abstract: TEXT(必需? - authors, journal, publication_year, pmid, doi 全文复筛字段?025-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(标题摘要筛选任务) ```sql 主键: 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(标题摘要筛选结果) ```sql 主键: 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(全文复筛任务)?新建 ```sql 主键: 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(全文复筛结果)?新建 ```sql 主键: 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` ?- 无数据泄漏到 `public` schema - Schema隔离策略执行严格 - 详见:[数据库迁移状态说明](./05-开发记?2025-11-23_数据库迁移状态说?md) --- ## 📊 数据流程(真实) ### 标题摘要初筛流程 ``` 用户上传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?2字段详细报告? - 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 轮询??次) ?前端: 显示进度条和结果 ``` ### 字段映射关系 #### PICOS字段 ```typescript // 前端/数据库格?picoCriteria: { P, I, C, O, S } // LLM服务兼容格式 picoCriteria: { P || population, I || intervention, C || comparison, O || outcome, S || studyDesign } // 映射位置: screeningService.ts (Line 82-92) ``` #### 模型名称 ```typescript // 前端展示??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配置 #### 模型参数 ```typescript { 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篇文? ?0-100?199篇文? ?3-66分钟(串行处理) 进度更新: ?条更新数据库 前端轮询: 1??``` --- ## ?已完成功? ### 1. 标题摘要初筛 - 设置与启?? #### 功能清单 - ?PICOS标准录入(P/I/C/O/S两栏布局?- ?纳入/排除标准录入(侧边对称布局?- ?Excel模板下载(包含字段说明) - ?Excel文件上传 - ?Excel解析(内存中,支持中英文表头?- ?文献去重(DOI优先,标题辅助) - ?文献预览表格(固定列宽,Tooltip显示全文?- ?启动AI初筛按钮 - ?自动跳转到审核工作台 #### 关键代码 ```typescript // 文件: 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?页) #### 关键代码 ```typescript // 文件: 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, 模型名) - ?文献验证(标?摘要必需?- ?详细日志输出 #### 关键代码 ```typescript // 文件: 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?- ?双模型并行调?- ?批量筛选(并发控制? #### 关键代码 ```typescript // 文件: 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 | 展开/收起 | **总宽?*?70px(无需横向滚动? #### 关键代码 ```typescript // 文件: 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判断中提取) - ?计算各类百分?- ?云原生:后端聚合,减少网络传? #### 关键代码 ```typescript // 文件: 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分钟?- ⚠️ 无任务暂?取消功能 - ⚠️ 无断点续传(中断后需重新开始) - ⚠️ 准确?0%(需要Prompt优化? ### 2. 技术债务 - ⚠️ 浏览器警告:`setTimeout handler took >50ms`(性能优化?- ⚠️ 前端轮询(建议改为WebSocket?- ⚠️ 缺少单元测试(E2E测试?- ⚠️ Excel后端导出优化(当数据?5000条时? ### 3. 用户体验 - ⚠️ 无估计剩余时?- ⚠️ 无当前处理文献标题显?- ⚠️ 批量修改决策功能未实? ### 4. 生产环境未就?- ⚠️ 使用默认测试用户(无真实认证?- ⚠️ 无消息队列(异步任务?- ⚠️ 无错误重试机?- ⚠️ 无成本控制(API调用?- ⚠️ 无监控和告警 **详细技术债务清单**:[技术债务清单](./06-技术债务/技术债务清单.md) --- ## 🚀 快速上手指? ### 环境要求 ``` Node.js: v22.18.0+ PostgreSQL: 16+ npm: 10+ ``` ### 1. 初始化数据库 ```bash cd backend npm install npx prisma generate npx prisma migrate dev ``` ### 2. 配置环境变量 创建 `backend/.env`: ```bash # 数据?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. 启动后端 ```bash 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. 启动前端 ```bash cd frontend-v2 npm install npm run dev ``` 应该看到?``` VITE v5.x.x ready in xxx ms ? Local: http://localhost:3000 ``` ### 5. 测试流程 1. 访问 `http://localhost:3001` 2. 点击顶部 **"AI智能文献"** 3. 自动跳转?**"设置与启?** 4. 填写PICOS标准(复制测试数据) 5. 下载Excel模板(或使用现有?6. 上传Excel(建议先测试5篇) 7. 点击 **"开始AI初筛"** 8. 等待10-100秒(取决于文献数?9. 查看 **"审核工作?** 10. 点击标题展开查看证据 11. 点击"复核"提交人工决策 ### 6. 查看后端日志 ``` 🚀 开始真实LLM筛? 任务ID: xxx 文献? 5 模型(映射后? [ 'deepseek-chat', 'qwen-max' ] PICOS-P: 2型糖尿病患?.. ?文献 1/5 处理成功 DS: include / Qwen: exclude 冲突: ?``` --- ## 🧪 测试指南 ### 1. LLM质量测试 ```bash cd backend # 方式1: 使用测试脚本 npm run test:llm # 方式2: 直接运行 npx ts-node scripts/test-llm-screening.ts ``` **测试数据**?- 位置:`backend/scripts/test-samples/asl-test-literatures.json` - 数量?0篇(6篇应排除?篇应纳入?篇边界) - PICOS:SGLT2抑制剂系统综? **预期输出**?``` 准确? 60% 一致率: 70-100% JSON验证? 100% 平均耗时: 10-15??``` ### 2. API测试 ```bash # 创建项目 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. 数据库验? ```sql -- 查看最新项?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 ```typescript // 使用接口而非类型别名(对外API?export interface ScreeningResult { ... } // 严格类型检?const picoCriteria: PicoCriteria = { ... }; // 使用可选链和空值合?const models = config?.models ?? ['deepseek-chat', 'qwen-max']; ``` #### React ```typescript // 使用函数组件 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. 注释规范 ```typescript /** * 筛选任务轮询Hook * * @param projectId - 项目ID * @param pollingInterval - 轮询间隔(毫秒),默?000 * @returns 任务状态和进度信息 */ export function useScreeningTask() { ... } // 🔧 修复:字段名映射(前端格??LLM格式?const picoCriteria = { ... }; // ⚠️ 注意:双模型是并行处?await Promise.all([...]); ``` ### 4. 错误处理 ```typescript // 后端 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提交规范](../../04-开发规?06-Git提交规范.md)? ```bash feat: 添加审核工作台进度显示优?fix: 修复列表显示顺序反向问题 refactor: 重构字段映射逻辑 docs: 更新模块状态文?test: 添加LLM筛选质量测?chore: 更新依赖版本 ``` --- ## 🔗 相关文档 ### 核心文档 1. **本文档(00-模块当前状态)**:模块真实状态快?2. [数据库设计](./02-技术设?01-数据库设?md):数据表结构 3. [API设计规范](./02-技术设?02-API设计规范.md):接口定?4. [开发计划](./04-开发计?03-任务分解.md):功能清单与计划 ### 开发记? **全文复筛**: - [2025-11-22 Day2-Day3 LLM服务与验证系统开发](./05-开发记?2025-11-22_Day2-Day3_LLM服务与验证系统开?md) ?**最?* **标题摘要初筛**: - [2025-11-21 真实LLM集成](./05-开发记?2025-11-21-真实LLM集成完成报告.md) - [2025-11-21 字段映射修复](./05-开发记?2025-11-21-字段映射问题修复.md) - [2025-11-21 用户体验优化](./05-开发记?2025-11-21-用户体验优化.md) - [2025-11-19 Week2-Day2完成](./05-开发记?2025-11-19-Week2-Day2完成报告.md) - [2025-11-18 Prompt设计与测试](./05-开发记?2025-11-18-Prompt设计与测试完成报?md) ### 测试文档 - [测试数据](./05-测试文档/03-测试数据/):PICOS示例、Excel模板 --- ## 💡 开发建? ### 对新开发人? 1. **先了解业?*:阅?[开发计划](./04-开发计?02-标题摘要初筛开发计?md) 2. **再看代码**:按照本文档的代码结构阅?3. **动手测试**:跑一遍完整流?4. **查看日志**:理解后端处理逻辑 5. **阅读Prompt**:理解LLM如何工作 ### 对AI助手 1. **优先阅读本文?*:了解真实状?2. **参考开发记?*:了解历史问题和解决方案 3. **查看测试数据**:了解实际使用场?4. **检查字段映?*:注意前后端格式差异 5. **理解限制**:不要承诺未实现的功? ### 常见陷阱 1. ?**PICOS格式混淆**:前端用P/I/C/O/S,不是population/intervention 2. ?**模型名称错误**:前端用DeepSeek-V3,API用deepseek-chat 3. ?**结果查询时机**:任务未完成时查询结果为?4. ?**轮询间隔过长**:用户体验差 5. ?**文献缺少摘要**: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?0条记录) Drawer打开: <50ms ``` ### 数据库性能 ``` 项目创建: <50ms 文献导入?99篇): <500ms 筛选结果查询(分页? <100ms 进度更新: <50ms ``` --- ## 🎯 下一步开发计? ### 当前Sprint(全文复筛MVP?1. 🚧 **全文复筛 Day 4**:批处理任务服务(进行中?2. ?**全文复筛 Day 5**:前端UI开发(待开始) 3. ?**全文复筛 Day 6**:API集成与联调(待开始) ### 短期优化(标题摘要初筛) 1. ?Prompt优化(提升准确率?5%+?2. ?添加任务暂停/取消功能 3. ?实现并发处理?-5个并发) 4. ?添加估计剩余时间显示 ### 中期(Month 2?1. 🚧 全文复筛功能(开发中?2. ?全文数据提取功能 3. ?用户自定义边界情?4. ?WebSocket实时推? ### 长期(Month 3+?1. ?多用户支持(真实认证?2. ?消息队列(Bull/RabbitMQ?3. ?分布式处?4. ?成本控制和监? --- **文档维护?*:AI智能文献开发团? **更新周期**:每个重要功能完成后更新 **反馈方式**:提交Issue或Pull Request --- **最后更?*?025-11-22(全文复?Day 2-3完成? **文档状?*:✅ 反映真实状? **下次更新时机**:全文复筛MVP完成 ?标题摘要Prompt优化完成 **本次更新内容**(v1.1): - ?更新当前状态(新增全文复筛开发进度) - ?更新关键里程碑(Day 2-3完成?- ?新增后端代码结构(common?+ fulltext-screening层) - ?新增开发记录链接(Day 2-3工作总结?- ?更新下一步开发计划(当前Sprint?