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
331 lines
10 KiB
TypeScript
331 lines
10 KiB
TypeScript
/**
|
||
* 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());
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|