feat(admin): Add user management and upgrade to module permission system
Features - User Management (Phase 4.1): - Database: Add user_modules table for fine-grained module permissions - Database: Add 4 user permissions (view/create/edit/delete) to role_permissions - Backend: UserService (780 lines) - CRUD with tenant isolation - Backend: UserController + UserRoutes (648 lines) - 13 API endpoints - Backend: Batch import users from Excel - Frontend: UserListPage (412 lines) - list/filter/search/pagination - Frontend: UserFormPage (341 lines) - create/edit with module config - Frontend: UserDetailPage (393 lines) - details/tenant/module management - Frontend: 3 modal components (592 lines) - import/assign/configure - API: GET/POST/PUT/DELETE /api/admin/users/* endpoints Architecture Upgrade - Module Permission System: - Backend: Add getUserModules() method in auth.service - Backend: Login API returns modules array in user object - Frontend: AuthContext adds hasModule() method - Frontend: Navigation filters modules based on user.modules - Frontend: RouteGuard checks requiredModule instead of requiredVersion - Frontend: Remove deprecated version-based permission system - UX: Only show accessible modules in navigation (clean UI) - UX: Smart redirect after login (avoid 403 for regular users) Fixes: - Fix UTF-8 encoding corruption in ~100 docs files - Fix pageSize type conversion in userService (String to Number) - Fix authUser undefined error in TopNavigation - Fix login redirect logic with role-based access check - Update Git commit guidelines v1.2 with UTF-8 safety rules Database Changes: - CREATE TABLE user_modules (user_id, tenant_id, module_code, is_enabled) - ADD UNIQUE CONSTRAINT (user_id, tenant_id, module_code) - INSERT 4 permissions + role assignments - UPDATE PUBLIC tenant with 8 module subscriptions Technical: - Backend: 5 new files (~2400 lines) - Frontend: 10 new files (~2500 lines) - Docs: 1 development record + 2 status updates + 1 guideline update - Total: ~4900 lines of code Status: User management 100% complete, module permission system operational
This commit is contained in:
@@ -1,14 +1,17 @@
|
||||
# AI<EFBFBD>箄<EFBFBD><EFBFBD><EFBFBD>讃璅∪<EFBFBD> - <20>唳旿摨栞挽霈?
|
||||
> **<2A><>﹝<EFBFBD><EFB99D>𧋦嚗?* v3.0
|
||||
> **<EFBFBD>𥕦遣<EFBFBD>交<EFBFBD>嚗?* 2025-10-29
|
||||
> **蝏湔擪<EFBFBD><EFBFBD><EFBFBD>** AI<41>箄<EFBFBD><E7AE84><EFBFBD>讃撘<E8AE83><E69298>穃𣪧<E7A983>?
|
||||
> **<EFBFBD><EFBFBD><EFBFBD>擧凒<EFBFBD>堆<EFBFBD>** 2025-11-22嚗㇄ay 4嚗𡁜<E59A97><F0A1819C><EFBFBD><EFBFBD>蝑𥟇㺭<F0A59F87>桀<EFBFBD>霈曇恣嚗?
|
||||
> **<EFBFBD>湔鰵霂湔<EFBFBD>嚗?* <20>啣<EFBFBD><E595A3>冽<EFBFBD>憭滨<E686AD><E6BBA8>詨<EFBFBD>銵剁<E98AB5>`AslLiterature`<60>拙<EFBFBD><E68B99><EFBFBD>AslFulltextScreeningTask`<60><>AslFulltextScreeningResult`嚗?
|
||||
# AI智能文献模块 - 数据库设计
|
||||
|
||||
> **文档版本:** v3.0
|
||||
> **创建日期:** 2025-10-29
|
||||
> **维护者:** AI智能文献开发团队
|
||||
> **最后更新:** 2025-11-22(Day 4:全文复筛数据库设计)
|
||||
> **更新说明:** 新增全文复筛相关表(`AslLiterature`扩展、`AslFulltextScreeningTask`、`AslFulltextScreeningResult`)
|
||||
|
||||
---
|
||||
|
||||
## 📋 文档说明
|
||||
|
||||
<EFBFBD>祆<EFBFBD>獢<EFBFBD><EFBFBD>餈蚊I<EFBFBD>箄<EFBFBD><EFBFBD><EFBFBD>讃璅∪<EFBFBD><EFBFBD><EFBFBD>㺭<EFBFBD>桀<EFBFBD>霈曇恣嚗<EFBFBD><EFBFBD><EFBFBD>祆㺭<EFBFBD>株”蝏𤘪<EFBFBD><EFBFBD><EFBFBD><EFBFBD>蝟餉挽霈~<EFBFBD><EFBFBD>揣撘閗挽霈∠<EFBFBD><EFBFBD>?
|
||||
本文档描述AI智能文献模块的数据库设计,包括数据表结构、关系设计、索引设计等。
|
||||
|
||||
**技术栈**:
|
||||
- 数据库:PostgreSQL 16+
|
||||
- ORM:Prisma
|
||||
@@ -17,30 +20,36 @@
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD><EFBFBD>儭?Schema<EFBFBD>嗆<EFBFBD>
|
||||
## 🏗️ Schema架构
|
||||
|
||||
ASL模块使用独立的 `asl_schema` 进行数据隔离,确保模块独立性和数据安全。
|
||||
|
||||
ASL璅∪<EFBFBD>雿輻鍂<EFBFBD>祉<EFBFBD><EFBFBD>?`asl_schema` 餈𥡝<E9A488><F0A5A19D>唳旿<E594B3>𠉛氖嚗𣬚&靽脲芋<E884B2>㛖𡠺蝡𧢲<E89DA1>批<EFBFBD><E689B9>唳旿摰匧<E691B0><E58CA7>?
|
||||
```
|
||||
platform_schema
|
||||
<EFBFBD>婙<EFBFBD><EFBFBD><EFBFBD> users (<EFBFBD>冽<EFBFBD>銵?
|
||||
<EFBFBD>?asl_schema
|
||||
<20>鎿<EFBFBD><E98EBF><EFBFBD> screening_projects (蝑偦<E89D91>厰★<E58EB0>?
|
||||
└── users (用户表)
|
||||
↓
|
||||
asl_schema
|
||||
├── screening_projects (筛选项目)
|
||||
├── literatures (文献条目)
|
||||
├── screening_results (标题初筛结果)
|
||||
├── screening_tasks (标题初筛任务)
|
||||
<EFBFBD>鎿<EFBFBD><EFBFBD><EFBFBD> fulltext_screening_tasks (<EFBFBD>冽<EFBFBD>憭滨<EFBFBD>隞餃𦛚) 潃?Day 4<EFBFBD>啣<EFBFBD>
|
||||
<EFBFBD>婙<EFBFBD><EFBFBD><EFBFBD> fulltext_screening_results (<EFBFBD>冽<EFBFBD>憭滨<EFBFBD>蝏𤘪<EFBFBD>) 潃?Day 4<EFBFBD>啣<EFBFBD>
|
||||
├── fulltext_screening_tasks (全文复筛任务) ⭐ Day 4新增
|
||||
└── fulltext_screening_results (全文复筛结果) ⭐ Day 4新增
|
||||
```
|
||||
|
||||
**v3.0 <EFBFBD>湔鰵霂湔<EFBFBD>嚗?025-11-22嚗?*嚗?- <20>?<3F>拙<EFBFBD> `literatures` 銵剁<E98AB5><E58981>舀<EFBFBD><E88880>冽<EFBFBD><E586BD>笔𦶢<E7AC94>冽<EFBFBD>蝞∠<E89D9E><E288A0><EFBFBD>DF摮睃<E691AE><E79D83><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>摰孵<E691B0><E5ADB5>?- <20>?<3F>啣<EFBFBD> `fulltext_screening_tasks` 銵剁<E98AB5>蝞∠<E89D9E><E288A0>冽<EFBFBD>憭滨<E686AD><E6BBA8>孵<EFBFBD><E5ADB5><EFBFBD>遙<EFBFBD>?- <20>?<3F>啣<EFBFBD> `fulltext_screening_results` 銵剁<E98AB5>摮睃<E691AE>12摮埈挾霂<E68CBE>摯蝏𤘪<E89D8F>
|
||||
- <EFBFBD>?蝚血<E89D9A>鈭穃<E988AD><E7A983>蠘<EFBFBD><E8A098><EFBFBD><EFBFBD><EFBFBD>冽<EFBFBD><E586BD><EFBFBD>捆摮睃<E691AE>撘閧鍂<E996A7>屸<EFBFBD><E5B1B8>湔𦻖摮睃<E691AE>
|
||||
**v3.0 更新说明(2025-11-22)**:
|
||||
- ✅ 扩展 `literatures` 表:支持全文生命周期管理、PDF存储、全文内容引用
|
||||
- ✅ 新增 `fulltext_screening_tasks` 表:管理全文复筛批处理任务
|
||||
- ✅ 新增 `fulltext_screening_results` 表:存储12字段评估结果
|
||||
- ✅ 符合云原生规范:全文内容存储引用而非直接存储
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD><EFBFBD>儭?<3F>詨<EFBFBD><E8A9A8>唳旿銵?
|
||||
## 🗄️ 核心数据表
|
||||
|
||||
### 1. 筛选项目表 (screening_projects)
|
||||
|
||||
**Prisma璅∪<EFBFBD><EFBFBD>?*: `AslScreeningProject`
|
||||
**Prisma模型名**: `AslScreeningProject`
|
||||
**表名**: `asl_schema.screening_projects`
|
||||
|
||||
```prisma
|
||||
@@ -55,19 +64,23 @@ model AslScreeningProject {
|
||||
picoCriteria Json @map("pico_criteria")
|
||||
// ⚠️ 格式兼容性说明:
|
||||
// 前端使用: { P, I, C, O, S }
|
||||
// <EFBFBD>𡒊垢<EFBFBD>澆捆: { P, I, C, O, S } <EFBFBD>?{ population, intervention, comparison, outcome, studyDesign }
|
||||
// 后端兼容: { P, I, C, O, S } 或 { population, intervention, comparison, outcome, studyDesign }
|
||||
// screeningService.ts 中有字段映射逻辑
|
||||
|
||||
// 蝑偦<EFBFBD>㗇<EFBFBD><EFBFBD>? inclusionCriteria String @map("inclusion_criteria") @db.Text
|
||||
// 筛选标准
|
||||
inclusionCriteria String @map("inclusion_criteria") @db.Text
|
||||
exclusionCriteria String @map("exclusion_criteria") @db.Text
|
||||
|
||||
// <EFBFBD>嗆<EFBFBD>? status String @default("draft")
|
||||
// <20>舫<EFBFBD>匧<EFBFBD>? draft, screening, completed
|
||||
// 状态
|
||||
status String @default("draft")
|
||||
// 可选值: draft, screening, completed
|
||||
|
||||
// 蝑偦<EFBFBD>厰<EFBFBD>蝵? screeningConfig Json? @map("screening_config")
|
||||
// 筛选配置
|
||||
screeningConfig Json? @map("screening_config")
|
||||
// 结构: { models: ["DeepSeek-V3", "Qwen-Max"], style: "standard" }
|
||||
// <EFBFBD>𩤃<EFBFBD> 璅∪<E79285><E288AA>滨妍<E6BBA8>惩<EFBFBD>嚗? // <20>滨垢撅閧內<E996A7>? DeepSeek-V3 <20>?API<50>? deepseek-chat
|
||||
// <EFBFBD>滨垢撅閧內<EFBFBD>? Qwen-Max <20>?API<50>? qwen-max
|
||||
// ⚠️ 模型名称映射:
|
||||
// 前端展示名: DeepSeek-V3 → API名: deepseek-chat
|
||||
// 前端展示名: Qwen-Max → API名: qwen-max
|
||||
// screeningService.ts 中有模型名映射逻辑
|
||||
|
||||
// 关联
|
||||
@@ -85,7 +98,7 @@ model AslScreeningProject {
|
||||
}
|
||||
```
|
||||
|
||||
**SQL銵函<EFBFBD><EFBFBD>?*:
|
||||
**SQL表结构**:
|
||||
```sql
|
||||
CREATE TABLE asl_schema.screening_projects (
|
||||
id TEXT PRIMARY KEY,
|
||||
@@ -108,12 +121,16 @@ CREATE INDEX idx_screening_projects_status ON asl_schema.screening_projects(stat
|
||||
|
||||
---
|
||||
|
||||
### 2. <EFBFBD><EFBFBD>讃<EFBFBD>∠𤌍銵?(literatures) 潃?v3.0<EFBFBD>湔鰵
|
||||
### 2. 文献条目表 (literatures) ⭐ v3.0更新
|
||||
|
||||
**Prisma璅∪<EFBFBD><EFBFBD>?*: `AslLiterature`
|
||||
**Prisma模型名**: `AslLiterature`
|
||||
**表名**: `asl_schema.literatures`
|
||||
|
||||
**v3.0 <EFBFBD>湔鰵霂湔<EFBFBD>**嚗?- <20>?<3F>啣<EFBFBD> `stage` 摮埈挾嚗朞蕭頦芣<E9A0A6><E88AA3>桃<EFBFBD><E6A183>賢𪂹<E8B3A2><F0AA82B9><EFBFBD>imported <20>?title_screened <20>?pdf_acquired <20>?fulltext_screened <20>?data_extracted嚗?- <20>?<3F>啣<EFBFBD> PDF摮睃<E691AE>摮埈挾嚗𡁏𣈲<F0A1818F><F0A388B2>ify/OSS<53>屸<EFBFBD><E5B1B8><EFBFBD>嚗ǑpdfStorageType`, `pdfStorageRef`, `pdfStatus`嚗?- <20>?<3F>啣<EFBFBD> <20>冽<EFBFBD>摮睃<E691AE>摮埈挾嚗?*蝚血<E89D9A>鈭穃<E988AD><E7A983>蠘<EFBFBD><E8A098><EFBFBD><EFBFBD>摮睃<E691AE>撘閧鍂<E996A7>屸<EFBFBD><E5B1B8><EFBFBD>捆**嚗ǑfullTextStorageRef`, `fullTextUrl`嚗?- <20>?<3F>啣<EFBFBD>蝝W<E89D9D>嚗䫤stage`, `hasPdf`, `pdfStatus` <20>𣂼<EFBFBD><F0A382BC>亥砭<E4BAA5>扯<EFBFBD>
|
||||
**v3.0 更新说明**:
|
||||
- ✅ 新增 `stage` 字段:追踪文献生命周期(imported → title_screened → pdf_acquired → fulltext_screened → data_extracted)
|
||||
- ✅ 新增 PDF存储字段:支持Dify/OSS双适配(`pdfStorageType`, `pdfStorageRef`, `pdfStatus`)
|
||||
- ✅ 新增 全文存储字段:**符合云原生规范,存储引用而非内容**(`fullTextStorageRef`, `fullTextUrl`)
|
||||
- ✅ 新增索引:`stage`, `hasPdf`, `pdfStatus` 提升查询性能
|
||||
|
||||
```prisma
|
||||
model AslLiterature {
|
||||
@@ -130,21 +147,25 @@ model AslLiterature {
|
||||
publicationYear Int? @map("publication_year")
|
||||
doi String?
|
||||
|
||||
// 潃?v3.0 <EFBFBD>啣<EFBFBD>嚗𡁏<EFBFBD><EFBFBD>桅𧫴畾蛛<EFBFBD><EFBFBD>笔𦶢<EFBFBD>冽<EFBFBD>蝞∠<EFBFBD>嚗? stage String @default("imported") @map("stage")
|
||||
// ⭐ v3.0 新增:文献阶段(生命周期管理)
|
||||
stage String @default("imported") @map("stage")
|
||||
// imported | title_screened | title_included | pdf_acquired | fulltext_screened | data_extracted
|
||||
|
||||
// 鈭穃<EFBFBD><EFBFBD>笔<EFBFBD><EFBFBD>典<EFBFBD>畾蛛<EFBFBD>V1.0 <20>嗆挾雿輻鍂嚗愢VP<56>嗆挾憸<E68CBE><E686B8>嚗? pdfUrl String? @map("pdf_url") // PDF霈輸䔮URL
|
||||
// 云原生存储字段(V1.0 阶段使用,MVP阶段预留)
|
||||
pdfUrl String? @map("pdf_url") // PDF访问URL
|
||||
pdfOssKey String? @map("pdf_oss_key") // OSS存储Key(用于删除)
|
||||
pdfFileSize Int? @map("pdf_file_size") // 文件大小(字节)
|
||||
|
||||
// 潃?v3.0 <EFBFBD>啣<EFBFBD>嚗䥪DF摮睃<EFBFBD>嚗㇄ify/OSS<53>屸<EFBFBD><E5B1B8><EFBFBD>嚗? hasPdf Boolean @default(false) @map("has_pdf")
|
||||
// ⭐ v3.0 新增:PDF存储(Dify/OSS双适配)
|
||||
hasPdf Boolean @default(false) @map("has_pdf")
|
||||
pdfStorageType String? @map("pdf_storage_type") // "dify" | "oss"
|
||||
pdfStorageRef String? @map("pdf_storage_ref") // Dify: document_id, OSS: object_key
|
||||
pdfStatus String? @map("pdf_status") // "uploading" | "ready" | "failed"
|
||||
pdfUploadedAt DateTime? @map("pdf_uploaded_at")
|
||||
|
||||
// 潃?v3.0 <EFBFBD>啣<EFBFBD>嚗𡁜<EFBFBD><EFBFBD><EFBFBD><EFBFBD>摰孵<EFBFBD><EFBFBD>剁<EFBFBD>鈭穃<EFBFBD><EFBFBD><EFBFBD><EFBFBD>摮睃<EFBFBD>撘閧鍂<EFBFBD>屸<EFBFBD><EFBFBD><EFBFBD>捆嚗? fullTextStorageType String? @map("full_text_storage_type") // "dify" | "oss"
|
||||
fullTextStorageRef String? @map("full_text_storage_ref") // document_id <20>?object_key
|
||||
// ⭐ v3.0 新增:全文内容存储(云原生:存储引用而非内容)
|
||||
fullTextStorageType String? @map("full_text_storage_type") // "dify" | "oss"
|
||||
fullTextStorageRef String? @map("full_text_storage_ref") // document_id 或 object_key
|
||||
fullTextUrl String? @map("full_text_url") // 访问URL
|
||||
fullTextFormat String? @map("full_text_format") // "markdown" | "plaintext"
|
||||
fullTextSource String? @map("full_text_source") // "nougat" | "pymupdf"
|
||||
@@ -153,7 +174,7 @@ model AslLiterature {
|
||||
|
||||
// 关联
|
||||
screeningResults AslScreeningResult[]
|
||||
fulltextScreeningResults AslFulltextScreeningResult[] // 潃?v3.0 <EFBFBD>啣<EFBFBD>
|
||||
fulltextScreeningResults AslFulltextScreeningResult[] // ⭐ v3.0 新增
|
||||
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
@@ -162,14 +183,14 @@ model AslLiterature {
|
||||
@@schema("asl_schema")
|
||||
@@index([projectId])
|
||||
@@index([doi])
|
||||
@@index([stage]) // 潃?v3.0 <EFBFBD>啣<EFBFBD>
|
||||
@@index([hasPdf]) // 潃?v3.0 <EFBFBD>啣<EFBFBD>
|
||||
@@index([pdfStatus]) // 潃?v3.0 <EFBFBD>啣<EFBFBD>
|
||||
@@index([stage]) // ⭐ v3.0 新增
|
||||
@@index([hasPdf]) // ⭐ v3.0 新增
|
||||
@@index([pdfStatus]) // ⭐ v3.0 新增
|
||||
@@unique([projectId, pmid])
|
||||
}
|
||||
```
|
||||
|
||||
**SQL銵函<EFBFBD><EFBFBD>?*嚗ǒ3.0嚗?
|
||||
**SQL表结构**(v3.0):
|
||||
```sql
|
||||
CREATE TABLE asl_schema.literatures (
|
||||
id TEXT PRIMARY KEY,
|
||||
@@ -187,11 +208,13 @@ CREATE TABLE asl_schema.literatures (
|
||||
-- 文献阶段
|
||||
stage TEXT NOT NULL DEFAULT 'imported',
|
||||
|
||||
-- PDF摮睃<EFBFBD>嚗<EFBFBD>唂摮埈挾嚗㲋1.0憸<EFBFBD><EFBFBD>嚗? pdf_url TEXT,
|
||||
-- PDF存储(旧字段,V1.0预留)
|
||||
pdf_url TEXT,
|
||||
pdf_oss_key TEXT,
|
||||
pdf_file_size INTEGER,
|
||||
|
||||
-- PDF摮睃<EFBFBD>嚗<EFBFBD>鰵摮埈挾嚗㷉ify/OSS<53>屸<EFBFBD><E5B1B8><EFBFBD>嚗? has_pdf BOOLEAN NOT NULL DEFAULT false,
|
||||
-- PDF存储(新字段,Dify/OSS双适配)
|
||||
has_pdf BOOLEAN NOT NULL DEFAULT false,
|
||||
pdf_storage_type TEXT,
|
||||
pdf_storage_ref TEXT,
|
||||
pdf_status TEXT,
|
||||
@@ -221,28 +244,32 @@ CREATE INDEX idx_literatures_has_pdf ON asl_schema.literatures(has_pdf);
|
||||
CREATE INDEX idx_literatures_pdf_status ON asl_schema.literatures(pdf_status);
|
||||
```
|
||||
|
||||
**摮埈挾霂湔<EFBFBD>**嚗?
|
||||
**字段说明**:
|
||||
|
||||
| 字段 | 类型 | 说明 | 设计理由 |
|
||||
|------|------|------|----------|
|
||||
| `stage` | String | <EFBFBD><EFBFBD>讃<EFBFBD>嗆挾 | 餈質葵<E8B3AA><E891B5>讃<EFBFBD>冽㟲銝芣<E98A9D>蝔衤葉<E8A1A4><E89189><EFBFBD>蝵?|
|
||||
| `pdfStorageType` | String | PDF摮睃<EFBFBD>蝐餃<EFBFBD> | "dify"\|"oss"嚗峕𣈲<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?|
|
||||
| `stage` | String | 文献阶段 | 追踪文献在整个流程中的位置 |
|
||||
| `pdfStorageType` | String | PDF存储类型 | "dify"\|"oss",支持双适配器 |
|
||||
| `pdfStorageRef` | String | PDF存储引用 | Dify的document_id或OSS的object_key |
|
||||
| `fullTextStorageType` | String | <EFBFBD>冽<EFBFBD>摮睃<EFBFBD>蝐餃<EFBFBD> | 鈭穃<E988AD><E7A983><EFBFBD><EFBFBD>銝滨凒<E6BBA8>亙<EFBFBD><E4BA99>冽<EFBFBD>嚗<EFBFBD><E59A97>撘閧鍂 <20>?|
|
||||
| `fullTextStorageRef` | String | <EFBFBD>冽<EFBFBD>摮睃<EFBFBD>撘閧鍂 | <20><><EFBFBD>Dify<66>𤈛SS銝剔<E98A9D><E58994>冽<EFBFBD><E586BD><EFBFBD>﹝ <20>?|
|
||||
| `fullTextStorageType` | String | 全文存储类型 | 云原生:不直接存全文,存引用 ✅ |
|
||||
| `fullTextStorageRef` | String | 全文存储引用 | 指向Dify或OSS中的全文文档 ✅ |
|
||||
| `fullTextUrl` | String | 全文访问URL | 直接访问全文的URL |
|
||||
| `fullTextTokenCount` | Int | Token数量 | 用于成本估算和LLM调用优化 |
|
||||
|
||||
**鈭穃<EFBFBD><EFBFBD>蠘挽霈∩漁<EFBFBD>?* 潃琜<E6BD83>
|
||||
- <20>?<3F>冽<EFBFBD><E586BD><EFBFBD>捆摮睃<E691AE><E79D83>汰SS/Dify嚗峕㺭<E5B395>桀<EFBFBD><E6A180>芸<EFBFBD>撘閧鍂嚗<E98D82>泵<EFBFBD><E6B3B5><EFBFBD><EFBFBD>毺<EFBFBD>閫<EFBFBD><E996AB>嚗?- <20>?<3F>舀<EFBFBD>Dify <20>?OSS<53>删<EFBFBD>餈<EFBFBD>宏嚗<E5AE8F>蘨<EFBFBD><E898A8><EFBFBD><EFBFBD>揢storageType嚗?- <20>?<3F>唳旿摨栞蝠<E6A09E>𧶏<EFBFBD><F0A7B68F>踹<EFBFBD>憭折<E686AD>TEXT摮埈挾
|
||||
**云原生设计亮点** ⭐:
|
||||
- ✅ 全文内容存储在OSS/Dify,数据库只存引用(符合云原生规范)
|
||||
- ✅ 支持Dify → OSS无缝迁移(只需切换storageType)
|
||||
- ✅ 数据库轻量,避免大量TEXT字段
|
||||
|
||||
---
|
||||
|
||||
### 3. 筛选结果表 (screening_results)
|
||||
|
||||
**Prisma璅∪<EFBFBD><EFBFBD>?*: `AslScreeningResult`
|
||||
**Prisma模型名**: `AslScreeningResult`
|
||||
**表名**: `asl_schema.screening_results`
|
||||
|
||||
**霈曇恣鈭桃<EFBFBD>**嚗𡁏𣈲<F0A1818F><F0A388B2><EFBFBD>璅∪<E79285>嚗㇄eepSeek + Qwen嚗匧僎銵屸<E98AB5>霂<EFBFBD><E99C82><EFBFBD><EFBFBD>鉄摰峕㟲<E5B395><E39FB2>ế<EFBFBD>准<EFBFBD><E58786><EFBFBD><EFBFBD>桀<EFBFBD><E6A180>脩<EFBFBD>璉<EFBFBD>瘚卝<E7989A>?
|
||||
**设计亮点**:支持双模型(DeepSeek + Qwen)并行验证,包含完整的判断、证据和冲突检测。
|
||||
|
||||
```prisma
|
||||
model AslScreeningResult {
|
||||
id String @id @default(uuid())
|
||||
@@ -283,27 +310,36 @@ model AslScreeningResult {
|
||||
qwenSEvidence String? @map("qwen_s_evidence") @db.Text
|
||||
qwenReason String? @map("qwen_reason") @db.Text
|
||||
|
||||
// <EFBFBD>脩<EFBFBD><EFBFBD>嗆<EFBFBD>? conflictStatus String @default("none") @map("conflict_status")
|
||||
// <20>舫<EFBFBD>匧<EFBFBD>? none, conflict, resolved
|
||||
// 冲突状态
|
||||
conflictStatus String @default("none") @map("conflict_status")
|
||||
// 可选值: none, conflict, resolved
|
||||
conflictFields Json? @map("conflict_fields")
|
||||
// 示例: ["P", "I", "conclusion"]
|
||||
|
||||
// <EFBFBD><EFBFBD>蝏<EFBFBD><EFBFBD>蝑吔<EFBFBD>Week 4 瘛瑕<E7989B><E79195>寞<EFBFBD>雿輻鍂嚗? finalDecision String? @map("final_decision") // "include" | "exclude" | null
|
||||
// 潃?Week 4 霂湔<E99C82>嚗帋犖撌亙<E6928C><E4BA99>詨<EFBFBD>霈曄蔭甇文<E79487>畾蛛<E795BE>雿靝蛹<E99D9D><E89BB9>蝏<EFBFBD><E89D8F>蝑? // - include: 鈭箏極<E7AE8F>喳<EFBFBD>蝥喳<E89DA5>嚗<EFBFBD>虾<EFBFBD>賣綫蝧翠I撱箄悅嚗? // - exclude: 鈭箏極<E7AE8F>喳<EFBFBD><E596B3>㘾膄嚗<E88684>虾<EFBFBD>賣綫蝧翠I撱箄悅嚗? // - null: <20>芸<EFBFBD><E88AB8>賂<EFBFBD>雿輻鍂AI<41>喟<EFBFBD>
|
||||
// 最终决策(Week 4 混合方案使用)
|
||||
finalDecision String? @map("final_decision") // "include" | "exclude" | null
|
||||
// ⭐ Week 4 说明:人工复核后设置此字段,作为最终决策
|
||||
// - include: 人工决定纳入(可能推翻AI建议)
|
||||
// - exclude: 人工决定排除(可能推翻AI建议)
|
||||
// - null: 未复核,使用AI决策
|
||||
|
||||
finalDecisionBy String? @map("final_decision_by") // userId
|
||||
finalDecisionAt DateTime? @map("final_decision_at")
|
||||
|
||||
exclusionReason String? @map("exclusion_reason") @db.Text
|
||||
// 潃?Week 4 霂湔<EFBFBD>嚗帋犖撌亙‵<EFBFBD>嗵<EFBFBD><EFBFBD>㘾膄<EFBFBD>笔<EFBFBD>嚗<EFBFBD><EFBFBD><EFBFBD><EFBFBD>漣擃䀝<EFBFBD>AI<EFBFBD>𣂼<EFBFBD>嚗? // - 憒<><E68692>finalDecision=exclude嚗峕迨摮埈挾摮睃<E691AE>鈭箏極憛怠<E6869B><E680A0><EFBFBD><EFBFBD><EFBFBD>? // - 憒<><E68692>銝槃ull嚗<6C><E59A97>蝡航䌊<E888AA>其<EFBFBD>AI<41>斗鱏銝剜<E98A9D><E5899C>吔<EFBFBD>dsPJudgment/dsIJudgment蝑㚁<E89D91>
|
||||
// ⭐ Week 4 说明:人工填写的排除原因(优先级高于AI提取)
|
||||
// - 如果finalDecision=exclude,此字段存储人工填写的原因
|
||||
// - 如果为null,前端自动从AI判断中提取(dsPJudgment/dsIJudgment等)
|
||||
// - Week 4 初筛结果页使用此字段显示排除原因
|
||||
|
||||
// AI憭<EFBFBD><EFBFBD><EFBFBD>嗆<EFBFBD>? aiProcessingStatus String @default("pending") @map("ai_processing_status")
|
||||
// <20>舫<EFBFBD>匧<EFBFBD>? pending, processing, completed, failed
|
||||
// AI处理状态
|
||||
aiProcessingStatus String @default("pending") @map("ai_processing_status")
|
||||
// 可选值: pending, processing, completed, failed
|
||||
aiProcessedAt DateTime? @map("ai_processed_at")
|
||||
aiErrorMessage String? @map("ai_error_message") @db.Text
|
||||
|
||||
// <EFBFBD>航蕭皞臭縑<EFBFBD>? promptVersion String @default("v1.0.0") @map("prompt_version")
|
||||
// 可追溯信息
|
||||
promptVersion String @default("v1.0.0") @map("prompt_version")
|
||||
rawOutput Json? @map("raw_output") // 原始LLM输出(备份)
|
||||
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
@@ -315,10 +351,11 @@ model AslScreeningResult {
|
||||
@@index([literatureId])
|
||||
@@index([conflictStatus])
|
||||
@@index([finalDecision])
|
||||
@@unique([projectId, literatureId]) // 銝<EFBFBD>蝭<EFBFBD><EFBFBD><EFBFBD>桀銁銝<EFBFBD>銝芷★<EFBFBD>桐葉<EFBFBD>芣<EFBFBD>銝<EFBFBD>銝芰<EFBFBD><EFBFBD>厩<EFBFBD><EFBFBD>?}
|
||||
@@unique([projectId, literatureId]) // 一篇文献在一个项目中只有一个筛选结果
|
||||
}
|
||||
```
|
||||
|
||||
**SQL銵函<EFBFBD><EFBFBD>?*嚗<><E59A97><EFBFBD>𣇉<EFBFBD>嚗?
|
||||
**SQL表结构**(简化版):
|
||||
```sql
|
||||
CREATE TABLE asl_schema.screening_results (
|
||||
id TEXT PRIMARY KEY,
|
||||
@@ -353,19 +390,23 @@ CREATE TABLE asl_schema.screening_results (
|
||||
qwen_s_evidence TEXT,
|
||||
qwen_reason TEXT,
|
||||
|
||||
-- <EFBFBD>脩<EFBFBD><EFBFBD>嗆<EFBFBD>? conflict_status TEXT NOT NULL DEFAULT 'none',
|
||||
-- 冲突状态
|
||||
conflict_status TEXT NOT NULL DEFAULT 'none',
|
||||
conflict_fields JSONB,
|
||||
|
||||
-- <EFBFBD><EFBFBD>蝏<EFBFBD><EFBFBD>蝑? final_decision TEXT,
|
||||
-- 最终决策
|
||||
final_decision TEXT,
|
||||
final_decision_by TEXT,
|
||||
final_decision_at TIMESTAMP(3),
|
||||
exclusion_reason TEXT,
|
||||
|
||||
-- AI憭<EFBFBD><EFBFBD><EFBFBD>嗆<EFBFBD>? ai_processing_status TEXT NOT NULL DEFAULT 'pending',
|
||||
-- AI处理状态
|
||||
ai_processing_status TEXT NOT NULL DEFAULT 'pending',
|
||||
ai_processed_at TIMESTAMP(3),
|
||||
ai_error_message TEXT,
|
||||
|
||||
-- <EFBFBD>航蕭皞臭縑<EFBFBD>? prompt_version TEXT NOT NULL DEFAULT 'v1.0.0',
|
||||
-- 可追溯信息
|
||||
prompt_version TEXT NOT NULL DEFAULT 'v1.0.0',
|
||||
raw_output JSONB,
|
||||
|
||||
created_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
@@ -388,7 +429,7 @@ CREATE INDEX idx_screening_results_final_decision ON asl_schema.screening_result
|
||||
|
||||
### 4. 筛选任务表 (screening_tasks)
|
||||
|
||||
**Prisma璅∪<EFBFBD><EFBFBD>?*: `AslScreeningTask`
|
||||
**Prisma模型名**: `AslScreeningTask`
|
||||
**表名**: `asl_schema.screening_tasks`
|
||||
|
||||
```prisma
|
||||
@@ -399,7 +440,7 @@ model AslScreeningTask {
|
||||
|
||||
taskType String @map("task_type") // "title_abstract" | "full_text"
|
||||
status String @default("pending")
|
||||
// <EFBFBD>舫<EFBFBD>匧<EFBFBD>? pending, running, completed, failed
|
||||
// 可选值: pending, running, completed, failed
|
||||
|
||||
// 进度统计
|
||||
totalItems Int @map("total_items")
|
||||
@@ -426,7 +467,7 @@ model AslScreeningTask {
|
||||
}
|
||||
```
|
||||
|
||||
**SQL銵函<EFBFBD><EFBFBD>?*:
|
||||
**SQL表结构**:
|
||||
```sql
|
||||
CREATE TABLE asl_schema.screening_tasks (
|
||||
id TEXT PRIMARY KEY,
|
||||
@@ -454,12 +495,13 @@ CREATE INDEX idx_screening_tasks_status ON asl_schema.screening_tasks(status);
|
||||
|
||||
---
|
||||
|
||||
### 5. <EFBFBD>冽<EFBFBD>憭滨<EFBFBD>隞餃𦛚銵?(fulltext_screening_tasks) 潃?v3.0<EFBFBD>啣<EFBFBD>
|
||||
### 5. 全文复筛任务表 (fulltext_screening_tasks) ⭐ v3.0新增
|
||||
|
||||
**Prisma璅∪<EFBFBD><EFBFBD>?*: `AslFulltextScreeningTask`
|
||||
**Prisma模型名**: `AslFulltextScreeningTask`
|
||||
**表名**: `asl_schema.fulltext_screening_tasks`
|
||||
|
||||
**霈曇恣<EFBFBD>格<EFBFBD>**嚗𡁶恣<F0A181B6><E681A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>蝑𤤿<E89D91><F0A4A4BF>孵<EFBFBD><E5ADB5><EFBFBD>遙<EFBFBD>∴<EFBFBD><E288B4>舀<EFBFBD><E88880>峕芋<E5B395>见僎銵諹<E98AB5><E8ABB9>具<EFBFBD><E585B7><EFBFBD><EFBFBD>祈蕭頦芥<E9A0A6><E88AA5><EFBFBD>蝥扳芋撘?
|
||||
**设计目标**:管理全文复筛的批处理任务,支持双模型并行调用、成本追踪、降级模式
|
||||
|
||||
```prisma
|
||||
model AslFulltextScreeningTask {
|
||||
id String @id @default(uuid())
|
||||
@@ -471,7 +513,8 @@ model AslFulltextScreeningTask {
|
||||
modelB String @map("model_b") // "qwen-max"
|
||||
promptVersion String @default("v1.0.0") @map("prompt_version")
|
||||
|
||||
// 隞餃𦛚<EFBFBD>嗆<EFBFBD>? status String @default("pending")
|
||||
// 任务状态
|
||||
status String @default("pending")
|
||||
// "pending" | "running" | "completed" | "failed" | "cancelled"
|
||||
|
||||
// 进度统计
|
||||
@@ -479,7 +522,8 @@ model AslFulltextScreeningTask {
|
||||
processedCount Int @default(0) @map("processed_count")
|
||||
successCount Int @default(0) @map("success_count")
|
||||
failedCount Int @default(0) @map("failed_count")
|
||||
degradedCount Int @default(0) @map("degraded_count") // <EFBFBD>閙芋<EFBFBD>𧢲<EFBFBD><EFBFBD>?
|
||||
degradedCount Int @default(0) @map("degraded_count") // 单模型成功
|
||||
|
||||
// 成本统计
|
||||
totalTokens Int @default(0) @map("total_tokens")
|
||||
totalCost Float @default(0) @map("total_cost")
|
||||
@@ -507,7 +551,7 @@ model AslFulltextScreeningTask {
|
||||
}
|
||||
```
|
||||
|
||||
**SQL銵函<EFBFBD><EFBFBD>?*:
|
||||
**SQL表结构**:
|
||||
```sql
|
||||
CREATE TABLE asl_schema.fulltext_screening_tasks (
|
||||
id TEXT PRIMARY KEY,
|
||||
@@ -518,7 +562,8 @@ CREATE TABLE asl_schema.fulltext_screening_tasks (
|
||||
model_b TEXT NOT NULL,
|
||||
prompt_version TEXT NOT NULL DEFAULT 'v1.0.0',
|
||||
|
||||
-- 隞餃𦛚<EFBFBD>嗆<EFBFBD>? status TEXT NOT NULL DEFAULT 'pending',
|
||||
-- 任务状态
|
||||
status TEXT NOT NULL DEFAULT 'pending',
|
||||
|
||||
-- 进度统计
|
||||
total_count INTEGER NOT NULL,
|
||||
@@ -552,25 +597,32 @@ CREATE INDEX idx_fulltext_screening_tasks_status ON asl_schema.fulltext_screenin
|
||||
CREATE INDEX idx_fulltext_screening_tasks_created_at ON asl_schema.fulltext_screening_tasks(created_at);
|
||||
```
|
||||
|
||||
**摮埈挾霂湔<EFBFBD>**嚗?
|
||||
**字段说明**:
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `modelA / modelB` | String | <EFBFBD>峕芋<EFBFBD>见<EFBFBD>蝘堆<EFBFBD>deepseek-v3 + qwen-max嚗?|
|
||||
| `degradedCount` | Int | <EFBFBD>閙芋<EFBFBD>𧢲<EFBFBD><EFBFBD>毺<EFBFBD>隞餃𦛚<EFBFBD>堆<EFBFBD>摰寥<EFBFBD><EFBFBD>箏<EFBFBD>嚗?|
|
||||
| `totalTokens` | Int | 蝝航恣Token雿輻鍂<EFBFBD>?|
|
||||
| `totalCost` | Float | 蝝航恣<EFBFBD>鞉𧋦嚗<EFBFBD><EFBFBD>嚗?|
|
||||
| `promptVersion` | String | Prompt<EFBFBD><EFBFBD>𧋦嚗<EFBFBD>虾餈賣滲嚗?|
|
||||
| `modelA / modelB` | String | 双模型名称(deepseek-v3 + qwen-max) |
|
||||
| `degradedCount` | Int | 单模型成功的任务数(容错机制) |
|
||||
| `totalTokens` | Int | 累计Token使用量 |
|
||||
| `totalCost` | Float | 累计成本(元) |
|
||||
| `promptVersion` | String | Prompt版本(可追溯) |
|
||||
|
||||
---
|
||||
|
||||
### 6. <EFBFBD>冽<EFBFBD>憭滨<EFBFBD>蝏𤘪<EFBFBD>銵?(fulltext_screening_results) 潃?v3.0<EFBFBD>啣<EFBFBD>
|
||||
### 6. 全文复筛结果表 (fulltext_screening_results) ⭐ v3.0新增
|
||||
|
||||
**Prisma璅∪<EFBFBD><EFBFBD>?*: `AslFulltextScreeningResult`
|
||||
**Prisma模型名**: `AslFulltextScreeningResult`
|
||||
**表名**: `asl_schema.fulltext_screening_results`
|
||||
|
||||
**霈曇恣<EFBFBD>格<EFBFBD>**嚗𡁜<E59A97><F0A1819C>?2摮埈挾霂衣<E99C82>霂<EFBFBD>摯蝏𤘪<E89D8F>嚗峕𣈲<E5B395><F0A388B2><EFBFBD>璅∪<E79285>撖寞<E69296><E5AF9E><EFBFBD><EFBFBD>霂<EFBFBD><E99C82><EFBFBD>栶<EFBFBD><E6A0B6><EFBFBD>蝒<EFBFBD><E89D92>瘚?
|
||||
**霈曇恣鈭桃<E988AD>**嚗?- <20>?摰峕㟲<E5B395><E39FB2><EFBFBD>璅∪<E79285>蝏𤘪<E89D8F>嚗Êields + overall + logs嚗?- <20>?<3F>餃郎<E9A483>餉<EFBFBD>撉諹<E69289><E8ABB9>諹<EFBFBD><E8ABB9>桅曎撉諹<E69289>蝏𤘪<E89D8F>
|
||||
- <20>?<3F>脩<EFBFBD>璉<EFBFBD>瘚见<E7989A>憭齿瓲隡睃<E99AA1>蝥?- <20>?<3F>滨漣璅∪<E79285><E288AA>舀<EFBFBD>嚗<EFBFBD><E59A97>璅∪<E79285><E288AA>𣂼<EFBFBD>嚗?- <20>?JSON摮睃<E691AE>12摮埈挾霂<E68CBE>摯嚗<E691AF>泵<EFBFBD><E6B3B5><EFBFBD><EFBFBD>毺<EFBFBD>閫<EFBFBD><E996AB>嚗?
|
||||
**设计目标**:存储12字段详细评估结果,支持双模型对比、验证结果、冲突检测
|
||||
|
||||
**设计亮点**:
|
||||
- ✅ 完整的双模型结果(fields + overall + logs)
|
||||
- ✅ 医学逻辑验证和证据链验证结果
|
||||
- ✅ 冲突检测和复核优先级
|
||||
- ✅ 降级模式支持(单模型成功)
|
||||
- ✅ JSON存储12字段评估(符合云原生规范)
|
||||
|
||||
```prisma
|
||||
model AslFulltextScreeningResult {
|
||||
id String @id @default(uuid())
|
||||
@@ -581,7 +633,7 @@ model AslFulltextScreeningResult {
|
||||
literatureId String @map("literature_id")
|
||||
literature AslLiterature @relation(fields: [literatureId], references: [id], onDelete: Cascade)
|
||||
|
||||
// ====== 璅∪<EFBFBD>A蝏𤘪<EFBFBD>嚗㇄eepSeek-V3嚗?=====
|
||||
// ====== 模型A结果(DeepSeek-V3)======
|
||||
modelAName String @map("model_a_name")
|
||||
modelAStatus String @map("model_a_status") // "success" | "failed"
|
||||
modelAFields Json @map("model_a_fields") // 12字段评估 { field1: {...}, field2: {...}, ... }
|
||||
@@ -592,7 +644,7 @@ model AslFulltextScreeningResult {
|
||||
modelACost Float? @map("model_a_cost")
|
||||
modelAError String? @map("model_a_error") @db.Text
|
||||
|
||||
// ====== 璅∪<EFBFBD>B蝏𤘪<EFBFBD>嚗㇋wen-Max嚗?=====
|
||||
// ====== 模型B结果(Qwen-Max)======
|
||||
modelBName String @map("model_b_name")
|
||||
modelBStatus String @map("model_b_status")
|
||||
modelBFields Json @map("model_b_fields")
|
||||
@@ -607,21 +659,22 @@ model AslFulltextScreeningResult {
|
||||
medicalLogicIssues Json? @map("medical_logic_issues") // MedicalLogicValidator输出
|
||||
evidenceChainIssues Json? @map("evidence_chain_issues") // EvidenceChainValidator输出
|
||||
|
||||
// ====== <EFBFBD>脩<EFBFBD>璉<EFBFBD>瘚?======
|
||||
// ====== 冲突检测 ======
|
||||
isConflict Boolean @default(false) @map("is_conflict")
|
||||
conflictSeverity String? @map("conflict_severity") // "high" | "medium" | "low"
|
||||
conflictFields String[] @map("conflict_fields") // ["field1", "field9", "overall"]
|
||||
conflictDetails Json? @map("conflict_details")
|
||||
reviewPriority Int? @map("review_priority") // 0-100憭齿瓲隡睃<EFBFBD>蝥? reviewDeadline DateTime? @map("review_deadline")
|
||||
reviewPriority Int? @map("review_priority") // 0-100复核优先级
|
||||
reviewDeadline DateTime? @map("review_deadline")
|
||||
|
||||
// ====== <EFBFBD><EFBFBD>蝏<EFBFBD><EFBFBD>蝑?======
|
||||
// ====== 最终决策 ======
|
||||
finalDecision String? @map("final_decision") // "include" | "exclude" | null
|
||||
finalDecisionBy String? @map("final_decision_by")
|
||||
finalDecisionAt DateTime? @map("final_decision_at")
|
||||
exclusionReason String? @map("exclusion_reason") @db.Text
|
||||
reviewNotes String? @map("review_notes") @db.Text
|
||||
|
||||
// ====== 憭<EFBFBD><EFBFBD><EFBFBD>嗆<EFBFBD>?======
|
||||
// ====== 处理状态 ======
|
||||
processingStatus String @default("pending") @map("processing_status")
|
||||
// "pending" | "processing" | "completed" | "failed" | "degraded"
|
||||
isDegraded Boolean @default(false) @map("is_degraded")
|
||||
@@ -629,7 +682,7 @@ model AslFulltextScreeningResult {
|
||||
|
||||
processedAt DateTime? @map("processed_at")
|
||||
|
||||
// ====== <EFBFBD>航蕭皞臭縑<EFBFBD>?======
|
||||
// ====== 可追溯信息 ======
|
||||
promptVersion String @default("v1.0.0") @map("prompt_version")
|
||||
rawOutputA Json? @map("raw_output_a")
|
||||
rawOutputB Json? @map("raw_output_b")
|
||||
@@ -645,10 +698,11 @@ model AslFulltextScreeningResult {
|
||||
@@index([isConflict])
|
||||
@@index([finalDecision])
|
||||
@@index([reviewPriority])
|
||||
@@unique([projectId, literatureId]) // 銝<EFBFBD>蝭<EFBFBD><EFBFBD><EFBFBD>桀蘨<EFBFBD>劐<EFBFBD>銝芸<EFBFBD><EFBFBD><EFBFBD><EFBFBD>蝑𤤿<EFBFBD><EFBFBD>?}
|
||||
@@unique([projectId, literatureId]) // 一篇文献只有一个全文复筛结果
|
||||
}
|
||||
```
|
||||
|
||||
**SQL銵函<EFBFBD><EFBFBD>?*嚗<><E59A97><EFBFBD>𣇉<EFBFBD>嚗<EFBFBD><E59A97><EFBFBD><EFBFBD><EFBFBD><EFBFBD>急<EFBFBD><E680A5>匧<EFBFBD>畾蛛<E795BE>:
|
||||
**SQL表结构**(简化版,实际包含所有字段):
|
||||
```sql
|
||||
CREATE TABLE asl_schema.fulltext_screening_results (
|
||||
id TEXT PRIMARY KEY,
|
||||
@@ -682,25 +736,29 @@ CREATE TABLE asl_schema.fulltext_screening_results (
|
||||
medical_logic_issues JSONB,
|
||||
evidence_chain_issues JSONB,
|
||||
|
||||
-- <EFBFBD>脩<EFBFBD>璉<EFBFBD>瘚? is_conflict BOOLEAN NOT NULL DEFAULT false,
|
||||
-- 冲突检测
|
||||
is_conflict BOOLEAN NOT NULL DEFAULT false,
|
||||
conflict_severity TEXT,
|
||||
conflict_fields TEXT[],
|
||||
conflict_details JSONB,
|
||||
review_priority INTEGER,
|
||||
review_deadline TIMESTAMP(3),
|
||||
|
||||
-- <EFBFBD><EFBFBD>蝏<EFBFBD><EFBFBD>蝑? final_decision TEXT,
|
||||
-- 最终决策
|
||||
final_decision TEXT,
|
||||
final_decision_by TEXT,
|
||||
final_decision_at TIMESTAMP(3),
|
||||
exclusion_reason TEXT,
|
||||
review_notes TEXT,
|
||||
|
||||
-- 憭<EFBFBD><EFBFBD><EFBFBD>嗆<EFBFBD>? processing_status TEXT NOT NULL DEFAULT 'pending',
|
||||
-- 处理状态
|
||||
processing_status TEXT NOT NULL DEFAULT 'pending',
|
||||
is_degraded BOOLEAN NOT NULL DEFAULT false,
|
||||
degraded_model TEXT,
|
||||
processed_at TIMESTAMP(3),
|
||||
|
||||
-- <EFBFBD>航蕭皞臭縑<EFBFBD>? prompt_version TEXT NOT NULL DEFAULT 'v1.0.0',
|
||||
-- 可追溯信息
|
||||
prompt_version TEXT NOT NULL DEFAULT 'v1.0.0',
|
||||
raw_output_a JSONB,
|
||||
raw_output_b JSONB,
|
||||
|
||||
@@ -724,7 +782,8 @@ CREATE INDEX idx_fulltext_screening_results_final_decision ON asl_schema.fulltex
|
||||
CREATE INDEX idx_fulltext_screening_results_review_priority ON asl_schema.fulltext_screening_results(review_priority);
|
||||
```
|
||||
|
||||
**JSON摮埈挾蝷箔<EFBFBD>**嚗?
|
||||
**JSON字段示例**:
|
||||
|
||||
**modelAFields (12字段评估)**:
|
||||
```json
|
||||
{
|
||||
@@ -732,7 +791,7 @@ CREATE INDEX idx_fulltext_screening_results_review_priority ON asl_schema.fullte
|
||||
"present": true,
|
||||
"completeness": "完整",
|
||||
"extractable": true,
|
||||
"quote": "蝚砌<E89D9A>雿𡏭<E99BBF><F0A18FAD><EFBFBD>Zhang et al., <EFBFBD>𤏸”鈭?JAMA 2023...",
|
||||
"quote": "第一作者:Zhang et al., 发表于 JAMA 2023...",
|
||||
"location": "Title page, Methods section",
|
||||
"note": "文献来源信息完整"
|
||||
},
|
||||
@@ -747,9 +806,9 @@ CREATE INDEX idx_fulltext_screening_results_review_priority ON asl_schema.fullte
|
||||
"decision": "include",
|
||||
"confidence": 0.92,
|
||||
"keyIssues": [
|
||||
"<22>𤩺㦤<F0A4A9BA>𡝗䲮瘜閙<E7989C>餈啣<E9A488><E595A3>?,
|
||||
"随机化方法描述完整",
|
||||
"盲法实施清晰",
|
||||
"蝏枏<E89D8F><E69E8F><EFBFBD><EFBFBD><EFBFBD>舀<EFBFBD><E88880>?
|
||||
"结局指标可提取"
|
||||
]
|
||||
}
|
||||
```
|
||||
@@ -767,7 +826,7 @@ CREATE INDEX idx_fulltext_screening_results_review_priority ON asl_schema.fullte
|
||||
{
|
||||
"field9": {
|
||||
"modelA": "完整",
|
||||
"modelB": "銝滚<E98A9D><E6BB9A>?,
|
||||
"modelB": "不完整",
|
||||
"severity": "high"
|
||||
}
|
||||
}
|
||||
@@ -775,7 +834,8 @@ CREATE INDEX idx_fulltext_screening_results_review_priority ON asl_schema.fullte
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD><EFBFBD> <20>唳旿<E594B3>喟頂<E5969F>橘<EFBFBD>v3.0<EFBFBD>湔鰵嚗?
|
||||
## 📊 数据关系图(v3.0更新)
|
||||
|
||||
```
|
||||
literature_screening_projects (1) ──< (N) literature_items
|
||||
literature_screening_projects (1) ──< (N) title_abstract_screening_results
|
||||
@@ -785,41 +845,43 @@ literature_screening_projects (1) ──< (N) screening_tasks
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD><EFBFBD> 蝝W<E89D9D>霈曇恣瘙<E681A3><E79899>鳴<EFBFBD>v3.0<EFBFBD>湔鰵嚗?
|
||||
## 🔍 索引设计汇总(v3.0更新)
|
||||
|
||||
| 表名 | 索引字段 | 索引类型 | 说明 |
|
||||
|------|---------|---------|------|
|
||||
| screening_projects | user_id | B-tree | 用户项目查询 |
|
||||
| screening_projects | status | B-tree | <EFBFBD>嗆<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?|
|
||||
| screening_projects | status | B-tree | 状态筛选 |
|
||||
| literatures | project_id | B-tree | 项目文献查询 |
|
||||
| literatures | doi | B-tree | DOI查重 |
|
||||
| literatures | stage 潃?| B-tree | <EFBFBD><EFBFBD>讃<EFBFBD>嗆挾<EFBFBD>亥砭 v3.0 |
|
||||
| literatures | has_pdf 潃?| B-tree | PDF<EFBFBD>瑕<EFBFBD><EFBFBD>嗆<EFBFBD>?v3.0 |
|
||||
| literatures | pdf_status 潃?| B-tree | PDF銝𠹺<EFBFBD><EFBFBD>嗆<EFBFBD>?v3.0 |
|
||||
| literatures | stage ⭐ | B-tree | 文献阶段查询 v3.0 |
|
||||
| literatures | has_pdf ⭐ | B-tree | PDF获取状态 v3.0 |
|
||||
| literatures | pdf_status ⭐ | B-tree | PDF上传状态 v3.0 |
|
||||
| literatures | (project_id, pmid) | Unique | 防止重复导入 |
|
||||
| screening_results | project_id | B-tree | 项目结果查询 |
|
||||
| screening_results | literature_id | B-tree | 文献结果查询 |
|
||||
| screening_results | conflict_status | B-tree | <EFBFBD>脩<EFBFBD>蝑偦<EFBFBD>?|
|
||||
| screening_results | final_decision | B-tree | <EFBFBD>喟<EFBFBD>蝑偦<EFBFBD>?|
|
||||
| screening_results | (project_id, literature_id) | Unique | <EFBFBD>臭<EFBFBD><EFBFBD>抒漲<EFBFBD>?|
|
||||
| screening_results | conflict_status | B-tree | 冲突筛选 |
|
||||
| screening_results | final_decision | B-tree | 决策筛选 |
|
||||
| screening_results | (project_id, literature_id) | Unique | 唯一性约束 |
|
||||
| screening_tasks | project_id | B-tree | 项目任务查询 |
|
||||
| screening_tasks | status | B-tree | 隞餃𦛚<EFBFBD>嗆<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?|
|
||||
| fulltext_screening_tasks 潃?| project_id | B-tree | <EFBFBD>冽<EFBFBD>隞餃𦛚<EFBFBD>亥砭 v3.0 |
|
||||
| fulltext_screening_tasks 潃?| status | B-tree | 隞餃𦛚<EFBFBD>嗆<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?v3.0 |
|
||||
| fulltext_screening_tasks 潃?| created_at | B-tree | <EFBFBD>園𡢿<EFBFBD>鍦<EFBFBD> v3.0 |
|
||||
| fulltext_screening_results 潃?| task_id | B-tree | 隞餃𦛚蝏𤘪<EFBFBD><EFBFBD>亥砭 v3.0 |
|
||||
| fulltext_screening_results 潃?| project_id | B-tree | 憿寧𤌍蝏𤘪<EFBFBD><EFBFBD>亥砭 v3.0 |
|
||||
| fulltext_screening_results 潃?| literature_id | B-tree | <EFBFBD><EFBFBD>讃蝏𤘪<EFBFBD><EFBFBD>亥砭 v3.0 |
|
||||
| fulltext_screening_results 潃?| is_conflict | B-tree | <EFBFBD>脩<EFBFBD>蝑偦<EFBFBD>?v3.0 |
|
||||
| fulltext_screening_results 潃?| final_decision | B-tree | <EFBFBD>喟<EFBFBD>蝑偦<EFBFBD>?v3.0 |
|
||||
| fulltext_screening_results 潃?| review_priority | B-tree | 憭齿瓲隡睃<EFBFBD>蝥?v3.0 |
|
||||
| fulltext_screening_results 潃?| (project_id, literature_id) | Unique | <EFBFBD>臭<EFBFBD><EFBFBD>抒漲<EFBFBD>?v3.0 |
|
||||
| screening_tasks | status | B-tree | 任务状态筛选 |
|
||||
| fulltext_screening_tasks ⭐ | project_id | B-tree | 全文任务查询 v3.0 |
|
||||
| fulltext_screening_tasks ⭐ | status | B-tree | 任务状态筛选 v3.0 |
|
||||
| fulltext_screening_tasks ⭐ | created_at | B-tree | 时间排序 v3.0 |
|
||||
| fulltext_screening_results ⭐ | task_id | B-tree | 任务结果查询 v3.0 |
|
||||
| fulltext_screening_results ⭐ | project_id | B-tree | 项目结果查询 v3.0 |
|
||||
| fulltext_screening_results ⭐ | literature_id | B-tree | 文献结果查询 v3.0 |
|
||||
| fulltext_screening_results ⭐ | is_conflict | B-tree | 冲突筛选 v3.0 |
|
||||
| fulltext_screening_results ⭐ | final_decision | B-tree | 决策筛选 v3.0 |
|
||||
| fulltext_screening_results ⭐ | review_priority | B-tree | 复核优先级 v3.0 |
|
||||
| fulltext_screening_results ⭐ | (project_id, literature_id) | Unique | 唯一性约束 v3.0 |
|
||||
|
||||
**索引总数**: 25个(v3.0新增13个)
|
||||
**唯一约束**: 4个(v3.0新增1个)
|
||||
|
||||
**v3.0蝝W<EFBFBD>隡睃<EFBFBD>霂湔<EFBFBD>**嚗?- <20>?`literatures.stage`: 敹恍<E695B9><E6818D>䰻霂Y鸌摰𡁻𧫴畾萇<E795BE><E89087><EFBFBD>讃嚗<E8AE83><E59A97>"pdf_acquired"敺<><E695BA><EFBFBD><EFBFBD><EFBFBD>蝑𨥈<E89D91>
|
||||
- <20>?`fulltext_screening_results.review_priority`: 隡睃<E99AA1>鈭箏極憭齿瓲<E9BDBF>笔<EFBFBD><E7AC94>鍦<EFBFBD>
|
||||
- <20>?`fulltext_screening_tasks.created_at`: 隞餃𦛚<E9A483><F0A69B9A>蟮<EFBFBD>亥砭隡睃<E99AA1>
|
||||
**v3.0索引优化说明**:
|
||||
- ✅ `literatures.stage`: 快速查询特定阶段的文献(如"pdf_acquired"待全文复筛)
|
||||
- ✅ `fulltext_screening_results.review_priority`: 优化人工复核队列排序
|
||||
- ✅ `fulltext_screening_tasks.created_at`: 任务历史查询优化
|
||||
|
||||
---
|
||||
|
||||
@@ -828,15 +890,15 @@ literature_screening_projects (1) ──< (N) screening_tasks
|
||||
### PICO标准 (picoCriteria JSON)
|
||||
```json
|
||||
{
|
||||
"population": "<22>𠉛弦鈭箇黎嚗<E9BB8E><E59A97>嚗?<3F>讠<EFBFBD>撠輻<E692A0><E8BCBB>𣂷犖<F0A382B7><E78A96><EFBFBD>?,
|
||||
"intervention": "撟脤<E6929F><E884A4>芣鴌嚗<E9B48C><E59A97>嚗锭GLT2<54>穃<EFBFBD><E7A983>?,
|
||||
"comparison": "撖寧<E69296>嚗<EFBFBD><E59A97>嚗𡁜<E59A97><F0A1819C>啣<EFBFBD><E595A3>硋虜閫<E8999C><E996AB>瘜?,
|
||||
"population": "研究人群,如:2型糖尿病成人患者",
|
||||
"intervention": "干预措施,如:SGLT2抑制剂",
|
||||
"comparison": "对照,如:安慰剂或常规疗法",
|
||||
"outcome": "结局指标,如:心血管结局",
|
||||
"studyDesign": "<22>𠉛弦霈曇恣嚗<E681A3><E59A97>嚗𡁻<E59A97><F0A181BB>箏笆<E7AE8F>扯<EFBFBD>撉?(RCT)"
|
||||
"studyDesign": "研究设计,如:随机对照试验 (RCT)"
|
||||
}
|
||||
```
|
||||
|
||||
### 蝑偦<EFBFBD>厰<EFBFBD>蝵?(screeningConfig JSON)
|
||||
### 筛选配置 (screeningConfig JSON)
|
||||
```json
|
||||
{
|
||||
"models": ["deepseek-chat", "qwen-max"],
|
||||
@@ -863,62 +925,97 @@ literature_screening_projects (1) ──< (N) screening_tasks
|
||||
## 🔒 数据安全
|
||||
|
||||
### Schema隔离
|
||||
- 雿輻鍂 `asl_schema` 銝𤾸<E98A9D>隞𡝗芋<F0A19D97>埈㺭<E59F88>桅<EFBFBD>蝳?- <20>冽<EFBFBD>銵典銁 `platform_schema`嚗𣬚<E59A97>銝<EFBFBD>蝞∠<E89D9E>
|
||||
- 使用 `asl_schema` 与其他模块数据隔离
|
||||
- 用户表在 `platform_schema`,统一管理
|
||||
|
||||
### 级联删除
|
||||
- <20>𣳇膄<F0A3B387>冽<EFBFBD> <20>?<3F>芸𢆡<E88AB8>𣳇膄<F0A3B387><E88684><EFBFBD>厩<EFBFBD><E58EA9>厰★<E58EB0>桀<EFBFBD><E6A180>唾<EFBFBD><E594BE>唳旿
|
||||
- <20>𣳇膄憿寧𤌍 <20>?<3F>芸𢆡<E88AB8>𣳇膄<F0A3B387><E88684>讃<EFBFBD><E8AE83><EFBFBD><EFBFBD>栶<EFBFBD><E6A0B6>遙<EFBFBD>?- <20>𣳇膄<F0A3B387><E88684>讃 <20>?<3F>芸𢆡<E88AB8>𣳇膄蝑偦<E89D91>厩<EFBFBD><E58EA9>?
|
||||
### <20>臭<EFBFBD><E887AD>抒漲<E68A92>?- <20>䔶<EFBFBD>憿寧𤌍銝致MID<49>臭<EFBFBD>嚗<EFBFBD><E59A97>霈豢<E99C88>PMID嚗?- <20>䔶<EFBFBD>憿寧𤌍銝凋<E98A9D>蝭<EFBFBD><E89DAD><EFBFBD>桀蘨<E6A180>劐<EFBFBD>銝芰<E98A9D><E88AB0>厩<EFBFBD><E58EA9>?
|
||||
- 删除用户 → 自动删除所有筛选项目及关联数据
|
||||
- 删除项目 → 自动删除文献、结果、任务
|
||||
- 删除文献 → 自动删除筛选结果
|
||||
|
||||
### 唯一性约束
|
||||
- 同一项目中PMID唯一(允许无PMID)
|
||||
- 同一项目中一篇文献只有一个筛选结果
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD><EFBFBD> <20>唳旿<E594B3>誯<EFBFBD>隡?
|
||||
| 憿寧𤌍閫<F0A48C8D>芋 | <20><>讃<EFBFBD>?| 蝑偦<E89D91>厩<EFBFBD><E58EA9>?| 摮睃<E691AE>蝛粹𡢿 |
|
||||
## 📈 数据量预估
|
||||
|
||||
| 项目规模 | 文献数 | 筛选结果 | 存储空间 |
|
||||
|---------|--------|---------|----------|
|
||||
| 小型 | 100-500 | 100-500 | < 10 MB |
|
||||
| 中型 | 500-2000 | 500-2000 | 10-50 MB |
|
||||
| 大型 | 2000-5000 | 2000-5000 | 50-200 MB |
|
||||
| 頞<EFBFBD>之<EFBFBD>?| 5000+ | 5000+ | 200 MB+ |
|
||||
| 超大型 | 5000+ | 5000+ | 200 MB+ |
|
||||
|
||||
**单条记录大小估算**:
|
||||
- 文献条目:~2-5 KB
|
||||
- 蝑偦<E89D91>厩<EFBFBD><E58EA9>頣<EFBFBD>~5-10 KB嚗<42>鉄<EFBFBD>峕芋<E5B395>见ế<E8A781>剖<EFBFBD>霂<EFBFBD>旿嚗?
|
||||
- 筛选结果:~5-10 KB(含双模型判断和证据)
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD>?<3F>𡒊賒閫<E8B392><E996AB>
|
||||
## ⏳ 后续规划
|
||||
|
||||
### Phase 2 (全文复筛) ✅ v3.0已完成
|
||||
- [x] 扩展 `literatures` 表(生命周期管理)
|
||||
- [x] 添加 `fulltext_screening_tasks` 表
|
||||
- [x] 添加 `fulltext_screening_results` 表(12字段)
|
||||
|
||||
### Phase 3 (数据提取) 待开发
|
||||
- [ ] 复用 `fulltext_screening_tasks` 表(切换模式)
|
||||
- [ ] 复用 `fulltext_screening_results` 表(存储提取数据)
|
||||
- [ ] 或新增 `data_extraction_results` 表(如需独立)
|
||||
|
||||
### Phase 4 (质量评估) 待规划
|
||||
- [ ] 质量评估结果表
|
||||
- [ ] 偏倚风险评估表
|
||||
- [ ] GRADE证据质量表
|
||||
|
||||
### Phase 2 (<28>冽<EFBFBD>憭滨<E686AD>) <20>?v3.0撌脣<EFBFBD><EFBFBD>?- [x] <20>拙<EFBFBD> `literatures` 銵剁<E98AB5><E58981>笔𦶢<E7AC94>冽<EFBFBD>蝞∠<E89D9E>嚗?- [x] 瘛餃<E7989B> `fulltext_screening_tasks` 銵?- [x] 瘛餃<E7989B> `fulltext_screening_results` 銵剁<E98AB5>12摮埈挾嚗?
|
||||
### Phase 3 (<28>唳旿<E594B3>𣂼<EFBFBD>) 敺<><E695BA><EFBFBD>?- [ ] 憭滨鍂 `fulltext_screening_tasks` 銵剁<E98AB5><E58981><EFBFBD>揢璅∪<E79285>嚗?- [ ] 憭滨鍂 `fulltext_screening_results` 銵剁<E98AB5>摮睃<E691AE><E79D83>𣂼<EFBFBD><F0A382BC>唳旿嚗?- [ ] <20>𡝗鰵憓?`data_extraction_results` 銵剁<E98AB5>憒<EFBFBD><E68692><EFBFBD>祉<EFBFBD>嚗?
|
||||
### Phase 4 (韐券<E99F90>霂<EFBFBD>摯) 敺<><E695BA><EFBFBD>?- [ ] 韐券<E99F90>霂<EFBFBD>摯蝏𤘪<E89D8F>銵?- [ ] <20>誩<EFBFBD>𡁻<EFBFBD><F0A181BB>抵<EFBFBD>隡啗”
|
||||
- [ ] GRADE霂<45>旿韐券<E99F90>銵?
|
||||
---
|
||||
|
||||
## 📝 v3.0 设计决策记录
|
||||
|
||||
### <EFBFBD>喟<EFBFBD>1: <20>冽<EFBFBD><E586BD><EFBFBD>捆摮睃<E691AE>撘閧鍂<E996A7>屸<EFBFBD><E5B1B8>湔𦻖摮睃<E691AE> <20>?
|
||||
### 决策1: 全文内容存储引用而非直接存储 ✅
|
||||
|
||||
**问题**:全文内容是否存储在数据库?
|
||||
|
||||
**<EFBFBD>寞<EFBFBD>撖寞<EFBFBD>**嚗?| <20>寞<EFBFBD> | 隡条<E99AA1> | 蝻箇<E89DBB> |
|
||||
**方案对比**:
|
||||
| 方案 | 优点 | 缺点 |
|
||||
|------|------|------|
|
||||
| 摮姯EXT | LLM靚<EFBFBD>鍂敹?| 餈肽<E9A488>鈭穃<E988AD><E7A983>蠘<EFBFBD><E8A098><EFBFBD><EFBFBD><EFBFBD>唳旿摨栞<E691A8><E6A09E>?|
|
||||
| 摮睃<EFBFBD><EFBFBD>?| 蝚血<E89D9A>閫<EFBFBD><E996AB>嚗諹蝠<E8ABB9>?| LLM靚<4D>鍂憓𧼮<E68693>100-200ms |
|
||||
| 存TEXT | LLM调用快 | 违背云原生规范,数据库臃肿 |
|
||||
| 存引用 | 符合规范,轻量 | LLM调用增加100-200ms |
|
||||
|
||||
**决策**:✅ 采用方案2(存引用)
|
||||
- 符合云原生存储与计算分离原则
|
||||
- 支持超大文献(>1MB)
|
||||
- RDS存储成本是OSS的5-10倍
|
||||
|
||||
### 决策2: 12字段使用JSON存储 ✅
|
||||
|
||||
**问题**:12字段是拆分为列还是JSON存储?
|
||||
|
||||
**<2A>喟<EFBFBD>**嚗尠<E59A97> <20><>鍂<EFBFBD>寞<EFBFBD>2嚗<32><E59A97>撘閧鍂嚗?- 蝚血<E89D9A>鈭穃<E988AD><E7A983>笔<EFBFBD><E7AC94>其<EFBFBD>霈∠<E99C88><E288A0><EFBFBD>氖<EFBFBD>笔<EFBFBD>
|
||||
- <20>舀<EFBFBD>頞<EFBFBD>之<EFBFBD><E4B98B>讃嚗?1MB嚗?- RDS摮睃<E691AE><E79D83>鞉𧋦<E99E89>烙SS<53>?-10<31>?
|
||||
### <20>喟<EFBFBD>2: 12摮埈挾雿輻鍂JSON摮睃<E691AE> <20>?
|
||||
**<2A>桅<EFBFBD>**嚗?2摮埈挾<E59F88>舀<EFBFBD><E88880><EFBFBD>蛹<EFBFBD>𡑒<EFBFBD><F0A19192>浥SON摮睃<E691AE>嚗?
|
||||
**决策**:✅ 使用PostgreSQL JSONB
|
||||
- 銝漤<E98A9D>閬<EFBFBD><E996AC><EFBFBD>祆䰻霂X<E99C82>銝芸<E98A9D>畾萄<E795BE><E89084>?- 摮埈挾蝏𤘪<E89D8F>憭齿<E686AD>嚗?銝芸<E98A9D>摮埈挾嚗?- JSONB<4E>扯<EFBFBD>隡条<E99AA1>銝娍𣈲<E5A88D><F0A388B2>IN蝝W<E89D9D>
|
||||
- 不需要单独查询某个字段内部
|
||||
- 字段结构复杂(6个子字段)
|
||||
- JSONB性能优秀且支持GIN索引
|
||||
|
||||
### <EFBFBD>喟<EFBFBD>3: <20>祉<EFBFBD><E7A589>冽<EFBFBD>憭滨<E686AD>蝏𤘪<E89D8F>銵?<3F>?
|
||||
**<2A>桅<EFBFBD>**嚗𡁏糓<F0A1818F>血<EFBFBD><E8A180>?`screening_results` 銵剁<E98AB5>
|
||||
### 决策3: 独立全文复筛结果表 ✅
|
||||
|
||||
**问题**:是否复用 `screening_results` 表?
|
||||
|
||||
**决策**:✅ 新增独立表 `fulltext_screening_results`
|
||||
- 数据结构完全不同(PICOS vs 12字段)
|
||||
- 避免字段冗余和逻辑耦合
|
||||
- 便于独立维护和优化
|
||||
|
||||
**<2A>喟<EFBFBD>**嚗尠<E59A97> <20>啣<EFBFBD><E595A3>祉<EFBFBD>銵?`fulltext_screening_results`
|
||||
- <20>唳旿蝏𤘪<E89D8F>摰<EFBFBD><E691B0>銝滚<E98A9D>嚗㇊ICOS vs 12摮埈挾嚗?- <20>踹<EFBFBD>摮埈挾<E59F88>𦯀<EFBFBD><F0A6AF80>屸<EFBFBD>餉<EFBFBD><E9A489>血<EFBFBD>
|
||||
- 靘蹂<E99D98><E8B982>祉<EFBFBD>蝏湔擪<E6B994>䔶<EFBFBD><E494B6>?
|
||||
---
|
||||
|
||||
**<EFBFBD><EFBFBD>﹝<EFBFBD><EFBFBD>𧋦嚗?* v3.0
|
||||
**<EFBFBD><EFBFBD><EFBFBD>擧凒<EFBFBD>堆<EFBFBD>** 2025-11-22嚗㇄ay 4嚗𡁜<EFBFBD><EFBFBD><EFBFBD><EFBFBD>蝑𥟇㺭<EFBFBD>桀<EFBFBD>霈曇恣嚗?
|
||||
**蝏湔擪<EFBFBD><EFBFBD><EFBFBD>** AI<EFBFBD>箄<EFBFBD><EFBFBD><EFBFBD>讃撘<EFBFBD><EFBFBD>穃𣪧<EFBFBD>?
|
||||
**<EFBFBD><EFBFBD>𧋦<EFBFBD><EFBFBD>蟮**嚗?- v3.0 (2025-11-22): <20>冽<EFBFBD>憭滨<E686AD><E6BBA8>唳旿摨栞挽霈∴<E99C88><E288B4>啣<EFBFBD>3銝芾”<E88ABE>𣬚㮾<F0A3AC9A>喳<EFBFBD>畾?- v2.2 (2025-11-21): Week 4蝏蠘恣<E8A098>蠘<EFBFBD>摰峕<E691B0>
|
||||
- v2.0 (2025-11-18): <20><><EFBFBD><EFBFBD>萘<EFBFBD><E89098>唳旿摨栞挽霈?- v1.0 (2025-10-29): <20>嘥<EFBFBD><E598A5><EFBFBD>𧋦
|
||||
**文档版本:** v3.0
|
||||
**最后更新:** 2025-11-22(Day 4:全文复筛数据库设计)
|
||||
**维护者:** AI智能文献开发团队
|
||||
|
||||
**版本历史**:
|
||||
- v3.0 (2025-11-22): 全文复筛数据库设计,新增3个表和相关字段
|
||||
- v2.2 (2025-11-21): Week 4统计功能完成
|
||||
- v2.0 (2025-11-18): 标题初筛数据库设计
|
||||
- v1.0 (2025-10-29): 初始版本
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
# AI智能文献模块 - API设计规范
|
||||
|
||||
> **<EFBFBD><EFBFBD>﹝<EFBFBD><EFBFBD>𧋦嚗?* v3.0
|
||||
> **<EFBFBD>𥕦遣<EFBFBD>交<EFBFBD>嚗?* 2025-10-29
|
||||
> **蝏湔擪<EFBFBD><EFBFBD><EFBFBD>** AI<41>箄<EFBFBD><E7AE84><EFBFBD>讃撘<E8AE83><E69298>穃𣪧<E7A983>?
|
||||
> **文档版本:** v3.0
|
||||
> **创建日期:** 2025-10-29
|
||||
> **维护者:** AI智能文献开发团队
|
||||
> **最后更新:** 2025-11-23
|
||||
> **<EFBFBD>湔鰵霂湔<EFBFBD>嚗?* <20>啣<EFBFBD><E595A3>冽<EFBFBD>憭滨<E686AD>API嚗?銝芣瓲敹<E793B2>𦻖<EFBFBD><F0A6BB96><EFBFBD>
|
||||
> **更新说明:** 新增全文复筛API(5个核心接口)
|
||||
|
||||
---
|
||||
|
||||
## 📋 文档说明
|
||||
|
||||
<EFBFBD>祆<EFBFBD>獢<EFBFBD><EFBFBD>餈蚊I<EFBFBD>箄<EFBFBD><EFBFBD><EFBFBD>讃璅∪<EFBFBD><EFBFBD><EFBFBD>PI霈曇恣閫<EFBFBD><EFBFBD>嚗<EFBFBD><EFBFBD><EFBFBD>祆𦻖<EFBFBD><EFBFBD><EFBFBD>銋剹<EFBFBD><EFBFBD>窈瘙<EFBFBD><EFBFBD>摨娍聢撘譌<EFBFBD><EFBFBD><EFBFBD>霂臬<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
|
||||
本文档描述AI智能文献模块的API设计规范,包括接口定义、请求响应格式、错误处理等。
|
||||
|
||||
**API基础信息**:
|
||||
- **Base URL**: `http://localhost:3001` (撘<EFBFBD><EFBFBD>𤑳㴓憓?
|
||||
- **Base URL**: `http://localhost:3001` (开发环境)
|
||||
- **API前缀**: `/api/v1/asl`
|
||||
- **协议**: HTTP/HTTPS
|
||||
- **数据格式**: JSON
|
||||
@@ -25,8 +26,9 @@
|
||||
1. **RESTful设计**: 遵循RESTful API设计规范
|
||||
2. **统一响应格式**: `{ success: boolean, data?: any, error?: string }`
|
||||
3. **分页支持**: 列表接口支持分页参数
|
||||
4. **<EFBFBD><EFBFBD>𧋦<EFBFBD>批<EFBFBD>**: API<EFBFBD><EFBFBD>𧋦<EFBFBD>𣇉恣<EFBFBD>?(`/api/v1/...`)
|
||||
5. **<EFBFBD>躰秤憭<EFBFBD><EFBFBD>**: 蝏煺<EFBFBD><EFBFBD><EFBFBD>TTP<EFBFBD>嗆<EFBFBD><EFBFBD><EFBFBD><EFBFBD>屸<EFBFBD>霂舀<EFBFBD><EFBFBD>?6. **璅∪<E79285><E288AA>𤥁楝<F0A4A581>?*: `/api/v1/asl/...` <20>祉<EFBFBD>頝舐眏蝛粹𡢿
|
||||
4. **版本控制**: API版本化管理 (`/api/v1/...`)
|
||||
5. **错误处理**: 统一的HTTP状态码和错误消息
|
||||
6. **模块化路由**: `/api/v1/asl/...` 独立路由空间
|
||||
|
||||
---
|
||||
|
||||
@@ -34,22 +36,24 @@
|
||||
|
||||
### 1. 项目管理 (Projects)
|
||||
|
||||
#### 1.1 <EFBFBD>𥕦遣蝑偦<EFBFBD>厰★<EFBFBD>?
|
||||
#### 1.1 创建筛选项目
|
||||
|
||||
**接口**: `POST /api/v1/asl/projects`
|
||||
**霈方<EFBFBD>**: <EFBFBD><EFBFBD>閬?(瘚贝<E7989A><E8B49D>嗆挾暺䁅恕<E48185>冽<EFBFBD>ID)
|
||||
**霂湔<EFBFBD>**: <EFBFBD>𥕦遣銝<EFBFBD>銝芣鰵<EFBFBD><EFBFBD><EFBFBD><EFBFBD>桃<EFBFBD><EFBFBD>厰★<EFBFBD>?
|
||||
**霂瑟<E99C82>雿?*:
|
||||
**认证**: 需要 (测试阶段默认用户ID)
|
||||
**说明**: 创建一个新的文献筛选项目
|
||||
|
||||
**请求体**:
|
||||
```json
|
||||
{
|
||||
"projectName": "SGLT2<EFBFBD>穃<EFBFBD><EFBFBD><EFBFBD>頂蝏毺遞餈?,
|
||||
"projectName": "SGLT2抑制剂系统综述",
|
||||
"picoCriteria": {
|
||||
"P": "2<EFBFBD>讠<EFBFBD>撠輻<EFBFBD><EFBFBD>𣂷犖<EFBFBD><EFBFBD><EFBFBD>?,
|
||||
"P": "2型糖尿病成人患者",
|
||||
"I": "SGLT2抑制剂(empagliflozin、dapagliflozin等)",
|
||||
"C": "安慰剂或常规降糖疗法",
|
||||
"O": "心血管结局(MACE、心衰住院、心血管死亡)",
|
||||
"S": "随机对照试验 (RCT)"
|
||||
},
|
||||
"inclusionCriteria": "<EFBFBD>望<EFBFBD><EFBFBD><EFBFBD>讃嚗朙CT<EFBFBD>𠉛弦嚗?010撟游<E6929F><E6B8B8>𤏸”",
|
||||
"inclusionCriteria": "英文文献,RCT研究,2010年后发表",
|
||||
"exclusionCriteria": "病例报告,综述,动物实验",
|
||||
"screeningConfig": {
|
||||
"models": ["deepseek-chat", "qwen-max"],
|
||||
@@ -65,15 +69,15 @@
|
||||
"data": {
|
||||
"id": "d67f0b9a-b035-4804-aca1-0bd672c27d81",
|
||||
"userId": "asl-test-user-001",
|
||||
"projectName": "SGLT2<EFBFBD>穃<EFBFBD><EFBFBD><EFBFBD>頂蝏毺遞餈?,
|
||||
"projectName": "SGLT2抑制剂系统综述",
|
||||
"picoCriteria": {
|
||||
"population": "2<EFBFBD>讠<EFBFBD>撠輻<EFBFBD><EFBFBD>𣂷犖<EFBFBD><EFBFBD><EFBFBD>?,
|
||||
"intervention": "SGLT2<EFBFBD>穃<EFBFBD><EFBFBD>?,
|
||||
"population": "2型糖尿病成人患者",
|
||||
"intervention": "SGLT2抑制剂",
|
||||
"comparison": "安慰剂或常规降糖疗法",
|
||||
"outcome": "心血管结局",
|
||||
"studyDesign": "随机对照试验 (RCT)"
|
||||
},
|
||||
"inclusionCriteria": "<EFBFBD>望<EFBFBD><EFBFBD><EFBFBD>讃嚗朙CT<EFBFBD>𠉛弦嚗?010撟游<EFBFBD><EFBFBD>𤏸”",
|
||||
"inclusionCriteria": "英文文献,RCT研究,2010年后发表",
|
||||
"exclusionCriteria": "病例报告,综述,动物实验",
|
||||
"status": "draft",
|
||||
"screeningConfig": {
|
||||
@@ -93,9 +97,9 @@ curl -X POST http://localhost:3001/api/v1/asl/projects \
|
||||
-d '{
|
||||
"projectName": "测试项目",
|
||||
"picoCriteria": {
|
||||
"population": "<EFBFBD>𣂷犖<EFBFBD><EFBFBD><EFBFBD>?,
|
||||
"population": "成人患者",
|
||||
"intervention": "药物A",
|
||||
"comparison": "摰㗇<EFBFBD><EFBFBD>?,
|
||||
"comparison": "安慰剂",
|
||||
"outcome": "主要结局",
|
||||
"studyDesign": "RCT"
|
||||
},
|
||||
@@ -109,9 +113,11 @@ curl -X POST http://localhost:3001/api/v1/asl/projects \
|
||||
#### 1.2 获取项目列表
|
||||
|
||||
**接口**: `GET /api/v1/asl/projects`
|
||||
**霈方<EFBFBD>**: <EFBFBD><EFBFBD>閬?
|
||||
**霂湔<EFBFBD>**: <EFBFBD>瑕<EFBFBD>敶枏<EFBFBD><EFBFBD>冽<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>厩<EFBFBD><EFBFBD>厰★<EFBFBD>?
|
||||
**<EFBFBD>亥砭<EFBFBD><EFBFBD>㺭**: <20>?
|
||||
**认证**: 需要
|
||||
**说明**: 获取当前用户的所有筛选项目
|
||||
|
||||
**查询参数**: 无
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
@@ -120,7 +126,7 @@ curl -X POST http://localhost:3001/api/v1/asl/projects \
|
||||
{
|
||||
"id": "d67f0b9a-b035-4804-aca1-0bd672c27d81",
|
||||
"userId": "asl-test-user-001",
|
||||
"projectName": "SGLT2<EFBFBD>穃<EFBFBD><EFBFBD><EFBFBD>頂蝏毺遞餈?,
|
||||
"projectName": "SGLT2抑制剂系统综述",
|
||||
"picoCriteria": {...},
|
||||
"status": "screening",
|
||||
"createdAt": "2025-11-18T07:30:00.000Z",
|
||||
@@ -144,8 +150,9 @@ curl http://localhost:3001/api/v1/asl/projects
|
||||
#### 1.3 获取项目详情
|
||||
|
||||
**接口**: `GET /api/v1/asl/projects/:projectId`
|
||||
**霈方<EFBFBD>**: <EFBFBD><EFBFBD>閬?
|
||||
**霂湔<EFBFBD>**: <EFBFBD>瑕<EFBFBD><EFBFBD><EFBFBD><EFBFBD>憿寧𤌍<EFBFBD><EFBFBD>祕蝏<EFBFBD>縑<EFBFBD>?
|
||||
**认证**: 需要
|
||||
**说明**: 获取指定项目的详细信息
|
||||
|
||||
**路径参数**:
|
||||
- `projectId`: 项目ID (UUID)
|
||||
|
||||
@@ -156,15 +163,15 @@ curl http://localhost:3001/api/v1/asl/projects
|
||||
"data": {
|
||||
"id": "d67f0b9a-b035-4804-aca1-0bd672c27d81",
|
||||
"userId": "asl-test-user-001",
|
||||
"projectName": "SGLT2<EFBFBD>穃<EFBFBD><EFBFBD><EFBFBD>頂蝏毺遞餈?,
|
||||
"projectName": "SGLT2抑制剂系统综述",
|
||||
"picoCriteria": {
|
||||
"population": "2<EFBFBD>讠<EFBFBD>撠輻<EFBFBD><EFBFBD>𣂷犖<EFBFBD><EFBFBD><EFBFBD>?,
|
||||
"intervention": "SGLT2<EFBFBD>穃<EFBFBD><EFBFBD>?,
|
||||
"population": "2型糖尿病成人患者",
|
||||
"intervention": "SGLT2抑制剂",
|
||||
"comparison": "安慰剂或常规降糖疗法",
|
||||
"outcome": "心血管结局",
|
||||
"studyDesign": "随机对照试验 (RCT)"
|
||||
},
|
||||
"inclusionCriteria": "<EFBFBD>望<EFBFBD><EFBFBD><EFBFBD>讃嚗朙CT<EFBFBD>𠉛弦嚗?010撟游<EFBFBD><EFBFBD>𤏸”",
|
||||
"inclusionCriteria": "英文文献,RCT研究,2010年后发表",
|
||||
"exclusionCriteria": "病例报告,综述,动物实验",
|
||||
"status": "screening",
|
||||
"screeningConfig": {
|
||||
@@ -192,13 +199,13 @@ curl http://localhost:3001/api/v1/asl/projects/{projectId}
|
||||
#### 1.4 更新项目
|
||||
|
||||
**接口**: `PUT /api/v1/asl/projects/:projectId`
|
||||
**霈方<EFBFBD>**: <EFBFBD><EFBFBD>閬?
|
||||
**认证**: 需要
|
||||
**说明**: 更新项目信息
|
||||
|
||||
**路径参数**:
|
||||
- `projectId`: 项目ID (UUID)
|
||||
|
||||
**霂瑟<EFBFBD>雿?*嚗<>𣈲<EFBFBD><F0A388B2><EFBFBD><EFBFBD><EFBFBD>凒<EFBFBD>堆<EFBFBD>:
|
||||
**请求体**(支持部分更新):
|
||||
```json
|
||||
{
|
||||
"projectName": "更新后的项目名称",
|
||||
@@ -232,8 +239,9 @@ curl -X PUT http://localhost:3001/api/v1/asl/projects/{projectId} \
|
||||
#### 1.5 删除项目
|
||||
|
||||
**接口**: `DELETE /api/v1/asl/projects/:projectId`
|
||||
**霈方<EFBFBD>**: <EFBFBD><EFBFBD>閬?
|
||||
**霂湔<EFBFBD>**: <EFBFBD>𣳇膄憿寧𤌍<EFBFBD>𦠜<EFBFBD><EFBFBD>匧<EFBFBD><EFBFBD>娍㺭<EFBFBD>殷<EFBFBD>蝥扯<EFBFBD><EFBFBD>𣳇膄嚗?
|
||||
**认证**: 需要
|
||||
**说明**: 删除项目及所有关联数据(级联删除)
|
||||
|
||||
**路径参数**:
|
||||
- `projectId`: 项目ID (UUID)
|
||||
|
||||
@@ -254,11 +262,13 @@ curl -X DELETE http://localhost:3001/api/v1/asl/projects/{projectId}
|
||||
|
||||
### 2. 文献管理 (Literatures)
|
||||
|
||||
#### 2.1 撖澆<EFBFBD><EFBFBD><EFBFBD>讃嚗㇇SON<EFBFBD>澆<EFBFBD>嚗?
|
||||
#### 2.1 导入文献(JSON格式)
|
||||
|
||||
**接口**: `POST /api/v1/asl/literatures/import`
|
||||
**霈方<EFBFBD>**: <EFBFBD><EFBFBD>閬?
|
||||
**霂湔<EFBFBD>**: <EFBFBD>寥<EFBFBD>撖澆<EFBFBD><EFBFBD><EFBFBD>讃嚗㇇SON<EFBFBD>澆<EFBFBD>嚗?
|
||||
**霂瑟<E99C82>雿?*:
|
||||
**认证**: 需要
|
||||
**说明**: 批量导入文献(JSON格式)
|
||||
|
||||
**请求体**:
|
||||
```json
|
||||
{
|
||||
"projectId": "d67f0b9a-b035-4804-aca1-0bd672c27d81",
|
||||
@@ -294,13 +304,13 @@ curl -X DELETE http://localhost:3001/api/v1/asl/projects/{projectId}
|
||||
```
|
||||
|
||||
**字段说明**:
|
||||
- `pmid`: PubMed ID (<EFBFBD>舫<EFBFBD>?
|
||||
- `pmid`: PubMed ID (可选)
|
||||
- `title`: 文献标题 (必填)
|
||||
- `abstract`: 摘要 (必填)
|
||||
- `authors`: 雿𡏭<EFBFBD>?(<28>舫<EFBFBD>?
|
||||
- `journal`: <EFBFBD>笔<EFBFBD> (<28>舫<EFBFBD>?
|
||||
- `publicationYear`: <EFBFBD>𤏸”撟港遢 (<28>舫<EFBFBD>?
|
||||
- `doi`: DOI (<EFBFBD>舫<EFBFBD>?
|
||||
- `authors`: 作者 (可选)
|
||||
- `journal`: 期刊 (可选)
|
||||
- `publicationYear`: 发表年份 (可选)
|
||||
- `doi`: DOI (可选)
|
||||
|
||||
**测试命令**:
|
||||
```bash
|
||||
@@ -319,9 +329,10 @@ curl -X POST http://localhost:3001/api/v1/asl/literatures/import \
|
||||
|
||||
---
|
||||
|
||||
#### 2.2 撖澆<EFBFBD><EFBFBD><EFBFBD>讃嚗𠄌xcel<EFBFBD><EFBFBD>辣嚗?
|
||||
#### 2.2 导入文献(Excel文件)
|
||||
|
||||
**接口**: `POST /api/v1/asl/literatures/import-excel`
|
||||
**霈方<EFBFBD>**: <EFBFBD><EFBFBD>閬?
|
||||
**认证**: 需要
|
||||
**说明**: 从Excel文件批量导入文献
|
||||
|
||||
**请求类型**: `multipart/form-data`
|
||||
@@ -331,15 +342,15 @@ curl -X POST http://localhost:3001/api/v1/asl/literatures/import \
|
||||
- `projectId`: 项目ID
|
||||
|
||||
**Excel格式要求**:
|
||||
| <EFBFBD>堒<EFBFBD>嚗<EFBFBD>葉<EFBFBD>望<EFBFBD><EFBFBD><EFBFBD>虾嚗?| 敹<>‵ | 霂湔<E99C82> |
|
||||
| 列名(中英文均可) | 必填 | 说明 |
|
||||
|------------------|------|------|
|
||||
| PMID / pmid / PMID蝻硋噡 | <EFBFBD>?| PubMed ID |
|
||||
| Title / title / <EFBFBD><EFBFBD><EFBFBD> | <20>?| <20><>讃<EFBFBD><E8AE83><EFBFBD> |
|
||||
| Abstract / abstract / <EFBFBD>䁅<EFBFBD> | <20>?| <20>䁅<EFBFBD> |
|
||||
| Authors / authors / 雿𡏭<EFBFBD>?| <20>?| 雿𡏭<E99BBF>?|
|
||||
| Journal / journal / <EFBFBD>笔<EFBFBD> | <20>?| <20>笔<EFBFBD><E7AC94>滨妍 |
|
||||
| Year / year / 撟港遢 | <20>?| <20>𤏸”撟港遢 |
|
||||
| DOI / doi | <EFBFBD>?| DOI |
|
||||
| PMID / pmid / PMID编号 | 否 | PubMed ID |
|
||||
| Title / title / 标题 | 是 | 文献标题 |
|
||||
| Abstract / abstract / 摘要 | 是 | 摘要 |
|
||||
| Authors / authors / 作者 | 否 | 作者 |
|
||||
| Journal / journal / 期刊 | 否 | 期刊名称 |
|
||||
| Year / year / 年份 | 否 | 发表年份 |
|
||||
| DOI / doi | 否 | DOI |
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
@@ -364,13 +375,16 @@ curl -X POST http://localhost:3001/api/v1/asl/literatures/import-excel \
|
||||
#### 2.3 获取文献列表
|
||||
|
||||
**接口**: `GET /api/v1/asl/projects/:projectId/literatures`
|
||||
**霈方<EFBFBD>**: <EFBFBD><EFBFBD>閬?
|
||||
**霂湔<EFBFBD>**: <EFBFBD>瑕<EFBFBD>憿寧𤌍<EFBFBD><EFBFBD><EFBFBD><EFBFBD>桀<EFBFBD>銵剁<EFBFBD><EFBFBD>舀<EFBFBD><EFBFBD><EFBFBD>△嚗?
|
||||
**认证**: 需要
|
||||
**说明**: 获取项目的文献列表(支持分页)
|
||||
|
||||
**路径参数**:
|
||||
- `projectId`: 项目ID (UUID)
|
||||
|
||||
**查询参数**:
|
||||
- `page`: 憿萇<EFBFBD>嚗<EFBFBD><EFBFBD>霈? 1嚗?- `limit`: 瘥誯△<E8AAAF>圈<EFBFBD>嚗<EFBFBD><E59A97>霈? 50嚗峕<E59A97>憭? 100嚗?
|
||||
- `page`: 页码(默认: 1)
|
||||
- `limit`: 每页数量(默认: 50,最大: 100)
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
@@ -416,7 +430,7 @@ curl "http://localhost:3001/api/v1/asl/projects/{projectId}/literatures?page=1&l
|
||||
#### 2.4 删除文献
|
||||
|
||||
**接口**: `DELETE /api/v1/asl/literatures/:literatureId`
|
||||
**霈方<EFBFBD>**: <EFBFBD><EFBFBD>閬?
|
||||
**认证**: 需要
|
||||
**说明**: 删除指定文献(级联删除筛选结果)
|
||||
|
||||
**路径参数**:
|
||||
@@ -437,14 +451,17 @@ curl -X DELETE http://localhost:3001/api/v1/asl/literatures/{literatureId}
|
||||
|
||||
---
|
||||
|
||||
### 3. 蝑偦<EFBFBD>劐遙<EFBFBD>∠恣<EFBFBD>?(Screening Tasks)
|
||||
### 3. 筛选任务管理 (Screening Tasks)
|
||||
|
||||
> **注意**: 以下接口为待实现功能(Week 2计划)
|
||||
|
||||
#### 3.1 启动筛选任务
|
||||
|
||||
> **瘜冽<E7989C>**: 隞乩<E99A9E><E4B9A9>亙藁銝箏<E98A9D>摰䂿緵<E482BF>蠘<EFBFBD>嚗Áeek 2霈∪<E99C88>嚗?
|
||||
#### 3.1 <20>臬𢆡蝑偦<E89D91>劐遙<E58A90>?
|
||||
**接口**: `POST /api/v1/asl/projects/:projectId/screening/start`
|
||||
**霈方<EFBFBD>**: <EFBFBD><EFBFBD>閬?
|
||||
**霂湔<EFBFBD>**: <EFBFBD>臬𢆡AI蝑偦<EFBFBD>劐遙<EFBFBD>∴<EFBFBD>撘<EFBFBD>郊<EFBFBD>扯<EFBFBD>嚗?
|
||||
**霂瑟<E99C82>雿?*:
|
||||
**认证**: 需要
|
||||
**说明**: 启动AI筛选任务(异步执行)
|
||||
|
||||
**请求体**:
|
||||
```json
|
||||
{
|
||||
"taskType": "title_abstract",
|
||||
@@ -468,10 +485,12 @@ curl -X DELETE http://localhost:3001/api/v1/asl/literatures/{literatureId}
|
||||
|
||||
---
|
||||
|
||||
#### 3.2 <EFBFBD>瑕<EFBFBD>蝑偦<EFBFBD>㕑<EFBFBD>摨?
|
||||
#### 3.2 获取筛选进度
|
||||
|
||||
**接口**: `GET /api/v1/asl/tasks/:taskId/progress`
|
||||
**霈方<EFBFBD>**: <EFBFBD><EFBFBD>閬?
|
||||
**霂湔<EFBFBD>**: <EFBFBD>瑕<EFBFBD>蝑偦<EFBFBD>劐遙<EFBFBD>∟<EFBFBD>摨?
|
||||
**认证**: 需要
|
||||
**说明**: 获取筛选任务进度
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
@@ -492,13 +511,18 @@ curl -X DELETE http://localhost:3001/api/v1/asl/literatures/{literatureId}
|
||||
|
||||
---
|
||||
|
||||
#### 3.3 <EFBFBD>瑕<EFBFBD>蝑偦<EFBFBD>厩<EFBFBD><EFBFBD>?
|
||||
#### 3.3 获取筛选结果
|
||||
|
||||
**接口**: `GET /api/v1/asl/projects/:projectId/results`
|
||||
**霈方<EFBFBD>**: <EFBFBD><EFBFBD>閬?
|
||||
**霂湔<EFBFBD>**: <EFBFBD>瑕<EFBFBD>蝑偦<EFBFBD>厩<EFBFBD><EFBFBD>𨅯<EFBFBD>銵?
|
||||
**认证**: 需要
|
||||
**说明**: 获取筛选结果列表
|
||||
|
||||
**查询参数**:
|
||||
- `page`: 憿萇<EFBFBD>嚗<EFBFBD><EFBFBD>霈? 1嚗?- `limit`: 瘥誯△<E8AAAF>圈<EFBFBD>嚗<EFBFBD><E59A97>霈? 50嚗?- `conflictOnly`: <20>芣遬蝷箏<E89DB7>蝒<EFBFBD>★嚗<E29885><E59A97>撠𥪜<E692A0>潘<EFBFBD>
|
||||
- `finalDecision`: 蝑偦<E89D91>匧<EFBFBD>蝑吔<E89D91>include / exclude / pending嚗?
|
||||
- `page`: 页码(默认: 1)
|
||||
- `limit`: 每页数量(默认: 50)
|
||||
- `conflictOnly`: 只显示冲突项(布尔值)
|
||||
- `finalDecision`: 筛选决策(include / exclude / pending)
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
@@ -534,10 +558,10 @@ curl -X DELETE http://localhost:3001/api/v1/asl/literatures/{literatureId}
|
||||
#### 3.4 审核冲突文献
|
||||
|
||||
**接口**: `POST /api/v1/asl/results/review`
|
||||
**霈方<EFBFBD>**: <EFBFBD><EFBFBD>閬?
|
||||
**认证**: 需要
|
||||
**说明**: 批量审核冲突文献
|
||||
|
||||
**霂瑟<EFBFBD>雿?*:
|
||||
**请求体**:
|
||||
```json
|
||||
{
|
||||
"projectId": "d67f0b9a-b035-4804-aca1-0bd672c27d81",
|
||||
@@ -569,14 +593,15 @@ curl -X DELETE http://localhost:3001/api/v1/asl/literatures/{literatureId}
|
||||
|
||||
### 4. 全文复筛管理 (Fulltext Screening)
|
||||
|
||||
> **<EFBFBD>嗆<EFBFBD>?*: <EFBFBD>?Day 5摰䂿緵銝哨<EFBFBD>2025-11-23嚗?
|
||||
> **状态**: ✅ Day 5实现中(2025-11-23)
|
||||
|
||||
#### 4.1 创建全文复筛任务
|
||||
|
||||
**接口**: `POST /api/v1/asl/fulltext-screening/tasks`
|
||||
**霈方<EFBFBD>**: <EFBFBD><EFBFBD>閬?
|
||||
**霂湔<EFBFBD>**: <EFBFBD>𥕦遣<EFBFBD>冽<EFBFBD>憭滨<EFBFBD>隞餃𦛚嚗<EFBFBD>笆<EFBFBD><EFBFBD><EFBFBD><EFBFBD>萘<EFBFBD><EFBFBD>朞<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>株<EFBFBD>銵?2摮埈挾霂<E68CBE>摯
|
||||
**认证**: 需要
|
||||
**说明**: 创建全文复筛任务,对标题初筛通过的文献进行12字段评估
|
||||
|
||||
**霂瑟<EFBFBD>雿?*:
|
||||
**请求体**:
|
||||
```json
|
||||
{
|
||||
"projectId": "proj-123",
|
||||
@@ -590,7 +615,10 @@ curl -X DELETE http://localhost:3001/api/v1/asl/literatures/{literatureId}
|
||||
**字段说明**:
|
||||
- `projectId`: 项目ID(必填)
|
||||
- `literatureIds`: 待筛选文献ID列表(必填,需要是标题初筛通过的文献)
|
||||
- `modelA`: 璅∪<EFBFBD>A<EFBFBD>滨妍嚗<EFBFBD>虾<EFBFBD>㚁<EFBFBD>暺䁅恕: deepseek-v3嚗?- `modelB`: 璅∪<E79285>B<EFBFBD>滨妍嚗<E5A68D>虾<EFBFBD>㚁<EFBFBD>暺䁅恕: qwen-max嚗?- `promptVersion`: Prompt<70><74>𧋦嚗<F0A78BA6>虾<EFBFBD>㚁<EFBFBD>暺䁅恕: v1.0.0嚗?
|
||||
- `modelA`: 模型A名称(可选,默认: deepseek-v3)
|
||||
- `modelB`: 模型B名称(可选,默认: qwen-max)
|
||||
- `promptVersion`: Prompt版本(可选,默认: v1.0.0)
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
@@ -603,20 +631,22 @@ curl -X DELETE http://localhost:3001/api/v1/asl/literatures/{literatureId}
|
||||
"modelA": "deepseek-v3",
|
||||
"modelB": "qwen-max",
|
||||
"createdAt": "2025-11-23T10:00:00.000Z",
|
||||
"message": "隞餃𦛚<EFBFBD>𥕦遣<EFBFBD>𣂼<EFBFBD>嚗峕迤<EFBFBD>典<EFBFBD><EFBFBD>啣<EFBFBD><EFBFBD>?
|
||||
"message": "任务创建成功,正在后台处理"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**业务规则**:
|
||||
1. 验证所有文献是否属于该项目
|
||||
2. 璉<EFBFBD><EFBFBD>交<EFBFBD><EFBFBD>格糓<EFBFBD>行<EFBFBD><EFBFBD>舐鍂<EFBFBD><EFBFBD>DF嚗ǑpdfStatus === 'ready'`嚗?3. 隞餃𦛚<E9A483>𥕦遣<F0A595A6>𡒊<EFBFBD><F0A1928A>唾<EFBFBD><E594BE>痹<EFBFBD><E797B9>𤾸蝱撘<E89DB1>郊憭<E9838A><E686AD>
|
||||
4. 憒<EFBFBD><EFBFBD><EFBFBD>典<EFBFBD><EFBFBD><EFBFBD>讃PDF<EFBFBD>芸停蝏迎<EFBFBD>隞<EFBFBD><EFBFBD><EFBFBD><EFBFBD>DF撠梁貌<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
|
||||
2. 检查文献是否有可用的PDF(`pdfStatus === 'ready'`)
|
||||
3. 任务创建后立即返回,后台异步处理
|
||||
4. 如果部分文献PDF未就绪,仅处理PDF就绪的文献
|
||||
|
||||
**错误响应**:
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"error": "<EFBFBD>典<EFBFBD><EFBFBD><EFBFBD>讃PDF<EFBFBD>芸停蝏迎<EFBFBD><EFBFBD>䭾<EFBFBD>撘<EFBFBD>憪见<EFBFBD><EFBFBD><EFBFBD><EFBFBD>蝑?
|
||||
"error": "部分文献PDF未就绪,无法开始全文复筛"
|
||||
}
|
||||
```
|
||||
|
||||
@@ -637,8 +667,9 @@ curl -X POST http://localhost:3001/api/v1/asl/fulltext-screening/tasks \
|
||||
#### 4.2 获取任务进度
|
||||
|
||||
**接口**: `GET /api/v1/asl/fulltext-screening/tasks/:taskId`
|
||||
**霈方<EFBFBD>**: <EFBFBD><EFBFBD>閬?
|
||||
**霂湔<EFBFBD>**: <EFBFBD>瑕<EFBFBD><EFBFBD>冽<EFBFBD>憭滨<EFBFBD>隞餃𦛚<EFBFBD><EFBFBD>祕蝏<EFBFBD><EFBFBD>摨虫縑<EFBFBD>?
|
||||
**认证**: 需要
|
||||
**说明**: 获取全文复筛任务的详细进度信息
|
||||
|
||||
**路径参数**:
|
||||
- `taskId`: 任务ID
|
||||
|
||||
@@ -684,9 +715,15 @@ curl -X POST http://localhost:3001/api/v1/asl/fulltext-screening/tasks \
|
||||
```
|
||||
|
||||
**字段说明**:
|
||||
- `status`: 隞餃𦛚<EFBFBD>嗆<EFBFBD>? - `pending`: 敺<><E695BA><EFBFBD>? - `processing`: 憭<><E686AD>銝? - `completed`: 撌脣<E6928C><E884A3>? - `failed`: 憭梯揖
|
||||
- `cancelled`: 撌脣<E6928C>瘨?- `successCount`: <20>峕芋<E5B395>钅<EFBFBD><E99285>𣂼<EFBFBD><F0A382BC><EFBFBD><EFBFBD><EFBFBD>格㺭
|
||||
- `degradedCount`: 隞<><E99A9E>銝芣芋<E88AA3>𧢲<EFBFBD><F0A7A2B2>毺<EFBFBD><E6AFBA><EFBFBD>讃<EFBFBD>堆<EFBFBD><E5A086>滨漣璅∪<E79285>嚗?- `failedCount`: <20>峕芋<E5B395>钅<EFBFBD>憭梯揖<E6A2AF><E68F96><EFBFBD><EFBFBD>格㺭
|
||||
- `status`: 任务状态
|
||||
- `pending`: 待处理
|
||||
- `processing`: 处理中
|
||||
- `completed`: 已完成
|
||||
- `failed`: 失败
|
||||
- `cancelled`: 已取消
|
||||
- `successCount`: 双模型都成功的文献数
|
||||
- `degradedCount`: 仅一个模型成功的文献数(降级模式)
|
||||
- `failedCount`: 双模型都失败的文献数
|
||||
- `totalCost`: 累计成本(单位:元)
|
||||
|
||||
**测试命令**:
|
||||
@@ -699,7 +736,7 @@ curl http://localhost:3001/api/v1/asl/fulltext-screening/tasks/fst-20251123-001
|
||||
#### 4.3 获取任务结果
|
||||
|
||||
**接口**: `GET /api/v1/asl/fulltext-screening/tasks/:taskId/results`
|
||||
**霈方<EFBFBD>**: <EFBFBD><EFBFBD>閬?
|
||||
**认证**: 需要
|
||||
**说明**: 获取全文复筛任务的详细结果,支持筛选和分页
|
||||
|
||||
**路径参数**:
|
||||
@@ -709,7 +746,13 @@ curl http://localhost:3001/api/v1/asl/fulltext-screening/tasks/fst-20251123-001
|
||||
- `filter`: 结果筛选(可选)
|
||||
- `all`: 全部(默认)
|
||||
- `conflict`: 仅冲突项
|
||||
- `pending`: 敺<EFBFBD>恣<EFBFBD>? - `reviewed`: 撌脣恣<E884A3>?- `page`: 憿萇<E686BF>嚗<EFBFBD><E59A97>霈? 1嚗?- `pageSize`: 瘥誯△<E8AAAF>圈<EFBFBD>嚗<EFBFBD><E59A97>霈? 20嚗峕<E59A97>憭? 100嚗?- `sortBy`: <20>鍦<EFBFBD>摮埈挾嚗<E68CBE>虾<EFBFBD>? `priority`, `createdAt`嚗?- `sortOrder`: <20>鍦<EFBFBD><E98DA6>孵<EFBFBD>嚗Ǒasc` | `desc`嚗屸<E59A97>霈? `desc`嚗?
|
||||
- `pending`: 待审核
|
||||
- `reviewed`: 已审核
|
||||
- `page`: 页码(默认: 1)
|
||||
- `pageSize`: 每页数量(默认: 20,最大: 100)
|
||||
- `sortBy`: 排序字段(可选: `priority`, `createdAt`)
|
||||
- `sortOrder`: 排序方向(`asc` | `desc`,默认: `desc`)
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
@@ -739,25 +782,25 @@ curl http://localhost:3001/api/v1/asl/fulltext-screening/tasks/fst-20251123-001
|
||||
"field1_source": {
|
||||
"assessment": "完整",
|
||||
"evidence": "第一作者Smith JA, Lancet 2023",
|
||||
"location": "蝚?憿?,
|
||||
"location": "第1页",
|
||||
"confidence": 0.98
|
||||
},
|
||||
"field2_studyType": {
|
||||
"assessment": "完整",
|
||||
"evidence": "憭帋葉敹<EFBFBD><EFBFBD><EFBFBD>箏笆<EFBFBD>扯<EFBFBD>撉?,
|
||||
"location": "Methods蝚?憿?,
|
||||
"evidence": "多中心随机对照试验",
|
||||
"location": "Methods第2页",
|
||||
"confidence": 0.95
|
||||
},
|
||||
"field5_population": {
|
||||
"assessment": "完整",
|
||||
"evidence": "蝥喳<EFBFBD>500靘?<EFBFBD>讠<EFBFBD>撠輻<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>撟湧<EFBFBD>58簣12撗?,
|
||||
"location": "Methods蝚?憿?,
|
||||
"evidence": "纳入500例2型糖尿病患者,年龄58±12岁",
|
||||
"location": "Methods第3页",
|
||||
"confidence": 0.92
|
||||
},
|
||||
"field9_outcomes": {
|
||||
"assessment": "完整",
|
||||
"evidence": "銝餉<EFBFBD>蝏枏<EFBFBD>eGFR<EFBFBD>睃<EFBFBD>嚗?15.2簣3.5 ml/min vs -8.1簣2.9 ml/min",
|
||||
"location": "Results蝚?憿菔”2",
|
||||
"evidence": "主要结局eGFR变化:-15.2±3.5 ml/min vs -8.1±2.9 ml/min",
|
||||
"location": "Results第5页表2",
|
||||
"confidence": 0.96
|
||||
}
|
||||
},
|
||||
@@ -821,8 +864,8 @@ curl http://localhost:3001/api/v1/asl/fulltext-screening/tasks/fst-20251123-001
|
||||
"fields": {
|
||||
"field9_outcomes": {
|
||||
"assessment": "缺失",
|
||||
"evidence": "<EFBFBD>芣𥁒<EFBFBD>𠰴<EFBFBD>雿𤘪㺭<EFBFBD>潘<EFBFBD>隞<EFBFBD><EFBFBD>P<EFBFBD>?,
|
||||
"location": "Results蝚?憿?,
|
||||
"evidence": "未报告具体数值,仅有P值",
|
||||
"location": "Results第4页",
|
||||
"confidence": 0.88
|
||||
}
|
||||
},
|
||||
@@ -879,17 +922,23 @@ curl http://localhost:3001/api/v1/asl/fulltext-screening/tasks/fst-20251123-001
|
||||
```
|
||||
|
||||
**12字段说明**:
|
||||
- `field1_source`: <EFBFBD><EFBFBD>讃<EFBFBD>交<EFBFBD>嚗<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>𨳍<EFBFBD><EFBFBD>僑隞賜<EFBFBD>嚗?- `field2_studyType`: <20>𠉛弦蝐餃<E89D90>嚗㇌CT<43><54><EFBFBD><EFBFBD>㛖<EFBFBD>蝛嗥<E89D9B>嚗?- `field3_studyDesign`: <20>𠉛弦霈曇恣蝏<E681A3><E89D8F>
|
||||
- `field1_source`: 文献来源(作者、期刊、年份等)
|
||||
- `field2_studyType`: 研究类型(RCT、队列研究等)
|
||||
- `field3_studyDesign`: 研究设计细节
|
||||
- `field4_diagnosis`: 疾病诊断标准
|
||||
- `field5_population`: 人群特征(样本量、基线等)⭐
|
||||
- `field6_baseline`: <EFBFBD>箇瑪<EFBFBD>唳旿潃?- `field7_intervention`: 撟脤<E6929F><E884A4>芣鴌潃?- `field8_control`: 撖寧<E69296><E5AFA7>芣鴌
|
||||
- `field9_outcomes`: 蝏枏<E89D8F><E69E8F><EFBFBD><EFBFBD>潃鐥<E6BD83>潃?<3F><><EFBFBD>喲睸
|
||||
- `field6_baseline`: 基线数据⭐
|
||||
- `field7_intervention`: 干预措施⭐
|
||||
- `field8_control`: 对照措施
|
||||
- `field9_outcomes`: 结局指标⭐⭐⭐ 最关键
|
||||
- `field10_statistics`: 统计方法
|
||||
- `field11_quality`: 韐券<EFBFBD>霂<EFBFBD>遠嚗<EFBFBD><EFBFBD><EFBFBD>箏<EFBFBD><EFBFBD><EFBFBD>𤩅瘜閧<EFBFBD>嚗争<EFBFBD>潃?- `field12_other`: <20>嗡<EFBFBD>靽⊥<E99DBD>
|
||||
- `field11_quality`: 质量评价(随机化、盲法等)⭐⭐
|
||||
- `field12_other`: 其他信息
|
||||
|
||||
**测试命令**:
|
||||
```bash
|
||||
# <EFBFBD>瑕<EFBFBD><EFBFBD><EFBFBD><EFBFBD>厩<EFBFBD><EFBFBD>?curl "http://localhost:3001/api/v1/asl/fulltext-screening/tasks/fst-20251123-001/results"
|
||||
# 获取所有结果
|
||||
curl "http://localhost:3001/api/v1/asl/fulltext-screening/tasks/fst-20251123-001/results"
|
||||
|
||||
# 仅获取冲突项
|
||||
curl "http://localhost:3001/api/v1/asl/fulltext-screening/tasks/fst-20251123-001/results?filter=conflict"
|
||||
@@ -903,12 +952,13 @@ curl "http://localhost:3001/api/v1/asl/fulltext-screening/tasks/fst-20251123-001
|
||||
#### 4.4 人工审核决策
|
||||
|
||||
**接口**: `PUT /api/v1/asl/fulltext-screening/results/:resultId/decision`
|
||||
**霈方<EFBFBD>**: <EFBFBD><EFBFBD>閬?
|
||||
**霂湔<EFBFBD>**: 撖孵<EFBFBD>銝芸<EFBFBD><EFBFBD><EFBFBD><EFBFBD>蝑𤤿<EFBFBD><EFBFBD>𡏭<EFBFBD>銵䔶犖撌亙恣<EFBFBD>詨<EFBFBD>蝑?
|
||||
**认证**: 需要
|
||||
**说明**: 对单个全文复筛结果进行人工审核决策
|
||||
|
||||
**路径参数**:
|
||||
- `resultId`: 结果ID
|
||||
|
||||
**霂瑟<EFBFBD>雿?*:
|
||||
**请求体**:
|
||||
```json
|
||||
{
|
||||
"finalDecision": "exclude",
|
||||
@@ -918,7 +968,8 @@ curl "http://localhost:3001/api/v1/asl/fulltext-screening/tasks/fst-20251123-001
|
||||
```
|
||||
|
||||
**字段说明**:
|
||||
- `finalDecision`: <EFBFBD><EFBFBD>蝏<EFBFBD><EFBFBD>蝑吔<EFBFBD>敹<EFBFBD>‵嚗? - `include`: 蝥喳<E89DA5>
|
||||
- `finalDecision`: 最终决策(必填)
|
||||
- `include`: 纳入
|
||||
- `exclude`: 排除
|
||||
- `exclusionReason`: 排除原因(`finalDecision === 'exclude'` 时必填)
|
||||
- `reviewNotes`: 审核备注(可选)
|
||||
@@ -943,8 +994,8 @@ curl -X PUT http://localhost:3001/api/v1/asl/fulltext-screening/results/fsr-002/
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"finalDecision": "exclude",
|
||||
"exclusionReason": "蝏枏<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>唳旿銝滚<EFBFBD><EFBFBD>?,
|
||||
"reviewNotes": "蝻箏<EFBFBD><EFBFBD><EFBFBD><EFBFBD>澆<EFBFBD><EFBFBD><EFBFBD><EFBFBD>撌?
|
||||
"exclusionReason": "结局指标数据不完整",
|
||||
"reviewNotes": "缺少均值和标准差"
|
||||
}'
|
||||
```
|
||||
|
||||
@@ -953,8 +1004,9 @@ curl -X PUT http://localhost:3001/api/v1/asl/fulltext-screening/results/fsr-002/
|
||||
#### 4.5 导出Excel
|
||||
|
||||
**接口**: `GET /api/v1/asl/fulltext-screening/tasks/:taskId/export`
|
||||
**霈方<EFBFBD>**: <EFBFBD><EFBFBD>閬?
|
||||
**霂湔<EFBFBD>**: 撖澆枂<EFBFBD>冽<EFBFBD>憭滨<EFBFBD>蝏𤘪<EFBFBD>銝慟xcel<EFBFBD><EFBFBD>辣嚗?銝杵heet嚗?
|
||||
**认证**: 需要
|
||||
**说明**: 导出全文复筛结果为Excel文件(3个Sheet)
|
||||
|
||||
**路径参数**:
|
||||
- `taskId`: 任务ID
|
||||
|
||||
@@ -969,52 +1021,52 @@ curl -X PUT http://localhost:3001/api/v1/asl/fulltext-screening/results/fsr-002/
|
||||
|------|------|
|
||||
| 序号 | 1, 2, 3... |
|
||||
| PMID | PubMed ID |
|
||||
| <EFBFBD><EFBFBD>讃<EFBFBD>交<EFBFBD> | 蝚砌<E89D9A>雿𡏭<E99BBF>?撟港遢 |
|
||||
| 文献来源 | 第一作者+年份 |
|
||||
| 标题 | 文献标题 |
|
||||
| 期刊 | 期刊名称 |
|
||||
| 年份 | 发表年份 |
|
||||
| DOI | DOI编号 |
|
||||
| <EFBFBD><EFBFBD>蝏<EFBFBD><EFBFBD>蝑?| 蝥喳<E89DA5> |
|
||||
| <EFBFBD>唳旿韐券<EFBFBD> | 擃?銝?雿?|
|
||||
| <EFBFBD>舀<EFBFBD><EFBFBD>𡝗<EFBFBD>?| <20>舀<EFBFBD><E88880>?<3F>典<EFBFBD><E585B8>舀<EFBFBD><E88880>?銝滚虾<E6BB9A>𣂼<EFBFBD> |
|
||||
| 璅∪<EFBFBD>銝<EFBFBD><EFBFBD>湔<EFBFBD>?| 銝<><E98A9D>?銝滢<E98A9D><E6BBA2>?|
|
||||
| <EFBFBD>臬炏鈭箏極摰⊥瓲 | <20>?<3F>?|
|
||||
| 最终决策 | 纳入 |
|
||||
| 数据质量 | 高/中/低 |
|
||||
| 可提取性 | 可提取/部分可提取/不可提取 |
|
||||
| 模型一致性 | 一致/不一致 |
|
||||
| 是否人工审核 | 是/否 |
|
||||
|
||||
**Sheet 2: 排除文献列表**
|
||||
| 列名 | 说明 |
|
||||
|------|------|
|
||||
| 序号 | 1, 2, 3... |
|
||||
| PMID | PubMed ID |
|
||||
| <EFBFBD><EFBFBD>讃<EFBFBD>交<EFBFBD> | 蝚砌<E89D9A>雿𡏭<E99BBF>?撟港遢 |
|
||||
| 文献来源 | 第一作者+年份 |
|
||||
| 标题 | 文献标题 |
|
||||
| 排除原因 | 详细排除原因 |
|
||||
| <EFBFBD>㘾膄摮埈挾 | field5, field9蝑?|
|
||||
| <EFBFBD>臬炏<EFBFBD>脩<EFBFBD> | <20>?<3F>?|
|
||||
| 摰⊥瓲鈭?| <20>冽<EFBFBD>ID |
|
||||
| 排除字段 | field5, field9等 |
|
||||
| 是否冲突 | 是/否 |
|
||||
| 审核人 | 用户ID |
|
||||
| 审核时间 | 2025-11-23 10:30 |
|
||||
|
||||
**Sheet 3: PRISMA统计**
|
||||
| 蝏蠘恣憿?| <20>圈<EFBFBD> | <20>曉<EFBFBD>瘥?|
|
||||
| 统计项 | 数量 | 百分比 |
|
||||
|--------|------|--------|
|
||||
| 全文复筛总数 | 30 | 100% |
|
||||
| <EFBFBD><EFBFBD>蝏<EFBFBD>熙<EFBFBD>?| 18 | 60% |
|
||||
| <EFBFBD><EFBFBD>蝏<EFBFBD><EFBFBD><EFBFBD>?| 12 | 40% |
|
||||
| - 蝏枏<EFBFBD><EFBFBD><EFBFBD><EFBFBD>蝻箏仃/銝滚<E98A9D><E6BB9A>?| 5 | 16.7% |
|
||||
| 最终纳入 | 18 | 60% |
|
||||
| 最终排除 | 12 | 40% |
|
||||
| - 结局指标缺失/不完整 | 5 | 16.7% |
|
||||
| - 人群特征不符 | 3 | 10% |
|
||||
| - 撟脤<EFBFBD><EFBFBD>芣鴌銝齿<EFBFBD>蝖?| 2 | 6.7% |
|
||||
| - 干预措施不明确 | 2 | 6.7% |
|
||||
| - 研究质量问题 | 1 | 3.3% |
|
||||
| - 其他原因 | 1 | 3.3% |
|
||||
| 璅∪<EFBFBD><EFBFBD>脩<EFBFBD><EFBFBD>?| 3 | 10% |
|
||||
| 鈭箏極摰⊥瓲<EFBFBD>?| 3 | 10% |
|
||||
| 模型冲突数 | 3 | 10% |
|
||||
| 人工审核数 | 3 | 10% |
|
||||
|
||||
**<EFBFBD>鞉𧋦蝏蠘恣嚗<EFBFBD><EFBFBD>憭𠼦heet嚗?*:
|
||||
| 憿寧𤌍 | <EFBFBD>?|
|
||||
**成本统计(额外Sheet)**:
|
||||
| 项目 | 值 |
|
||||
|------|-----|
|
||||
| <EFBFBD>蓉oken<EFBFBD>?| 450,000 |
|
||||
| 总Token数 | 450,000 |
|
||||
| 总成本(元) | ¥2.25 |
|
||||
| 撟喳<EFBFBD><EFBFBD>鞉𧋦/蝭?| 瞼0.075 |
|
||||
| 平均成本/篇 | ¥0.075 |
|
||||
| 模型组合 | DeepSeek-V3 + Qwen-Max |
|
||||
| 憭<EFBFBD><EFBFBD><EFBFBD>園𡢿 | 8<>?0蝘?|
|
||||
| 处理时间 | 8分30秒 |
|
||||
|
||||
**测试命令**:
|
||||
```bash
|
||||
@@ -1038,7 +1090,9 @@ curl -O -J http://localhost:3001/api/v1/asl/fulltext-screening/tasks/fst-2025112
|
||||
```
|
||||
|
||||
**HTTP状态码**:
|
||||
- `200` - <EFBFBD>𣂼<EFBFBD>嚗𠃑ET<EFBFBD><EFBFBD>UT嚗?- `201` - <20>𥕦遣<F0A595A6>𣂼<EFBFBD>嚗㇊OST嚗?
|
||||
- `200` - 成功(GET、PUT)
|
||||
- `201` - 创建成功(POST)
|
||||
|
||||
---
|
||||
|
||||
### 2. 错误响应
|
||||
@@ -1051,7 +1105,7 @@ curl -O -J http://localhost:3001/api/v1/asl/fulltext-screening/tasks/fst-2025112
|
||||
}
|
||||
```
|
||||
|
||||
<EFBFBD>吔<EFBFBD>霂衣<EFBFBD><EFBFBD>躰秤嚗?
|
||||
或(详细错误):
|
||||
```json
|
||||
{
|
||||
"error": "Missing required fields"
|
||||
@@ -1060,7 +1114,11 @@ curl -O -J http://localhost:3001/api/v1/asl/fulltext-screening/tasks/fst-2025112
|
||||
|
||||
**常见HTTP状态码**:
|
||||
- `400` - 请求参数错误
|
||||
- `401` - <EFBFBD>芣<EFBFBD><EFBFBD>?- `403` - <20>䭾<EFBFBD><E4ADBE>?- `404` - 韏<><E99F8F>銝滚<E98A9D><E6BB9A>?- `500` - <20>滚𦛚<E6BB9A>典<EFBFBD><E585B8>券<EFBFBD>霂?
|
||||
- `401` - 未授权
|
||||
- `403` - 无权限
|
||||
- `404` - 资源不存在
|
||||
- `500` - 服务器内部错误
|
||||
|
||||
**错误示例**:
|
||||
```json
|
||||
// 400 - 参数错误
|
||||
@@ -1068,11 +1126,13 @@ curl -O -J http://localhost:3001/api/v1/asl/fulltext-screening/tasks/fst-2025112
|
||||
"error": "Missing required fields"
|
||||
}
|
||||
|
||||
// 404 - 韏<EFBFBD><EFBFBD>銝滚<EFBFBD><EFBFBD>?{
|
||||
// 404 - 资源不存在
|
||||
{
|
||||
"error": "Project not found"
|
||||
}
|
||||
|
||||
// 500 - <EFBFBD>滚𦛚<EFBFBD>券<EFBFBD>霂?{
|
||||
// 500 - 服务器错误
|
||||
{
|
||||
"error": "Failed to create project"
|
||||
}
|
||||
```
|
||||
@@ -1086,7 +1146,8 @@ curl -O -J http://localhost:3001/api/v1/asl/fulltext-screening/tasks/fst-2025112
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"items": [...], // <EFBFBD>?literatures<EFBFBD><EFBFBD>esults 蝑? "pagination": {
|
||||
"items": [...], // 或 literatures、results 等
|
||||
"pagination": {
|
||||
"page": 1,
|
||||
"limit": 50,
|
||||
"total": 150,
|
||||
@@ -1100,12 +1161,14 @@ curl -O -J http://localhost:3001/api/v1/asl/fulltext-screening/tasks/fst-2025112
|
||||
- `page`: 当前页码(从1开始)
|
||||
- `limit`: 每页数量
|
||||
- `total`: 总记录数
|
||||
- `totalPages`: <EFBFBD>駁△<EFBFBD>?
|
||||
- `totalPages`: 总页数
|
||||
|
||||
---
|
||||
|
||||
## 🔐 认证授权
|
||||
|
||||
### 敶枏<EFBFBD><EFBFBD>嗆<EFBFBD><EFBFBD><EFBFBD>瘚贝<EFBFBD>璅∪<EFBFBD>嚗?
|
||||
### 当前状态(测试模式)
|
||||
|
||||
**测试用户**:
|
||||
- **用户ID**: `asl-test-user-001`
|
||||
- **邮箱**: `asl-test@example.com`
|
||||
@@ -1115,16 +1178,18 @@ curl -O -J http://localhost:3001/api/v1/asl/fulltext-screening/tasks/fst-2025112
|
||||
- 优先从JWT中获取`userId`
|
||||
- JWT不存在时使用默认测试用户ID
|
||||
|
||||
### <EFBFBD>煺漣<EFBFBD>臬<EFBFBD>嚗<EFBFBD><EFBFBD>摰䂿緵嚗?
|
||||
### 生产环境(待实现)
|
||||
|
||||
**认证流程**:
|
||||
1. 用户登录获取JWT Token
|
||||
2. 请求头携带Token: `Authorization: Bearer {token}`
|
||||
3. 中间件验证Token并提取`userId`
|
||||
4. 控制器使用`userId`查询用户数据
|
||||
|
||||
**銝剝𡢿隞嗥內靘?*:
|
||||
**中间件示例**:
|
||||
```typescript
|
||||
// 敺<EFBFBD><EFBFBD><EFBFBD>?fastify.addHook('preHandler', async (request, reply) => {
|
||||
// 待实现
|
||||
fastify.addHook('preHandler', async (request, reply) => {
|
||||
const token = request.headers.authorization?.replace('Bearer ', '');
|
||||
if (!token) {
|
||||
return reply.status(401).send({ error: 'Unauthorized' });
|
||||
@@ -1138,7 +1203,8 @@ curl -O -J http://localhost:3001/api/v1/asl/fulltext-screening/tasks/fst-2025112
|
||||
|
||||
## 🧪 API测试
|
||||
|
||||
### 敹恍<EFBFBD><EFBFBD><EFBFBD>霂閗<EFBFBD><EFBFBD>?
|
||||
### 快速测试脚本
|
||||
|
||||
**测试所有API**:
|
||||
```bash
|
||||
cd AIclinicalresearch/backend
|
||||
@@ -1147,9 +1213,18 @@ npx tsx scripts/test-asl-api.ts
|
||||
|
||||
**测试结果**:
|
||||
```
|
||||
<EFBFBD><EFBFBD> 撘<>憪𧢲<E686AA>霂?ASL 璅∪<EFBFBD> API...
|
||||
<EFBFBD><EFBFBD> 瘚贝<E7989A> 1/7: <20>亙熒璉<E78692><E79289>? <20>?<3F><> 瘚贝<E7989A> 2/7: <20>𥕦遣蝑偦<E89D91>厰★<E58EB0>? <20>?<3F><> 瘚贝<E7989A> 3/7: <20>瑕<EFBFBD>憿寧𤌍<E5AFA7>𡑒” <20>?<3F><> 瘚贝<E7989A> 4/7: <20>瑕<EFBFBD>憿寧𤌍霂行<E99C82> <20>?<3F><> 瘚贝<E7989A> 5/7: 撖澆<E69296><E6BE86><EFBFBD>讃 <20>?<3F><> 瘚贝<E7989A> 6/7: <20>瑕<EFBFBD><E79195><EFBFBD>讃<EFBFBD>𡑒” <20>?<3F><> 瘚贝<E7989A> 7/7: <20>湔鰵憿寧𤌍 <20>?<3F>鐥<EFBFBD><E990A5>鐥<EFBFBD><E990A5>鐥<EFBFBD><E990A5>鐥<EFBFBD><E990A5>鐥<EFBFBD><E990A5>鐥<EFBFBD><E990A5>鐥<EFBFBD><E990A5>鐥<EFBFBD><E990A5>鐥<EFBFBD><E990A5>鐥<EFBFBD><E990A5>鐥<EFBFBD><E990A5>鐥<EFBFBD><E990A5>鐥<EFBFBD><E990A5>鐥<EFBFBD><E990A5>鐥<EFBFBD><E990A5>鐥<EFBFBD><E990A5>鐥<EFBFBD><E990A5>?<3F><> <20><><EFBFBD>㗇<EFBFBD>霂閖<E99C82>朞<EFBFBD>嚗?7/7 - 100%)
|
||||
<EFBFBD>鐥<EFBFBD><EFBFBD>鐥<EFBFBD><EFBFBD>鐥<EFBFBD><EFBFBD>鐥<EFBFBD><EFBFBD>鐥<EFBFBD><EFBFBD>鐥<EFBFBD><EFBFBD>鐥<EFBFBD><EFBFBD>鐥<EFBFBD><EFBFBD>鐥<EFBFBD><EFBFBD>鐥<EFBFBD><EFBFBD>鐥<EFBFBD><EFBFBD>鐥<EFBFBD><EFBFBD>鐥<EFBFBD><EFBFBD>鐥<EFBFBD><EFBFBD>鐥<EFBFBD><EFBFBD>鐥<EFBFBD><EFBFBD>鐥<EFBFBD><EFBFBD>?```
|
||||
🚀 开始测试 ASL 模块 API...
|
||||
📍 测试 1/7: 健康检查 ✅
|
||||
📍 测试 2/7: 创建筛选项目 ✅
|
||||
📍 测试 3/7: 获取项目列表 ✅
|
||||
📍 测试 4/7: 获取项目详情 ✅
|
||||
📍 测试 5/7: 导入文献 ✅
|
||||
📍 测试 6/7: 获取文献列表 ✅
|
||||
📍 测试 7/7: 更新项目 ✅
|
||||
═══════════════════════════════════
|
||||
🎉 所有测试通过!(7/7 - 100%)
|
||||
═══════════════════════════════════
|
||||
```
|
||||
|
||||
### Postman集合
|
||||
|
||||
@@ -1182,35 +1257,41 @@ Body (raw JSON):
|
||||
|
||||
| 接口类型 | 目标响应时间 | 说明 |
|
||||
|---------|-------------|------|
|
||||
| <EFBFBD>蓥葵<EFBFBD>亥砭 | < 100ms | 憿寧𤌍霂行<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>株祕<EFBFBD>?|
|
||||
| <EFBFBD>𡑒”<EFBFBD>亥砭 | < 200ms | 憿寧𤌍<EFBFBD>𡑒”<EFBFBD><EFBFBD><EFBFBD><EFBFBD>桀<EFBFBD>銵?|
|
||||
| <EFBFBD>𥕦遣/<2F>湔鰵 | < 300ms | <EFBFBD>𥕦遣憿寧𤌍<EFBFBD><EFBFBD>凒<EFBFBD>圈★<EFBFBD>?|
|
||||
| <EFBFBD>寥<EFBFBD>撖澆<EFBFBD> | < 2s | 撖澆<EFBFBD>100蝭<EFBFBD><EFBFBD><EFBFBD>?|
|
||||
| LLM蝑偦<EFBFBD>?| 4-6s/蝭?| <20>峕芋<E5B395>见僎銵𣬚<E98AB5><F0A3AC9A>?|
|
||||
| 单个查询 | < 100ms | 项目详情、文献详情 |
|
||||
| 列表查询 | < 200ms | 项目列表、文献列表 |
|
||||
| 创建/更新 | < 300ms | 创建项目、更新项目 |
|
||||
| 批量导入 | < 2s | 导入100篇文献 |
|
||||
| LLM筛选 | 4-6s/篇 | 双模型并行筛选 |
|
||||
|
||||
### 并发能力
|
||||
|
||||
- **API<EFBFBD>滚𦛚<EFBFBD>?*: <20>舀<EFBFBD>100+撟嗅<E6929F>霂瑟<E99C82>
|
||||
- **LLM蝑偦<EFBFBD>?*: 撟嗅<E6929F><E59785>唬蛹3嚗<33>虾<EFBFBD>滨蔭嚗?- **<2A>唳旿摨栞<E691A8><E6A09E>交<EFBFBD>**: 17銝芾<E98A9D><E88ABE>?
|
||||
- **API服务器**: 支持100+并发请求
|
||||
- **LLM筛选**: 并发数为3(可配置)
|
||||
- **数据库连接池**: 17个连接
|
||||
|
||||
---
|
||||
|
||||
## 🔄 版本历史
|
||||
|
||||
### v3.0 (2025-11-23)
|
||||
- <20>?<3F>啣<EFBFBD><E595A3>冽<EFBFBD>憭滨<E686AD>蝞∠<E89D9E>API嚗?銝芣𦻖<E88AA3><F0A6BB96><EFBFBD>
|
||||
- ✅ 新增全文复筛管理API(5个接口)
|
||||
- 创建任务、获取进度、获取结果、人工审核、导出Excel
|
||||
- <20>?<3F>舀<EFBFBD>12摮埈挾霂衣<E99C82>霂<EFBFBD>摯
|
||||
- <20>?<3F>舀<EFBFBD><E88880>峕芋<E5B395>见笆瘥𥪜<E798A5><F0A5AA9C>脩<EFBFBD>璉<EFBFBD>瘚?- <20>?摰峕㟲<E5B395><E39FB2>xcel撖澆枂<E6BE86>蠘<EFBFBD>嚗? Sheets嚗?- <20>?靚<>㟲<EFBFBD><E39FB2>﹝蝏𤘪<E89D8F>嚗?憭扳芋<E689B3>梹<EFBFBD>
|
||||
- ✅ 支持12字段详细评估
|
||||
- ✅ 支持双模型对比和冲突检测
|
||||
- ✅ 完整的Excel导出功能(3 Sheets)
|
||||
- ✅ 调整文档结构(5大模块)
|
||||
|
||||
### v2.1 (2025-11-21)
|
||||
- <20>?<3F>啣<EFBFBD>蝏蠘恣API<50>亙藁
|
||||
- <20>?<3F>湔鰵PICOS<4F>澆<EFBFBD>霂湔<E99C82>
|
||||
- <20>?瘛餃<E7989B>鈭穃<E988AD><E7A983><EFBFBD>沲<EFBFBD><E6B2B2><EFBFBD>瘜?
|
||||
- ✅ 新增统计API接口
|
||||
- ✅ 更新PICOS格式说明
|
||||
- ✅ 添加云原生架构标注
|
||||
|
||||
### v2.0 (2025-11-18)
|
||||
- <20>?摰䂿緵10銝芣瓲敹<E793B2>PI蝡舐<E89DA1>
|
||||
- <20>?摰峕<E691B0>憿寧𤌍蝞∠<E89D9E><E288A0>蠘<EFBFBD>
|
||||
- <20>?摰峕<E691B0><E5B395><EFBFBD>讃蝞∠<E89D9E><E288A0>蠘<EFBFBD>
|
||||
- <20>?瘛餃<E7989B>瘚贝<E7989A><E8B49D>𡁏𧋦<F0A1818F>峕<EFBFBD>獢?- <20>?<3F><><EFBFBD>㗇𦻖<E39787><F0A6BB96><EFBFBD>霂閖<E99C82>朞<EFBFBD>
|
||||
- ✅ 实现10个核心API端点
|
||||
- ✅ 完成项目管理功能
|
||||
- ✅ 完成文献管理功能
|
||||
- ✅ 添加测试脚本和文档
|
||||
- ✅ 所有接口测试通过
|
||||
|
||||
### v1.0 (2025-10-29)
|
||||
- 初始API设计规范
|
||||
@@ -1218,15 +1299,17 @@ Body (raw JSON):
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD>?<3F>𡒊賒閫<E8B392><E996AB>
|
||||
## ⏳ 后续规划
|
||||
|
||||
### Week 2
|
||||
- [ ] 摰䂿緵蝑偦<E89D91>劐遙<E58A90>,PI (3銝芣𦻖<E88AA3>?
|
||||
- [ ] 摰䂿緵<E482BF>脩<EFBFBD>摰⊥瓲API (2銝芣𦻖<EFBFBD>?
|
||||
- [ ] 瘛餃<E7989B>SSE餈𥕦漲<F0A595A6>券<EFBFBD>?- [ ] <20><><EFBFBD>撘<EFBFBD>郊隞餃𦛚<E9A483>笔<EFBFBD>
|
||||
- [ ] 实现筛选任务API (3个接口)
|
||||
- [ ] 实现冲突审核API (2个接口)
|
||||
- [ ] 添加SSE进度推送
|
||||
- [ ] 集成异步任务队列
|
||||
|
||||
### Week 3-4
|
||||
- [ ] 瘛餃<E7989B>JWT霈方<E99C88>銝剝𡢿隞?- [ ] 摰䂿緵<E482BF><E7B7B5><EFBFBD><EFBFBD>批<EFBFBD>
|
||||
- [ ] 添加JWT认证中间件
|
||||
- [ ] 实现权限控制
|
||||
- [ ] 添加API限流
|
||||
- [ ] 完善错误处理
|
||||
|
||||
@@ -1239,8 +1322,9 @@ Body (raw JSON):
|
||||
#### 5.1 获取项目统计数据(云原生:后端聚合)
|
||||
|
||||
**接口**: `GET /api/v1/asl/projects/:projectId/statistics`
|
||||
**霈方<EFBFBD>**: <EFBFBD><EFBFBD>閬?
|
||||
**霂湔<EFBFBD>**: <EFBFBD>瑕<EFBFBD>憿寧𤌍<EFBFBD><EFBFBD><EFBFBD><EFBFBD>厩<EFBFBD>霈⊥㺭<EFBFBD>殷<EFBFBD><EFBFBD>餅㺭<EFBFBD><EFBFBD>熙<EFBFBD>亦<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>斤<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>文<EFBFBD><EFBFBD>惩<EFBFBD><EFBFBD>鞟<EFBFBD>嚗?
|
||||
**认证**: 需要
|
||||
**说明**: 获取项目的筛选统计数据(总数、纳入率、排除率、排除原因分析等)
|
||||
|
||||
**路径参数**:
|
||||
- `projectId`: 项目ID
|
||||
|
||||
@@ -1256,9 +1340,9 @@ Body (raw JSON):
|
||||
"conflict": 24,
|
||||
"reviewed": 175,
|
||||
"exclusionReasons": {
|
||||
"P銝滚龪<EFBFBD>㵪<EFBFBD>鈭箇黎嚗?: 40,
|
||||
"I銝滚龪<EFBFBD>㵪<EFBFBD>撟脤<EFBFBD>嚗?: 25,
|
||||
"S銝滚龪<EFBFBD>㵪<EFBFBD><EFBFBD>𠉛弦霈曇恣嚗?: 15,
|
||||
"P不匹配(人群)": 40,
|
||||
"I不匹配(干预)": 25,
|
||||
"S不匹配(研究设计)": 15,
|
||||
"其他原因": 10
|
||||
},
|
||||
"includedRate": "42.7",
|
||||
@@ -1268,9 +1352,11 @@ Body (raw JSON):
|
||||
}
|
||||
```
|
||||
|
||||
**<EFBFBD>寧<EFBFBD>**嚗?- <20>?鈭穃<E988AD><E7A983><EFBFBD><EFBFBD><EFBFBD>𡒊垢Prisma<6D>𡁜<EFBFBD><F0A1819C>亥砭嚗?銝芸僎銵峕䰻霂g<E99C82>
|
||||
- <EFBFBD>?<3F>扯<EFBFBD>嚗?500ms嚗?99蝭<39><E89DAD><EFBFBD>殷<EFBFBD>
|
||||
- <EFBFBD>?<3F>誩<EFBFBD>蝵𤑳<E89DB5>隡㰘<E99AA1>嚗帋<E59A97>MB蝥折<E89DA5><E68A98>袁B蝥?
|
||||
**特点**:
|
||||
- ✅ 云原生:后端Prisma聚合查询(6个并行查询)
|
||||
- ✅ 性能:<500ms(199篇文献)
|
||||
- ✅ 减少网络传输:从MB级降到KB级
|
||||
|
||||
**测试命令**:
|
||||
```bash
|
||||
curl http://localhost:3001/api/v1/asl/projects/55941145-bba0-4b15-bda4-f0a398d78208/statistics
|
||||
@@ -1278,18 +1364,21 @@ curl http://localhost:3001/api/v1/asl/projects/55941145-bba0-4b15-bda4-f0a398d78
|
||||
|
||||
---
|
||||
|
||||
**<EFBFBD><EFBFBD>﹝<EFBFBD><EFBFBD>𧋦嚗?* v3.0
|
||||
**<EFBFBD><EFBFBD><EFBFBD>擧凒<EFBFBD>堆<EFBFBD>** 2025-11-23嚗㇄ay 5: <EFBFBD>冽<EFBFBD>憭滨<EFBFBD>API嚗?
|
||||
**蝏湔擪<EFBFBD><EFBFBD><EFBFBD>** AI<EFBFBD>箄<EFBFBD><EFBFBD><EFBFBD>讃撘<EFBFBD><EFBFBD>穃𣪧<EFBFBD>?
|
||||
**<EFBFBD>祆活<EFBFBD>湔鰵**嚗?- <20>?<3F>啣<EFBFBD><E595A3>冽<EFBFBD>憭滨<E686AD>蝞∠<E89D9E>API嚗?銝芣瓲敹<E793B2>𦻖<EFBFBD><F0A6BB96><EFBFBD>
|
||||
- <20>?霂衣<E99C82><E8A1A3>?2摮埈挾霂<E68CBE>摯<EFBFBD><E691AF>﹝
|
||||
- <EFBFBD>?<3F>峕芋<E5B395>见笆瘥𥪜<E798A5><F0A5AA9C>脩<EFBFBD>璉<EFBFBD>瘚贝秩<E8B49D>?- <20>?Excel撖澆枂<E6BE86>澆<EFBFBD>閫<EFBFBD><E996AB>
|
||||
- <EFBFBD>?摰峕㟲<E5B395><E39FB2>窈瘙?<3F>滚<EFBFBD>蝷箔<E89DB7>
|
||||
**文档版本:** v3.0
|
||||
**最后更新:** 2025-11-23(Day 5: 全文复筛API)
|
||||
**维护者:** AI智能文献开发团队
|
||||
|
||||
**本次更新**:
|
||||
- ✅ 新增全文复筛管理API(5个核心接口)
|
||||
- ✅ 详细的12字段评估文档
|
||||
- ✅ 双模型对比和冲突检测说明
|
||||
- ✅ Excel导出格式规范
|
||||
- ✅ 完整的请求/响应示例
|
||||
|
||||
---
|
||||
|
||||
## 📚 相关文档
|
||||
|
||||
- [<EFBFBD>唳旿摨栞挽霈⊥<EFBFBD>獢β(./01-<2D>唳旿摨栞挽霈?md)
|
||||
- [数据库设计文档](./01-数据库设计.md)
|
||||
- [API测试报告](../../../backend/ASL-API-测试报告.md)
|
||||
- [Week 1摰峕<EFBFBD><EFBFBD>亙<EFBFBD>](../05-撘<EFBFBD><EFBFBD>𤏸扇敶?2025-11-18-Week1摰峕<EFBFBD><EFBFBD>亙<EFBFBD>.md)
|
||||
- [Week 1完成报告](../05-开发记录/2025-11-18-Week1完成报告.md)
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
# AI智能文献模块 - 前端组件设计
|
||||
|
||||
> **<EFBFBD><EFBFBD>﹝<EFBFBD><EFBFBD>𧋦嚗?* v1.0
|
||||
> **<EFBFBD>𥕦遣<EFBFBD>交<EFBFBD>嚗?* 2025-10-29
|
||||
> **蝏湔擪<EFBFBD><EFBFBD><EFBFBD>** AI<41>箄<EFBFBD><E7AE84><EFBFBD>讃撘<E8AE83><E69298>穃𣪧<E7A983>?
|
||||
> **文档版本:** v1.0
|
||||
> **创建日期:** 2025-10-29
|
||||
> **维护者:** AI智能文献开发团队
|
||||
> **最后更新:** 2025-10-29
|
||||
|
||||
---
|
||||
|
||||
## 📋 文档说明
|
||||
|
||||
<EFBFBD>祆<EFBFBD>獢<EFBFBD><EFBFBD>餈蚊I<EFBFBD>箄<EFBFBD><EFBFBD><EFBFBD>讃璅∪<EFBFBD><EFBFBD><EFBFBD><EFBFBD>蝡舐<EFBFBD>隞嗉挽霈∴<EFBFBD><EFBFBD><EFBFBD>𡠺蝏<EFBFBD>辣蝏𤘪<EFBFBD><EFBFBD><EFBFBD><EFBFBD>隞嗆𦻖<EFBFBD><EFBFBD><EFBFBD><EFBFBD>漱鈭坿挽霈∠<EFBFBD><EFBFBD>?
|
||||
本文档描述AI智能文献模块的前端组件设计,包括组件结构、组件接口、交互设计等。
|
||||
|
||||
---
|
||||
|
||||
@@ -20,37 +20,37 @@
|
||||
```
|
||||
LiteratureScreeningModule/
|
||||
├── TitleAbstractScreening/
|
||||
<EFBFBD>? <20>鎿<EFBFBD><E98EBF><EFBFBD> SetupView/ # 霈曄蔭銝𤾸鍳<EFBFBD>刻<EFBFBD><EFBFBD>?
|
||||
<EFBFBD>? <20>? <20>鎿<EFBFBD><E98EBF><EFBFBD> CriteriaReference.tsx # <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>𢒰<EFBFBD>?
|
||||
<EFBFBD>? <20>? <20>鎿<EFBFBD><E98EBF><EFBFBD> CriteriaAdjustment.tsx # 銝湔𧒄靚<EFBFBD>㟲<EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD>? <20>? <20>鎿<EFBFBD><E98EBF><EFBFBD> LiteratureImport.tsx # <EFBFBD><EFBFBD>讃撖澆<EFBFBD>蝏<EFBFBD>辣
|
||||
<EFBFBD>? <20>? <20>婙<EFBFBD><E5A999><EFBFBD> StartScreeningButton.tsx # <EFBFBD>臬𢆡蝑偦<EFBFBD>㗇<EFBFBD><EFBFBD>?
|
||||
<EFBFBD>? <20>?
|
||||
<EFBFBD>? <20>鎿<EFBFBD><E98EBF><EFBFBD> ReviewTableView/ # 銵冽聢<EFBFBD>硋恣<EFBFBD>詨極雿𨅯蝱 潃鞉瓲敹?
|
||||
<EFBFBD>? <20>? <20>鎿<EFBFBD><E98EBF><EFBFBD> ScreeningTable.tsx # 銝餉”<EFBFBD>潛<EFBFBD>隞?
|
||||
<EFBFBD>? <20>? <20>鎿<EFBFBD><E98EBF><EFBFBD> TableHeader.tsx # 銵典仍嚗<EFBFBD><EFBFBD>銵𣬚<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD>? <20>? <20>鎿<EFBFBD><E98EBF><EFBFBD> TableRow.tsx # 銵冽聢銵?
|
||||
<EFBFBD>? <20>? <20>鎿<EFBFBD><E98EBF><EFBFBD> ExpandableRow.tsx # <EFBFBD>臬<EFBFBD>撘<EFBFBD>銵䕘<EFBFBD>霂<EFBFBD>旿撅閧內嚗?
|
||||
<EFBFBD>? <20>? <20>鎿<EFBFBD><E98EBF><EFBFBD> JudgmentCell.tsx # <EFBFBD>斗鱏<EFBFBD>訫<EFBFBD><EFBFBD>潘<EFBFBD><EFBFBD>?<3F>??嚗?
|
||||
<EFBFBD>? <20>? <20>鎿<EFBFBD><E98EBF><EFBFBD> ConflictIndicator.tsx # <EFBFBD>脩<EFBFBD><EFBFBD>嗆<EFBFBD><EFBFBD><EFBFBD>蝷箏膥
|
||||
<EFBFBD>? <20>? <20>婙<EFBFBD><E5A999><EFBFBD> DecisionSelector.tsx # <EFBFBD><EFBFBD>蝏<EFBFBD><EFBFBD>蝑㚚<EFBFBD>㗇𥋘<EFBFBD>?
|
||||
<EFBFBD>? <20>?
|
||||
<EFBFBD>? <20>鎿<EFBFBD><E98EBF><EFBFBD> EvidenceModal/ # <EFBFBD>諹<EFBFBD><EFBFBD>曉<EFBFBD><EFBFBD><EFBFBD>恣<EFBFBD>交芋<EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD>? <20>? <20>鎿<EFBFBD><E98EBF><EFBFBD> ModalContainer.tsx # 璅⊥<EFBFBD><EFBFBD><EFBFBD>摰孵膥
|
||||
<EFBFBD>? <20>? <20>鎿<EFBFBD><E98EBF><EFBFBD> AbstractView.tsx # 撌虫儒嚗𡁏<EFBFBD>閬<EFBFBD><EFBFBD><EFBFBD>?
|
||||
<EFBFBD>? <20>? <20>鎿<EFBFBD><E98EBF><EFBFBD> EvidenceView.tsx # <EFBFBD>喃儒嚗朞<EFBFBD><EFBFBD>株<EFBFBD><EFBFBD>?
|
||||
<EFBFBD>? <20>? <20>婙<EFBFBD><E5A999><EFBFBD> HighlightedText.tsx # 擃䀝漁<EFBFBD><EFBFBD>𧋦蝏<EFBFBD>辣
|
||||
<EFBFBD>? <20>?
|
||||
<EFBFBD>? <20>鎿<EFBFBD><E98EBF><EFBFBD> ResultView/ # 蝏𤘪<EFBFBD>撅閧內閫<EFBFBD>㦛
|
||||
<EFBFBD>? <20>? <20>鎿<EFBFBD><E98EBF><EFBFBD> StatisticsCards.tsx # 蝏蠘恣<EFBFBD>∠<EFBFBD>
|
||||
<EFBFBD>? <20>? <20>鎿<EFBFBD><E98EBF><EFBFBD> PrismaSummary.tsx # PRISMA撘𤩺<EFBFBD><EFBFBD>斗<EFBFBD>餌<EFBFBD>
|
||||
<EFBFBD>? <20>? <20>鎿<EFBFBD><E98EBF><EFBFBD> ResultTabs.tsx # 蝏𤘪<EFBFBD>Tab憿?
|
||||
<EFBFBD>? <20>? <20>婙<EFBFBD><E5A999><EFBFBD> ResultTable.tsx # 蝏𤘪<EFBFBD>銵冽聢
|
||||
<EFBFBD>? <20>?
|
||||
<EFBFBD>? <20>婙<EFBFBD><E5A999><EFBFBD> shared/ # <EFBFBD>曹澈蝏<EFBFBD>辣
|
||||
<EFBFBD>? <EFBFBD>鎿<EFBFBD><EFBFBD><EFBFBD> ProtocolOverview.tsx # <EFBFBD>𠉛弦<EFBFBD>寞<EFBFBD>璁<EFBFBD><EFBFBD><EFBFBD>X踎
|
||||
<EFBFBD>? <EFBFBD>鎿<EFBFBD><EFBFBD><EFBFBD> BatchOperation.tsx # <EFBFBD>寥<EFBFBD><EFBFBD>滢<EFBFBD>蝏<EFBFBD>辣
|
||||
<EFBFBD>? <EFBFBD>婙<EFBFBD><EFBFBD><EFBFBD> ExportButton.tsx # 撖澆枂<EFBFBD>厰僼
|
||||
│ ├── SetupView/ # 设置与启动视图
|
||||
│ │ ├── CriteriaReference.tsx # 标准参考面板
|
||||
│ │ ├── CriteriaAdjustment.tsx # 临时调整标准
|
||||
│ │ ├── LiteratureImport.tsx # 文献导入组件
|
||||
│ │ └── StartScreeningButton.tsx # 启动筛选按钮
|
||||
│ │
|
||||
│ ├── ReviewTableView/ # 表格化审核工作台 ⭐核心
|
||||
│ │ ├── ScreeningTable.tsx # 主表格组件
|
||||
│ │ ├── TableHeader.tsx # 表头(双行结构)
|
||||
│ │ ├── TableRow.tsx # 表格行
|
||||
│ │ ├── ExpandableRow.tsx # 可展开行(证据展示)
|
||||
│ │ ├── JudgmentCell.tsx # 判断单元格(✓/✗/?)
|
||||
│ │ ├── ConflictIndicator.tsx # 冲突状态指示器
|
||||
│ │ └── DecisionSelector.tsx # 最终决策选择器
|
||||
│ │
|
||||
│ ├── EvidenceModal/ # 双视图原文审查模态框
|
||||
│ │ ├── ModalContainer.tsx # 模态框容器
|
||||
│ │ ├── AbstractView.tsx # 左侧:摘要视图
|
||||
│ │ ├── EvidenceView.tsx # 右侧:证据视图
|
||||
│ │ └── HighlightedText.tsx # 高亮文本组件
|
||||
│ │
|
||||
│ ├── ResultView/ # 结果展示视图
|
||||
│ │ ├── StatisticsCards.tsx # 统计卡片
|
||||
│ │ ├── PrismaSummary.tsx # PRISMA式排除总结
|
||||
│ │ ├── ResultTabs.tsx # 结果Tab页
|
||||
│ │ └── ResultTable.tsx # 结果表格
|
||||
│ │
|
||||
│ └── shared/ # 共享组件
|
||||
│ ├── ProtocolOverview.tsx # 研究方案概览面板
|
||||
│ ├── BatchOperation.tsx # 批量操作组件
|
||||
│ └── ExportButton.tsx # 导出按钮
|
||||
```
|
||||
|
||||
---
|
||||
@@ -60,7 +60,7 @@ LiteratureScreeningModule/
|
||||
### 1. ScreeningTable (表格化审核工作台)
|
||||
|
||||
**组件职责**:
|
||||
- 撅閧內<EFBFBD><EFBFBD>讃<EFBFBD>𡑒”<EFBFBD>𣬚<EFBFBD><EFBFBD>厩<EFBFBD><EFBFBD>?
|
||||
- 展示文献列表和筛选结果
|
||||
- 支持展开/收起查看证据
|
||||
- 支持点击判断查看详情
|
||||
- 支持批量操作
|
||||
@@ -80,7 +80,7 @@ interface ScreeningTableProps {
|
||||
|
||||
**组件职责**:
|
||||
- 左侧显示摘要/全文
|
||||
- <EFBFBD>喃儒<EFBFBD>曄內AI<EFBFBD>斗鱏<EFBFBD>諹<EFBFBD><EFBFBD>?
|
||||
- 右侧显示AI判断和证据
|
||||
- 支持文本高亮
|
||||
- 支持查看引用来源
|
||||
|
||||
@@ -98,14 +98,14 @@ interface EvidenceModalProps {
|
||||
|
||||
**组件职责**:
|
||||
- 整合表格和模态框
|
||||
- 蝞∠<EFBFBD>蝑偦<EFBFBD>厩𠶖<EFBFBD>?
|
||||
- 管理筛选状态
|
||||
- 处理用户交互
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD><EFBFBD> <20>嗆<EFBFBD><E59786>恣<EFBFBD>?
|
||||
## 🔄 状态管理
|
||||
|
||||
### 雿輻鍂Zustand蝞∠<EFBFBD>蝑偦<EFBFBD>厩𠶖<EFBFBD>?
|
||||
### 使用Zustand管理筛选状态
|
||||
|
||||
```typescript
|
||||
interface ScreeningStore {
|
||||
@@ -124,26 +124,26 @@ interface ScreeningStore {
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD>𢲡 <20>滚<EFBFBD>撘讛挽霈?
|
||||
## 📱 响应式设计
|
||||
|
||||
### 表格布局适配
|
||||
- **獢屸𢒰蝡?*: 摰峕㟲銵冽聢<E586BD>曄內
|
||||
- **撟單踎蝡?*: <20>舀赤<E88880>烐<EFBFBD><E78390>剁<EFBFBD><E58981>喲睸<E596B2>堒𤐄摰?
|
||||
- **蝘餃𢆡蝡?*: <20>∠<EFBFBD>撘誩<E69298>撅<EFBFBD><E69285>蹂誨銵冽聢
|
||||
- **桌面端**: 完整表格显示
|
||||
- **平板端**: 可横向滚动,关键列固定
|
||||
- **移动端**: 卡片式布局替代表格
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD>?敺<><E695BA><EFBFBD><EFBFBD><EFBFBD>摰?
|
||||
## ⏳ 待完善内容
|
||||
|
||||
后续将补充:
|
||||
- 详细组件接口定义
|
||||
- 蝏<EFBFBD>辣鈭支<EFBFBD>瘚<EFBFBD><EFBFBD><EFBFBD>?
|
||||
- 组件交互流程图
|
||||
- 样式设计规范
|
||||
- 组件使用示例
|
||||
|
||||
---
|
||||
|
||||
**<EFBFBD><EFBFBD>﹝<EFBFBD><EFBFBD>𧋦嚗?* v1.0
|
||||
**文档版本:** v1.0
|
||||
**最后更新:** 2025-10-29
|
||||
|
||||
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
# AI模型集成设计
|
||||
|
||||
> **鏂囨。鐗堟湰锛?* v1.0
|
||||
> **鍒涘缓鏃ユ湡锛?* 2025-10-29
|
||||
> **缁存姢鑰咃細** AI鏅鸿兘鏂囩尞寮€鍙戝洟闃?
|
||||
> **文档版本:** v1.0
|
||||
> **创建日期:** 2025-10-29
|
||||
> **维护者:** AI智能文献开发团队
|
||||
|
||||
---
|
||||
|
||||
## 鈴?寰呭畬鍠?
|
||||
## ⏳ 待完善
|
||||
|
||||
鏈<EFBFBD>枃妗e唴瀹瑰緟瑙勫垝瀹屽杽锛岀洰鍓嶄粎浣滀负鍗犱綅鏂囨。銆?
|
||||
本文档内容待规划完善,目前仅作为占位文档。
|
||||
|
||||
---
|
||||
|
||||
**鏂囨。鐗堟湰锛?* v1.0
|
||||
**文档版本:** v1.0
|
||||
**最后更新:** 2025-10-29
|
||||
|
||||
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
# 文件处理设计
|
||||
|
||||
> **鏂囨。鐗堟湰锛?* v1.0
|
||||
> **鍒涘缓鏃ユ湡锛?* 2025-10-29
|
||||
> **缁存姢鑰咃細** AI鏅鸿兘鏂囩尞寮€鍙戝洟闃?
|
||||
> **文档版本:** v1.0
|
||||
> **创建日期:** 2025-10-29
|
||||
> **维护者:** AI智能文献开发团队
|
||||
|
||||
---
|
||||
|
||||
## 鈴?寰呭畬鍠?
|
||||
## ⏳ 待完善
|
||||
|
||||
鏈<EFBFBD>枃妗e唴瀹瑰緟瑙勫垝瀹屽杽锛岀洰鍓嶄粎浣滀负鍗犱綅鏂囨。銆?
|
||||
本文档内容待规划完善,目前仅作为占位文档。
|
||||
|
||||
---
|
||||
|
||||
**鏂囨。鐗堟湰锛?* v1.0
|
||||
**文档版本:** v1.0
|
||||
**最后更新:** 2025-10-29
|
||||
|
||||
|
||||
|
||||
@@ -1,71 +1,71 @@
|
||||
# ASL 质量保障与可追溯策略
|
||||
|
||||
> **鏂囨。鐗堟湰锛?* V1.0
|
||||
> **鍒涘缓鏃ユ湡锛?* 2025-11-15
|
||||
> **閫傜敤妯″潡锛?* AI 鏅鸿兘鏂囩尞锛圓SL锛?
|
||||
> **鐩<EFBFBD>爣锛?* 鍒嗛樁娈垫彁鍗囨枃鐚<E69E83>瓫閫夈€佹暟鎹<E69A9F>彁鍙栫殑鍑嗙‘鐜囥€佽川閲忔帶鍒跺拰鍙<E68BB0>拷婧<E68BB7>€?
|
||||
> **文档版本:** V1.0
|
||||
> **创建日期:** 2025-11-15
|
||||
> **适用模块:** AI 智能文献(ASL)
|
||||
> **目标:** 分阶段提升文献筛选、数据提取的准确率、质量控制和可追溯性
|
||||
|
||||
---
|
||||
|
||||
## 📋 文档概述
|
||||
|
||||
鏈<EFBFBD>枃妗e畾涔変簡 ASL 妯″潡鍦?**MVP 鈫?V1.0 鈫?V2.0** 涓変釜闃舵<E99783>涓<EFBFBD>紝濡備綍閫愭<E996AB>鎻愬崌锛?
|
||||
1. **鎻愬彇鍑嗙‘鐜?*锛氫粠鍩虹<E98DA9>鍙<EFBFBD>敤 鈫?楂樿川閲?鈫?鍖诲<E98D96>绾ф爣鍑?
|
||||
2. **璐ㄩ噺鎺у埗**锛氫粠浜哄伐鎶芥煡 鈫?鑷<>姩楠岃瘉 鈫?鏅鸿兘浠茶<E6B5A0>
|
||||
3. **鍙<EFBFBD>拷婧<EFBFBD>€?*锛氫粠鍩烘湰璁板綍 鈫?瀹屾暣璇佹嵁閾?鈫?瀹¤<E780B9>绾ф棩蹇?
|
||||
本文档定义了 ASL 模块在 **MVP → V1.0 → V2.0** 三个阶段中,如何逐步提升:
|
||||
1. **提取准确率**:从基础可用 → 高质量 → 医学级标准
|
||||
2. **质量控制**:从人工抽查 → 自动验证 → 智能仲裁
|
||||
3. **可追溯性**:从基本记录 → 完整证据链 → 审计级日志
|
||||
|
||||
### 核心设计原则
|
||||
|
||||
| 原则 | 说明 |
|
||||
|------|------|
|
||||
| **鎴愭湰鍙<EFBFBD>帶** | MVP 闃舵<EFBFBD>浼樺厛浣跨敤 DeepSeek + Qwen3锛屾垚鏈<EFBFBD>晱鎰?|
|
||||
| **璐ㄩ噺鍙<EFBFBD>崌绾?* | 鍙<>垏鎹㈠埌 GPT-5-Pro + Claude-4.5 楂樼<EFBFBD>缁勫悎 |
|
||||
| **鍒嗘<EFBFBD>瀹炴柦** | 閬垮厤杩囧害璁捐<EFBFBD>锛屾瘡涓<EFBFBD>樁娈典氦浠樺彲鐢ㄥ姛鑳?|
|
||||
| **鍖诲<EFBFBD>鍦烘櫙浼樺寲** | 閽堝<E996BD>鑻辨枃鍖诲<E98D96>鏂囩尞鐨勭壒鐐逛紭鍖栫瓥鐣?|
|
||||
| **成本可控** | MVP 阶段优先使用 DeepSeek + Qwen3,成本敏感 |
|
||||
| **质量可升级** | 可切换到 GPT-5-Pro + Claude-4.5 高端组合 |
|
||||
| **分步实施** | 避免过度设计,每个阶段交付可用功能 |
|
||||
| **医学场景优化** | 针对英文医学文献的特点优化策略 |
|
||||
|
||||
---
|
||||
|
||||
## 🎯 三阶段路线图
|
||||
|
||||
```
|
||||
MVP (4鍛? V1.0 (6鍛? V2.0 (8鍛?
|
||||
鈹溾攢 鍩虹<E98DA9>鍙屾ā鍨嬮獙璇? 鈹溾攢 鏅鸿兘璐ㄩ噺鎺у埗 鈹溾攢 鍖诲<E98D96>绾ц川閲忎繚闅?
|
||||
鈹溾攢 JSON Schema 绾︽潫 鈹溾攢 鍒嗘<E98D92>鎻愬彇浼樺寲 鈹溾攢 澶氭ā鍨嬪叡璇嗕徊瑁?
|
||||
鈹溾攢 缃<>俊搴﹁瘎鍒? 鈹溾攢 璇佹嵁閾惧畬鏁磋拷婧? 鈹溾攢 鑷<>姩璐ㄩ噺瀹¤<E780B9>
|
||||
鈹溾攢 浜哄伐澶嶆牳鏈哄埗 鈹溾攢 瑙勫垯寮曟搸楠岃瘉 鈹溾攢 鎻愮ず璇嶇増鏈<E5A297><E98F88>鐞?
|
||||
鈹斺攢 鍩烘湰杩芥函鏃ュ織 鈹斺攢 Few-shot 绀轰緥搴? 鈹斺攢 HITL 鏅鸿兘鍒嗘祦
|
||||
鈫? 鈫? 鈫?
|
||||
鍙<EFBFBD>敤 楂樿川閲? 鍖诲<EFBFBD>绾?
|
||||
MVP (4周) V1.0 (6周) V2.0 (8周)
|
||||
├─ 基础双模型验证 ├─ 智能质量控制 ├─ 医学级质量保障
|
||||
├─ JSON Schema 约束 ├─ 分段提取优化 ├─ 多模型共识仲裁
|
||||
├─ 置信度评分 ├─ 证据链完整追溯 ├─ 自动质量审计
|
||||
├─ 人工复核机制 ├─ 规则引擎验证 ├─ 提示词版本管理
|
||||
└─ 基本追溯日志 └─ Few-shot 示例库 └─ HITL 智能分流
|
||||
↓ ↓ ↓
|
||||
可用 高质量 医学级
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 馃殌 MVP 闃舵<EFBFBD>锛? 鍛<>級
|
||||
## 🚀 MVP 阶段(4 周)
|
||||
|
||||
### 目标定位
|
||||
|
||||
- **鍑嗙‘鐜囩洰鏍?*锛氣墺 85%
|
||||
- **鎴愭湰棰勭畻**锛氱瓫閫?1000 绡囨枃鐚?鈮?楼50
|
||||
- **准确率目标**:≥ 85%
|
||||
- **成本预算**:筛选 1000 篇文献 ≤ ¥50
|
||||
- **交付标准**:基础功能可用,支持双模型对比
|
||||
|
||||
### 一、模型选择策略
|
||||
|
||||
#### 1.1 主力模型组合(成本优先)
|
||||
|
||||
| 瑙掕壊 | 妯″瀷 | Model ID | 鐢ㄩ€?| 鎴愭湰 |
|
||||
| 角色 | 模型 | Model ID | 用途 | 成本 |
|
||||
|------|------|---------|------|------|
|
||||
| **妯″瀷 A** | DeepSeek-V3 | `deepseek-chat` | 蹇<EFBFBD>€熷垵绛?| 楼0.001/1K tokens |
|
||||
| **模型 A** | DeepSeek-V3 | `deepseek-chat` | 快速初筛 | ¥0.001/1K tokens |
|
||||
| **模型 B** | Qwen3-72B | `qwen-max` | 交叉验证 | ¥0.004/1K tokens |
|
||||
|
||||
**鍒囨崲閫夐」**锛堣川閲忎紭鍏堬級锛?
|
||||
**切换选项**(质量优先):
|
||||
- **高端组合**:GPT-5-Pro (`gpt-5-pro`) + Claude-4.5-Sonnet (`claude-sonnet-4-5-20250929`)
|
||||
- **鎴愭湰澧炲姞**锛氱害 3-5 鍊?
|
||||
- **鍑嗙‘鐜囨彁鍗?*锛?5% 鈫?92%+
|
||||
- **成本增加**:约 3-5 倍
|
||||
- **准确率提升**:85% → 92%+
|
||||
|
||||
#### 1.2 模型调用策略
|
||||
|
||||
```typescript
|
||||
// 鍙屾ā鍨嬪苟琛岃皟鐢?
|
||||
// 双模型并行调用
|
||||
async function dualModelScreening(
|
||||
literature: Literature,
|
||||
protocol: Protocol
|
||||
@@ -80,7 +80,7 @@ async function dualModelScreening(
|
||||
const decisionA = parseJSON(resultA.content);
|
||||
const decisionB = parseJSON(resultB.content);
|
||||
|
||||
// 涓€鑷存€у垽鏂?
|
||||
// 一致性判断
|
||||
if (decisionA.decision === decisionB.decision) {
|
||||
return {
|
||||
finalDecision: decisionA.decision,
|
||||
@@ -90,7 +90,7 @@ async function dualModelScreening(
|
||||
};
|
||||
}
|
||||
|
||||
// 鍐茬獊 鈫?浜哄伐澶嶆牳
|
||||
// 冲突 → 人工复核
|
||||
return {
|
||||
finalDecision: 'uncertain',
|
||||
consensus: 'conflict',
|
||||
@@ -100,16 +100,16 @@ async function dualModelScreening(
|
||||
}
|
||||
```
|
||||
|
||||
### 浜屻€佹牳蹇冩妧鏈<EFBFBD>瓥鐣?
|
||||
### 二、核心技术策略
|
||||
|
||||
#### 2.1 鉁?鍙屾ā鍨嬩氦鍙夐獙璇?
|
||||
#### 2.1 ✅ 双模型交叉验证
|
||||
|
||||
**瀹炴柦鏂规<EFBFBD>**锛?
|
||||
- 鎵€鏈夌瓫閫変换鍔″悓鏃惰皟鐢ㄤ袱涓<EFBFBD>ā鍨?
|
||||
- 鑷<EFBFBD>姩瀵规瘮缁撴灉锛屾爣璁板樊寮?
|
||||
- 涓€鑷寸巼浣滀负璐ㄩ噺鎸囨爣锛堢洰鏍?鈮?80%锛?
|
||||
**实施方案**:
|
||||
- 所有筛选任务同时调用两个模型
|
||||
- 自动对比结果,标记差异
|
||||
- 一致率作为质量指标(目标 ≥ 80%)
|
||||
|
||||
**浠g爜绀轰緥**锛?
|
||||
**代码示例**:
|
||||
```typescript
|
||||
interface DualModelResult {
|
||||
consensus: 'high' | 'conflict';
|
||||
@@ -119,14 +119,14 @@ interface DualModelResult {
|
||||
}
|
||||
```
|
||||
|
||||
#### 2.2 鉁?JSON Schema 绾︽潫
|
||||
#### 2.2 ✅ JSON Schema 约束
|
||||
|
||||
**瀹炴柦鏂规<EFBFBD>**锛?
|
||||
- 瀹氫箟涓ユ牸鐨勮緭鍑烘牸寮?
|
||||
- 浣跨敤鏋氫妇闄愬埗鍙栧€?
|
||||
- 鍖哄垎蹇呭~/鍙<>€夊瓧娈?
|
||||
**实施方案**:
|
||||
- 定义严格的输出格式
|
||||
- 使用枚举限制取值
|
||||
- 区分必填/可选字段
|
||||
|
||||
**Schema 瀹氫箟**锛?
|
||||
**Schema 定义**:
|
||||
```json
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
@@ -177,10 +177,10 @@ interface DualModelResult {
|
||||
}
|
||||
```
|
||||
|
||||
**鎻愮ず璇嶆ā鏉?*锛?
|
||||
**提示词模板**:
|
||||
```typescript
|
||||
const prompt = `
|
||||
浣犳槸涓€浣嶅尰瀛︽枃鐚<EFBFBD>瓫閫変笓瀹躲€傝<EFBFBD>鏍规嵁浠ヤ笅 PICO 鏍囧噯鍒ゆ柇杩欑瘒鏂囩尞鏄<E5B09E>惁搴旇<E690B4>绾冲叆绯荤粺璇勪环銆?
|
||||
你是一位医学文献筛选专家。请根据以下 PICO 标准判断这篇文献是否应该纳入系统评价。
|
||||
|
||||
# PICO 标准
|
||||
- Population: ${protocol.population}
|
||||
@@ -193,26 +193,26 @@ const prompt = `
|
||||
摘要: ${literature.abstract}
|
||||
|
||||
# 输出要求
|
||||
璇蜂弗鏍兼寜鐓т互涓?JSON Schema 杈撳嚭缁撴灉锛?
|
||||
请严格按照以下 JSON Schema 输出结果:
|
||||
|
||||
${JSON.stringify(schema, null, 2)}
|
||||
|
||||
娉ㄦ剰锛?
|
||||
1. decision 鍙<EFBFBD>兘鏄?"include"銆?exclude" 鎴?"uncertain"
|
||||
2. reason 蹇呴』鍏蜂綋璇存槑鍒ゆ柇渚濇嵁锛?0-500瀛楋級
|
||||
3. confidence 涓?0-1 涔嬮棿鐨勬暟鍊硷紝琛ㄧず浣犵殑鍒ゆ柇鎶婃彙
|
||||
注意:
|
||||
1. decision 只能是 "include"、"exclude" 或 "uncertain"
|
||||
2. reason 必须具体说明判断依据(10-500字)
|
||||
3. confidence 为 0-1 之间的数值,表示你的判断把握
|
||||
4. pico 字段逐项评估匹配程度
|
||||
`;
|
||||
```
|
||||
|
||||
#### 2.3 鉁?缃<>俊搴﹁瘎鍒?
|
||||
#### 2.3 ✅ 置信度评分
|
||||
|
||||
**瀹炴柦鏂规<EFBFBD>**锛?
|
||||
- 瑕佹眰妯″瀷瀵规瘡涓<EFBFBD>垽鏂<EFBFBD>粰鍑虹疆淇″害锛?-1锛?
|
||||
- 缃<EFBFBD>俊搴?< 0.7 鑷<EFBFBD>姩鏍囪<EFBFBD>涓洪渶浜哄伐澶嶆牳
|
||||
- 璁板綍缃<EFBFBD>俊搴﹀垎甯冿紝浼樺寲闃堝€?
|
||||
**实施方案**:
|
||||
- 要求模型对每个判断给出置信度(0-1)
|
||||
- 置信度 < 0.7 自动标记为需人工复核
|
||||
- 记录置信度分布,优化阈值
|
||||
|
||||
**鑷<EFBFBD>姩鍒嗘祦瑙勫垯**锛?
|
||||
**自动分流规则**:
|
||||
```typescript
|
||||
function autoTriage(result: DualModelResult) {
|
||||
const avgConfidence = (
|
||||
@@ -220,29 +220,29 @@ function autoTriage(result: DualModelResult) {
|
||||
result.models[1].confidence
|
||||
) / 2;
|
||||
|
||||
// 瑙勫垯1锛氬啿绐?鈫?蹇呴』澶嶆牳
|
||||
// 规则1:冲突 → 必须复核
|
||||
if (result.consensus === 'conflict') {
|
||||
return { needReview: true, priority: 'high' };
|
||||
}
|
||||
|
||||
// 瑙勫垯2锛氫綆缃<EFBFBD>俊搴?鈫?闇€瑕佸<E79195>鏍?
|
||||
// 规则2:低置信度 → 需要复核
|
||||
if (avgConfidence < 0.7) {
|
||||
return { needReview: true, priority: 'medium' };
|
||||
}
|
||||
|
||||
// 瑙勫垯3锛氶珮缃<EFBFBD>俊搴?+ 涓€鑷?鈫?鑷<>姩閫氳繃
|
||||
// 规则3:高置信度 + 一致 → 自动通过
|
||||
return { needReview: false, priority: 'low' };
|
||||
}
|
||||
```
|
||||
|
||||
#### 2.4 鉁?鍩虹<E98DA9>鍙<EFBFBD>拷婧?
|
||||
#### 2.4 ✅ 基础可追溯
|
||||
|
||||
**瀹炴柦鏂规<EFBFBD>**锛?
|
||||
**实施方案**:
|
||||
- 保存原始提示词和模型输出
|
||||
- 记录模型版本和时间戳
|
||||
- 关联人工复核记录
|
||||
|
||||
**鏁版嵁搴撹<EFBFBD>璁?*锛?
|
||||
**数据库设计**:
|
||||
```prisma
|
||||
model ScreeningResult {
|
||||
id String @id @default(uuid())
|
||||
@@ -259,7 +259,7 @@ model ScreeningResult {
|
||||
modelBOutput Json
|
||||
modelBConfidence Float
|
||||
|
||||
// 鏈€缁堝喅绛?
|
||||
// 最终决策
|
||||
finalDecision String // "include"/"exclude"/"uncertain"
|
||||
consensus String // "high"/"conflict"
|
||||
needReview Boolean
|
||||
@@ -270,7 +270,7 @@ model ScreeningResult {
|
||||
reviewDecision String?
|
||||
reviewNotes String?
|
||||
|
||||
// 鍙<EFBFBD>拷婧<EFBFBD>俊鎭?
|
||||
// 可追溯信息
|
||||
promptTemplate String @db.Text // 使用的提示词模板
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@ -280,53 +280,53 @@ model ScreeningResult {
|
||||
|
||||
### 三、MVP 成本预算
|
||||
|
||||
**鍦烘櫙锛氱瓫閫?1000 绡囨枃鐚?*
|
||||
**场景:筛选 1000 篇文献**
|
||||
|
||||
| 项目 | DeepSeek | Qwen3 | 合计 |
|
||||
|------|----------|-------|------|
|
||||
| 输入 tokens(平均) | 800 | 800 | - |
|
||||
| 输出 tokens(平均) | 200 | 200 | - |
|
||||
| 单次成本 | ¥0.001 | ¥0.004 | ¥0.005 |
|
||||
| **1000 绡囨€绘垚鏈?* | 楼1 | 楼4 | **楼5** |
|
||||
| **1000 篇总成本** | ¥1 | ¥4 | **¥5** |
|
||||
|
||||
**鍐茬獊鐜?20% 浜哄伐澶嶆牳**锛?
|
||||
- 鑷<EFBFBD>姩閫氳繃锛?00 绡?脳 楼0.005 = 楼4
|
||||
- 浜哄伐澶嶆牳锛?00 绡?脳 2 鍒嗛挓 = 6.7 灏忔椂
|
||||
- **鎬绘垚鏈?*锛毬? + 浜哄伐鎴愭湰
|
||||
**冲突率 20% 人工复核**:
|
||||
- 自动通过:800 篇 × ¥0.005 = ¥4
|
||||
- 人工复核:200 篇 × 2 分钟 = 6.7 小时
|
||||
- **总成本**:¥4 + 人工成本
|
||||
|
||||
### 四、MVP 验收标准
|
||||
|
||||
| 指标 | 目标 | 验证方法 |
|
||||
|------|------|----------|
|
||||
| 鍙屾ā鍨嬩竴鑷寸巼 | 鈮?80% | 缁熻<EFBFBD>鎶ヨ〃 |
|
||||
| JSON Schema 楠岃瘉閫氳繃鐜?| 鈮?95% | 鑷<>姩妫€鏌?|
|
||||
| 浜哄伐澶嶆牳闃熷垪鍗犳瘮 | 鈮?20% | 绯荤粺缁熻<EFBFBD> |
|
||||
| 鎻愬彇缁撴灉鍙<EFBFBD>拷婧?| 100% | 瀹¤<EFBFBD>妫€鏌?|
|
||||
| 鎴愭湰鎺у埗 | 鈮?楼50/1000 绡?| 璐﹀崟鐩戞帶 |
|
||||
| 双模型一致率 | ≥ 80% | 统计报表 |
|
||||
| JSON Schema 验证通过率 | ≥ 95% | 自动检查 |
|
||||
| 人工复核队列占比 | ≤ 20% | 系统统计 |
|
||||
| 提取结果可追溯 | 100% | 审计检查 |
|
||||
| 成本控制 | ≤ ¥50/1000 篇 | 账单监控 |
|
||||
|
||||
---
|
||||
|
||||
## 馃搱 V1.0 闃舵<EFBFBD>锛? 鍛<>級
|
||||
## 📈 V1.0 阶段(6 周)
|
||||
|
||||
### 目标定位
|
||||
|
||||
- **鍑嗙‘鐜囩洰鏍?*锛氣墺 90%
|
||||
- **鎴愭湰棰勭畻**锛氱瓫閫?1000 绡囨枃鐚?鈮?楼80
|
||||
- **浜や粯鏍囧噯**锛氶珮璐ㄩ噺杈撳嚭锛屾櫤鑳借川閲忔帶鍒?
|
||||
- **准确率目标**:≥ 90%
|
||||
- **成本预算**:筛选 1000 篇文献 ≤ ¥80
|
||||
- **交付标准**:高质量输出,智能质量控制
|
||||
|
||||
### 涓€銆佹ā鍨嬬瓥鐣ヤ紭鍖?
|
||||
### 一、模型策略优化
|
||||
|
||||
#### 1.1 成本优化策略
|
||||
|
||||
**鏍稿績鎬濊矾**锛?0% 鐢ㄤ綆鎴愭湰妯″瀷锛?0% 楂樹环鍊间换鍔$敤椤剁骇妯″瀷
|
||||
**核心思路**:80% 用低成本模型,20% 高价值任务用顶级模型
|
||||
|
||||
```typescript
|
||||
async function smartScreening(literature: Literature, protocol: Protocol) {
|
||||
// 绗<EFBFBD>竴闃舵<EFBFBD>锛氬揩閫熷垵绛涳紙DeepSeek锛?
|
||||
// 第一阶段:快速初筛(DeepSeek)
|
||||
const quickResult = await llmService.chat('deepseek', buildPrompt(...));
|
||||
const quickDecision = parseJSON(quickResult.content);
|
||||
|
||||
// 濡傛灉楂樼疆淇″害 + 鏄庣‘缁撹<E7BC81> 鈫?鐩存帴閲囩撼
|
||||
// 如果高置信度 + 明确结论 → 直接采纳
|
||||
if (
|
||||
quickDecision.confidence > 0.85 &&
|
||||
quickDecision.decision !== 'uncertain'
|
||||
@@ -338,7 +338,7 @@ async function smartScreening(literature: Literature, protocol: Protocol) {
|
||||
};
|
||||
}
|
||||
|
||||
// 鍚﹀垯 鈫?鍚<>敤楂樼<E6A582>妯″瀷澶嶆牳
|
||||
// 否则 → 启用高端模型复核
|
||||
const detailedResult = await llmService.chat('gpt5', buildPrompt(...));
|
||||
return {
|
||||
finalDecision: detailedResult.decision,
|
||||
@@ -348,21 +348,21 @@ async function smartScreening(literature: Literature, protocol: Protocol) {
|
||||
}
|
||||
```
|
||||
|
||||
**棰勬湡鎴愭湰鑺傜渷**锛?
|
||||
- 80% 浠诲姟鐢?DeepSeek锛?00 脳 楼0.001 = 楼0.8
|
||||
- 20% 浠诲姟鐢?GPT-5锛?00 脳 楼0.10 = 楼20
|
||||
- **鎬绘垚鏈?*锛毬?0.8锛堢浉姣斿叏鐢?GPT-5 鑺傜渷 80%锛?
|
||||
**预期成本节省**:
|
||||
- 80% 任务用 DeepSeek:800 × ¥0.001 = ¥0.8
|
||||
- 20% 任务用 GPT-5:200 × ¥0.10 = ¥20
|
||||
- **总成本**:¥20.8(相比全用 GPT-5 节省 80%)
|
||||
|
||||
### 浜屻€佹牳蹇冩妧鏈<EFBFBD><EFBFBD>寮?
|
||||
### 二、核心技术增强
|
||||
|
||||
#### 2.1 鉁?Few-shot 绀轰緥搴?
|
||||
#### 2.1 ✅ Few-shot 示例库
|
||||
|
||||
**瀹炴柦鏂规<EFBFBD>**锛?
|
||||
**实施方案**:
|
||||
- 人工标注 20-30 个高质量示例
|
||||
- 针对不同研究类型分类(RCT、队列、病例对照)
|
||||
- 鍔ㄦ€侀€夋嫨鐩镐技绀轰緥宓屽叆鎻愮ず璇?
|
||||
- 动态选择相似示例嵌入提示词
|
||||
|
||||
**绀轰緥鏍煎紡**锛?
|
||||
**示例格式**:
|
||||
```json
|
||||
{
|
||||
"examples": [
|
||||
@@ -371,7 +371,7 @@ async function smartScreening(literature: Literature, protocol: Protocol) {
|
||||
"abstract": "...",
|
||||
"goldStandard": {
|
||||
"decision": "include",
|
||||
"reason": "RCT鐮旂┒锛屼汉缇や负绯栧翱鐥呮偅鑰咃紙鍖归厤P锛夛紝骞查<EFBFBD>涓洪樋鍙稿尮鏋楋紙鍖归厤I锛夛紝瀵圭収涓哄畨鎱板墏锛堝尮閰岰锛夛紝缁撳眬涓哄績琛€绠′簨浠讹紙鍖归厤O锛?,
|
||||
"reason": "RCT研究,人群为糖尿病患者(匹配P),干预为阿司匹林(匹配I),对照为安慰剂(匹配C),结局为心血管事件(匹配O)",
|
||||
"pico": {
|
||||
"population": "match",
|
||||
"intervention": "match",
|
||||
@@ -385,12 +385,12 @@ async function smartScreening(literature: Literature, protocol: Protocol) {
|
||||
}
|
||||
```
|
||||
|
||||
**鎻愮ず璇嶅<EFBFBD>寮?*锛?
|
||||
**提示词增强**:
|
||||
```typescript
|
||||
const promptWithExamples = `
|
||||
# 鍙傝€冪ず渚?
|
||||
# 参考示例
|
||||
|
||||
浠ヤ笅鏄?3 涓<>爣娉ㄥソ鐨勭ず渚嬶紝甯<E7B49D>姪浣犵悊瑙e垽鏂<E59EBD>爣鍑嗭細
|
||||
以下是 3 个标注好的示例,帮助你理解判断标准:
|
||||
|
||||
${examples.map((ex, i) => `
|
||||
## 示例 ${i + 1}
|
||||
@@ -400,22 +400,22 @@ ${examples.map((ex, i) => `
|
||||
理由: ${ex.goldStandard.reason}
|
||||
`).join('\n')}
|
||||
|
||||
# 寰呯瓫閫夋枃鐚?
|
||||
# 待筛选文献
|
||||
标题: ${literature.title}
|
||||
摘要: ${literature.abstract}
|
||||
|
||||
璇峰弬鑰冧笂杩扮ず渚嬶紝杈撳嚭浣犵殑鍒ゆ柇缁撴灉锛圝SON鏍煎紡锛夈€?
|
||||
请参考上述示例,输出你的判断结果(JSON格式)。
|
||||
`;
|
||||
```
|
||||
|
||||
#### 2.2 鉁?鍒嗘<E98D92>鎻愬彇
|
||||
#### 2.2 ✅ 分段提取
|
||||
|
||||
**瀹炴柦鏂规<EFBFBD>**锛?
|
||||
**实施方案**:
|
||||
- 针对全文数据提取,按章节分段处理
|
||||
- 每段独立提取,减少上下文混淆
|
||||
- 鏈€鍚庡悎骞剁粨鏋滐紝浜ゅ弶楠岃瘉涓€鑷存€?
|
||||
- 最后合并结果,交叉验证一致性
|
||||
|
||||
**鍒嗘<EFBFBD>绛栫暐**锛?
|
||||
**分段策略**:
|
||||
```typescript
|
||||
async function segmentedExtraction(fullText: string, protocol: Protocol) {
|
||||
// 分段
|
||||
@@ -437,54 +437,54 @@ async function segmentedExtraction(fullText: string, protocol: Protocol) {
|
||||
}
|
||||
```
|
||||
|
||||
**鎻愬彇绀轰緥锛堟柟娉曞<EFBFBD>閮ㄥ垎锛?*锛?
|
||||
**提取示例(方法学部分)**:
|
||||
```typescript
|
||||
const methodsPrompt = `
|
||||
请从以下方法学部分提取研究设计信息:
|
||||
|
||||
# 鏂规硶瀛﹀師鏂?
|
||||
# 方法学原文
|
||||
${methodsSection}
|
||||
|
||||
# 提取字段
|
||||
- 研究设计类型(RCT/cohort/case-control等)
|
||||
- 鏍锋湰閲忥紙骞查<EFBFBD>缁?瀵圭収缁勶級
|
||||
- 样本量(干预组/对照组)
|
||||
- 纳入标准
|
||||
- 排除标准
|
||||
- 闅忔満鍖栨柟娉曪紙濡傞€傜敤锛?
|
||||
- 鐩叉硶锛堝<EFBFBD>閫傜敤锛?
|
||||
- 随机化方法(如适用)
|
||||
- 盲法(如适用)
|
||||
|
||||
# 杈撳嚭鏍煎紡锛圝SON锛?
|
||||
# 输出格式(JSON)
|
||||
${methodsSchema}
|
||||
`;
|
||||
```
|
||||
|
||||
#### 2.3 鉁?瑙勫垯寮曟搸楠岃瘉
|
||||
#### 2.3 ✅ 规则引擎验证
|
||||
|
||||
**瀹炴柦鏂规<EFBFBD>**锛?
|
||||
**实施方案**:
|
||||
- 定义业务规则,自动检查逻辑错误
|
||||
- 鏁板€艰寖鍥撮獙璇?
|
||||
- 蹇呭~瀛楁<EFBFBD>瀹屾暣鎬ф<EFBFBD>鏌?
|
||||
- 数值范围验证
|
||||
- 必填字段完整性检查
|
||||
|
||||
**楠岃瘉瑙勫垯**锛?
|
||||
**验证规则**:
|
||||
```typescript
|
||||
const validationRules = [
|
||||
{
|
||||
name: '鏍锋湰閲忓悎鐞嗘€?,
|
||||
name: '样本量合理性',
|
||||
check: (data) => {
|
||||
const total = data.sampleSize.intervention + data.sampleSize.control;
|
||||
return total >= 10 && total <= 100000;
|
||||
},
|
||||
errorMessage: '鏍锋湰閲忚秴鍑哄悎鐞嗚寖鍥达紙10-100000锛?
|
||||
errorMessage: '样本量超出合理范围(10-100000)'
|
||||
},
|
||||
{
|
||||
name: 'P鍊艰寖鍥?,
|
||||
name: 'P值范围',
|
||||
check: (data) => {
|
||||
return data.pValue >= 0 && data.pValue <= 1;
|
||||
},
|
||||
errorMessage: 'P值必须在0-1之间'
|
||||
},
|
||||
{
|
||||
name: '蹇呭~瀛楁<EFBFBD>瀹屾暣鎬?,
|
||||
name: '必填字段完整性',
|
||||
check: (data) => {
|
||||
const required = ['studyDesign', 'sampleSize', 'primaryOutcome'];
|
||||
return required.every(field => data[field] != null);
|
||||
@@ -507,14 +507,14 @@ function validateExtraction(data: ExtractionResult): ValidationReport {
|
||||
}
|
||||
```
|
||||
|
||||
#### 2.4 鉁?瀹屾暣璇佹嵁閾?
|
||||
#### 2.4 ✅ 完整证据链
|
||||
|
||||
**瀹炴柦鏂规<EFBFBD>**锛?
|
||||
**实施方案**:
|
||||
- 记录原文引用位置(页码、段落、句子)
|
||||
- 淇濆瓨妯″瀷瀹屾暣杈撳嚭锛堝惈涓<EFBFBD>棿鎺ㄧ悊锛?
|
||||
- 鍏宠仈鎵€鏈変汉宸ヤ慨鏀硅<EFBFBD>褰?
|
||||
- 保存模型完整输出(含中间推理)
|
||||
- 关联所有人工修改记录
|
||||
|
||||
**鏁版嵁搴撳<EFBFBD>寮?*锛?
|
||||
**数据库增强**:
|
||||
```prisma
|
||||
model ExtractionResult {
|
||||
id String @id @default(uuid())
|
||||
@@ -522,7 +522,7 @@ model ExtractionResult {
|
||||
// 提取内容
|
||||
extractedData Json
|
||||
|
||||
// 璇佹嵁閾撅紙鏂板<EFBFBD>锛?
|
||||
// 证据链(新增)
|
||||
evidenceChain Json // {
|
||||
// "sampleSize": {
|
||||
// "value": 150,
|
||||
@@ -538,7 +538,7 @@ model ExtractionResult {
|
||||
modelName String
|
||||
modelVersion String
|
||||
promptVersion String // "v1.2.0"
|
||||
rawOutput String @db.Text // 鍘熷<EFBFBD>杈撳嚭锛堝惈CoT鎺ㄧ悊锛?
|
||||
rawOutput String @db.Text // 原始输出(含CoT推理)
|
||||
|
||||
// 修改历史
|
||||
revisions ExtractionRevision[]
|
||||
@@ -551,7 +551,7 @@ model ExtractionRevision {
|
||||
id String @id @default(uuid())
|
||||
extractionId String
|
||||
|
||||
fieldName String // 淇<EFBFBD>敼鐨勫瓧娈?
|
||||
fieldName String // 修改的字段
|
||||
oldValue Json
|
||||
newValue Json
|
||||
reason String // 修改理由
|
||||
@@ -566,41 +566,41 @@ model ExtractionRevision {
|
||||
|
||||
### 三、V1.0 成本预算
|
||||
|
||||
**鍦烘櫙锛氱瓫閫?1000 绡?+ 鎻愬彇 200 绡囧叏鏂?*
|
||||
**场景:筛选 1000 篇 + 提取 200 篇全文**
|
||||
|
||||
| 任务 | 策略 | 成本 |
|
||||
|------|------|------|
|
||||
| 鏍囬<EFBFBD>鎽樿<EFBFBD>绛涢€?| 80% DeepSeek + 20% GPT-5 | 楼21 |
|
||||
| 鍏ㄦ枃鏁版嵁鎻愬彇 | 鍒嗘<E98D92>鎻愬彇锛圙PT-5锛?| 楼60 |
|
||||
| **鎬绘垚鏈?* | - | **楼81** |
|
||||
| 标题摘要筛选 | 80% DeepSeek + 20% GPT-5 | ¥21 |
|
||||
| 全文数据提取 | 分段提取(GPT-5) | ¥60 |
|
||||
| **总成本** | - | **¥81** |
|
||||
|
||||
### 四、V1.0 验收标准
|
||||
|
||||
| 指标 | 目标 | 验证方法 |
|
||||
|------|------|----------|
|
||||
| 鎻愬彇鍑嗙‘鐜?| 鈮?90% | 浜哄伐鎶芥煡 50 绡?|
|
||||
| Few-shot 绀轰緥搴?| 鈮?20 涓?| 浜哄伐鏍囨敞 |
|
||||
| 瑙勫垯寮曟搸瑕嗙洊鐜?| 鈮?80% | 浠g爜瀹℃煡 |
|
||||
| 璇佹嵁閾惧畬鏁存€?| 100% | 瀹¤<EFBFBD>妫€鏌?|
|
||||
| 鎴愭湰鎺у埗 | 鈮?楼80/椤圭洰 | 璐﹀崟鐩戞帶 |
|
||||
| 提取准确率 | ≥ 90% | 人工抽查 50 篇 |
|
||||
| Few-shot 示例库 | ≥ 20 个 | 人工标注 |
|
||||
| 规则引擎覆盖率 | ≥ 80% | 代码审查 |
|
||||
| 证据链完整性 | 100% | 审计检查 |
|
||||
| 成本控制 | ≤ ¥80/项目 | 账单监控 |
|
||||
|
||||
---
|
||||
|
||||
## 馃弳 V2.0 闃舵<EFBFBD>锛? 鍛<>級
|
||||
## 🏆 V2.0 阶段(8 周)
|
||||
|
||||
### 目标定位
|
||||
|
||||
- **鍑嗙‘鐜囩洰鏍?*锛氣墺 95%锛堝尰瀛︾骇锛?
|
||||
- **准确率目标**:≥ 95%(医学级)
|
||||
- **成本预算**:按需配置
|
||||
- **浜や粯鏍囧噯**锛氳嚜鍔ㄥ寲璐ㄩ噺瀹¤<E780B9>锛岀<E9949B>鍚堜复搴婄爺绌惰<E7BB8C>鑼?
|
||||
- **交付标准**:自动化质量审计,符合临床研究规范
|
||||
|
||||
### 一、医学级质量保障
|
||||
|
||||
#### 1.1 鉁?涓夋ā鍨嬪叡璇嗕徊瑁?
|
||||
#### 1.1 ✅ 三模型共识仲裁
|
||||
|
||||
**瀹炴柦鏂规<EFBFBD>**锛?
|
||||
**实施方案**:
|
||||
- 双模型冲突时,自动启用第三方仲裁
|
||||
- 涓夋ā鍨嬫姇绁ㄥ喅绛?
|
||||
- 三模型投票决策
|
||||
- 记录仲裁过程
|
||||
|
||||
```typescript
|
||||
@@ -608,7 +608,7 @@ async function threeModelArbitration(
|
||||
literature: Literature,
|
||||
protocol: Protocol
|
||||
) {
|
||||
// 绗<EFBFBD>竴杞<EFBFBD>細鍙屾ā鍨?
|
||||
// 第一轮:双模型
|
||||
const [resultA, resultB] = await Promise.all([
|
||||
llmService.chat('deepseek', buildPrompt(...)),
|
||||
llmService.chat('qwen', buildPrompt(...))
|
||||
@@ -619,11 +619,11 @@ async function threeModelArbitration(
|
||||
return { finalDecision: resultA.decision, arbitration: false };
|
||||
}
|
||||
|
||||
// 鍐茬獊 鈫?鍚<>敤 Claude 浠茶<EFBFBD>
|
||||
console.log('妫€娴嬪埌鍐茬獊锛屽惎鐢?Claude-4.5 浠茶<EFBFBD>...');
|
||||
// 冲突 → 启用 Claude 仲裁
|
||||
console.log('检测到冲突,启用 Claude-4.5 仲裁...');
|
||||
const resultC = await llmService.chat('claude', buildPrompt(...));
|
||||
|
||||
// 涓夋ā鍨嬫姇绁?
|
||||
// 三模型投票
|
||||
const votes = [resultA.decision, resultB.decision, resultC.decision];
|
||||
const voteCount = {
|
||||
include: votes.filter(v => v === 'include').length,
|
||||
@@ -631,7 +631,7 @@ async function threeModelArbitration(
|
||||
uncertain: votes.filter(v => v === 'uncertain').length,
|
||||
};
|
||||
|
||||
// 澶氭暟鍐?
|
||||
// 多数决
|
||||
const winner = Object.entries(voteCount)
|
||||
.sort((a, b) => b[1] - a[1])[0][0];
|
||||
|
||||
@@ -644,39 +644,39 @@ async function threeModelArbitration(
|
||||
}
|
||||
```
|
||||
|
||||
**鎴愭湰鎺у埗**锛?
|
||||
- 浠呭湪鍐茬獊鏃跺惎鐢ㄤ徊瑁侊紙棰勮<EFBFBD> 10-15%锛?
|
||||
- 鍗曟<EFBFBD>浠茶<EFBFBD>棰濆<EFBFBD>鎴愭湰锛毬?.021锛圕laude-4.5锛?
|
||||
**成本控制**:
|
||||
- 仅在冲突时启用仲裁(预计 10-15%)
|
||||
- 单次仲裁额外成本:¥0.021(Claude-4.5)
|
||||
|
||||
#### 1.2 鉁?HITL 鏅鸿兘鍒嗘祦
|
||||
#### 1.2 ✅ HITL 智能分流
|
||||
|
||||
**瀹炴柦鏂规<EFBFBD>**锛?
|
||||
**实施方案**:
|
||||
- 基于规则的智能优先级排序
|
||||
- 楂樹环鍊?楂橀<E6A582>闄╀换鍔′紭鍏堜汉宸ュ<E5AEB8>鏍?
|
||||
- 高价值/高风险任务优先人工复核
|
||||
- 低风险任务自动化处理
|
||||
|
||||
**鍒嗘祦瑙勫垯**锛?
|
||||
**分流规则**:
|
||||
```typescript
|
||||
function intelligentTriage(result: ScreeningResult): TriageDecision {
|
||||
let priority = 0;
|
||||
let needReview = false;
|
||||
|
||||
// 瑙勫垯1锛氫笁妯″瀷浠嶄笉涓€鑷?鈫?鏈€楂樹紭鍏堢骇
|
||||
// 规则1:三模型仍不一致 → 最高优先级
|
||||
if (result.arbitration && result.consensus === 'weak') {
|
||||
priority = 100;
|
||||
needReview = true;
|
||||
}
|
||||
// 瑙勫垯2锛歊CT 鐮旂┒ 鈫?涓<>瓑浼樺厛绾?
|
||||
// 规则2:RCT 研究 → 中等优先级
|
||||
else if (result.studyDesign === 'RCT') {
|
||||
priority = 70;
|
||||
needReview = result.confidence < 0.9;
|
||||
}
|
||||
// 瑙勫垯3锛氬叧閿<EFBFBD>粨灞€鎸囨爣 鈫?楂樹紭鍏堢骇
|
||||
// 规则3:关键结局指标 → 高优先级
|
||||
else if (result.outcome.includes('mortality')) {
|
||||
priority = 80;
|
||||
needReview = result.confidence < 0.85;
|
||||
}
|
||||
// 瑙勫垯4锛氶珮缃<EFBFBD>俊搴?+ 涓€鑷?鈫?鑷<>姩閫氳繃
|
||||
// 规则4:高置信度 + 一致 → 自动通过
|
||||
else if (result.confidence > 0.95 && result.consensus === 'high') {
|
||||
priority = 10;
|
||||
needReview = false;
|
||||
@@ -686,27 +686,27 @@ function intelligentTriage(result: ScreeningResult): TriageDecision {
|
||||
}
|
||||
```
|
||||
|
||||
#### 1.3 鉁?鎻愮ず璇嶇増鏈<E5A297><E98F88>鐞?
|
||||
#### 1.3 ✅ 提示词版本管理
|
||||
|
||||
**瀹炴柦鏂规<EFBFBD>**锛?
|
||||
- Git 绠$悊鎻愮ず璇嶆ā鏉?
|
||||
**实施方案**:
|
||||
- Git 管理提示词模板
|
||||
- 版本号标记(语义化版本)
|
||||
- A/B 测试不同版本效果
|
||||
|
||||
**鐩<EFBFBD>綍缁撴瀯**锛?
|
||||
**目录结构**:
|
||||
```
|
||||
backend/prompts/asl/
|
||||
├── screening/
|
||||
鈹? 鈹溾攢鈹€ v1.0.0-basic.txt
|
||||
鈹? 鈹溾攢鈹€ v1.1.0-with-examples.txt
|
||||
鈹? 鈹斺攢鈹€ v1.2.0-cot.txt
|
||||
│ ├── v1.0.0-basic.txt
|
||||
│ ├── v1.1.0-with-examples.txt
|
||||
│ └── v1.2.0-cot.txt
|
||||
├── extraction/
|
||||
鈹? 鈹溾攢鈹€ v1.0.0-methods.txt
|
||||
鈹? 鈹斺攢鈹€ v1.1.0-methods-segmented.txt
|
||||
│ ├── v1.0.0-methods.txt
|
||||
│ └── v1.1.0-methods-segmented.txt
|
||||
└── changelog.md
|
||||
```
|
||||
|
||||
**鐗堟湰璁板綍**锛?
|
||||
**版本记录**:
|
||||
```prisma
|
||||
model PromptVersion {
|
||||
id String @id @default(uuid())
|
||||
@@ -727,14 +727,14 @@ model PromptVersion {
|
||||
}
|
||||
```
|
||||
|
||||
#### 1.4 鉁?鑷<>姩璐ㄩ噺瀹¤<E780B9>
|
||||
#### 1.4 ✅ 自动质量审计
|
||||
|
||||
**瀹炴柦鏂规<EFBFBD>**锛?
|
||||
- 瀹氭湡鎵归噺鎶芥煡锛?0%锛?
|
||||
**实施方案**:
|
||||
- 定期批量抽查(10%)
|
||||
- 自动生成质量报告
|
||||
- 异常检测和告警
|
||||
|
||||
**瀹¤<EFBFBD>鎶ヨ〃**锛?
|
||||
**审计报表**:
|
||||
```typescript
|
||||
interface QualityAuditReport {
|
||||
period: { start: Date; end: Date };
|
||||
@@ -742,8 +742,8 @@ interface QualityAuditReport {
|
||||
sampledTasks: number;
|
||||
|
||||
metrics: {
|
||||
accuracy: number; // 鍑嗙‘鐜?
|
||||
interRaterAgreement: number; // 浜烘満涓€鑷存€?
|
||||
accuracy: number; // 准确率
|
||||
interRaterAgreement: number; // 人机一致性
|
||||
falsePositiveRate: number; // 假阳性率
|
||||
falseNegativeRate: number; // 假阴性率
|
||||
};
|
||||
@@ -766,14 +766,14 @@ interface QualityAuditReport {
|
||||
|
||||
### 二、高级提示词工程
|
||||
|
||||
#### 2.1 鉁?Chain of Thought (CoT)
|
||||
#### 2.1 ✅ Chain of Thought (CoT)
|
||||
|
||||
**瀹炴柦鏂规<EFBFBD>**锛?
|
||||
**实施方案**:
|
||||
- 要求模型输出推理过程
|
||||
- 鍒嗘<EFBFBD>楠ゅ垽鏂?PICO 鍖归厤搴?
|
||||
- 鏈€鍚庣粰鍑虹患鍚堢粨璁?
|
||||
- 分步骤判断 PICO 匹配度
|
||||
- 最后给出综合结论
|
||||
|
||||
**鎻愮ず璇嶇ず渚?*锛?
|
||||
**提示词示例**:
|
||||
```
|
||||
请按照以下步骤判断这篇文献是否应该纳入:
|
||||
|
||||
@@ -788,15 +788,15 @@ interface QualityAuditReport {
|
||||
- Outcome: 详细分析结局指标是否匹配
|
||||
|
||||
# Step 3: 综合判断
|
||||
- 姹囨€讳互涓婂垎鏋?
|
||||
- 缁欏嚭鏈€缁堝喅绛栵紙include/exclude/uncertain锛?
|
||||
- 璇勪及缃<EFBFBD>俊搴︼紙0-1锛?
|
||||
- 汇总以上分析
|
||||
- 给出最终决策(include/exclude/uncertain)
|
||||
- 评估置信度(0-1)
|
||||
|
||||
# 输出格式
|
||||
{
|
||||
"reasoning": {
|
||||
"studyDesign": "杩欐槸涓€椤?..",
|
||||
"population": "浜虹兢鍖归厤搴﹀垎鏋?..",
|
||||
"studyDesign": "这是一项...",
|
||||
"population": "人群匹配度分析...",
|
||||
"intervention": "干预措施分析...",
|
||||
"comparison": "对照分析...",
|
||||
"outcome": "结局指标分析..."
|
||||
@@ -807,19 +807,19 @@ interface QualityAuditReport {
|
||||
}
|
||||
```
|
||||
|
||||
#### 2.2 鉁?鍔ㄦ€佺ず渚嬮€夋嫨
|
||||
#### 2.2 ✅ 动态示例选择
|
||||
|
||||
**瀹炴柦鏂规<EFBFBD>**锛?
|
||||
- 璁$畻寰呯瓫閫夋枃鐚<EFBFBD>笌绀轰緥搴撶殑璇<EFBFBD>箟鐩镐技搴?
|
||||
- 鍔ㄦ€侀€夋嫨鏈€鐩镐技鐨?3-5 涓<>ず渚?
|
||||
- 宓屽叆鎻愮ず璇?
|
||||
**实施方案**:
|
||||
- 计算待筛选文献与示例库的语义相似度
|
||||
- 动态选择最相似的 3-5 个示例
|
||||
- 嵌入提示词
|
||||
|
||||
```typescript
|
||||
async function selectSimilarExamples(
|
||||
literature: Literature,
|
||||
examplePool: Example[]
|
||||
): Promise<Example[]> {
|
||||
// 浣跨敤宓屽叆妯″瀷璁$畻鐩镐技搴?
|
||||
// 使用嵌入模型计算相似度
|
||||
const literatureEmbedding = await getEmbedding(
|
||||
`${literature.title} ${literature.abstract}`
|
||||
);
|
||||
@@ -829,7 +829,7 @@ async function selectSimilarExamples(
|
||||
similarity: cosineSimilarity(literatureEmbedding, ex.embedding)
|
||||
}));
|
||||
|
||||
// 杩斿洖鏈€鐩镐技鐨?5 涓?
|
||||
// 返回最相似的 5 个
|
||||
return similarities
|
||||
.sort((a, b) => b.similarity - a.similarity)
|
||||
.slice(0, 5)
|
||||
@@ -839,25 +839,25 @@ async function selectSimilarExamples(
|
||||
|
||||
### 三、V2.0 成本预算
|
||||
|
||||
**鍦烘櫙锛氶珮璐ㄩ噺绯荤粺璇勪环椤圭洰锛堢瓫閫?5000 绡?+ 鎻愬彇 300 绡囷級**
|
||||
**场景:高质量系统评价项目(筛选 5000 篇 + 提取 300 篇)**
|
||||
|
||||
| 任务 | 策略 | 成本 |
|
||||
|------|------|------|
|
||||
| 鏍囬<EFBFBD>鎽樿<EFBFBD>绛涢€?| 鎴愭湰浼樺寲 + 15% 浠茶<EFBFBD> | 楼120 |
|
||||
| 鍏ㄦ枃鏁版嵁鎻愬彇 | GPT-5 + Claude 鍙屾ā鍨?| 楼350 |
|
||||
| 标题摘要筛选 | 成本优化 + 15% 仲裁 | ¥120 |
|
||||
| 全文数据提取 | GPT-5 + Claude 双模型 | ¥350 |
|
||||
| 质量审计 | 10% 抽查 | ¥30 |
|
||||
| **鎬绘垚鏈?* | - | **楼500** |
|
||||
| **总成本** | - | **¥500** |
|
||||
|
||||
### 四、V2.0 验收标准
|
||||
|
||||
| 指标 | 目标 | 验证方法 |
|
||||
|------|------|----------|
|
||||
| 鎻愬彇鍑嗙‘鐜?| 鈮?95% | 浜哄伐鎶芥煡 100 绡?|
|
||||
| 浜烘満涓€鑷存€?| 鈮?90% | Cohen's Kappa |
|
||||
| 鍋囬槼鎬х巼 | 鈮?5% | 缁熻<EFBFBD>鍒嗘瀽 |
|
||||
| 鍋囬槾鎬х巼 | 鈮?3% | 缁熻<EFBFBD>鍒嗘瀽 |
|
||||
| 鎻愮ず璇嶇増鏈<EFBFBD><EFBFBD>鐞?| 100% | Git 鍘嗗彶 |
|
||||
| 鑷<EFBFBD>姩鍖栧<EFBFBD>璁?| 姣忓懆 1 娆?| 绯荤粺鎶ヨ〃 |
|
||||
| 提取准确率 | ≥ 95% | 人工抽查 100 篇 |
|
||||
| 人机一致性 | ≥ 90% | Cohen's Kappa |
|
||||
| 假阳性率 | ≤ 5% | 统计分析 |
|
||||
| 假阴性率 | ≤ 3% | 统计分析 |
|
||||
| 提示词版本管理 | 100% | Git 历史 |
|
||||
| 自动化审计 | 每周 1 次 | 系统报表 |
|
||||
|
||||
---
|
||||
|
||||
@@ -865,87 +865,87 @@ async function selectSimilarExamples(
|
||||
|
||||
| 维度 | MVP | V1.0 | V2.0 |
|
||||
|------|-----|------|------|
|
||||
| **鍑嗙‘鐜?* | 85% | 90% | 95% |
|
||||
| **妯″瀷缁勫悎** | DeepSeek + Qwen3 | 鎴愭湰浼樺寲绛栫暐 | 涓夋ā鍨嬩徊瑁?|
|
||||
| **璐ㄩ噺鎺у埗** | 鍙屾ā鍨嬮獙璇?| 瑙勫垯寮曟搸 + Few-shot | HITL + 鑷<EFBFBD>姩瀹¤<EFBFBD> |
|
||||
| **鍙<EFBFBD>拷婧<EFBFBD>€?* | 鍩烘湰鏃ュ織 | 瀹屾暣璇佹嵁閾?| 瀹¤<E780B9>绾ц<E7BBBE>褰?|
|
||||
| **鎴愭湰/1000 绡?* | 楼5 | 楼21 | 楼24 + 浠茶<EFBFBD> |
|
||||
| **寮€鍙戝懆鏈?* | 4 鍛?| 6 鍛?| 8 鍛?|
|
||||
| **閫傜敤鍦烘櫙** | 蹇<EFBFBD>€熼獙璇?| 甯歌<E794AF>椤圭洰 | 楂樿川閲忓彂琛?|
|
||||
| **准确率** | 85% | 90% | 95% |
|
||||
| **模型组合** | DeepSeek + Qwen3 | 成本优化策略 | 三模型仲裁 |
|
||||
| **质量控制** | 双模型验证 | 规则引擎 + Few-shot | HITL + 自动审计 |
|
||||
| **可追溯性** | 基本日志 | 完整证据链 | 审计级记录 |
|
||||
| **成本/1000 篇** | ¥5 | ¥21 | ¥24 + 仲裁 |
|
||||
| **开发周期** | 4 周 | 6 周 | 8 周 |
|
||||
| **适用场景** | 快速验证 | 常规项目 | 高质量发表 |
|
||||
|
||||
---
|
||||
|
||||
## 🔄 实施路径
|
||||
|
||||
### 闃舵<EFBFBD> 1: MVP 寮€鍙戯紙Week 1-4锛?
|
||||
### 阶段 1: MVP 开发(Week 1-4)
|
||||
|
||||
**Week 1**:基础架构
|
||||
- [ ] LLM 鏈嶅姟灏佽<EFBFBD>锛圖eepSeek + Qwen3锛?
|
||||
- [ ] LLM 服务封装(DeepSeek + Qwen3)
|
||||
- [ ] JSON Schema 定义
|
||||
- [ ] 数据库表设计
|
||||
|
||||
**Week 2**锛氭牳蹇冨姛鑳?
|
||||
- [ ] 鍙屾ā鍨嬪苟琛岃皟鐢?
|
||||
**Week 2**:核心功能
|
||||
- [ ] 双模型并行调用
|
||||
- [ ] 一致性判断逻辑
|
||||
- [ ] 人工复核队列
|
||||
|
||||
**Week 3**锛氬墠绔<E5A2A0>紑鍙?
|
||||
**Week 3**:前端开发
|
||||
- [ ] 筛选工作台
|
||||
- [ ] 冲突对比视图
|
||||
- [ ] 人工复核界面
|
||||
|
||||
**Week 4**锛氭祴璇曢獙鏀?
|
||||
**Week 4**:测试验收
|
||||
- [ ] 功能测试
|
||||
- [ ] 鍑嗙‘鐜囪瘎浼?
|
||||
- [ ] 准确率评估
|
||||
- [ ] 成本监控
|
||||
|
||||
### 闃舵<EFBFBD> 2: V1.0 澧炲己锛圵eek 5-10锛?
|
||||
### 阶段 2: V1.0 增强(Week 5-10)
|
||||
|
||||
**Week 5-6**锛氭櫤鑳戒紭鍖?
|
||||
**Week 5-6**:智能优化
|
||||
- [ ] 成本优化策略
|
||||
- [ ] Few-shot 绀轰緥搴?
|
||||
- [ ] Few-shot 示例库
|
||||
- [ ] 动态示例选择
|
||||
|
||||
**Week 7-8**锛氳川閲忔帶鍒?
|
||||
**Week 7-8**:质量控制
|
||||
- [ ] 分段提取
|
||||
- [ ] 规则引擎
|
||||
- [ ] 证据链完整化
|
||||
|
||||
**Week 9-10**锛氭祴璇曚紭鍖?
|
||||
**Week 9-10**:测试优化
|
||||
- [ ] A/B 测试
|
||||
- [ ] 鍑嗙‘鐜囨彁鍗?
|
||||
- [ ] 准确率提升
|
||||
- [ ] 文档完善
|
||||
|
||||
### 闃舵<EFBFBD> 3: V2.0 瀹屽杽锛圵eek 11-18锛?
|
||||
### 阶段 3: V2.0 完善(Week 11-18)
|
||||
|
||||
**Week 11-13**锛氶珮绾у姛鑳?
|
||||
- [ ] 涓夋ā鍨嬩徊瑁?
|
||||
**Week 11-13**:高级功能
|
||||
- [ ] 三模型仲裁
|
||||
- [ ] HITL 智能分流
|
||||
- [ ] 鎻愮ず璇嶇増鏈<EFBFBD><EFBFBD>鐞?
|
||||
- [ ] 提示词版本管理
|
||||
|
||||
**Week 14-16**锛氳川閲忓<E996B2>璁?
|
||||
**Week 14-16**:质量审计
|
||||
- [ ] 自动审计系统
|
||||
- [ ] 质量报表
|
||||
- [ ] 寮傚父妫€娴?
|
||||
- [ ] 异常检测
|
||||
|
||||
**Week 17-18**锛氬彂甯冨噯澶?
|
||||
**Week 17-18**:发布准备
|
||||
- [ ] 全量测试
|
||||
- [ ] 医学专家验证
|
||||
- [ ] 鏂囨。鍜屽煿璁?
|
||||
- [ ] 文档和培训
|
||||
|
||||
---
|
||||
|
||||
## 📚 相关文档
|
||||
|
||||
- [CloseAI 闆嗘垚鎸囧崡](../../../02-閫氱敤鑳藉姏灞?01-LLM澶фā鍨嬬綉鍏?03-CloseAI闆嗘垚鎸囧崡.md)
|
||||
- [CloseAI 集成指南](../../../02-通用能力层/01-LLM大模型网关/03-CloseAI集成指南.md)
|
||||
- [AI 模型集成设计](./04-AI模型集成设计.md)
|
||||
- [鏁版嵁搴撹<EFBFBD>璁<EFBFBD>(./01-鏁版嵁搴撹<E690B4>璁?md)
|
||||
- [数据库设计](./01-数据库设计.md)
|
||||
- [API 设计规范](./02-API设计规范.md)
|
||||
|
||||
---
|
||||
|
||||
**鏇存柊鏃ュ織**锛?
|
||||
- 2025-11-15: 鍒涘缓鏂囨。锛屽畾涔?MVP/V1.0/V2.0 涓夐樁娈电瓥鐣?
|
||||
**更新日志**:
|
||||
- 2025-11-15: 创建文档,定义 MVP/V1.0/V2.0 三阶段策略
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,86 +1,86 @@
|
||||
# ASL 文献处理技术选型
|
||||
|
||||
> **<EFBFBD><EFBFBD>﹝<EFBFBD><EFBFBD>𧋦嚗?* V1.0
|
||||
> **<EFBFBD>𥕦遣<EFBFBD>交<EFBFBD>嚗?* 2025-11-15
|
||||
> **<EFBFBD><EFBFBD>鍂璅∪<EFBFBD>嚗?* AI <20>箄<EFBFBD><E7AE84><EFBFBD>讃嚗㇁SL嚗?
|
||||
> **<EFBFBD>格<EFBFBD>嚗?* 摰帋<E691B0><E5B88B>萘<EFBFBD><E89098><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>蝑䜘<E89D91><E49C98><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>𣇉<EFBFBD><F0A38789><EFBFBD><EFBFBD>舀<EFBFBD><E88880><EFBFBD><EFBFBD><EFBFBD>啗楝敺?
|
||||
> **文档版本:** V1.0
|
||||
> **创建日期:** 2025-11-15
|
||||
> **适用模块:** AI 智能文献(ASL)
|
||||
> **目标:** 定义初筛、全文复筛、全文提取的技术栈和实现路径
|
||||
|
||||
---
|
||||
|
||||
## 📋 文档概述
|
||||
|
||||
ASL 璅∪<EFBFBD>瘨匧<EFBFBD>銝厩<EFBFBD>銝滚<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>桀<EFBFBD><EFBFBD><EFBFBD>㦤<EFBFBD>荔<EFBFBD>瘥讐<EFBFBD><EFBFBD>箸艶<EFBFBD>劐<EFBFBD><EFBFBD>𣬚<EFBFBD><EFBFBD><EFBFBD><EFBFBD>舐鸌<EFBFBD>孵<EFBFBD>摰䂿緵<EFBFBD>寞<EFBFBD>嚗?
|
||||
ASL 模块涉及三种不同的文献处理场景,每种场景有不同的技术特点和实现方案:
|
||||
|
||||
| <EFBFBD>箸艶 | 颲枏<E9A2B2><E69E8F>澆<EFBFBD> | <20>詨<EFBFBD><E8A9A8><EFBFBD><EFBFBD>?| 銝餉<E98A9D><E9A489>烐<EFBFBD> |
|
||||
| 场景 | 输入格式 | 核心技术 | 主要挑战 |
|
||||
|------|---------|---------|---------|
|
||||
| **<EFBFBD><EFBFBD><EFBFBD><EFBFBD>䁅<EFBFBD><EFBFBD>萘<EFBFBD>** | Excel <EFBFBD><EFBFBD>辣 | Excel 閫<EFBFBD><EFBFBD> + LLM 蝑偦<EFBFBD>?| <20>寥<EFBFBD>憭<EFBFBD><E686AD><EFBFBD><EFBFBD><EFBFBD> |
|
||||
| **<EFBFBD>冽<EFBFBD>憭滨<EFBFBD>** | PDF <EFBFBD>冽<EFBFBD> | PDF <EFBFBD>𣂼<EFBFBD> + LLM 蝑偦<EFBFBD>?| PDF 閫<EFBFBD><EFBFBD><EFBFBD><EFBFBD>&<EFBFBD>?|
|
||||
| **<EFBFBD>冽<EFBFBD><EFBFBD>唳旿<EFBFBD>𣂼<EFBFBD>** | PDF <EFBFBD>冽<EFBFBD> | PDF <EFBFBD>𣂼<EFBFBD> + LLM 蝏𤘪<EFBFBD><EFBFBD>𡝗<EFBFBD><EFBFBD>?| 銵冽聢<E586BD><E881A2><EFBFBD>撘誩<E69298>蝖格<E89D96><E6A0BC>?|
|
||||
| **标题摘要初筛** | Excel 文件 | Excel 解析 + LLM 筛选 | 批量处理效率 |
|
||||
| **全文复筛** | PDF 全文 | PDF 提取 + LLM 筛选 | PDF 解析准确率 |
|
||||
| **全文数据提取** | PDF 全文 | PDF 提取 + LLM 结构化提取 | 表格、公式准确提取 |
|
||||
|
||||
---
|
||||
|
||||
## 🎯 技术架构总览
|
||||
|
||||
```
|
||||
<EFBFBD>𢞖<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
|
||||
<EFBFBD>? ASL <EFBFBD><EFBFBD>讃憭<EFBFBD><EFBFBD>瘚<EFBFBD><EFBFBD> <EFBFBD>?
|
||||
<EFBFBD>婙<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
|
||||
<EFBFBD>?
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ ASL 文献处理流程 │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
│
|
||||
├─ 场景 1: 标题摘要初筛
|
||||
<EFBFBD>? <20>婙<EFBFBD> <20>冽<EFBFBD>銝𠹺<E98A9D> Excel <20>?閫<><E996AB> <20>?LLM <20>寥<EFBFBD>蝑偦<E89D91>?<3F>?撖澆枂蝏𤘪<E89D8F>
|
||||
<EFBFBD>?
|
||||
│ └─ 用户上传 Excel → 解析 → LLM 批量筛选 → 导出结果
|
||||
│
|
||||
├─ 场景 2: 全文复筛
|
||||
<EFBFBD>? <20>婙<EFBFBD> <20>冽<EFBFBD>銝𠹺<E98A9D> PDF <EFBFBD>?PDF <EFBFBD>𣂼<EFBFBD> <20>?LLM 蝑偦<E89D91>?<3F>?憭齿瓲
|
||||
<EFBFBD>?
|
||||
│ └─ 用户上传 PDF → PDF 提取 → LLM 筛选 → 复核
|
||||
│
|
||||
└─ 场景 3: 全文数据提取
|
||||
<EFBFBD>婙<EFBFBD> PDF <EFBFBD>?<3F>𣂼<EFBFBD> + 蝏𤘪<E89D8F><F0A498AA>?<3F>?LLM <20>𣂼<EFBFBD><F0A382BC>唳旿 <20>?鈭箏極憭齿瓲
|
||||
└─ PDF → 提取 + 结构化 → LLM 提取数据 → 人工复核
|
||||
|
||||
<EFBFBD>𢞖<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
|
||||
<EFBFBD>? <EFBFBD><EFBFBD><EFBFBD>舀<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>嗆<EFBFBD>嚗<EFBFBD><EFBFBD>鈭恬<EFBFBD> <EFBFBD>?
|
||||
<EFBFBD>鎿<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
|
||||
<EFBFBD>? <20>滨垢撅? React 19 + Ant Design 5 + xlsx/exceljs <EFBFBD>?
|
||||
<EFBFBD>鎿<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
|
||||
<EFBFBD>? <20>𡒊垢撅? Node.js (Fastify) + TypeScript <EFBFBD>?
|
||||
<EFBFBD>鎿<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
|
||||
<EFBFBD>? <20><>﹝憭<EFB99D><E686AD>撅? Python 敺格<EFBFBD><EFBFBD>?(extraction_service) <EFBFBD>?
|
||||
<EFBFBD>? <EFBFBD>鎿<EFBFBD> PyMuPDF: 敹恍<EFBFBD>?PDF <EFBFBD>𣂼<EFBFBD> <EFBFBD>?
|
||||
<EFBFBD>? <EFBFBD>鎿<EFBFBD> Nougat: <EFBFBD>望<EFBFBD>蝘穃郎<EFBFBD><EFBFBD>讃擃䁅捶<EFBFBD>𤩺<EFBFBD><EFBFBD>?潃? <EFBFBD>?
|
||||
<EFBFBD>? <EFBFBD>婙<EFBFBD> Language Detector: <EFBFBD>芸𢆡霂剛<EFBFBD>璉<EFBFBD>瘚? <EFBFBD>?
|
||||
<EFBFBD>鎿<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
|
||||
<EFBFBD>? LLM 撅? DeepSeek-V3 + Qwen3 / GPT-5 + Claude-4.5 <EFBFBD>?
|
||||
<EFBFBD>鎿<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
|
||||
<EFBFBD>? <20>唳旿摨? PostgreSQL 15 (asl_schema) <EFBFBD>?
|
||||
<EFBFBD>婙<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ 技术栈分层架构(共享) │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ 前端层: React 19 + Ant Design 5 + xlsx/exceljs │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ 后端层: Node.js (Fastify) + TypeScript │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ 文档处理层: Python 微服务 (extraction_service) │
|
||||
│ ├─ PyMuPDF: 快速 PDF 提取 │
|
||||
│ ├─ Nougat: 英文科学文献高质量提取 ⭐ │
|
||||
│ └─ Language Detector: 自动语言检测 │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ LLM 层: DeepSeek-V3 + Qwen3 / GPT-5 + Claude-4.5 │
|
||||
├─────────────────────────────────────────────────────────┤
|
||||
│ 数据库: PostgreSQL 15 (asl_schema) │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📌 场景 1: 标题摘要初筛
|
||||
|
||||
### 1.1 <EFBFBD><EFBFBD><EFBFBD>舐鸌<EFBFBD>?
|
||||
### 1.1 技术特点
|
||||
|
||||
- **输入格式**: Excel 文件 (`.xlsx` / `.xls`)
|
||||
- **<EFBFBD>唳旿閫<EFBFBD>芋**: 50-500 蝭<EFBFBD><EFBFBD><EFBFBD>?<3F>寞活
|
||||
- **銝餉<EFBFBD>摮埈挾**: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>閬<EFBFBD><E996AC><EFBFBD>OI<4F><49><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>銵典僑隞賬<E99A9E><E8B3AC><EFBFBD><EFBFBD>?
|
||||
- **数据规模**: 50-500 篇文献/批次
|
||||
- **主要字段**: 标题、摘要、DOI、作者、发表年份、期刊
|
||||
- **处理重点**: 批量高效处理,无需 PDF 解析
|
||||
|
||||
### 1.2 技术选型
|
||||
|
||||
#### <EFBFBD>滨垢嚗鍃xcel 銝𠹺<E98A9D>銝舘圾<E88898>?
|
||||
#### 前端:Excel 上传与解析
|
||||
|
||||
| <EFBFBD><EFBFBD><EFBFBD>?| 摨?| <20>券<EFBFBD>?| 隡睃飵 |
|
||||
| 技术 | 库 | 用途 | 优势 |
|
||||
|------|-----|------|------|
|
||||
| **Excel 上传** | `antd Upload` | 文件上传组件 | 拖拽上传、进度条 |
|
||||
| **Excel 閫<EFBFBD><EFBFBD>** | `xlsx` / `exceljs` | <EFBFBD>滨垢閫<EFBFBD><EFBFBD> Excel | 蝥臬<EFBFBD>蝡臬<EFBFBD><EFBFBD><EFBFBD><EFBFBD>敹恍<EFBFBD>罸<EFBFBD>閫?|
|
||||
| **璅⊥踎撉諹<EFBFBD>** | <EFBFBD>芸<EFBFBD>銋厰<EFBFBD>餉<EFBFBD> | <20>⊿<EFBFBD><E28ABF>堒<EFBFBD><E5A092>峕㺭<E5B395>格聢撘?| <20>𣂼<EFBFBD><F0A382BC>𤑳緵<F0A491B3>澆<EFBFBD><E6BE86>躰秤 |
|
||||
| **Excel 解析** | `xlsx` / `exceljs` | 前端解析 Excel | 纯前端处理,快速预览 |
|
||||
| **模板验证** | 自定义逻辑 | 校验列名和数据格式 | 提前发现格式错误 |
|
||||
|
||||
**<EFBFBD>刻<EFBFBD><EFBFBD>寞<EFBFBD>嚗䫤xlsx` 摨橒<EFBFBD>SheetJS嚗?*
|
||||
- <20>?<3F>舀<EFBFBD> `.xlsx` <20>?`.xls` <20>澆<EFBFBD>
|
||||
- <20>?蝥?JavaScript嚗<EFBFBD><EFBFBD>蝡舐凒<EFBFBD>亥圾<EFBFBD>?
|
||||
- <20>?雿梶妖撠𧶏<E692A0>~600KB嚗㚁<E59A97><E39A81>扯<EFBFBD>憟?
|
||||
- <20>?<3F>舀<EFBFBD>憭扳<E686AD>隞塚<E99A9E>1000+ 銵䕘<EFBFBD>
|
||||
**推荐方案:`xlsx` 库(SheetJS)**
|
||||
- ✅ 支持 `.xlsx` 和 `.xls` 格式
|
||||
- ✅ 纯 JavaScript,前端直接解析
|
||||
- ✅ 体积小(~600KB),性能好
|
||||
- ✅ 支持大文件(1000+ 行)
|
||||
|
||||
**隞<EFBFBD><EFBFBD>蝷箔<EFBFBD>嚗?*
|
||||
**代码示例:**
|
||||
```typescript
|
||||
import * as XLSX from 'xlsx';
|
||||
|
||||
@@ -97,15 +97,15 @@ function parseExcel(file: File): Promise<Literature[]> {
|
||||
const sheetName = workbook.SheetNames[0];
|
||||
const worksheet = workbook.Sheets[sheetName];
|
||||
|
||||
// 頧祆揢銝?JSON
|
||||
// 转换为 JSON
|
||||
const jsonData = XLSX.utils.sheet_to_json(worksheet);
|
||||
|
||||
// <EFBFBD>惩<EFBFBD>銝箸<EFBFBD><EFBFBD><EFBFBD>聢撘?
|
||||
// 映射为标准格式
|
||||
const literatures = jsonData.map((row: any) => ({
|
||||
title: row['Title'] || row['标题'],
|
||||
abstract: row['Abstract'] || row['摘要'],
|
||||
doi: row['DOI'],
|
||||
authors: row['Authors'] || row['雿𡏭<E99BBF>?],
|
||||
authors: row['Authors'] || row['作者'],
|
||||
year: row['Year'] || row['年份'],
|
||||
journal: row['Journal'] || row['期刊'],
|
||||
}));
|
||||
@@ -122,20 +122,20 @@ function parseExcel(file: File): Promise<Literature[]> {
|
||||
}
|
||||
```
|
||||
|
||||
#### <EFBFBD>𡒊垢嚗𡁏鸌<EFBFBD>讐<EFBFBD><EFBFBD>匧<EFBFBD><EFBFBD>?
|
||||
#### 后端:批量筛选处理
|
||||
|
||||
**憭<EFBFBD><EFBFBD>瘚<EFBFBD><EFBFBD>嚗?*
|
||||
**处理流程:**
|
||||
```
|
||||
Excel <EFBFBD>唳旿 <20>?<3F>寥<EFBFBD><E5AFA5><EFBFBD><EFBFBD>嚗?0-20 蝭?蝏<><E89D8F><EFBFBD>?撟嗉<E6929F>靚<EFBFBD>鍂 LLM <20>?瘙<><E79899>餌<EFBFBD><E9A48C>?
|
||||
Excel 数据 → 批量分组(10-20 篇/组)→ 并行调用 LLM → 汇总结果
|
||||
```
|
||||
|
||||
**<EFBFBD>喲睸<EFBFBD><EFBFBD><EFBFBD>舐<EFBFBD>嚗?*
|
||||
1. **<2A>寥<EFBFBD><E5AFA5><EFBFBD><EFBFBD>**嚗𡁻<E59A97><F0A181BB>滚<EFBFBD>甈∟窈瘙<E7AA88><E79899>憭改<E686AD>10-20 蝭?蝏<><E89D8F>隡?
|
||||
2. **撟嗉<E6929F>憭<EFBFBD><E686AD>**嚗帋蝙<E5B88B>?`Promise.all` 撟嗉<E6929F>靚<EFBFBD>鍂 LLM
|
||||
3. **餈𥕦漲<F0A595A6>券<EFBFBD>?*嚗阳ebSocket 摰墧𧒄<E5A2A7>券<EFBFBD><E588B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>摨?
|
||||
**关键技术点:**
|
||||
1. **批量分组**:避免单次请求过大,10-20 篇/组最优
|
||||
2. **并行处理**:使用 `Promise.all` 并行调用 LLM
|
||||
3. **进度推送**:WebSocket 实时推送处理进度
|
||||
4. **断点续传**:支持任务中断后继续
|
||||
|
||||
**隞<EFBFBD><EFBFBD>蝷箔<EFBFBD>嚗?*
|
||||
**代码示例:**
|
||||
```typescript
|
||||
async function batchScreening(
|
||||
literatures: Literature[],
|
||||
@@ -156,7 +156,7 @@ async function batchScreening(
|
||||
|
||||
results.push(...batchResults);
|
||||
|
||||
// <EFBFBD>券<EFBFBD><EFBFBD><EFBFBD>摨?
|
||||
// 推送进度
|
||||
const progress = Math.round(((i + 1) / batches.length) * 100);
|
||||
progressCallback(progress);
|
||||
}
|
||||
@@ -165,55 +165,55 @@ async function batchScreening(
|
||||
}
|
||||
```
|
||||
|
||||
### 1.3 <EFBFBD>唳旿瘚?
|
||||
### 1.3 数据流
|
||||
|
||||
```
|
||||
用户操作 前端处理 后端处理 LLM 处理
|
||||
<EFBFBD>? <EFBFBD>? <EFBFBD>? <EFBFBD>?
|
||||
<EFBFBD>鎿<EFBFBD> 銝𠹺<E98A9D> Excel <EFBFBD>? <EFBFBD>? <EFBFBD>?
|
||||
<EFBFBD>? <EFBFBD>婙<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>圝<EFBFBD> <EFBFBD>? <EFBFBD>?
|
||||
<EFBFBD>? <EFBFBD>鎿<EFBFBD> 閫<><E996AB> Excel <EFBFBD>? <EFBFBD>?
|
||||
<EFBFBD>? <EFBFBD>鎿<EFBFBD> 撉諹<E69289><E8ABB9>澆<EFBFBD> <EFBFBD>? <EFBFBD>?
|
||||
<EFBFBD>? <EFBFBD>鎿<EFBFBD> <20>曄內憸<E585A7><E686B8> <EFBFBD>? <EFBFBD>?
|
||||
<EFBFBD>? <EFBFBD>? <EFBFBD>? <EFBFBD>?
|
||||
<EFBFBD>? <EFBFBD>鎿<EFBFBD> <20>𣂷漱蝑偦<E89D91>劐遙<E58A90>? <EFBFBD>? <EFBFBD>?
|
||||
<EFBFBD>? <EFBFBD>? <EFBFBD>婙<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>圝<EFBFBD> <EFBFBD>?
|
||||
<EFBFBD>? <EFBFBD>? <EFBFBD>鎿<EFBFBD> 靽嘥<E99DBD>隞餃𦛚 <EFBFBD>?
|
||||
<EFBFBD>? <EFBFBD>? <EFBFBD>鎿<EFBFBD> <20><><EFBFBD>嚗?5 蝭?蝏<><E89D8F> <20>?
|
||||
<EFBFBD>? <EFBFBD>? <EFBFBD>? <EFBFBD>?
|
||||
<EFBFBD>? <EFBFBD>? <EFBFBD>鎿<EFBFBD> <20>寞活 1 <EFBFBD>?
|
||||
<EFBFBD>? <EFBFBD>? <EFBFBD>? <20>婙<EFBFBD><E5A999><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>圝<EFBFBD>
|
||||
<EFBFBD>? <EFBFBD>? <EFBFBD>? <EFBFBD>鎿<EFBFBD> DeepSeek 蝑偦<EFBFBD>?
|
||||
<EFBFBD>? <EFBFBD>? <EFBFBD>? <EFBFBD>鎿<EFBFBD> Qwen3 蝑偦<EFBFBD>?
|
||||
<EFBFBD>? <20>? <EFBFBD>? <EFBFBD>鎿<EFBFBD> 撖寞<E69296>蝏𤘪<E89D8F>
|
||||
<EFBFBD>? <EFBFBD>? <EFBFBD>? <20>鐥<EFBFBD><E990A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
|
||||
<EFBFBD>? <EFBFBD>? <EFBFBD>鎿<EFBFBD> 靽嘥<E99DBD>蝏𤘪<E89D8F> <EFBFBD>?
|
||||
<EFBFBD>? <EFBFBD>? <EFBFBD>? <EFBFBD>?
|
||||
<EFBFBD>? <EFBFBD>? <EFBFBD>鎿<EFBFBD> <20>寞活 2... <EFBFBD>?
|
||||
<EFBFBD>? <EFBFBD>? <EFBFBD>? <EFBFBD>?
|
||||
<EFBFBD>? <EFBFBD>? <20>鐥<EFBFBD><E990A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?餈𥪜<E9A488>摰峕㟲蝏𤘪<E89D8F> <EFBFBD>?
|
||||
<EFBFBD>? <EFBFBD>鐥<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<3F>曄內蝏𤘪<E89D8F> <EFBFBD>? <EFBFBD>?
|
||||
<EFBFBD>婙<EFBFBD> 鈭箏極憭齿瓲 <EFBFBD>? <EFBFBD>? <EFBFBD>?
|
||||
│ │ │ │
|
||||
├─ 上传 Excel │ │ │
|
||||
│ └──────────────→│ │ │
|
||||
│ ├─ 解析 Excel │ │
|
||||
│ ├─ 验证格式 │ │
|
||||
│ ├─ 显示预览 │ │
|
||||
│ │ │ │
|
||||
│ ├─ 提交筛选任务 │ │
|
||||
│ │ └───────────────→│ │
|
||||
│ │ ├─ 保存任务 │
|
||||
│ │ ├─ 分组(15 篇/组) │
|
||||
│ │ │ │
|
||||
│ │ ├─ 批次 1 │
|
||||
│ │ │ └──────────────→│
|
||||
│ │ │ ├─ DeepSeek 筛选
|
||||
│ │ │ ├─ Qwen3 筛选
|
||||
│ │ │ ├─ 对比结果
|
||||
│ │ │ ←──────────────┘
|
||||
│ │ ├─ 保存结果 │
|
||||
│ │ │ │
|
||||
│ │ ├─ 批次 2... │
|
||||
│ │ │ │
|
||||
│ │ ←───────────────┤ 返回完整结果 │
|
||||
│ ←──────────────┤ 显示结果 │ │
|
||||
└─ 人工复核 │ │ │
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD><EFBFBD> <20>箸艶 2 & 3: <EFBFBD>冽<EFBFBD>憭滨<EFBFBD>銝擧㺭<EFBFBD>格<EFBFBD><EFBFBD>?
|
||||
## 📌 场景 2 & 3: 全文复筛与数据提取
|
||||
|
||||
### 2.1 <EFBFBD><EFBFBD><EFBFBD>舐鸌<EFBFBD>?
|
||||
### 2.1 技术特点
|
||||
|
||||
- **输入格式**: PDF 文件(英文医学文献)
|
||||
- **文件特点**:
|
||||
- 科学论文格式(标题、摘要、引言、方法、结果、讨论、参考文献)
|
||||
- <20><>鉄憭齿<E686AD>銵冽聢<E586BD><E881A2><EFBFBD>撘譌<E69298><E8AD8C>㦛銵?
|
||||
- <20>𡁜虜 10-30 憿?
|
||||
- 包含复杂表格、公式、图表
|
||||
- 通常 10-30 页
|
||||
- **处理重点**: 高准确率提取,保留结构和格式
|
||||
|
||||
### 2.2 技术选型:PDF 提取
|
||||
|
||||
#### <EFBFBD>詨<EFBFBD><EFBFBD>寞<EFBFBD>嚗鐭ougat + PyMuPDF 憿箏<EFBFBD><EFBFBD>滨漣蝑𣇉裦 潃?
|
||||
#### 核心方案:Nougat + PyMuPDF 顺序降级策略 ⭐
|
||||
|
||||
**<EFBFBD>唳<EFBFBD><EFBFBD>嗆<EFBFBD>**嚗<>歇摰䂿緵嚗䔶<E59A97>鈭?`extraction_service/`嚗㚁<E59A97>
|
||||
**现有架构**(已实现,位于 `extraction_service/`):
|
||||
|
||||
```python
|
||||
# 顺序降级策略
|
||||
@@ -221,75 +221,75 @@ def extract_pdf(file_path: str):
|
||||
# Step 1: 检测语言
|
||||
language = detect_language(file_path)
|
||||
|
||||
# Step 2: 銝剜<EFBFBD> PDF <EFBFBD>?PyMuPDF嚗<EFBFBD>翰<EFBFBD><EFBFBD><EFBFBD>
|
||||
# Step 2: 中文 PDF → PyMuPDF(快速)
|
||||
if language == 'chinese':
|
||||
return extract_pdf_pymupdf(file_path)
|
||||
|
||||
# Step 3: <EFBFBD>望<EFBFBD> PDF <EFBFBD>?撠肽<E692A0> Nougat
|
||||
# Step 3: 英文 PDF → 尝试 Nougat
|
||||
if check_nougat_available():
|
||||
result = extract_pdf_nougat(file_path)
|
||||
|
||||
# 韐券<EFBFBD>璉<EFBFBD><EFBFBD>伐<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?0.7嚗?
|
||||
# 质量检查(阈值 0.7)
|
||||
if result['quality_score'] >= 0.7:
|
||||
return result # <EFBFBD>?Nougat <EFBFBD>𣂼<EFBFBD>
|
||||
return result # ✅ Nougat 成功
|
||||
|
||||
# Step 4: <EFBFBD>滨漣<EFBFBD>?PyMuPDF
|
||||
# Step 4: 降级到 PyMuPDF
|
||||
return extract_pdf_pymupdf(file_path)
|
||||
```
|
||||
|
||||
#### <EFBFBD><EFBFBD><EFBFBD>臬笆瘥?
|
||||
#### 技术对比
|
||||
|
||||
| 方案 | 优势 | 劣势 | 适用场景 |
|
||||
|------|------|------|---------|
|
||||
| **Nougat** 潃?| <20>?銝㮖蛹蝘穃郎<E7A983><E9838E>讃霈曇恣<br><3E>?<3F>砍<EFBFBD><E7A08D><EFBFBD>”<EFBFBD>澆<EFBFBD>蝖桃<E89D96>擃?br><3E>?颲枏枂 Markdown <EFBFBD>澆<EFBFBD><br><EFBFBD>?靽萘<E99DBD><E89098><EFBFBD>﹝蝏𤘪<E89D8F> | <20>?<3F>笔漲<E7AC94>g<EFBFBD>1-2 <EFBFBD><EFBFBD><EFBFBD>/20 憿蛛<EFBFBD><br><EFBFBD>?<3F><>閬?GPU <20>𣳇<EFBFBD>?br><3E>?<3F><><EFBFBD><EFBFBD>删鍂憭改<E686AD>~4GB嚗?| <20>望<EFBFBD><E69C9B>餃郎<E9A483><E9838E>讃<EFBFBD>冽<EFBFBD><E586BD>𣂼<EFBFBD> |
|
||||
| **PyMuPDF** | <EFBFBD>?<3F>笔漲敹恬<E695B9>蝘垍漣嚗?br><3E>?<3F><><EFBFBD><EFBFBD>删鍂雿?br><3E>?<3F>函蔡蝞<E894A1><E89D9E>?| <20>?<3F>砍<EFBFBD><E7A08D><EFBFBD>”<EFBFBD>潭<EFBFBD>銝W仃<br><3E>?蝥舀<E89DA5><E88880>祈<EFBFBD><E7A588>?br><3E>?撣<><E692A3><EFBFBD>𤘪毽銋?| 銝剜<E98A9D><E5899C><EFBFBD>讃<EFBFBD><E8AE83>翰<EFBFBD>罸<EFBFBD>閫?|
|
||||
| **Adobe API** | <EFBFBD>?<3F><><EFBFBD>蝥批<E89DA5>蝖桃<E89D96><br><3E>?鈭𤑳垢憭<E59EA2><E686AD> | <20>?<3F><>隞䁅晶<br><3E>?蝵𤑳<E89DB5>靘肽<E99D98><br><3E>?<3F>鞟<EFBFBD>憌𡡞埯 | 銝齿綫<E9BDBF>琜<EFBFBD><E7909C>鞉𧋦擃矋<E69383> |
|
||||
| **Tesseract OCR** | <EFBFBD>?撘<>皞𣂼<E79A9E>韐?br><3E>?<3F>舀<EFBFBD>憭朞祗閮<E7A597> | <20>?<3F><>閬<EFBFBD>㦛<EFBFBD>誯<EFBFBD>憭<EFBFBD><E686AD><br><3E>?<3F><>&<EFBFBD><EFBC86><EFBFBD>蝔喳<E89D94> | <20>急<EFBFBD><E680A5>?PDF嚗<46><E59A97><EFBFBD>㚁<EFBFBD> |
|
||||
| **Nougat** ⭐ | • 专为科学文献设计<br>• 公式、表格准确率高<br>• 输出 Markdown 格式<br>• 保留文档结构 | • 速度慢(1-2 分钟/20 页)<br>• 需要 GPU 加速<br>• 内存占用大(~4GB) | 英文医学文献全文提取 |
|
||||
| **PyMuPDF** | • 速度快(秒级)<br>• 内存占用低<br>• 部署简单 | • 公式、表格易丢失<br>• 纯文本输出<br>• 布局易混乱 | 中文文献、快速预览 |
|
||||
| **Adobe API** | • 商业级准确率<br>• 云端处理 | • 需付费<br>• 网络依赖<br>• 隐私风险 | 不推荐(成本高) |
|
||||
| **Tesseract OCR** | • 开源免费<br>• 支持多语言 | • 需要图像预处理<br>• 准确率不稳定 | 扫描版 PDF(备选) |
|
||||
|
||||
**<EFBFBD>刻<EFBFBD><EFBFBD>寞<EFBFBD>嚗鐭ougat嚗<EFBFBD>蜓嚗?+ PyMuPDF嚗<46><E59A97>蝥改<E89DA5> 潃?*
|
||||
**推荐方案:Nougat(主) + PyMuPDF(降级) ⭐**
|
||||
|
||||
#### Nougat 核心优势(医学文献场景)
|
||||
|
||||
```
|
||||
<EFBFBD>?銝㮖蛹蝘穃郎<E7A983><E9838E>讃霈曇恣
|
||||
✅ 专为科学文献设计
|
||||
├─ 训练数据:arXiv 论文 + 科学期刊
|
||||
├─ 公式识别:LaTeX 格式输出
|
||||
├─ 表格保留:Markdown 表格格式
|
||||
<EFBFBD>婙<EFBFBD> 蝏𤘪<E89D8F><F0A498AA>𤥁<EFBFBD><F0A4A581>綽<EFBFBD>蝡㰘<E89DA1><E3B098><EFBFBD>挾<EFBFBD>賣<EFBFBD><E8B3A3>?
|
||||
└─ 结构化输出:章节、段落清晰
|
||||
|
||||
<EFBFBD>?颲枏枂<E69E8F>澆<EFBFBD>嚗鐝arkdown
|
||||
<EFBFBD>鎿<EFBFBD> <20><><EFBFBD>撅<EFBFBD>漣嚗? ## ###
|
||||
✅ 输出格式:Markdown
|
||||
├─ 标题层级:# ## ###
|
||||
├─ 表格:| Header | Data |
|
||||
<EFBFBD>鎿<EFBFBD> <20>砍<EFBFBD>嚗?$ formula $$
|
||||
├─ 公式:$$ formula $$
|
||||
└─ 引用:[1] [2] [3]
|
||||
|
||||
<EFBFBD>?韐券<E99F90>霂<EFBFBD>摯<EFBFBD>箏<EFBFBD>
|
||||
<EFBFBD>鎿<EFBFBD> <20>芸𢆡韐券<E99F90>霂<EFBFBD><E99C82>嚗?-1嚗?
|
||||
<EFBFBD>鎿<EFBFBD> 雿舘捶<E88898>讛䌊<E8AE9B>券<EFBFBD>蝥?PyMuPDF
|
||||
<EFBFBD>婙<EFBFBD> 靽肽<E99DBD><E882BD>𣂼<EFBFBD><F0A382BC>𣂼<EFBFBD><F0A382BC>?
|
||||
✅ 质量评估机制
|
||||
├─ 自动质量评分(0-1)
|
||||
├─ 低质量自动降级 PyMuPDF
|
||||
└─ 保证提取成功率
|
||||
```
|
||||
|
||||
#### 实现细节
|
||||
|
||||
**<EFBFBD>滚𦛚<EFBFBD>嗆<EFBFBD>嚗?*
|
||||
**服务架构:**
|
||||
```
|
||||
Node.js Backend (Port 3001)
|
||||
<EFBFBD>?
|
||||
│
|
||||
├─ 调用 ExtractionClient.ts
|
||||
<EFBFBD>? <20>婙<EFBFBD> HTTP 霂瑟<E99C82> <20>?Python 敺格<E695BA><E6A0BC>?
|
||||
<EFBFBD>?
|
||||
│ └─ HTTP 请求 → Python 微服务
|
||||
│
|
||||
Python Extraction Service (Port 8000)
|
||||
<EFBFBD>?
|
||||
│
|
||||
├─ /api/extract/pdf
|
||||
<EFBFBD>? <20>鎿<EFBFBD> detect_language()
|
||||
<EFBFBD>? <20>鎿<EFBFBD> extract_pdf_nougat() <EFBFBD>?Nougat Model
|
||||
<EFBFBD>? <20>婙<EFBFBD> extract_pdf_pymupdf() <EFBFBD>?PyMuPDF
|
||||
<EFBFBD>?
|
||||
│ ├─ detect_language()
|
||||
│ ├─ extract_pdf_nougat() → Nougat Model
|
||||
│ └─ extract_pdf_pymupdf() → PyMuPDF
|
||||
│
|
||||
└─ /api/health
|
||||
<EFBFBD>婙<EFBFBD> 璉<><E79289>?Nougat <20>舐鍂<E88890>?
|
||||
└─ 检查 Nougat 可用性
|
||||
```
|
||||
|
||||
**Node.js 靚<EFBFBD>鍂隞<EFBFBD><EFBFBD>嚗?*
|
||||
**Node.js 调用代码:**
|
||||
```typescript
|
||||
import { extractionClient } from '@common/document/ExtractionClient';
|
||||
|
||||
@@ -320,7 +320,7 @@ async function extractLiteraturePDF(file: Buffer, filename: string) {
|
||||
}
|
||||
```
|
||||
|
||||
**Python <EFBFBD>𣂼<EFBFBD>隞<EFBFBD><EFBFBD>嚗?*
|
||||
**Python 提取代码:**
|
||||
```python
|
||||
# extraction_service/services/nougat_extractor.py
|
||||
|
||||
@@ -336,14 +336,14 @@ def extract_pdf_nougat(file_path: str) -> Dict[str, Any]:
|
||||
file_path,
|
||||
'-o', output_dir,
|
||||
'--markdown', # 输出 Markdown 格式
|
||||
'--no-skipping' # 銝滩歲餈<EFBFBD>遙雿閖△<EFBFBD>?
|
||||
'--no-skipping' # 不跳过任何页面
|
||||
]
|
||||
|
||||
# <EFBFBD>扯<EFBFBD> Nougat嚗<EFBFBD><EFBFBD><EFBFBD>?5 <20><><EFBFBD>嚗?
|
||||
# 执行 Nougat(超时 5 分钟)
|
||||
process = subprocess.Popen(cmd, ...)
|
||||
stdout, stderr = process.communicate(timeout=300)
|
||||
|
||||
# 霂餃<EFBFBD>颲枏枂<EFBFBD><EFBFBD>辣嚗?mmd嚗?
|
||||
# 读取输出文件(.mmd)
|
||||
markdown_text = read_output_file()
|
||||
|
||||
# 质量评估
|
||||
@@ -362,9 +362,9 @@ def extract_pdf_nougat(file_path: str) -> Dict[str, Any]:
|
||||
}
|
||||
```
|
||||
|
||||
### 2.3 <EFBFBD><EFBFBD>𧋦<EFBFBD>𤾸<EFBFBD><EFBFBD>?
|
||||
### 2.3 文本后处理
|
||||
|
||||
**Nougat 颲枏枂隡睃<EFBFBD>嚗?*
|
||||
**Nougat 输出优化:**
|
||||
```typescript
|
||||
function postProcessNougatOutput(markdown: string): ProcessedText {
|
||||
return {
|
||||
@@ -380,10 +380,10 @@ function postProcessNougatOutput(markdown: string): ProcessedText {
|
||||
// 公式提取
|
||||
formulas: extractFormulas(markdown),
|
||||
|
||||
// 蝥舀<EFBFBD><EFBFBD>穿<EFBFBD><EFBFBD>駁膄<EFBFBD>澆<EFBFBD>嚗?
|
||||
// 纯文本(去除格式)
|
||||
plainText: markdownToPlainText(markdown),
|
||||
|
||||
// 蝏𤘪<EFBFBD><EFBFBD>𡝗㺭<EFBFBD>殷<EFBFBD><EFBFBD>其<EFBFBD> LLM嚗?
|
||||
// 结构化数据(用于 LLM)
|
||||
structured: {
|
||||
title: extractTitle(markdown),
|
||||
abstract: extractAbstract(markdown),
|
||||
@@ -398,13 +398,13 @@ function postProcessNougatOutput(markdown: string): ProcessedText {
|
||||
|
||||
## 📌 场景 4: 文献下载(Unpaywall API)⭐
|
||||
|
||||
### 3.1 <EFBFBD><EFBFBD><EFBFBD>航<EFBFBD><EFBFBD>?
|
||||
### 3.1 技术背景
|
||||
|
||||
**Unpaywall** <20>臭<EFBFBD>銝芸<E98A9D>韐寧<E99F90>撘<EFBFBD><E69298>曇繮<E69B87>吔<EFBFBD>Open Access嚗㗇<E59A97><E39787>?API嚗<49>虾隞伐<E99A9E>
|
||||
- <20>?<3F>朞<EFBFBD> DOI <20>亥砭<E4BAA5><E7A0AD>讃<EFBFBD>臬炏<E887AC>匧<EFBFBD>韐孵<E99F90><E5ADB5>?
|
||||
- <20>?<3F>瑕<EFBFBD><E79195><EFBFBD><EFBFBD><EFBFBD>?PDF 銝贝蝸<E8B49D>暹𦻖
|
||||
- <20>?摰<><E691B0><EFBFBD>滩晶嚗峕<E59A97><E5B395><EFBFBD>隞䁅晶
|
||||
- <20>?<3F>唳旿摨栞<E691A8><E6A09E>?3000+ 銝<><E98A9D><EFBFBD><EFBFBD>讃
|
||||
**Unpaywall** 是一个免费的开放获取(Open Access)文献 API,可以:
|
||||
- ✅ 通过 DOI 查询文献是否有免费全文
|
||||
- ✅ 获取合法的 PDF 下载链接
|
||||
- ✅ 完全免费,无需付费
|
||||
- ✅ 数据库覆盖 3000+ 万篇文献
|
||||
|
||||
**官网**: https://unpaywall.org/products/api
|
||||
|
||||
@@ -412,18 +412,18 @@ function postProcessNougatOutput(markdown: string): ProcessedText {
|
||||
|
||||
#### API 调用方式
|
||||
|
||||
**<EFBFBD>箇<EFBFBD>靽⊥<EFBFBD>嚗?*
|
||||
**基础信息:**
|
||||
- **API 端点**: `https://api.unpaywall.org/v2/{doi}?email={your_email}`
|
||||
- **请求方法**: GET
|
||||
- **认证方式**: 无需 API Key,仅需提供邮箱
|
||||
- **<2A>毺<EFBFBD><E6AFBA>𣂼<EFBFBD>**: 100,000 甈?憭抬<E686AD><E68AAC>滩晶嚗?
|
||||
- **速率限制**: 100,000 次/天(免费)
|
||||
|
||||
**蝷箔<EFBFBD>霂瑟<EFBFBD>嚗?*
|
||||
**示例请求:**
|
||||
```bash
|
||||
curl "https://api.unpaywall.org/v2/10.1038/nature12373?email=YOUR_EMAIL"
|
||||
```
|
||||
|
||||
**<EFBFBD>滚<EFBFBD>蝷箔<EFBFBD>嚗?*
|
||||
**响应示例:**
|
||||
```json
|
||||
{
|
||||
"doi": "10.1038/nature12373",
|
||||
@@ -443,7 +443,7 @@ curl "https://api.unpaywall.org/v2/10.1038/nature12373?email=YOUR_EMAIL"
|
||||
|
||||
#### Node.js 实现
|
||||
|
||||
**<EFBFBD>滚𦛚撠<EFBFBD><EFBFBD>嚗?*
|
||||
**服务封装:**
|
||||
```typescript
|
||||
// backend/src/common/literature/UnpaywallClient.ts
|
||||
|
||||
@@ -453,7 +453,7 @@ import { config } from '../../config/env';
|
||||
export interface UnpaywallResult {
|
||||
doi: string;
|
||||
title: string;
|
||||
isOA: boolean; // <EFBFBD>臬炏撘<EFBFBD><EFBFBD>曇繮<EFBFBD>?
|
||||
isOA: boolean; // 是否开放获取
|
||||
oaStatus: string; // "gold" | "green" | "hybrid" | "bronze" | "closed"
|
||||
pdfUrl: string | null; // PDF 下载链接
|
||||
landingPageUrl: string; // 文献页面链接
|
||||
@@ -476,12 +476,12 @@ class UnpaywallClient {
|
||||
try {
|
||||
const url = `${this.baseUrl}/${doi}?email=${this.email}`;
|
||||
const response = await axios.get(url, {
|
||||
timeout: 10000, // 10 蝘坿<EFBFBD><EFBFBD>?
|
||||
timeout: 10000, // 10 秒超时
|
||||
});
|
||||
|
||||
const data = response.data;
|
||||
|
||||
// <EFBFBD>瑕<EFBFBD><EFBFBD><EFBFBD>雿喃<EFBFBD>頧賭<EFBFBD>蝵?
|
||||
// 获取最佳下载位置
|
||||
const bestOA = data.best_oa_location;
|
||||
|
||||
return {
|
||||
@@ -505,7 +505,7 @@ class UnpaywallClient {
|
||||
}
|
||||
|
||||
/**
|
||||
* <EFBFBD>寥<EFBFBD><EFBFBD>亥砭嚗<EFBFBD>蒂<EFBFBD>毺<EFBFBD><EFBFBD>𣂼<EFBFBD>嚗?
|
||||
* 批量查询(带速率限制)
|
||||
*/
|
||||
async getBatch(dois: string[]): Promise<UnpaywallResult[]> {
|
||||
const results = [];
|
||||
@@ -515,7 +515,7 @@ class UnpaywallClient {
|
||||
const result = await this.getByDoi(doi);
|
||||
results.push(result);
|
||||
|
||||
// <EFBFBD>毺<EFBFBD><EFBFBD>𣂼<EFBFBD>嚗?00ms/霂瑟<EFBFBD>
|
||||
// 速率限制:100ms/请求
|
||||
await new Promise(resolve => setTimeout(resolve, 100));
|
||||
} catch (error) {
|
||||
console.error(`Failed to fetch ${doi}:`, error.message);
|
||||
@@ -547,7 +547,7 @@ class UnpaywallClient {
|
||||
export const unpaywallClient = new UnpaywallClient();
|
||||
```
|
||||
|
||||
**<EFBFBD>臬<EFBFBD><EFBFBD>㗛<EFBFBD><EFBFBD>滨蔭嚗?*
|
||||
**环境变量配置:**
|
||||
```env
|
||||
# .env
|
||||
UNPAYWALL_EMAIL=your-email@example.com
|
||||
@@ -560,7 +560,7 @@ UNPAYWALL_EMAIL=your-email@example.com
|
||||
async function checkLiteratureAvailability(literatures: Literature[]) {
|
||||
const dois = literatures
|
||||
.map(lit => lit.doi)
|
||||
.filter(doi => doi); // 餈<EFBFBD>誘蝛?DOI
|
||||
.filter(doi => doi); // 过滤空 DOI
|
||||
|
||||
const results = await unpaywallClient.getBatch(dois);
|
||||
|
||||
@@ -572,7 +572,7 @@ async function checkLiteratureAvailability(literatures: Literature[]) {
|
||||
}
|
||||
```
|
||||
|
||||
**<EFBFBD>箸艶 2嚗𡁶鍂<F0A181B6>瑞<EFBFBD><E7919E>颱<EFBFBD>頧賢<E9A0A7><E8B3A2>?*
|
||||
**场景 2:用户点击下载全文**
|
||||
```typescript
|
||||
async function downloadLiteratureFullText(doi: string) {
|
||||
// Step 1: 查询 Unpaywall
|
||||
@@ -588,7 +588,7 @@ async function downloadLiteratureFullText(doi: string) {
|
||||
|
||||
await unpaywallClient.downloadPdf(unpaywallResult.pdfUrl, outputPath);
|
||||
|
||||
// Step 3: <EFBFBD>𣂼<EFBFBD><EFBFBD><EFBFBD>𧋦嚗<EFBFBD><EFBFBD><EFBFBD>?extraction_service嚗?
|
||||
// Step 3: 提取文本(调用 extraction_service)
|
||||
const extractionResult = await extractionClient.extractPdf(
|
||||
fs.readFileSync(outputPath),
|
||||
filename,
|
||||
@@ -605,9 +605,9 @@ async function downloadLiteratureFullText(doi: string) {
|
||||
|
||||
### 3.3 前端集成
|
||||
|
||||
**<EFBFBD>寥<EFBFBD>銝贝蝸<EFBFBD>厰僼嚗?*
|
||||
**批量下载按钮:**
|
||||
```typescript
|
||||
// <20>寥<EFBFBD>璉<EFBFBD><E79289>亙虾銝贝蝸<E8B49D>?
|
||||
// 批量检查可下载性
|
||||
async function checkDownloadable(selectedRows: Literature[]) {
|
||||
setLoading(true);
|
||||
|
||||
@@ -631,7 +631,7 @@ async function downloadFullText(literature: Literature) {
|
||||
const result = await api.downloadLiteratureFullText(literature.doi);
|
||||
message.success('下载成功');
|
||||
|
||||
// <EFBFBD>枏<EFBFBD> PDF <EFBFBD>亦<EFBFBD><EFBFBD>?
|
||||
// 打开 PDF 查看器
|
||||
openPdfViewer(result.pdfPath);
|
||||
} catch (error) {
|
||||
message.error(`下载失败: ${error.message}`);
|
||||
@@ -645,23 +645,23 @@ async function downloadFullText(literature: Literature) {
|
||||
|
||||
### 4.1 您提到的技术点总结
|
||||
|
||||
| <EFBFBD><EFBFBD><EFBFBD>舐<EFBFBD> | <20>嗆<EFBFBD>?| 霂湔<E99C82> |
|
||||
| 技术点 | 状态 | 说明 |
|
||||
|--------|------|------|
|
||||
| <EFBFBD>?Nougat 璅∪<EFBFBD> | 撌脣<E6928C><E884A3>?| `extraction_service/services/nougat_extractor.py` |
|
||||
| <EFBFBD>?PyMuPDF | 撌脣<EFBFBD><EFBFBD>?| `extraction_service/services/pdf_extractor.py` |
|
||||
| <EFBFBD>?憿箏<E686BF><E7AE8F>滨漣蝑𣇉裦 | 撌脣<E6928C><E884A3>?| <20>望<EFBFBD><E69C9B>𩦝ougat嚗䔶葉<E494B6><E89189><EFBFBD>PyMuPDF |
|
||||
| <EFBFBD><EFBFBD> Unpaywall API | <EFBFBD><EFBFBD><EFBFBD>啣<EFBFBD> | <20>祆<EFBFBD>獢<EFBFBD><E78DA2>靘𥕦<E99D98><F0A595A6>唳䲮獢?|
|
||||
| <EFBFBD>?Excel 閫<EFBFBD><EFBFBD> | <20><><EFBFBD>啣<EFBFBD> | 雿輻鍂 `xlsx` 摨橒<E691A8><E6A992>滨垢嚗?|
|
||||
| ✅ Nougat 模型 | 已实现 | `extraction_service/services/nougat_extractor.py` |
|
||||
| ✅ PyMuPDF | 已实现 | `extraction_service/services/pdf_extractor.py` |
|
||||
| ✅ 顺序降级策略 | 已实现 | 英文→Nougat,中文→PyMuPDF |
|
||||
| 🆕 Unpaywall API | 需新增 | 本文档提供实现方案 |
|
||||
| ✅ Excel 解析 | 需新增 | 使用 `xlsx` 库(前端) |
|
||||
|
||||
### 4.2 <EFBFBD>航<EFBFBD><EFBFBD>埈<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>舐<EFBFBD> 潃?
|
||||
### 4.2 可能遗漏的技术点 ⭐
|
||||
|
||||
#### 嚗?嚗㕑”<E39591>潭<EFBFBD><E6BDAD>硋<EFBFBD>撘?
|
||||
#### (1)表格提取增强
|
||||
|
||||
**<EFBFBD>桅<EFBFBD>**嚗鐭ougat <20>賜<EFBFBD>靽萘<E99DBD>銵冽聢蝏𤘪<E89D8F>嚗䔶<E59A97> LLM <20>湔𦻖憭<F0A6BB96><E686AD> Markdown 銵冽聢<E586BD>航<EFBFBD>銝滚<E98A9D>蝖柴<E89D96>?
|
||||
**问题**:Nougat 虽然保留表格结构,但 LLM 直接处理 Markdown 表格可能不准确。
|
||||
|
||||
**解决方案:Table Transformer**
|
||||
```python
|
||||
# 雿輻鍂敺株蔓<E6A0AA>?Table Transformer 璅∪<EFBFBD>
|
||||
# 使用微软的 Table Transformer 模型
|
||||
# https://github.com/microsoft/table-transformer
|
||||
|
||||
from transformers import TableTransformerForObjectDetection
|
||||
@@ -675,7 +675,7 @@ def extract_tables_enhanced(pdf_path: str):
|
||||
"microsoft/table-transformer-detection"
|
||||
)
|
||||
|
||||
# 璉<EFBFBD>瘚贝”<EFBFBD>潔<EFBFBD>蝵?
|
||||
# 检测表格位置
|
||||
tables = model.detect_tables(pdf_path)
|
||||
|
||||
# 提取每个表格
|
||||
@@ -686,22 +686,22 @@ def extract_tables_enhanced(pdf_path: str):
|
||||
return structured_tables
|
||||
```
|
||||
|
||||
**隡睃<EFBFBD>蝥改<EFBFBD>V2.0**嚗㇈VP <20>嗆挾 Nougat 頞喳<EFBFBD>嚗?
|
||||
**优先级:V2.0**(MVP 阶段 Nougat 足够)
|
||||
|
||||
#### 嚗?嚗匧<E59A97><E58CA7>刻圾<E588BB>𣂷<EFBFBD><F0A382B7>暹𦻖
|
||||
#### (2)引用解析与链接
|
||||
|
||||
**<EFBFBD>桅<EFBFBD>**嚗𡁶<E59A97>摮行<E691AE><E8A18C>桀<EFBFBD><E6A180>怠之<E680A0>誩<EFBFBD><E8AAA9>?`[1] [2] [3]`嚗屸<E59A97>閬<EFBFBD>圾<EFBFBD>𣂼僎<F0A382BC>暹𦻖<E69AB9>啣<EFBFBD><E595A3><EFBFBD><EFBFBD><EFBFBD>柴<EFBFBD>?
|
||||
**问题**:科学文献包含大量引用 `[1] [2] [3]`,需要解析并链接到参考文献。
|
||||
|
||||
**解决方案:GROBID**
|
||||
```python
|
||||
# GROBID: 撘<EFBFBD>皞鞟<EFBFBD>摮行<EFBFBD><EFBFBD>株圾<EFBFBD>𣂼極<EFBFBD>?
|
||||
# GROBID: 开源科学文献解析工具
|
||||
# https://github.com/kermitt2/grobid
|
||||
|
||||
import requests
|
||||
|
||||
def parse_references(pdf_path: str):
|
||||
"""
|
||||
雿輻鍂 GROBID 閫<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
|
||||
使用 GROBID 解析参考文献
|
||||
"""
|
||||
with open(pdf_path, 'rb') as f:
|
||||
files = {'input': f}
|
||||
@@ -714,11 +714,11 @@ def parse_references(pdf_path: str):
|
||||
return response.json()['references']
|
||||
```
|
||||
|
||||
**隡睃<EFBFBD>蝥改<EFBFBD>V2.0**嚗<><E59A97><EFBFBD>詨<EFBFBD><E8A9A8>蠘<EFBFBD>嚗?
|
||||
**优先级:V2.0**(非核心功能)
|
||||
|
||||
#### 嚗?嚗匧<E59A97>撘讛<E69298><E8AE9B>思<EFBFBD>皜脫<E79A9C>
|
||||
#### (3)公式识别与渲染
|
||||
|
||||
**<EFBFBD>桅<EFBFBD>**嚗鐭ougat 颲枏枂 LaTeX <EFBFBD>砍<EFBFBD>嚗<EFBFBD><EFBFBD>蝡舫<EFBFBD>閬<EFBFBD>葡<EFBFBD>瓐<EFBFBD>?
|
||||
**问题**:Nougat 输出 LaTeX 公式,前端需要渲染。
|
||||
|
||||
**解决方案:KaTeX / MathJax**
|
||||
```typescript
|
||||
@@ -736,9 +736,9 @@ function renderFormula(latex: string) {
|
||||
|
||||
**优先级:MVP**(提升用户体验)
|
||||
|
||||
#### 嚗?嚗侨DF 憸<><E686B8>銝擧<E98A9D>瘜?
|
||||
#### (4)PDF 预览与标注
|
||||
|
||||
**<EFBFBD>桅<EFBFBD>**嚗帋犖撌亙<E6928C><E4BA99>豢𧒄<E8B1A2><F0A79284>閬<EFBFBD>䰻<EFBFBD>见<EFBFBD><E8A781><EFBFBD><EFBFBD>撟園<E6929F>鈭格<E988AD>瘜具<E7989C>?
|
||||
**问题**:人工复核时需要查看原文,并高亮标注。
|
||||
|
||||
**解决方案:PDF.js + Annotator.js**
|
||||
```typescript
|
||||
@@ -762,11 +762,11 @@ function PdfViewer({ pdfUrl, annotations }) {
|
||||
|
||||
**优先级:MVP**(核心功能)
|
||||
|
||||
#### 嚗?嚗㗇<E59A97><E39787>桀縧<E6A180>?
|
||||
#### (5)文献去重
|
||||
|
||||
**<EFBFBD>桅<EFBFBD>**嚗鍃xcel 銝𠹺<E98A9D><F0A0B9BA>航<EFBFBD><E888AA><EFBFBD>鉄<EFBFBD>滚<EFBFBD><E6BB9A><EFBFBD>讃嚗<E8AE83><E59A97>銝<EFBFBD>蝭<EFBFBD><E89DAD><EFBFBD>桐<EFBFBD><E6A190>𣬚<EFBFBD><F0A3AC9A>穿<EFBFBD><E7A9BF>?
|
||||
**问题**:Excel 上传可能包含重复文献(同一篇文献不同版本)。
|
||||
|
||||
**閫<EFBFBD><EFBFBD><EFBFBD>寞<EFBFBD>嚗𡁜抅鈭?DOI <20>峕<EFBFBD>憸条<E686B8><E69DA1>駁<EFBFBD>**
|
||||
**解决方案:基于 DOI 和标题的去重**
|
||||
```typescript
|
||||
function deduplicateLiteratures(literatures: Literature[]) {
|
||||
const seen = new Set();
|
||||
@@ -791,16 +791,16 @@ function normalizeTitle(title: string): string {
|
||||
return title
|
||||
.toLowerCase()
|
||||
.replace(/[^\w\s]/g, '') // 去除标点
|
||||
.replace(/\s+/g, ' ') // 閫<EFBFBD><EFBFBD><EFBFBD>𣇉征<EFBFBD>?
|
||||
.replace(/\s+/g, ' ') // 规范化空格
|
||||
.trim();
|
||||
}
|
||||
```
|
||||
|
||||
**优先级:MVP**(必须功能)
|
||||
|
||||
#### 嚗?嚗㗇<E59A97><E39787>桀<EFBFBD><E6A180>唳旿銵亙<E98AB5>
|
||||
#### (6)文献元数据补全
|
||||
|
||||
**<EFBFBD>桅<EFBFBD>**嚗鍃xcel 銝𠹺<E98A9D><F0A0B9BA><EFBFBD>㺭<EFBFBD>桀虾<E6A180>賭<EFBFBD>摰峕㟲嚗<E39FB2>撩 DOI<4F><49>僑隞賜<E99A9E>嚗剹<E59A97>?
|
||||
**问题**:Excel 上传的数据可能不完整(缺 DOI、年份等)。
|
||||
|
||||
**解决方案:Crossref API**
|
||||
```typescript
|
||||
@@ -826,9 +826,9 @@ async function enrichMetadata(literature: Literature) {
|
||||
|
||||
**优先级:V1.0**(增强功能)
|
||||
|
||||
#### 嚗?嚗㗇鸌憭<E9B88C><E686AD>餈𥕦漲<F0A595A6><E6BCB2><EFBFBD><EFBFBD>?
|
||||
#### (7)批处理进度持久化
|
||||
|
||||
**<EFBFBD>桅<EFBFBD>**嚗𡁏鸌<F0A1818F>讐<EFBFBD><E8AE90>㕑<EFBFBD>埈𧒄<E59F88>選<EFBFBD>1000 蝭?> 10 <EFBFBD><EFBFBD><EFBFBD>嚗㚁<EFBFBD><EFBFBD><EFBFBD><EFBFBD>舀<EFBFBD><EFBFBD>剔<EFBFBD>蝏凋<EFBFBD><EFBFBD>?
|
||||
**问题**:批量筛选耗时长(1000 篇 > 10 分钟),需支持断点续传。
|
||||
|
||||
**解决方案:Redis + 任务队列**
|
||||
```typescript
|
||||
@@ -862,11 +862,11 @@ screeningQueue.process(async (job) => {
|
||||
|
||||
**优先级:V1.0**(体验优化)
|
||||
|
||||
#### 嚗?嚗厰<E59A97>霂臬<E99C82><E887AC><EFBFBD><EFBFBD><EFBFBD>滩<EFBFBD>
|
||||
#### (8)错误处理与重试
|
||||
|
||||
**<EFBFBD>桅<EFBFBD>**嚗匁LM 靚<>鍂<EFBFBD>航<EFBFBD>憭梯揖嚗<E68F96><E59A97>蝏栶<E89D8F><E6A0B6><EFBFBD><EFBFBD>嗚<EFBFBD><E5979A><EFBFBD>瘚<EFBFBD><E7989A><EFBFBD>?
|
||||
**问题**:LLM 调用可能失败(网络、超时、限流)。
|
||||
|
||||
**閫<EFBFBD><EFBFBD><EFBFBD>寞<EFBFBD>嚗𡁏<EFBFBD><EFBFBD>圈<EFBFBD><EFBFBD><EFBFBD>輸<EFBFBD>霂?*
|
||||
**解决方案:指数退避重试**
|
||||
```typescript
|
||||
async function retryWithBackoff<T>(
|
||||
fn: () => Promise<T>,
|
||||
@@ -892,30 +892,30 @@ async function retryWithBackoff<T>(
|
||||
|
||||
## 📊 技术选型总结
|
||||
|
||||
### MVP <EFBFBD>嗆挾敹<EFBFBD><EFBFBD>㗇<EFBFBD><EFBFBD>?
|
||||
### MVP 阶段必选技术
|
||||
|
||||
| 撅<EFBFBD>漣 | <20><><EFBFBD>?| <20>券<EFBFBD>?|
|
||||
| 层级 | 技术 | 用途 |
|
||||
|------|------|------|
|
||||
| **前端** | `xlsx` | Excel 解析 |
|
||||
| **前端** | `PDF.js` | PDF 预览 |
|
||||
| **前端** | `KaTeX` | 公式渲染 |
|
||||
| **<EFBFBD>𡒊垢** | `ExtractionClient` | 靚<EFBFBD>鍂 Python 敺格<EFBFBD><EFBFBD>?|
|
||||
| **后端** | `ExtractionClient` | 调用 Python 微服务 |
|
||||
| **后端** | `UnpaywallClient` | 文献下载 |
|
||||
| **Python** | `Nougat` | 英文 PDF 提取 |
|
||||
| **Python** | `PyMuPDF` | 敹恍<EFBFBD>?PDF <EFBFBD>𣂼<EFBFBD> |
|
||||
| **<EFBFBD>唳旿摨?* | `asl_schema` | <EFBFBD>唳旿摮睃<EFBFBD> |
|
||||
| **Python** | `PyMuPDF` | 快速 PDF 提取 |
|
||||
| **数据库** | `asl_schema` | 数据存储 |
|
||||
|
||||
### V1.0 憓𧼮撩<EFBFBD><EFBFBD><EFBFBD>?
|
||||
### V1.0 增强技术
|
||||
|
||||
| <EFBFBD><EFBFBD><EFBFBD>?| <20>券<EFBFBD>?|
|
||||
| 技术 | 用途 |
|
||||
|------|------|
|
||||
| Crossref API | <EFBFBD><EFBFBD>㺭<EFBFBD>株‘<EFBFBD>?|
|
||||
| Crossref API | 元数据补全 |
|
||||
| Bull Queue | 任务队列 |
|
||||
| Redis | 餈𥕦漲<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?|
|
||||
| Redis | 进度持久化 |
|
||||
|
||||
### V2.0 擃条漣<EFBFBD><EFBFBD><EFBFBD>?
|
||||
### V2.0 高级技术
|
||||
|
||||
| <EFBFBD><EFBFBD><EFBFBD>?| <20>券<EFBFBD>?|
|
||||
| 技术 | 用途 |
|
||||
|------|------|
|
||||
| Table Transformer | 表格精确提取 |
|
||||
| GROBID | 引用解析 |
|
||||
@@ -932,63 +932,63 @@ AIclinicalresearch/docs/03-业务模块/ASL-AI智能文献/
|
||||
└── 05-测试文档/
|
||||
├── 01-测试计划.md
|
||||
├── 02-标题摘要初筛测试用例.md
|
||||
<EFBFBD>婙<EFBFBD><EFBFBD><EFBFBD> 03-瘚贝<E7989A><E8B49D>唳旿/ <20>?<3F>啣遣<E595A3><E981A3>辣憭?
|
||||
<EFBFBD>鎿<EFBFBD><EFBFBD><EFBFBD> README.md <EFBFBD>?霂湔<E99C82><E6B994><EFBFBD>﹝
|
||||
└── 03-测试数据/ ← 新建文件夹
|
||||
├── README.md ← 说明文档
|
||||
├── screening-test-data/
|
||||
<EFBFBD>? <20>鎿<EFBFBD><E98EBF><EFBFBD> literature-list-199.xlsx <EFBFBD>?199 蝭<EFBFBD><EFBFBD><EFBFBD>桀<EFBFBD>銵?
|
||||
<EFBFBD>? <20>鎿<EFBFBD><E98EBF><EFBFBD> picos-criteria.txt <EFBFBD>?PICOS <EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD>? <20>婙<EFBFBD><E5A999><EFBFBD> expected-results.json <EFBFBD>?憸<><E686B8>蝏𤘪<E89D8F>嚗<EFBFBD><E59A97><EFBFBD><EFBFBD><EFBFBD>嚗?
|
||||
│ ├── literature-list-199.xlsx ← 199 篇文献列表
|
||||
│ ├── picos-criteria.txt ← PICOS 标准
|
||||
│ └── expected-results.json ← 预期结果(金标准)
|
||||
├── pdf-samples/
|
||||
<EFBFBD>? <20>鎿<EFBFBD><E98EBF><EFBFBD> sample-rct-01.pdf
|
||||
<EFBFBD>? <20>鎿<EFBFBD><E98EBF><EFBFBD> sample-cohort-01.pdf
|
||||
<EFBFBD>? <20>婙<EFBFBD><E5A999><EFBFBD> README.md
|
||||
│ ├── sample-rct-01.pdf
|
||||
│ ├── sample-cohort-01.pdf
|
||||
│ └── README.md
|
||||
└── extraction-test-data/
|
||||
└── README.md
|
||||
```
|
||||
|
||||
**<EFBFBD>刻<EFBFBD>蝏𤘪<EFBFBD>嚗?*
|
||||
**推荐结构:**
|
||||
```
|
||||
05-测试文档/
|
||||
├── 01-测试计划.md
|
||||
├── 02-标题摘要初筛测试用例.md
|
||||
└── 03-测试数据/
|
||||
<EFBFBD>鎿<EFBFBD><EFBFBD><EFBFBD> README.md <EFBFBD>?<3F>滩<EFBFBD>嚗<EFBFBD>秩<EFBFBD>擧<EFBFBD>霂閙㺭<E99699>格䔉皞僐<E79A9E><E58390><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>蝙<EFBFBD>冽䲮瘜?
|
||||
├── README.md ← 重要!说明测试数据来源、版权、使用方法
|
||||
├── screening/
|
||||
<EFBFBD>? <20>鎿<EFBFBD><E98EBF><EFBFBD> literature-list-199.xlsx
|
||||
<EFBFBD>? <20>鎿<EFBFBD><E98EBF><EFBFBD> picos-criteria.txt
|
||||
<EFBFBD>? <20>鎿<EFBFBD><E98EBF><EFBFBD> inclusion-criteria.txt
|
||||
<EFBFBD>? <20>鎿<EFBFBD><E98EBF><EFBFBD> exclusion-criteria.txt
|
||||
<EFBFBD>? <20>婙<EFBFBD><E5A999><EFBFBD> gold-standard.json <EFBFBD>?鈭箏極<E7AE8F><E6A5B5>釣<EFBFBD><E987A3>迤蝖桃<E89D96>獢?
|
||||
│ ├── literature-list-199.xlsx
|
||||
│ ├── picos-criteria.txt
|
||||
│ ├── inclusion-criteria.txt
|
||||
│ ├── exclusion-criteria.txt
|
||||
│ └── gold-standard.json ← 人工标注的正确答案
|
||||
└── pdf-extraction/
|
||||
├── sample-01-high-quality.pdf
|
||||
├── sample-02-with-tables.pdf
|
||||
└── sample-03-chinese.pdf
|
||||
```
|
||||
|
||||
**README.md 蝷箔<EFBFBD>嚗?*
|
||||
**README.md 示例:**
|
||||
```markdown
|
||||
# ASL 瘚贝<EFBFBD><EFBFBD>唳旿<EFBFBD>?
|
||||
# ASL 测试数据集
|
||||
|
||||
## 📋 数据说明
|
||||
|
||||
### 1. 标题摘要初筛测试数据
|
||||
- **文件**: `literature-list-199.xlsx`
|
||||
- **<2A>圈<EFBFBD>**: 199 蝭<>㘚<EFBFBD><E3989A>龫摮行<E691AE><E8A18C>?
|
||||
- **摮埈挾**: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>閬<EFBFBD><E996AC><EFBFBD>OI<4F><49><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>僑隞賬<E99A9E><E8B3AC><EFBFBD><EFBFBD>?
|
||||
- **数量**: 199 篇英文医学文献
|
||||
- **字段**: 标题、摘要、DOI、作者、年份、期刊
|
||||
- **来源**: [描述数据来源]
|
||||
- **版权**: [说明版权信息]
|
||||
|
||||
### 2. PICOS 标准
|
||||
- **文件**: `picos-criteria.txt`
|
||||
- **内容**: Population, Intervention, Comparison, Outcome, Study Design
|
||||
- **蝥喳<E89DA5><E596B3><EFBFBD><EFBFBD>**: 5 <EFBFBD>?
|
||||
- **<2A>㘾膄<E398BE><E88684><EFBFBD>**: 8 <EFBFBD>?
|
||||
- **纳入标准**: 5 条
|
||||
- **排除标准**: 8 条
|
||||
|
||||
### 3. <EFBFBD>烐<EFBFBD><EFBFBD><EFBFBD><EFBFBD>鈭箏極<EFBFBD><EFBFBD>釣蝏𤘪<EFBFBD>嚗?
|
||||
### 3. 金标准(人工标注结果)
|
||||
- **文件**: `gold-standard.json`
|
||||
- **<2A><>釣鈭?*: [<5B><>釣銝枏振靽⊥<E99DBD>]
|
||||
- **标注人**: [标注专家信息]
|
||||
- **标注时间**: [时间]
|
||||
- **憸<><E686B8><EFBFBD><EFBFBD>&<EFBFBD>?*: <EFBFBD>?90%
|
||||
- **预期准确率**: ≥ 90%
|
||||
|
||||
## 🎯 使用方法
|
||||
|
||||
@@ -997,15 +997,15 @@ AIclinicalresearch/docs/03-业务模块/ASL-AI智能文献/
|
||||
npm run test:asl:screening
|
||||
```
|
||||
|
||||
### 霂<EFBFBD>摯<EFBFBD><EFBFBD>&<EFBFBD>?
|
||||
### 评估准确率
|
||||
```bash
|
||||
npm run test:asl:evaluate -- --gold-standard gold-standard.json
|
||||
```
|
||||
|
||||
## 📊 预期结果
|
||||
- 蝥喳<E89DA5>: 45 蝭?
|
||||
- <20>㘾膄: 132 蝭?
|
||||
- 銝滨&摰? 22 蝭?
|
||||
- 纳入: 45 篇
|
||||
- 排除: 132 篇
|
||||
- 不确定: 22 篇
|
||||
```
|
||||
|
||||
---
|
||||
@@ -1013,13 +1013,13 @@ npm run test:asl:evaluate -- --gold-standard gold-standard.json
|
||||
## 📚 相关文档
|
||||
|
||||
- [质量保障与可追溯策略](./06-质量保障与可追溯策略.md)
|
||||
- [<EFBFBD>唳旿摨栞挽霈((./01-<2D>唳旿摨栞挽霈?md)
|
||||
- [数据库设计](./01-数据库设计.md)
|
||||
- [API 设计规范](./02-API设计规范.md)
|
||||
- [文档提取微服务](../../../../extraction_service/README.md)
|
||||
|
||||
---
|
||||
|
||||
**<EFBFBD>湔鰵<EFBFBD>亙<EFBFBD>**嚗?
|
||||
**更新日志**:
|
||||
- 2025-11-15: 创建文档,定义初筛、全文处理、文献下载技术选型
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# <EFBFBD>箄<EFBFBD>Prompt<EFBFBD><EFBFBD><EFBFBD>璅∪<EFBFBD> - 撘<><E69298>𤏸恣<F0A48FB8>?
|
||||
# 智能Prompt生成模块 - 开发计划
|
||||
|
||||
**版本**: v1.0
|
||||
**日期**: 2025-11-18
|
||||
@@ -8,11 +8,11 @@
|
||||
|
||||
## 核心目标
|
||||
|
||||
**閫<EFBFBD><EFBFBD><EFBFBD>桅<EFBFBD>**: 瘨<EFBFBD>膄AI銝𦒘犖蝐餃笆颲寧<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>閫<EFBFBD>榆撘?
|
||||
**解决问题**: 消除AI与人类对边界情况的理解差异
|
||||
|
||||
**核心流程**:
|
||||
```
|
||||
<EFBFBD>冽<EFBFBD>颲枏<EFBFBD>PICOS <20>?AI<41><49>圾<EFBFBD><E59CBE><EFBFBD> <20>?<3F><><EFBFBD>Prompt <20>?<3F>冽<EFBFBD>靽格㺿 <20>?撘<>憪讠<E686AA><E8AEA0>?
|
||||
用户输入PICOS → AI理解分析 → 生成Prompt → 用户修改 → 开始筛选
|
||||
```
|
||||
|
||||
---
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
### 功能范围
|
||||
|
||||
#### 1. <EFBFBD>冽<EFBFBD>颲枏<EFBFBD> <20>?
|
||||
#### 1. 用户输入 ✅
|
||||
|
||||
**前端表单**:
|
||||
```typescript
|
||||
@@ -42,7 +42,7 @@
|
||||
|
||||
---
|
||||
|
||||
#### 2. AI<EFBFBD><EFBFBD>圾銝𤾸<EFBFBD><EFBFBD>?<3F><>
|
||||
#### 2. AI理解与分析 🆕
|
||||
|
||||
**输入**: 用户的PICOS + 纳排标准
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
id: number;
|
||||
question: string; // "如果研究人群是欧美但RCT质量高?"
|
||||
aiSuggestion: 'include' | 'exclude' | 'uncertain';
|
||||
reason: string; // AI<EFBFBD><EFBFBD>遣霈桃<EFBFBD><EFBFBD>?
|
||||
reason: string; // AI的建议理由
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -76,11 +76,11 @@ POST /api/v1/asl/analyze-picos
|
||||
#### 3. 用户确认界面 🆕
|
||||
|
||||
**显示**:
|
||||
- <EFBFBD>?敹<>◆蝥喳<E89DA5>嚗<EFBFBD>虾<EFBFBD>暸<EFBFBD>?<3F>𡝗<EFBFBD>嚗?
|
||||
- <EFBFBD>?敹<>◆<EFBFBD>㘾膄嚗<E88684>虾<EFBFBD>暸<EFBFBD>?<3F>𡝗<EFBFBD>嚗?
|
||||
- <EFBFBD><EFBFBD> 颲寧<E9A2B2><E5AFA7><EFBFBD><EFBFBD>嚗<EFBFBD><E59A97>𣂷葵蝖株恕嚗𡁶熙<F0A181B6>?<3F>㘾膄/銝滨&摰𡄯<E691B0>
|
||||
- ✅ 必须纳入(可勾选/取消)
|
||||
- ❌ 必须排除(可勾选/取消)
|
||||
- 🤔 边界情况(逐个确认:纳入/排除/不确定)
|
||||
|
||||
**摰䂿緵**: Modal撖寡<EFBFBD>獢<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>銝芸躹<EFBFBD>?
|
||||
**实现**: Modal对话框,分三个区域
|
||||
|
||||
---
|
||||
|
||||
@@ -90,14 +90,14 @@ POST /api/v1/asl/analyze-picos
|
||||
|
||||
**输出**: 完整的筛选Prompt
|
||||
|
||||
**<EFBFBD>喲睸**: 撠<EFBFBD>鍂<EFBFBD>瑞&霈斤<EFBFBD>颲寧<EFBFBD>閫<EFBFBD><EFBFBD>瘜典<EFBFBD><EFBFBD>訐rompt銝?
|
||||
**关键**: 将用户确认的边界规则注入到Prompt中
|
||||
|
||||
```
|
||||
## 特殊规则(基于您的确认)
|
||||
|
||||
1. 地域要求:优先亚洲人群,但欧美高质量RCT也可纳入
|
||||
2. <EFBFBD>𠉛弦蝐餃<EFBFBD>嚗𡁏<EFBFBD><EFBFBD>斤遞餈堆<EFBFBD>雿?020撟游<E6929F>Meta<74><61><EFBFBD><EFBFBD>舐熙<E88890>?
|
||||
3. 撖寧<EFBFBD>蝐餃<EFBFBD>嚗𡁜<EFBFBD><EFBFBD>啣<EFBFBD>撖寧<EFBFBD>嚗峕<EFBFBD><EFBFBD>虫<EFBFBD>蝘齿<EFBFBD><EFBFBD><EFBFBD>晓<EFBFBD>拐<EFBFBD><EFBFBD>舀𦻖<EFBFBD>?
|
||||
2. 研究类型:排除综述,但2020年后Meta分析可纳入
|
||||
3. 对照类型:安慰剂对照,或另一种标准药物也可接受
|
||||
...
|
||||
```
|
||||
|
||||
@@ -108,54 +108,54 @@ POST /api/v1/asl/generate-prompt
|
||||
|
||||
---
|
||||
|
||||
#### 5. Prompt蝻𤥁<EFBFBD><EFBFBD>?<3F><>
|
||||
#### 5. Prompt编辑器 🆕
|
||||
|
||||
**功能**:
|
||||
- 显示生成的Prompt
|
||||
- 支持用户编辑
|
||||
- 靽嘥<EFBFBD>撟嗡蝙<EFBFBD>?
|
||||
- 保存并使用
|
||||
|
||||
**实现**: 简单的Textarea + 保存按钮
|
||||
|
||||
---
|
||||
|
||||
#### 6. 蝑偦<EFBFBD>厩<EFBFBD><EFBFBD>𨅯<EFBFBD>撘?潃?**<2A>滩<EFBFBD>**
|
||||
#### 6. 筛选结果增强 ⭐ **重要**
|
||||
|
||||
**敶枏<EFBFBD><EFBFBD>桅<EFBFBD>**: <EFBFBD>芣遬蝷箸<EFBFBD>蝏<EFBFBD><EFBFBD>蝑吔<EFBFBD>include/exclude/pending嚗?
|
||||
**当前问题**: 只显示最终决策(include/exclude/pending)
|
||||
|
||||
**<EFBFBD>寡<EFBFBD>**: <EFBFBD>曄內**銝支葵璅∪<E79285><E288AA><EFBFBD><EFBFBD><EFBFBD>渡<EFBFBD><E6B8A1>?*
|
||||
**改进**: 显示**两个模型的完整理由**
|
||||
|
||||
```typescript
|
||||
{
|
||||
literatureId: string;
|
||||
finalDecision: 'include' | 'exclude' | 'pending';
|
||||
|
||||
// 潃?<3F>啣<EFBFBD>嚗帋舅銝芣芋<E88AA3>讠<EFBFBD>霂衣<E99C82>蝏𤘪<E89D8F>
|
||||
// ⭐ 新增:两个模型的详细结果
|
||||
model1: {
|
||||
modelName: 'DeepSeek-V3';
|
||||
conclusion: 'exclude';
|
||||
confidence: 0.92;
|
||||
judgment: { P: 'match', I: 'match', C: 'mismatch', S: 'match' };
|
||||
reason: '<EFBFBD>賜<EFBFBD>P<EFBFBD><EFBFBD><EFBFBD><EFBFBD>蝏游漲<EFBFBD>寥<EFBFBD>嚗䔶<EFBFBD>撖寧<EFBFBD>蝏<EFBFBD>蛹<EFBFBD>虫<EFBFBD>蝘滩晓<EFBFBD>抵<EFBFBD>屸<EFBFBD>摰㗇<EFBFBD><EFBFBD>?..' // 潃?<3F>喲睸
|
||||
reason: '虽然P、I、S维度匹配,但对照组为另一种药物而非安慰剂...' // ⭐ 关键
|
||||
},
|
||||
model2: {
|
||||
modelName: 'Qwen-Max';
|
||||
conclusion: 'include';
|
||||
confidence: 0.85;
|
||||
judgment: { P: 'match', I: 'match', C: 'partial', S: 'match' };
|
||||
reason: '<EFBFBD>𠉛弦鈭箇黎<EFBFBD><EFBFBD>僕憸<EFBFBD>綳<EFBFBD>賢龪<EFBFBD>㵪<EFBFBD>撖寧<EFBFBD>蝏<EFBFBD>蒾<EFBFBD>𧼮<EFBFBD><EFBFBD>啣<EFBFBD>雿<EFBFBD><EFBFBD>撖寞<EFBFBD><EFBFBD>譍<EFBFBD>...' // 潃?<3F>喲睸
|
||||
reason: '研究人群和干预措施匹配,对照组虽非安慰剂但有对比意义...' // ⭐ 关键
|
||||
},
|
||||
|
||||
hasConflict: true; // 銝支葵璅∪<EFBFBD><EFBFBD>斗鱏銝滢<EFBFBD><EFBFBD>?
|
||||
hasConflict: true; // 两个模型判断不一致
|
||||
conflictFields: ['conclusion', 'C'];
|
||||
}
|
||||
```
|
||||
|
||||
**前端显示**:
|
||||
```jsx
|
||||
<Card title="蝑偦<EFBFBD>厩<EFBFBD><EFBFBD>?>
|
||||
<Card title="筛选结果">
|
||||
<Alert type={finalDecision === 'pending' ? 'warning' : 'success'}>
|
||||
<EFBFBD><EFBFBD>蝏<EFBFBD><EFBFBD>蝑? {finalDecision}
|
||||
最终决策: {finalDecision}
|
||||
</Alert>
|
||||
|
||||
<Divider />
|
||||
@@ -166,10 +166,10 @@ POST /api/v1/asl/generate-prompt
|
||||
<Tag color={model1.conclusion === 'include' ? 'green' : 'red'}>
|
||||
{model1.conclusion}
|
||||
</Tag>
|
||||
<Statistic title="蝵桐縑摨? value={model1.confidence} />
|
||||
<Statistic title="置信度" value={model1.confidence} />
|
||||
<Divider />
|
||||
<h4>判断理由:</h4>
|
||||
<p>{model1.reason}</p> {/* 潃?<3F>曄內<E69B84><E585A7>眏 */}
|
||||
<p>{model1.reason}</p> {/* ⭐ 显示理由 */}
|
||||
<Collapse>
|
||||
<Panel header="PICO维度详情">
|
||||
P: {model1.judgment.P}<br/>
|
||||
@@ -194,37 +194,37 @@ POST /api/v1/asl/generate-prompt
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
{/* 潃?鈭箏極憭齿瓲<E9BDBF>厰僼 */}
|
||||
{/* ⭐ 人工复核按钮 */}
|
||||
<Button type="primary" onClick={handleManualReview}>
|
||||
鈭箏極憭齿瓲甇斗<EFBFBD><EFBFBD>?
|
||||
人工复核此文献
|
||||
</Button>
|
||||
</Card>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### MVP撘<EFBFBD><EFBFBD>烐<EFBFBD><EFBFBD>?
|
||||
### MVP开发清单
|
||||
|
||||
**Week 1: 后端**
|
||||
|
||||
| 隞餃𦛚 | 隡唳𧒄 | 隡睃<E99AA1>蝥?|
|
||||
| 任务 | 估时 | 优先级 |
|
||||
|------|------|--------|
|
||||
| API: <EFBFBD><EFBFBD><EFBFBD>PICOS | 2憭?| P0 |
|
||||
| API: <EFBFBD><EFBFBD><EFBFBD>Prompt | 1憭?| P0 |
|
||||
| 憓𧼮撩蝑偦<EFBFBD>厩<EFBFBD><EFBFBD>𦦵<EFBFBD><EFBFBD>?| 0.5憭?| P0 |
|
||||
| 瘚贝<EFBFBD> | 0.5憭?| P0 |
|
||||
| API: 分析PICOS | 2天 | P0 |
|
||||
| API: 生成Prompt | 1天 | P0 |
|
||||
| 增强筛选结果结构 | 0.5天 | P0 |
|
||||
| 测试 | 0.5天 | P0 |
|
||||
|
||||
**Week 2: 前端**
|
||||
|
||||
| 隞餃𦛚 | 隡唳𧒄 | 隡睃<E99AA1>蝥?|
|
||||
| 任务 | 估时 | 优先级 |
|
||||
|------|------|--------|
|
||||
| PICOS颲枏<EFBFBD>銵典<EFBFBD> | 0.5憭?| P0 |
|
||||
| <EFBFBD>冽<EFBFBD>蝖株恕<EFBFBD>屸𢒰 | 1.5憭?| P0 |
|
||||
| Prompt蝻𤥁<EFBFBD><EFBFBD>?| 0.5憭?| P0 |
|
||||
| 蝏𤘪<EFBFBD>撅閧內憓𧼮撩 | 1憭?| P0 |
|
||||
| 瘚贝<EFBFBD>銝舘<EFBFBD>隡?| 0.5憭?| P0 |
|
||||
| PICOS输入表单 | 0.5天 | P0 |
|
||||
| 用户确认界面 | 1.5天 | P0 |
|
||||
| Prompt编辑器 | 0.5天 | P0 |
|
||||
| 结果展示增强 | 1天 | P0 |
|
||||
| 测试与调优 | 0.5天 | P0 |
|
||||
|
||||
**<EFBFBD>餉恣**: 2<EFBFBD>剁<EFBFBD>10銝芸極雿𨀣𠯫嚗?
|
||||
**总计**: 2周(10个工作日)
|
||||
|
||||
---
|
||||
|
||||
@@ -232,16 +232,16 @@ POST /api/v1/asl/generate-prompt
|
||||
|
||||
### 功能1: Few-shot自动学习 🔮
|
||||
|
||||
**閫血<EFBFBD><EFBFBD>箸艶**: <EFBFBD>冽<EFBFBD>蝥䭾迤AI<EFBFBD>斗鱏<EFBFBD>?
|
||||
**触发场景**: 用户纠正AI判断后
|
||||
|
||||
**流程**:
|
||||
```
|
||||
1. AI判断: Exclude
|
||||
2. 用户纠正: 应该是Include
|
||||
3. <EFBFBD>冽<EFBFBD>霂湔<EFBFBD><EFBFBD><EFBFBD>眏: "<22>賜<EFBFBD><E8B39C>舀洹蝢𦒘犖蝢歹<E89DA2>雿<EFBFBD>CT韐券<E99F90>擃?
|
||||
<EFBFBD>?
|
||||
3. 用户说明理由: "虽然是欧美人群,但RCT质量高"
|
||||
↓
|
||||
4. 系统记录案例
|
||||
<EFBFBD>?
|
||||
↓
|
||||
5. 下次筛选时,将此案例作为Few-shot示例加入Prompt
|
||||
```
|
||||
|
||||
@@ -255,7 +255,7 @@ POST /api/v1/asl/generate-prompt
|
||||
},
|
||||
aiDecision: 'exclude';
|
||||
userDecision: 'include';
|
||||
userReason: '<EFBFBD>賜<EFBFBD><EFBFBD>舀洹蝢𦒘犖蝢歹<EFBFBD>雿<EFBFBD>CT韐券<EFBFBD>擃?;
|
||||
userReason: '虽然是欧美人群,但RCT质量高';
|
||||
picoCriteria: {...}; // 当时的PICOS
|
||||
createdAt: Date;
|
||||
}
|
||||
@@ -263,7 +263,7 @@ POST /api/v1/asl/generate-prompt
|
||||
|
||||
**Prompt增强**:
|
||||
```
|
||||
## <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>靘页<EFBFBD>Few-shot蝷箔<EFBFBD>嚗?
|
||||
## 参考案例(Few-shot示例)
|
||||
|
||||
以下是您之前纠正的案例,请参考:
|
||||
|
||||
@@ -271,14 +271,14 @@ POST /api/v1/asl/generate-prompt
|
||||
标题: TICA-CLOP STUDY...
|
||||
AI判断: Exclude(因为北非人群)
|
||||
您的决策: Include
|
||||
<EFBFBD>函<EFBFBD><EFBFBD><EFBFBD>眏: <20>賜<EFBFBD><E8B39C>臬<EFBFBD><E887AC>硺犖蝢歹<E89DA2>雿<EFBFBD>CT韐券<E99F90>擃矋<E69383><E79F8B>寞<EFBFBD><E5AF9E>匧<EFBFBD><E58CA7><EFBFBD>遠<EFBFBD>?
|
||||
<EFBFBD>?<3F>舐內: <20>啣<EFBFBD>閬<EFBFBD><E996AC><EFBFBD>臭誑<E887AD>菜暑嚗<E69A91><E59A97><EFBFBD>𦦵<EFBFBD>蝛嗉捶<E59789>誯<EFBFBD>
|
||||
您的理由: 虽然是北非人群,但RCT质量高,方法有参考价值
|
||||
→ 启示: 地域要求可以灵活,如果研究质量高
|
||||
|
||||
案例2:
|
||||
...
|
||||
```
|
||||
|
||||
**摰䂿緵憭齿<EFBFBD>摨?*: 銝剔<E98A9D>嚗<EFBFBD><E59A97>閬<EFBFBD><E996AC>靘见<E99D98>蝞∠<E89D9E>嚗?
|
||||
**实现复杂度**: 中等(需要案例库管理)
|
||||
|
||||
---
|
||||
|
||||
@@ -288,21 +288,21 @@ AI判断: Exclude(因为北非人群)
|
||||
|
||||
**流程**:
|
||||
```
|
||||
1. <EFBFBD>冽<EFBFBD>銝𠹺<EFBFBD>10蝭<EFBFBD><EFBFBD>霂閙<EFBFBD><EFBFBD>殷<EFBFBD>5蝭<EFBFBD>熙<EFBFBD>?+ 5蝭<35><E89DAD><EFBFBD>歹<EFBFBD>
|
||||
<EFBFBD>?
|
||||
1. 用户上传10篇测试文献(5篇纳入 + 5篇排除)
|
||||
↓
|
||||
2. 用户逐篇标注: Include/Exclude + 理由
|
||||
<EFBFBD>?
|
||||
3. AI摮虫<EFBFBD><EFBFBD>冽<EFBFBD><EFBFBD><EFBFBD>ế<EFBFBD>剜芋撘?
|
||||
<EFBFBD>?
|
||||
↓
|
||||
3. AI学习用户的判断模式
|
||||
↓
|
||||
4. 生成定制化Prompt
|
||||
<EFBFBD>?
|
||||
5. <EFBFBD>其<EFBFBD>甇<EFBFBD><EFBFBD>蝑偦<EFBFBD>?
|
||||
↓
|
||||
5. 用于正式筛选
|
||||
```
|
||||
|
||||
**界面**:
|
||||
```jsx
|
||||
<TestMode>
|
||||
<Upload>銝𠹺<EFBFBD>10蝭<EFBFBD><EFBFBD>霂閙<EFBFBD><EFBFBD>殷<EFBFBD>Excel/JSON嚗?/Upload>
|
||||
<Upload>上传10篇测试文献(Excel/JSON)</Upload>
|
||||
|
||||
<Table>
|
||||
{testCases.map(lit => (
|
||||
@@ -315,7 +315,7 @@ AI判断: Exclude(因为北非人群)
|
||||
</Radio.Group>
|
||||
</td>
|
||||
<td>
|
||||
<Input.TextArea placeholder="霂瑁秩<EFBFBD>𡒊<EFBFBD><EFBFBD>? />
|
||||
<Input.TextArea placeholder="请说明理由" />
|
||||
</td>
|
||||
</Row>
|
||||
))}
|
||||
@@ -333,55 +333,55 @@ AI判断: Exclude(因为北非人群)
|
||||
|
||||
1. 地域灵活性:
|
||||
- 案例1(北非RCT)→ 纳入
|
||||
- 獢<EFBFBD><EFBFBD>3嚗<EFBFBD>洹瘣脤<EFBFBD><EFBFBD>梹<EFBFBD><EFBFBD>?<3F>㘾膄
|
||||
<EFBFBD>?蝏栞捏: <20>芾<EFBFBD><E88ABE>爹CT撠勗虾<E58B97>亙<EFBFBD><E4BA99>硺<EFBFBD>瘣脖犖蝢?
|
||||
- 案例3(欧洲队列)→ 排除
|
||||
→ 结论: 只要是RCT就可接受非亚洲人群
|
||||
|
||||
2. <EFBFBD>𠉛弦蝐餃<EFBFBD>嚗?
|
||||
2. 研究类型:
|
||||
- 案例2(Meta分析)→ 纳入
|
||||
- 獢<EFBFBD><EFBFBD>5嚗<EFBFBD><EFBFBD>蝏毺遞餈堆<EFBFBD><EFBFBD>?<3F>㘾膄
|
||||
<EFBFBD>?蝏栞捏: Meta<EFBFBD><EFBFBD><EFBFBD><EFBFBD>舀𦻖<EFBFBD>梹<EFBFBD>隡删<EFBFBD>蝏潸膩<EFBFBD>㘾膄
|
||||
- 案例5(传统综述)→ 排除
|
||||
→ 结论: Meta分析可接受,传统综述排除
|
||||
|
||||
3. <EFBFBD>園𡢿閬<EFBFBD><EFBFBD>嚗?
|
||||
- 獢<EFBFBD><EFBFBD>4嚗?019撟游<E6929F>銵剁<E98AB5><E58981>?<3F>㘾膄
|
||||
<EFBFBD>?蝏栞捏: 銝交聢<E4BAA4>扯<EFBFBD>2020撟游<E6929F>閬<EFBFBD><E996AC>
|
||||
3. 时间要求:
|
||||
- 案例4(2019年发表)→ 排除
|
||||
→ 结论: 严格执行2020年后要求
|
||||
```
|
||||
|
||||
**摰䂿緵憭齿<EFBFBD>摨?*: 擃矋<E69383><E79F8B><EFBFBD>閬<EFBFBD>芋撘讛<E69298><E8AE9B>恬<EFBFBD>
|
||||
**实现复杂度**: 高(需要模式识别)
|
||||
|
||||
---
|
||||
|
||||
### <EFBFBD>蠘<EFBFBD>3: Prompt璅⊥踎摨?<3F><>
|
||||
### 功能3: Prompt模板库 📚
|
||||
|
||||
**功能**:
|
||||
- 靽嘥<EFBFBD><EFBFBD>冽<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>rompt銝箸芋<EFBFBD>?
|
||||
- 保存用户生成的Prompt为模板
|
||||
- 下次可以直接复用
|
||||
- <EFBFBD>臭誑<EFBFBD><EFBFBD>澈蝏坔𣪧<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
|
||||
- 可以分享给团队成员
|
||||
|
||||
**摰䂿緵憭齿<EFBFBD>摨?*: 雿?
|
||||
**实现复杂度**: 低
|
||||
|
||||
---
|
||||
|
||||
### 2.0撘<EFBFBD><EFBFBD>烐<EFBFBD><EFBFBD>?
|
||||
### 2.0开发清单
|
||||
|
||||
| <EFBFBD>蠘<EFBFBD> | 隡唳𧒄 | 隡睃<E99AA1>蝥?| 靘肽<E99D98> |
|
||||
| 功能 | 估时 | 优先级 | 依赖 |
|
||||
|------|------|--------|------|
|
||||
| Few-shot摮虫<EFBFBD> | 3憭?| P1 | MVP摰峕<EFBFBD> |
|
||||
| 瘚贝<EFBFBD>璅∪<EFBFBD> | 5憭?| P2 | MVP摰峕<EFBFBD> |
|
||||
| Prompt璅⊥踎摨?| 2憭?| P1 | MVP摰峕<EFBFBD> |
|
||||
| Few-shot学习 | 3天 | P1 | MVP完成 |
|
||||
| 测试模式 | 5天 | P2 | MVP完成 |
|
||||
| Prompt模板库 | 2天 | P1 | MVP完成 |
|
||||
|
||||
**<EFBFBD>餉恣**: 2<EFBFBD>?
|
||||
**总计**: 2周
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD><EFBFBD><EFBFBD>臬<EFBFBD><EFBFBD>啁<EFBFBD><EFBFBD>?
|
||||
## 技术实现细节
|
||||
|
||||
### 1. AI分析PICOS的Prompt
|
||||
|
||||
```typescript
|
||||
const analyzePrompt = `
|
||||
雿䭾糓<EFBFBD>餃郎<EFBFBD><EFBFBD>讃蝑偦<EFBFBD>劐<EFBFBD>摰嗚<EFBFBD><EFBFBD>鍂<EFBFBD>瑟<EFBFBD>靘𥕢<EFBFBD>PICOS<EFBFBD><EFBFBD><EFBFBD><EFBFBD>𣬚熙<EFBFBD>埝<EFBFBD><EFBFBD><EFBFBD><EFBFBD>霂瑕<EFBFBD><EFBFBD>𣂼僎<EFBFBD><EFBFBD><EFBFBD>嚗?
|
||||
你是医学文献筛选专家。用户提供了PICOS标准和纳排标准,请分析并生成:
|
||||
|
||||
<EFBFBD>鞟鍂<EFBFBD>瑁<EFBFBD><EFBFBD>乓<EFBFBD>?
|
||||
【用户输入】
|
||||
人群: ${population}
|
||||
干预: ${intervention}
|
||||
对照: ${comparison}
|
||||
@@ -394,16 +394,16 @@ ${inclusionCriteria}
|
||||
排除标准:
|
||||
${exclusionCriteria}
|
||||
|
||||
<EFBFBD>𣂼<EFBFBD><EFBFBD>𣂷遙<EFBFBD>~<EFBFBD>?
|
||||
【分析任务】
|
||||
1. 提取必须纳入的核心要素(3-5条)
|
||||
2. 提取必须排除的要素(3-5条)
|
||||
3. 识别模糊的边界情况(5-8个),每个边界情况包括:
|
||||
- 具体问题描述
|
||||
- 雿删<EFBFBD>撱箄悅嚗ǎnclude/exclude/uncertain嚗?
|
||||
- 你的建议(include/exclude/uncertain)
|
||||
- 建议理由
|
||||
|
||||
<EFBFBD>鞱<EFBFBD><EFBFBD>箸聢撘譌<EFBFBD>?
|
||||
銝交聢JSON<EFBFBD>澆<EFBFBD>嚗?
|
||||
【输出格式】
|
||||
严格JSON格式:
|
||||
{
|
||||
"mustInclude": ["要素1", "要素2", ...],
|
||||
"mustExclude": ["要素1", "要素2", ...],
|
||||
@@ -435,24 +435,24 @@ function generateCustomPrompt(
|
||||
// 基础Prompt(从标准模板开始)
|
||||
let prompt = getStandardPromptTemplate();
|
||||
|
||||
// 瘜典<EFBFBD><EFBFBD>冽<EFBFBD>蝖株恕<EFBFBD><EFBFBD>器<EFBFBD>諹<EFBFBD><EFBFBD>?
|
||||
// 注入用户确认的边界规则
|
||||
const boundaryRulesSection = `
|
||||
## 潃?<3F>寞<EFBFBD>颲寧<E9A2B2>閫<EFBFBD><E996AB>嚗<EFBFBD>抅鈭擧<E988AD><E693A7><EFBFBD>&霈歹<E99C88>
|
||||
## ⭐ 特殊边界规则(基于您的确认)
|
||||
|
||||
${userConfirmedRules.map((rule, index) => `
|
||||
${index + 1}. ${rule.category}:
|
||||
- 标准规则: ${rule.standardRule}
|
||||
- <EFBFBD>函<EFBFBD>蝖株恕: ${rule.userDecision === 'include' ? '<EFBFBD>?<3F>臭誑蝥喳<E89DA5>' : '<EFBFBD>?敹<>◆<EFBFBD>㘾膄'}
|
||||
- 您的确认: ${rule.userDecision === 'include' ? '✅ 可以纳入' : '❌ 必须排除'}
|
||||
- 具体情况: ${rule.situation}
|
||||
`).join('\n')}
|
||||
|
||||
<EFBFBD>𩤃<EFBFBD> 霂瑚艇<E7919A>潮<EFBFBD>摰<EFBFBD>誑銝羓鸌畾𡃏<E795BE><F0A1838F>辷<EFBFBD>餈嗘<E9A488><E59798>舐鍂<E88890>瑟<EFBFBD>蝖桃&霈斤<E99C88><E696A4>斗鱏<E69697><E9B18F><EFBFBD><EFBFBD>?
|
||||
⚠️ 请严格遵守以上特殊规则,这些是用户明确确认的判断标准。
|
||||
`;
|
||||
|
||||
// 撠<EFBFBD>器<EFBFBD>諹<EFBFBD><EFBFBD>蹱<EFBFBD><EFBFBD>亙<EFBFBD>Prompt<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>蝵?
|
||||
// 将边界规则插入到Prompt的合适位置
|
||||
prompt = prompt.replace(
|
||||
'## 蝑偦<EFBFBD>劐遙<EFBFBD>?,
|
||||
boundaryRulesSection + '\n\n## 蝑偦<EFBFBD>劐遙<EFBFBD>?
|
||||
'## 筛选任务',
|
||||
boundaryRulesSection + '\n\n## 筛选任务'
|
||||
);
|
||||
|
||||
return prompt;
|
||||
@@ -461,7 +461,7 @@ ${index + 1}. ${rule.category}:
|
||||
|
||||
---
|
||||
|
||||
### 3. <EFBFBD>唳旿摨栞挽霈?
|
||||
### 3. 数据库设计
|
||||
|
||||
**新表: prompt_configurations**
|
||||
|
||||
@@ -484,9 +484,9 @@ CREATE TABLE asl_schema.prompt_configurations (
|
||||
|
||||
-- 生成的Prompt
|
||||
generated_prompt TEXT NOT NULL,
|
||||
final_prompt TEXT NOT NULL, -- <EFBFBD>冽<EFBFBD>蝻𤥁<EFBFBD><EFBFBD>𡒊<EFBFBD><EFBFBD><EFBFBD>蝏<EFBFBD><EFBFBD><EFBFBD>?
|
||||
final_prompt TEXT NOT NULL, -- 用户编辑后的最终版本
|
||||
|
||||
-- <EFBFBD><EFBFBD>㺭<EFBFBD>?
|
||||
-- 元数据
|
||||
version VARCHAR(20) DEFAULT 'v1.0',
|
||||
is_template BOOLEAN DEFAULT false,
|
||||
template_name VARCHAR(100),
|
||||
@@ -496,7 +496,7 @@ CREATE TABLE asl_schema.prompt_configurations (
|
||||
);
|
||||
```
|
||||
|
||||
**<EFBFBD>啗”: few_shot_cases**嚗?.0<EFBFBD>嗆挾嚗?
|
||||
**新表: few_shot_cases**(2.0阶段)
|
||||
|
||||
```sql
|
||||
CREATE TABLE asl_schema.few_shot_cases (
|
||||
@@ -517,7 +517,7 @@ CREATE TABLE asl_schema.few_shot_cases (
|
||||
user_decision VARCHAR(20) NOT NULL,
|
||||
user_reason TEXT NOT NULL,
|
||||
|
||||
-- PICOS銝𠹺<EFBFBD><EFBFBD>?
|
||||
-- PICOS上下文
|
||||
pico_criteria JSONB NOT NULL,
|
||||
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
@@ -584,7 +584,7 @@ Request:
|
||||
{
|
||||
"ambiguityId": 1,
|
||||
"userDecision": "include", // include/exclude/uncertain
|
||||
"userNote": "<EFBFBD>賜<EFBFBD>銝齿糓鈭𡁏散鈭箇黎嚗䔶<EFBFBD>RCT韐券<EFBFBD>擃? // <EFBFBD>舫<EFBFBD>?
|
||||
"userNote": "虽然不是亚洲人群,但RCT质量高" // 可选
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -610,7 +610,7 @@ Request:
|
||||
"configId": "uuid",
|
||||
"finalPrompt": "用户编辑后的Prompt...",
|
||||
"saveAsTemplate": false,
|
||||
"templateName": "" // 憒<EFBFBD><EFBFBD>靽嘥<EFBFBD>銝箸芋<EFBFBD>?
|
||||
"templateName": "" // 如果保存为模板
|
||||
}
|
||||
|
||||
Response:
|
||||
@@ -625,7 +625,7 @@ Response:
|
||||
|
||||
---
|
||||
|
||||
#### 4. 雿輻鍂<EFBFBD>芸<EFBFBD>銋侨rompt蝑偦<EFBFBD>?
|
||||
#### 4. 使用自定义Prompt筛选
|
||||
|
||||
```
|
||||
POST /api/v1/asl/screen/literature
|
||||
@@ -645,14 +645,14 @@ Response:
|
||||
"literatureId": "uuid",
|
||||
"finalDecision": "pending",
|
||||
|
||||
// 潃?<3F>喲睸嚗帋舅銝芣芋<E88AA3>讠<EFBFBD>霂衣<E99C82>蝏𤘪<E89D8F>
|
||||
// ⭐ 关键:两个模型的详细结果
|
||||
"model1": {
|
||||
"modelName": "DeepSeek-V3",
|
||||
"conclusion": "exclude",
|
||||
"confidence": 0.92,
|
||||
"judgment": {...},
|
||||
"evidence": {...},
|
||||
"reason": "摰峕㟲<EFBFBD><EFBFBD><EFBFBD><EFBFBD>斤<EFBFBD><EFBFBD>?.." // 潃?
|
||||
"reason": "完整的排除理由..." // ⭐
|
||||
},
|
||||
"model2": {
|
||||
"modelName": "Qwen-Max",
|
||||
@@ -660,7 +660,7 @@ Response:
|
||||
"confidence": 0.85,
|
||||
"judgment": {...},
|
||||
"evidence": {...},
|
||||
"reason": "摰峕㟲<EFBFBD><EFBFBD>熙<EFBFBD>亦<EFBFBD><EFBFBD>?.." // 潃?
|
||||
"reason": "完整的纳入理由..." // ⭐
|
||||
},
|
||||
|
||||
"hasConflict": true,
|
||||
@@ -685,7 +685,7 @@ Request:
|
||||
"aiDecision": "exclude",
|
||||
"aiReason": "...",
|
||||
"userDecision": "include",
|
||||
"userReason": "<EFBFBD>賜<EFBFBD><EFBFBD>舀洹蝢𦒘犖蝢歹<EFBFBD>雿?.."
|
||||
"userReason": "虽然是欧美人群,但..."
|
||||
}
|
||||
|
||||
Response:
|
||||
@@ -726,28 +726,28 @@ Response:
|
||||
|
||||
### MVP测试
|
||||
|
||||
**瘚贝<EFBFBD><EFBFBD>唳旿**: <EFBFBD>雴葉<EFBFBD>𠉛弦嚗<EFBFBD>歇<EFBFBD>?蝭<><E89DAD>
|
||||
**测试数据**: 卒中研究(已有5篇)
|
||||
|
||||
**测试场景**:
|
||||
|
||||
1. **场景1: 正常流程**
|
||||
- 颲枏<EFBFBD>PICOS <EFBFBD>?AI<41><49><EFBFBD> <20>?<3F>冽<EFBFBD>蝖株恕 <20>?<3F><><EFBFBD>Prompt <EFBFBD>?蝑偦<E89D91>?
|
||||
- 输入PICOS → AI分析 → 用户确认 → 生成Prompt → 筛选
|
||||
- 验证:两个模型的理由是否完整显示
|
||||
|
||||
2. **场景2: 边界情况确认**
|
||||
- <EFBFBD>冽<EFBFBD>蝖株恕"甈抒<E79488>RCT<43>舐熙<E88890>? <20>?撉諹<E69289>Prompt銝剜糓<E5899C>血<EFBFBD><E8A180>急迨閫<E8BFA8><E996AB>
|
||||
- 撉諹<EFBFBD>嚗𡁜<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>㗇𧒄<EFBFBD>臬炏<EFBFBD>萄<EFBFBD>甇方<EFBFBD><EFBFBD>?
|
||||
- 用户确认"欧美RCT可纳入" → 验证Prompt中是否包含此规则
|
||||
- 验证:实际筛选时是否遵守此规则
|
||||
|
||||
3. **场景3: 用户编辑Prompt**
|
||||
- <EFBFBD>冽<EFBFBD>靽格㺿<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>rompt <20>?撉諹<E69289>靽格㺿<E6A0BC>臬炏<E887AC><E7828F><EFBFBD>
|
||||
- 用户修改生成的Prompt → 验证修改是否生效
|
||||
|
||||
4. **场景4: 模型冲突**
|
||||
- 撉諹<EFBFBD>嚗帋舅銝芣芋<EFBFBD>见ế<EFBFBD>凋<EFBFBD>銝<EFBFBD><EFBFBD>湔𧒄嚗𣬚<EFBFBD><EFBFBD>望糓<EFBFBD>行<EFBFBD><EFBFBD>啣<EFBFBD>蝷?
|
||||
- 验证:两个模型判断不一致时,理由是否清晰展示
|
||||
|
||||
**测试指标**:
|
||||
- Prompt<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>&<EFBFBD>? >90%
|
||||
- <EFBFBD>冽<EFBFBD>皛⊥<EFBFBD>摨? >80%
|
||||
- <EFBFBD><EFBFBD>眏撅閧內摰峕㟲<EFBFBD>? 100%
|
||||
- Prompt生成准确率: >90%
|
||||
- 用户满意度: >80%
|
||||
- 理由展示完整性: 100%
|
||||
|
||||
---
|
||||
|
||||
@@ -756,11 +756,11 @@ Response:
|
||||
**测试场景**:
|
||||
|
||||
1. **Few-shot学习**
|
||||
- <EFBFBD>冽<EFBFBD>蝥䭾迤3銝芣<EFBFBD>靘?<3F>?撉諹<E69289>Prompt銝剜糓<E5899C>血<EFBFBD><E8A180>怨<EFBFBD>鈭𥟇<E988AD>靘?
|
||||
- 撉諹<EFBFBD>嚗𡁏鰵<EFBFBD><EFBFBD><EFBFBD><EFBFBD>㗇糓<EFBFBD>行㺿餈?
|
||||
- 用户纠正3个案例 → 验证Prompt中是否包含这些案例
|
||||
- 验证:新的筛选是否改进
|
||||
|
||||
2. **测试模式**
|
||||
- <EFBFBD>冽<EFBFBD><EFBFBD><EFBFBD>釣10蝭?<3F>?AI<41><49><EFBFBD>璅∪<E79285> <20>?<3F><><EFBFBD>Prompt
|
||||
- 用户标注10篇 → AI分析模式 → 生成Prompt
|
||||
- 验证:生成的Prompt是否符合用户偏好
|
||||
|
||||
---
|
||||
@@ -771,44 +771,44 @@ Response:
|
||||
|
||||
| 指标 | 目标 |
|
||||
|------|------|
|
||||
| Prompt<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>&<EFBFBD>?| >90% |
|
||||
| Prompt生成准确率 | >90% |
|
||||
| 用户完成配置时间 | <5分钟 |
|
||||
| <EFBFBD><EFBFBD>眏撅閧內摰峕㟲<EFBFBD>?| 100% |
|
||||
| 璅∪<EFBFBD><EFBFBD>脩<EFBFBD>霂<EFBFBD><EFBFBD><EFBFBD>?| 100% |
|
||||
| <EFBFBD>冽<EFBFBD>皛⊥<EFBFBD>摨?| >80% |
|
||||
| 理由展示完整性 | 100% |
|
||||
| 模型冲突识别率 | 100% |
|
||||
| 用户满意度 | >80% |
|
||||
|
||||
### 2.0阶段
|
||||
|
||||
| 指标 | 目标 |
|
||||
|------|------|
|
||||
| Few-shot<EFBFBD>寡<EFBFBD><EFBFBD><EFBFBD>&<EFBFBD>?| +15% |
|
||||
| 瘚贝<EFBFBD>璅∪<EFBFBD><EFBFBD>寥<EFBFBD>摨?| >85% |
|
||||
| Prompt璅⊥踎憭滨鍂<EFBFBD>?| >60% |
|
||||
| Few-shot改进准确率 | +15% |
|
||||
| 测试模式匹配度 | >85% |
|
||||
| Prompt模板复用率 | >60% |
|
||||
|
||||
---
|
||||
|
||||
## 憌𡡞埯銝𤾸<EFBFBD>撖?
|
||||
## 风险与应对
|
||||
|
||||
### 风险1: LLM生成的边界问题质量不稳定
|
||||
|
||||
**应对**:
|
||||
- 使用Few-shot Prompt
|
||||
- 人工审核常见边界情况
|
||||
- <EFBFBD>𣂷<EFBFBD>暺䁅恕颲寧<EFBFBD><EFBFBD>桅<EFBFBD>摨?
|
||||
- 提供默认边界问题库
|
||||
|
||||
### 风险2: 用户不愿意花时间确认
|
||||
|
||||
**应对**:
|
||||
- <EFBFBD>芣遬蝷?銝芷<E98A9D>隡睃<E99AA1>蝥折䔮憸?
|
||||
- 只显示5个高优先级问题
|
||||
- 其他使用AI默认建议
|
||||
- <EFBFBD>𣂷<EFBFBD>"敹恍<E695B9><E6818D>芋撘?嚗<>歲餈<E6ADB2>&霈歹<E99C88>
|
||||
- 提供"快速模式"(跳过确认)
|
||||
|
||||
### 憌𡡞埯3: 銝支葵璅∪<E79285><E288AA><EFBFBD>眏餈<E79C8F>鵭嚗屸𠗕隞亙笆瘥?
|
||||
### 风险3: 两个模型理由过长,难以对比
|
||||
|
||||
**应对**:
|
||||
- <EFBFBD>𣂼<EFBFBD><EFBFBD><EFBFBD>眏<EFBFBD>喲睸<EFBFBD>伐<EFBFBD><EFBFBD>?00摮梹<E691AE>
|
||||
- 提取理由关键句(前100字)
|
||||
- 提供展开/收起按钮
|
||||
- 擃䀝漁<EFBFBD>脩<EFBFBD><EFBFBD>?
|
||||
- 高亮冲突点
|
||||
|
||||
---
|
||||
|
||||
@@ -816,14 +816,14 @@ Response:
|
||||
|
||||
### MVP核心(必做)
|
||||
|
||||
1. <EFBFBD>?PICOS颲枏<EFBFBD>銵典<EFBFBD>
|
||||
2. <EFBFBD>?AI<41><49><EFBFBD>銝舘器<E88898>屸䔮憸条<E686B8><E69DA1>?
|
||||
3. <EFBFBD>?<3F>冽<EFBFBD>蝖株恕<E6A0AA>屸𢒰
|
||||
4. <EFBFBD>?<3F>芸𢆡<E88AB8><F0A286A1><EFBFBD>Prompt
|
||||
5. <EFBFBD>?Prompt蝻𤥁<EFBFBD><EFBFBD>?
|
||||
6. <EFBFBD>?**<2A>曄內銝支葵璅∪<E79285><E288AA><EFBFBD><EFBFBD><EFBFBD>渡<EFBFBD><E6B8A1>?* 潃?
|
||||
1. ✅ PICOS输入表单
|
||||
2. ✅ AI分析与边界问题生成
|
||||
3. ✅ 用户确认界面
|
||||
4. ✅ 自动生成Prompt
|
||||
5. ✅ Prompt编辑器
|
||||
6. ✅ **显示两个模型的完整理由** ⭐
|
||||
|
||||
**撘<EFBFBD><EFBFBD>烐𧒄<EFBFBD>?*: 2<EFBFBD>?
|
||||
**开发时间**: 2周
|
||||
|
||||
---
|
||||
|
||||
@@ -831,20 +831,20 @@ Response:
|
||||
|
||||
1. 🔮 Few-shot自动学习
|
||||
2. 🧪 测试模式
|
||||
3. <EFBFBD><EFBFBD> Prompt璅⊥踎摨?
|
||||
3. 📚 Prompt模板库
|
||||
|
||||
**撘<EFBFBD><EFBFBD>烐𧒄<EFBFBD>?*: 2<EFBFBD>?
|
||||
**开发时间**: 2周
|
||||
|
||||
---
|
||||
|
||||
**<EFBFBD>笔<EFBFBD>**: MVP<EFBFBD><EFBFBD><EFBFBD><EFBFBD>啁<EFBFBD><EFBFBD>訫虾<EFBFBD>剁<EFBFBD>2.0<EFBFBD>滚<EFBFBD><EFBFBD>箄<EFBFBD><EFBFBD>?
|
||||
**原则**: MVP先做到简单可用,2.0再做智能化
|
||||
|
||||
**銝衤<EFBFBD>甇?*: 撘<>憪𨳒VP<56>嗆挾撘<E68CBE><E69298>?
|
||||
**下一步**: 开始MVP阶段开发
|
||||
|
||||
---
|
||||
|
||||
**文档版本**: v1.0
|
||||
**雿𡏭<EFBFBD>?*: AI Assistant
|
||||
**作者**: AI Assistant
|
||||
**审核**: [待用户确认]
|
||||
**日期**: 2025-11-18
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user