/** * RVW模块 Prompt 迁移脚本 * * 将现有文件Prompt迁移到数据库 * * 迁移内容: * 1. RVW_EDITORIAL - 稿约规范性评估 (review_editorial_system.txt) * 2. RVW_METHODOLOGY - 方法学质量评估 (review_methodology_system.txt) * 3. RVW_TOPIC_SYSTEM - 选题评估系统提示 (topic_evaluation_system.txt) * 4. RVW_TOPIC_USER - 选题评估用户模板 (topic_evaluation_user.txt) */ import { PrismaClient, PromptStatus } from '@prisma/client'; import * as fs from 'fs'; import * as path from 'path'; import { fileURLToPath } from 'url'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const prisma = new PrismaClient(); // 变量提取函数 function extractVariables(content: string): string[] { const regex = /\{\{(\w+)\}\}/g; const variables = new Set(); let match; while ((match = regex.exec(content)) !== null) { // 排除 Handlebars 控制语句如 #if, /if if (!match[1].startsWith('#') && !match[1].startsWith('/')) { variables.add(match[1]); } } return Array.from(variables); } // RVW Prompt 配置 // 注意:topic_evaluation_* 是"选题评估"功能,不属于 RVW 审稿模块 const rvwPrompts = [ { code: 'RVW_EDITORIAL', name: '稿约规范性评估', module: 'RVW', description: '评估医学稿件是否符合期刊稿约规范,包括文题、摘要、参考文献等11项标准。输出JSON格式的评分和建议。', file: 'review_editorial_system.txt', modelConfig: { model: 'deepseek-v3', temperature: 0.3 }, }, { code: 'RVW_METHODOLOGY', name: '方法学质量评估', module: 'RVW', description: '评估医学稿件的科研设计、统计学方法和统计分析质量,共20个检查点。输出JSON格式的评分和建议。', file: 'review_methodology_system.txt', modelConfig: { model: 'deepseek-v3', temperature: 0.3 }, }, { code: 'RVW_DATA_VALIDATION', name: '数据验证 LLM 核查', module: 'RVW', description: '使用大语言模型对医学科研稿件中的表格进行核查,包括百分比计算、统计检验方法、统计分析结果准确性等。', inlineContent: `你正在处理的是医学科研稿件,请对附件中的表格进行核查,包括百分比计算是准确,统计检验方法使用是否正确,统计分析检验结果是否准确,卡方检验中如果适用fisher精确检验的条件,不给卡方值不是问题,请忽略。最终形成一个核查报告,重点列出核查出的问题。 请按表格逐个输出核查结果,使用以下格式: ## 表N: <表格标题> <该表格的核查结论和发现的问题>`, modelConfig: { model: 'deepseek-v3', temperature: 0.3 }, }, { code: 'RVW_CLINICAL', name: '临床专业评估', module: 'RVW', description: '基于 FINER 标准(可行性、创新性、伦理性、相关性)对研究选题进行系统评估,涵盖创新性、临床价值、科学性、可行性四个维度。', inlineContent: `你作为临床研究设计智能顾问(CRD-IA),将依据 FINER 标准(可行性 Feasibility、创新性 Interesting、伦理性 Ethical、相关性 Relevant)对研究选题进行系统评估并用中文回答。 第一步:研究问题的明确性评估 1. 判断研究问题是否清晰 研究问题是否包含完整的 PICO 要素(Population/Intervention/Comparator/Outcome)。 若 PICO 不完整,提示研究者补充必要信息。 2. 研究问题的完善与优化 研究者已有明确的临床问题:通过对话识别其陈述中的关键信息,优化 PICO 框架。 研究者尚未形成清晰的研究问题:询问其关注的疾病领域,并协助提出可供研究的具体问题。 判断是否需进一步咨询专家:若研究问题仍不够明确,建议研究者寻求该领域专家的意见。 第二步:研究问题的要素完整性验证 CRD-IA 将按以下维度评估研究问题的完整性,确保其符合 FINER 标准,并依据 循证医学原则 和 ICH-GCP 规范 进行多维度价值评估。评估逻辑包括 假设解构 → 知识验证 → 缺陷识别 → 优化建议,所有结论需明确 证据等级(A/B/C类)。 1. 创新性评估 检索国际指南、PubMed 已发表论文,以及 ICTRP、ClinicalTrials.gov 近三年注册研究,分析研究选题的 相似度(相似度<30%为高创新)。 识别研究假设中的 知识突破点,判断是否填补现有研究空白。 2. 临床价值评估 通过 PubMed 检索该疾病的 疾病负担指数(参考最新 GBD 数据),判断该研究的 临床紧迫性。 检索该疾病相关的 国际指南,明确指南是否指出该问题 需要进一步证据。 评估研究者定义的 结局指标 是否与临床关注的核心获益一致;如偏离临床重点,应予以提示。 3. 科学性评估 研究假设是否 符合基本科学原理,若存在与已知科学常识矛盾的部分,应提示研究者重新审视理论基础。 该研究问题能否通过 合理的研究设计 进行科学验证。 4. 可行性评估 进行 风险-受益比分析(基于 DECISION 模型),评估该研究是否存在 重大伦理风险,影响可行性。 估算目标患者群体的 潜在样本量,若可能难以收集足够样本,应明确指出并建议调整研究方案。 第三步:最终评估结论与优化建议 在综合分析 创新性、临床价值、科学性、可行性 之后,CRD-IA 将: 总结研究选题的整体评估结果,标明各项评估的 证据等级(A/B/C类)。 提出优化建议,帮助研究者改进研究设计,使其更具科学价值、临床意义和可操作性。 回答需要考虑聊天历史。 如果过程中有不明确的问题,通过聊天让用户补充相关信息。除特殊要求外,用中文回复。`, modelConfig: { model: 'deepseek-v3', temperature: 0.3 }, }, ]; async function main() { console.log('🚀 开始迁移 RVW Prompt 到数据库...\n'); const promptsDir = path.join(__dirname, '..', 'prompts'); for (const prompt of rvwPrompts) { console.log(`📄 处理: ${prompt.code} (${prompt.name})`); // 读取内容:优先使用 inlineContent,否则从文件读取 let content: string; if ((prompt as any).inlineContent) { content = (prompt as any).inlineContent; console.log(` 📝 使用内联内容,长度: ${content.length} 字符`); } else { const filePath = path.join(promptsDir, (prompt as any).file); if (!fs.existsSync(filePath)) { console.log(` ⚠️ 文件不存在: ${filePath}`); continue; } content = fs.readFileSync(filePath, 'utf-8').trim(); } const variables = extractVariables(content); console.log(` 📝 内容长度: ${content.length} 字符`); console.log(` 🔤 提取变量: [${variables.join(', ')}]`); // 创建或更新模板 const template = await prisma.prompt_templates.upsert({ where: { code: prompt.code }, update: { name: prompt.name, description: prompt.description, variables: variables.length > 0 ? variables : null, updated_at: new Date(), }, create: { code: prompt.code, name: prompt.name, module: prompt.module, description: prompt.description, variables: variables.length > 0 ? 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: content, model_config: prompt.modelConfig, status: PromptStatus.ACTIVE, changelog: '从文件迁移的初始版本', created_by: 'system-migration', }, }); console.log(` ✅ 创建 ACTIVE 版本 (v1)`); } console.log(''); } // 验证结果 console.log('═══════════════════════════════════════════════════════'); console.log('📊 迁移结果验证\n'); const templates = await prisma.prompt_templates.findMany({ where: { module: 'RVW' }, include: { versions: { orderBy: { version: 'desc' }, take: 1, }, }, }); console.log(`✅ 共迁移 ${templates.length} 个 RVW Prompt:\n`); for (const t of templates) { const latestVersion = t.versions[0]; console.log(` 📋 ${t.code}`); console.log(` 名称: ${t.name}`); console.log(` 变量: ${t.variables ? JSON.stringify(t.variables) : '无'}`); console.log(` 最新版本: v${latestVersion?.version} (${latestVersion?.status})`); console.log(''); } console.log('✅ RVW Prompt 迁移完成!'); } main() .catch((error) => { console.error('❌ 迁移失败:', error); process.exit(1); }) .finally(() => prisma.$disconnect());