/** * 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 = {}; 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());