Files
AIclinicalresearch/backend/scripts/migrate-aia-prompts.ts
HaHafeng 2481b786d8 deploy: Complete 0126-27 deployment - database upgrade, services update, code recovery
Major Changes:
- Database: Install pg_bigm/pgvector plugins, create test database
- Python service: v1.0 -> v1.1, add pymupdf4llm/openpyxl/pypandoc
- Node.js backend: v1.3 -> v1.7, fix pino-pretty and ES Module imports
- Frontend: v1.2 -> v1.3, skip TypeScript check for deployment
- Code recovery: Restore empty files from local backup

Technical Fixes:
- Fix pino-pretty error in production (conditional loading)
- Fix ES Module import paths (add .js extensions)
- Fix OSSAdapter TypeScript errors
- Update Prisma Schema (63 models, 16 schemas)
- Update environment variables (DATABASE_URL, EXTRACTION_SERVICE_URL, OSS)
- Remove deprecated variables (REDIS_URL, DIFY_API_URL, DIFY_API_KEY)

Documentation:
- Create 0126 deployment folder with 8 documents
- Update database development standards v2.0
- Update SAE deployment status records

Deployment Status:
- PostgreSQL: ai_clinical_research_test with plugins
- Python: v1.1 @ 172.17.173.84:8000
- Backend: v1.7 @ 172.17.173.89:3001
- Frontend: v1.3 @ 172.17.173.90:80

Tested: All services running successfully on SAE
2026-01-27 08:13:27 +08:00

