refactor(asl): ASL frontend architecture refactoring with left navigation

- feat: Create ASLLayout component with 7-module left navigation
- feat: Implement Title Screening Settings page with optimized PICOS layout
- feat: Add placeholder pages for Workbench and Results
- fix: Fix nested routing structure for React Router v6
- fix: Resolve Spin component warning in MainLayout
- fix: Add QueryClientProvider to App.tsx
- style: Optimize PICOS form layout (P+I left, C+O+S right)
- style: Align Inclusion/Exclusion criteria side-by-side
- docs: Add architecture refactoring and routing fix reports

Ref: Week 2 Frontend Development
Scope: ASL module MVP - Title Abstract Screening
This commit is contained in:
2025-11-18 21:51:51 +08:00
parent e3e7e028e8
commit 3634933ece
213 changed files with 20054 additions and 442 deletions

View File

@@ -0,0 +1,261 @@
/**
* ASL LLM筛选输出的JSON Schema
* 用于验证AI模型输出格式
*/
import { JSONSchemaType } from 'ajv';
import { LLMScreeningOutput } from '../types/index.js';
export const screeningOutputSchema: JSONSchemaType<LLMScreeningOutput> = {
type: 'object',
properties: {
judgment: {
type: 'object',
properties: {
P: { type: 'string', enum: ['match', 'partial', 'mismatch'] },
I: { type: 'string', enum: ['match', 'partial', 'mismatch'] },
C: { type: 'string', enum: ['match', 'partial', 'mismatch'] },
S: { type: 'string', enum: ['match', 'partial', 'mismatch'] },
},
required: ['P', 'I', 'C', 'S'],
},
evidence: {
type: 'object',
properties: {
P: { type: 'string' },
I: { type: 'string' },
C: { type: 'string' },
S: { type: 'string' },
},
required: ['P', 'I', 'C', 'S'],
},
conclusion: {
type: 'string',
enum: ['include', 'exclude', 'uncertain'],
},
confidence: {
type: 'number',
minimum: 0,
maximum: 1,
},
reason: {
type: 'string',
},
},
required: ['judgment', 'evidence', 'conclusion', 'confidence', 'reason'],
additionalProperties: false,
};
/**
* 筛选风格类型
*/
export type ScreeningStyle = 'lenient' | 'standard' | 'strict';
/**
* 生成LLM筛选的Prompt (v1.1.0 - 支持三种风格)
*
* @param style - 筛选风格:
* - lenient: 宽松模式,宁可多纳入也不错过(适合初筛)
* - standard: 标准模式,平衡准确率和召回率(默认)
* - strict: 严格模式,宁可错杀也不放过(适合精筛)
*/
export function generateScreeningPrompt(
title: string,
abstract: string,
picoCriteria: any,
inclusionCriteria: string,
exclusionCriteria: string,
style: ScreeningStyle = 'standard',
authors?: string,
journal?: string,
publicationYear?: number
): string {
// 根据风格选择不同的Prompt基调
const styleConfig = {
lenient: {
role: '你是一位经验丰富的系统综述专家,负责对医学文献进行**初步筛选(标题摘要筛选)**。',
context: `⚠️ **重要提示**: 这是筛选流程的**第一步**,筛选后还需要下载全文进行复筛。因此:
- **宁可多纳入,也不要错过可能有价值的文献**
- **当信息不足时,倾向于"纳入"或"不确定",而非直接排除**
- **只排除明显不符合的文献**`,
picoGuideline: `**⭐ 宽松模式原则**:
- 只要有部分匹配,就标记为 \`partial\`,不要轻易标记为 \`mismatch\`
- 信息不足时,倾向于 \`partial\` 而非 \`mismatch\``,
decisionRules: `**⭐ 宽松模式决策规则**:
1. **优先纳入**: 当判断不确定时,选择 \`include\`\`uncertain\`,而非 \`exclude\`
2. **只排除明显不符**: 只有当文献明确不符合核心PICO标准时才排除
3. **容忍边界情况**: 对于边界情况(如地域差异、时间窗口、对照类型),倾向于纳入
4. **看潜在价值**: 即使不完全匹配,但有参考价值的也纳入
**具体容忍规则**:
- **人群地域**: 即使不是目标地域,但研究结果有参考价值 → \`include\`
- **时间窗口**: 即使不完全在时间范围内,但研究方法可参考 → \`include\`
- **对照类型**: 即使对照不是安慰剂,但有对比意义 → \`include\`
- **研究设计**: 即使不是理想的RCT但有科学价值 → \`include\``,
confidenceRule: '**⭐ 宽松模式**: 置信度要求降低0.5以上即可纳入',
reasonExample: '虽然对照组不是安慰剂而是另一种药物,但研究方法严谨,结果有参考价值,且研究人群与目标人群有一定相似性。建议纳入全文复筛阶段进一步评估。',
finalReminder: '**记住**: 这是**初筛**阶段,**宁可多纳入,也不要错过**。只要有任何可能的价值,就应该纳入全文复筛!'
},
standard: {
role: '你是一位经验丰富的系统综述专家负责根据PICO标准和纳排标准对医学文献进行初步筛选。',
context: '',
picoGuideline: '',
decisionRules: '',
confidenceRule: '',
reasonExample: '具体说明你的筛选决策理由,需包含:(1)为什么纳入或排除 (2)哪些PICO标准符合或不符合 (3)是否有特殊考虑',
finalReminder: '现在开始筛选请严格按照JSON格式输出结果。'
},
strict: {
role: '你是一位严谨的系统综述专家负责根据PICO标准和纳排标准对医学文献进行**严格筛选**。',
context: `⚠️ **重要提示**: 这是**严格筛选模式**,要求:
- **严格匹配PICO标准任何维度不匹配都应排除**
- **对边界情况持保守态度**
- **优先排除而非纳入**
- **只纳入高度确定符合标准的文献**`,
picoGuideline: `**⭐ 严格模式原则**:
- 只有**明确且完全匹配**才能标记为 \`match\`
- 任何不确定或不够明确的,标记为 \`partial\`\`mismatch\`
- 对标准的理解要严格,不做宽松解释`,
decisionRules: `**⭐ 严格模式决策规则**:
1. **一票否决**: 任何一个PICO维度为 \`mismatch\`,直接排除
2. **多个partial即排除**: 超过2个维度为 \`partial\`,也应排除
3. **触发任一排除标准**: 立即排除
4. **不确定时倾向排除**: 当信息不足无法判断时,倾向于排除
5. **要求高置信度**: 只有置信度≥0.8才纳入
**具体严格规则**:
- **人群地域**: 必须严格匹配目标地域,其他地域一律排除
- **时间窗口**: 必须严格在时间范围内,边界情况也排除
- **对照类型**: 必须是指定的对照类型(如安慰剂),其他对照排除
- **研究设计**: 必须是指定的研究设计,次优设计也排除`,
confidenceRule: '**⭐ 严格模式**: 只有置信度≥0.8才能纳入',
reasonExample: '虽然研究人群和干预措施匹配,但对照组为另一种药物而非安慰剂,不符合严格的对照要求。在严格筛选模式下,必须排除。',
finalReminder: '**记住**: 这是**严格筛选**模式,**宁可错杀,不可放过**。只纳入**完全确定符合**所有标准的高质量文献!'
}
};
const config = styleConfig[style];
return `${config.role}
${config.context}
## 研究方案信息
**PICO标准**
- **P (研究人群)**: ${picoCriteria.population}
- **I (干预措施)**: ${picoCriteria.intervention}
- **C (对照)**: ${picoCriteria.comparison}
- **O (结局指标)**: ${picoCriteria.outcome}
- **S (研究设计)**: ${picoCriteria.studyDesign}
**纳入标准:**
${inclusionCriteria}
**排除标准:**
${exclusionCriteria}
---
## 待筛选文献
**标题:** ${title}
**摘要:** ${abstract}
${authors ? `**作者:** ${authors}` : ''}
${journal ? `**期刊:** ${journal}` : ''}
${publicationYear ? `**年份:** ${publicationYear}` : ''}
---
## 筛选任务
请按照以下步骤进行筛选:
### 步骤1: PICO逐项评估
对文献的每个PICO维度进行评估判断是否匹配
- **match** (匹配):文献明确符合该标准
- **partial** (部分匹配):文献部分符合,或表述不够明确
- **mismatch** (不匹配):文献明确不符合该标准
${config.picoGuideline}
### 步骤2: 提取证据
从标题和摘要中提取支持你判断的**原文片段**,每个维度给出具体证据。
### 步骤3: 综合决策
基于PICO评估、纳排标准给出最终筛选决策
- **include** (纳入)文献符合所有或大部分PICO标准且满足纳入标准
- **exclude** (排除)文献明确不符合PICO标准或触发排除标准
- **uncertain** (不确定):信息不足,无法做出明确判断
${config.decisionRules}
### 步骤4: 置信度评分
给出你对此判断的把握程度0-1之间
- **0.9-1.0**: 非常确定,有充分证据支持
- **0.7-0.9**: 比较确定,证据较为充分
- **0.5-0.7**: 中等把握,证据有限
- **0.0-0.5**: 不确定,信息严重不足
${config.confidenceRule}
---
## 输出格式要求
请**严格按照**以下JSON格式输出不要添加任何额外文字
⚠️ **重要**: 必须使用ASCII引号"),不要使用中文引号(""
\`\`\`json
{
"judgment": {
"P": "match",
"I": "match",
"C": "partial",
"S": "match"
},
"evidence": {
"P": "从摘要中引用支持P判断的原文",
"I": "从摘要中引用支持I判断的原文",
"C": "从摘要中引用支持C判断的原文",
"S": "从摘要中引用支持S判断的原文"
},
"conclusion": "include",
"confidence": 0.85,
"reason": "${config.reasonExample}"
}
\`\`\`
## 关键约束
1. **judgment** 的每个字段只能是:\`"match"\`, \`"partial"\`, \`"mismatch"\`
2. **evidence** 必须引用原文,不要编造内容
3. **conclusion** 只能是:\`"include"\`, \`"exclude"\`, \`"uncertain"\`
4. **confidence** 必须是0-1之间的数字
5. **reason** 长度在50-300字之间说理充分
6. 输出必须是合法的JSON格式
## 医学文献筛选原则
- 优先考虑研究设计的严谨性RCT > 队列研究 > 病例对照)
- 标题和摘要信息不足时,倾向于 \`"uncertain"\` 而非直接排除
- 对于综述、系统评价、Meta分析通常排除除非方案特别说明
- 动物实验、体外实验通常排除(除非方案特别说明)
- 会议摘要、病例报告通常排除
- 注意区分干预措施的具体类型(如药物剂量、手术方式)
- 结局指标要与方案一致(主要结局 vs 次要结局)
---
${config.finalReminder}
`;
}