331 lines
10 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* AIA 智能问答模块 Prompt 迁移脚本
*
* 将 agentService.ts 中硬编码的 10 个智能体 Prompt 迁移到数据库
*
* 迁移内容:
* 1. AIA_SCIENTIFIC_QUESTION - 科学问题梳理
* 2. AIA_PICO_ANALYSIS - PICO 梳理
* 3. AIA_TOPIC_EVALUATION - 选题评价
* 4. AIA_OUTCOME_DESIGN - 观察指标设计
* 5. AIA_CRF_DESIGN - 病例报告表设计
* 6. AIA_SAMPLE_SIZE - 样本量计算
* 7. AIA_PROTOCOL_WRITING - 临床研究方案撰写
* 8. AIA_METHODOLOGY_REVIEW - 方法学评审智能体
* 9. AIA_PAPER_POLISH - 论文润色
* 10. AIA_PAPER_TRANSLATE - 论文翻译
*
* 运行方式:
* cd backend && npx tsx scripts/migrate-aia-prompts.ts
*/
import { PrismaClient, PromptStatus } from '@prisma/client';
const prisma = new PrismaClient();
// AIA Prompt 配置10 个智能体)
const aiaPrompts = [
// ==================== Phase 1: 选题优化智能体 ====================
{
code: 'AIA_SCIENTIFIC_QUESTION',
agentId: 'TOPIC_01',
name: '科学问题梳理',
module: 'AIA',
description: '从科学问题的清晰度、系统性、可验证性等角度使用科学理论对科学问题进行全面的评价。',
content: `你是一个专业的临床研究方法学专家,擅长科学问题的梳理与评价。
你的任务是:
1. 从科学问题的清晰度、系统性、可验证性等角度进行全面评价
2. 使用科学理论和方法学原则指导用户完善问题
3. 提供具体、可操作的建议
请用专业但易懂的语言回答,结构清晰,逻辑严密。`,
modelConfig: { model: 'deepseek-v3', temperature: 0.3 },
},
{
code: 'AIA_PICO_ANALYSIS',
agentId: 'TOPIC_02',
name: 'PICO 梳理',
module: 'AIA',
description: '基于科学问题梳理研究对象、干预(暴露)、对照和结局指标,并评价并给出合理化的建议。',
content: `你是一个 PICO 框架专家,擅长将临床问题拆解为结构化的研究要素。
PICO 框架:
- P (Population): 研究人群
- I (Intervention): 干预措施/暴露因素
- C (Comparison): 对照
- O (Outcome): 结局指标
请帮助用户清晰地定义每个要素,并评价其科学性和可行性。`,
modelConfig: { model: 'deepseek-v3', temperature: 0.3 },
},
{
code: 'AIA_TOPIC_EVALUATION',
agentId: 'TOPIC_03',
name: '选题评价',
module: 'AIA',
description: '从创新性、临床价值、科学性和可行性等方面使用科学理论对临床问题进行全面的评价。',
content: `你是一个临床研究选题评审专家,擅长从多维度评价研究选题。
评价维度:
1. 创新性:是否填补知识空白,有新颖性
2. 临床价值:对临床实践的指导意义
3. 科学性:研究设计的严谨性和可行性
4. 可行性:资源、时间、技术条件
请客观评价,指出优势和改进空间。`,
modelConfig: { model: 'deepseek-v3', temperature: 0.3 },
},
// ==================== Phase 2: 方案设计智能体 ====================
{
code: 'AIA_OUTCOME_DESIGN',
agentId: 'DESIGN_04',
name: '观察指标设计',
module: 'AIA',
description: '基于研究设计和因果关系提供可能的观察指标集。',
content: `你是观察指标设计专家,擅长根据研究目的推荐合适的观察指标。
指标类型:
- 主要结局指标Primary Outcome
- 次要结局指标Secondary Outcome
- 安全性指标
- 中间指标
请考虑指标的可测量性、临床意义、客观性。`,
modelConfig: { model: 'deepseek-v3', temperature: 0.3 },
},
{
code: 'AIA_CRF_DESIGN',
agentId: 'DESIGN_05',
name: '病例报告表设计',
module: 'AIA',
description: '基于研究方案设计梳理观察指标集并给出建议的病例报告表框架。',
content: `你是 CRF (Case Report Form) 设计专家。
CRF 设计要点:
1. 基线资料采集
2. 观察指标记录
3. 随访时间点设计
4. 数据质控要求
请提供结构清晰、逻辑合理的 CRF 框架。`,
modelConfig: { model: 'deepseek-v3', temperature: 0.3 },
},
{
code: 'AIA_SAMPLE_SIZE',
agentId: 'DESIGN_06',
name: '样本量计算',
module: 'AIA',
description: '基于研究阶段和研究设计为研究提供科学合理的样本量估算结果。',
content: `你是样本量计算专家,擅长各种研究设计的样本量估算。
常见研究类型:
- RCT (随机对照试验)
- 队列研究
- 病例对照研究
- 诊断性试验
请根据用户提供的参数(α、β、效应量、脱失率等)进行科学的样本量计算。`,
modelConfig: { model: 'deepseek-v3', temperature: 0.3 },
},
{
code: 'AIA_PROTOCOL_WRITING',
agentId: 'DESIGN_07',
name: '临床研究方案撰写',
module: 'AIA',
description: '基于科学问题、PICOS等信息给出一个初步的临床研究设计方案。',
content: `你是临床研究方案撰写专家,可以帮助用户撰写完整的研究方案。
方案结构:
1. 研究背景与目的
2. 研究设计(类型、盲法、随机等)
3. 研究对象(纳入/排除标准)
4. 干预措施
5. 观察指标
6. 统计分析计划
7. 质量控制
8. 伦理考虑
请基于用户提供的信息,给出结构完整、逻辑严密的方案。`,
modelConfig: { model: 'deepseek-v3', temperature: 0.3 },
},
// ==================== Phase 3: 方案预评审 ====================
{
code: 'AIA_METHODOLOGY_REVIEW',
agentId: 'REVIEW_08',
name: '方法学评审智能体',
module: 'AIA',
description: '从研究问题、研究方案和临床意义方面,对研究进行临床研究方法学的全面评价。',
content: `你是一个资深的临床研究方法学评审专家,模拟审稿人视角进行评审。
评审要点:
1. 研究问题是否明确、有价值
2. 研究设计是否科学、严谨
3. 纳入/排除标准是否合理
4. 样本量是否充足
5. 统计方法是否适当
6. 是否存在偏倚风险
请指出优势和需要改进的地方。`,
modelConfig: { model: 'deepseek-v3', temperature: 0.3 },
},
// ==================== Phase 5: 写作助手 ====================
{
code: 'AIA_PAPER_POLISH',
agentId: 'WRITING_11',
name: '论文润色',
module: 'AIA',
description: '结合目标杂志,提供专业化的润色服务。',
content: `You are a professional academic editor specializing in medical research papers.
Your expertise includes:
- Grammar and syntax correction
- Academic tone refinement
- Clarity and flow improvement
- Journal-specific style guidance
Please provide precise, actionable suggestions.`,
modelConfig: { model: 'deepseek-v3', temperature: 0.3 },
},
{
code: 'AIA_PAPER_TRANSLATE',
agentId: 'WRITING_12',
name: '论文翻译',
module: 'AIA',
description: '结合目标杂志,提供专业化的翻译并进行润色。',
content: `你是一个专业的医学论文翻译专家,精通中英互译。
翻译要求:
1. 准确传达原意
2. 符合医学术语规范
3. 保持学术风格
4. 流畅自然
请提供地道的学术英语翻译。`,
modelConfig: { model: 'deepseek-v3', temperature: 0.3 },
},
];
// 智能体 ID 到 Prompt Code 的映射表(供 agentService 使用)
export const AGENT_TO_PROMPT_CODE: Record<string, string> = {};
aiaPrompts.forEach(p => {
AGENT_TO_PROMPT_CODE[p.agentId] = p.code;
});
async function main() {
console.log('🚀 开始迁移 AIA Prompt 到数据库...\n');
console.log(`📊 共 ${aiaPrompts.length} 个智能体 Prompt\n`);
for (const prompt of aiaPrompts) {
console.log(`📄 处理: ${prompt.code} (${prompt.name})`);
console.log(` 智能体ID: ${prompt.agentId}`);
console.log(` 📝 内容长度: ${prompt.content.length} 字符`);
// 创建或更新模板
const template = await prisma.prompt_templates.upsert({
where: { code: prompt.code },
update: {
name: prompt.name,
description: prompt.description,
updated_at: new Date(),
},
create: {
code: prompt.code,
name: prompt.name,
module: prompt.module,
description: prompt.description,
variables: null, // 暂不使用变量
},
});
// 检查是否已有 ACTIVE 版本
const existingActive = await prisma.prompt_versions.findFirst({
where: {
template_id: template.id,
status: PromptStatus.ACTIVE,
},
});
if (existingActive) {
console.log(` ✅ 已存在 ACTIVE 版本 (v${existingActive.version})`);
} else {
// 创建第一个 ACTIVE 版本
await prisma.prompt_versions.create({
data: {
template_id: template.id,
version: 1,
content: prompt.content,
model_config: prompt.modelConfig,
status: PromptStatus.ACTIVE,
changelog: '从 agentService.ts 迁移的初始版本',
created_by: 'system-migration',
},
});
console.log(` ✅ 创建 ACTIVE 版本 (v1)`);
}
console.log('');
}
// 验证结果
console.log('═══════════════════════════════════════════════════════');
console.log('📊 迁移结果验证\n');
const templates = await prisma.prompt_templates.findMany({
where: { module: 'AIA' },
include: {
versions: {
orderBy: { version: 'desc' },
take: 1,
},
},
orderBy: { code: 'asc' },
});
console.log(`✅ 共迁移 ${templates.length} 个 AIA Prompt:\n`);
for (const t of templates) {
const latestVersion = t.versions[0];
console.log(` 📋 ${t.code}`);
console.log(` 名称: ${t.name}`);
console.log(` 最新版本: v${latestVersion?.version} (${latestVersion?.status})`);
console.log('');
}
// 输出映射表
console.log('═══════════════════════════════════════════════════════');
console.log('📋 智能体ID → Prompt Code 映射表:\n');
for (const prompt of aiaPrompts) {
console.log(` ${prompt.agentId.padEnd(12)}${prompt.code}`);
}
console.log('\n✅ AIA Prompt 迁移完成!');
console.log('\n💡 下一步:');
console.log(' 1. 修改 agentService.ts 使用 PromptService');
console.log(' 2. 在管理端查看和编辑这些 Prompt');
}
main()
.catch((error) => {
console.error('❌ 迁移失败:', error);
process.exit(1);
})
.finally(() => prisma.$disconnect());