Files
AIclinicalresearch/backend/prisma/seed-protocol-agent.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

394 lines
12 KiB
TypeScript
Raw 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.
/**
* Protocol Agent 独立 Seed 脚本
*
* 只初始化 Protocol Agent 相关的配置数据,不影响其他模块
*
* 运行方式:
* npx ts-node prisma/seed-protocol-agent.ts
* 或者:
* npx tsx prisma/seed-protocol-agent.ts
*/
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
async function seedProtocolAgent() {
console.log('🌱 开始初始化 Protocol Agent 配置...\n');
try {
// ============================================
// 1. 创建 Agent 定义
// ============================================
console.log('📌 创建 Agent 定义...');
const protocolAgent = await prisma.agentDefinition.upsert({
where: { code: 'protocol_agent' },
update: {
name: '全流程研究方案制定',
description: '引导用户完成5个核心阶段科学问题、PICO、研究设计、样本量、观察指标最终一键生成研究方案',
version: '1.0.0',
config: {
defaultModel: 'deepseek-v3',
maxTurns: 100,
timeout: 120000,
enableTrace: true,
enableReflexion: true,
},
isActive: true,
},
create: {
code: 'protocol_agent',
name: '全流程研究方案制定',
description: '引导用户完成5个核心阶段科学问题、PICO、研究设计、样本量、观察指标最终一键生成研究方案',
version: '1.0.0',
config: {
defaultModel: 'deepseek-v3',
maxTurns: 100,
timeout: 120000,
enableTrace: true,
enableReflexion: true,
},
isActive: true,
},
});
console.log(` ✅ Agent 定义创建成功: ${protocolAgent.name} (ID: ${protocolAgent.id})`);
// ============================================
// 2. 创建 5 个阶段
// ============================================
console.log('📌 创建 5 个阶段配置...');
const stages = [
{
stageCode: 'scientific_question',
stageName: '科学问题梳理',
sortOrder: 1,
isInitial: true,
isFinal: false,
nextStages: ['pico']
},
{
stageCode: 'pico',
stageName: 'PICO要素',
sortOrder: 2,
isInitial: false,
isFinal: false,
nextStages: ['study_design']
},
{
stageCode: 'study_design',
stageName: '研究设计',
sortOrder: 3,
isInitial: false,
isFinal: false,
nextStages: ['sample_size']
},
{
stageCode: 'sample_size',
stageName: '样本量计算',
sortOrder: 4,
isInitial: false,
isFinal: false,
nextStages: ['endpoints']
},
{
stageCode: 'endpoints',
stageName: '观察指标',
sortOrder: 5,
isInitial: false,
isFinal: true,
nextStages: []
},
];
const stageMap = new Map<string, string>();
for (const stage of stages) {
const created = await prisma.agentStage.upsert({
where: {
agentId_stageCode: {
agentId: protocolAgent.id,
stageCode: stage.stageCode
}
},
update: {
stageName: stage.stageName,
sortOrder: stage.sortOrder,
isInitial: stage.isInitial,
isFinal: stage.isFinal,
nextStages: stage.nextStages,
},
create: {
agentId: protocolAgent.id,
stageCode: stage.stageCode,
stageName: stage.stageName,
sortOrder: stage.sortOrder,
isInitial: stage.isInitial,
isFinal: stage.isFinal,
nextStages: stage.nextStages,
},
});
stageMap.set(stage.stageCode, created.id);
console.log(` ✅ 阶段 ${stage.sortOrder}: ${stage.stageName}`);
}
// ============================================
// 3. 创建系统 Prompt
// ============================================
console.log('📌 创建系统 Prompt...');
const systemPromptContent = `你是一位资深的临床研究方法学专家,正在帮助医生设计临床研究方案。
## 你的角色
- 你是一位友好、专业的研究方案设计顾问
- 你会引导用户一步步完成研究方案的核心要素
- 你善于提问,帮助用户理清思路
## 当前工作流程
你将引导用户完成5个核心阶段
1. 科学问题梳理 - 明确研究要解决的核心问题
2. PICO要素 - 确定研究人群(P)、干预(I)、对照(C)和结局(O)
3. 研究设计 - 选择合适的研究类型和方法
4. 样本量计算 - 估算所需的样本量
5. 观察指标 - 定义基线、暴露、结局指标和混杂因素
## 输出要求
1. 回复要简洁、专业、有针对性
2. 每次只关注当前阶段的问题
3. 当用户提供了足够信息后,整理成结构化内容
4. 整理完成后,在回复末尾输出提取的数据(用于同步到方案)
## 数据提取格式
当你认为当前阶段的信息已经收集完整,请在回复末尾添加:
<extracted_data>
{
"字段1": "值1",
"字段2": "值2"
}
</extracted_data>
注意:只有在信息收集完整时才输出 extracted_data 标签。`;
await prisma.agentPrompt.upsert({
where: {
agentId_promptCode_version: {
agentId: protocolAgent.id,
promptCode: 'system',
version: 1
}
},
update: {
content: systemPromptContent,
isActive: true,
},
create: {
agentId: protocolAgent.id,
promptType: 'system',
promptCode: 'system',
content: systemPromptContent,
variables: ['context', 'intent'],
version: 1,
isActive: true,
},
});
console.log(` ✅ 系统 Prompt 创建成功`);
// ============================================
// 4. 创建各阶段 Prompt
// ============================================
console.log('📌 创建各阶段 Prompt...');
const stagePrompts = [
{
stageCode: 'scientific_question',
content: `## 当前阶段:科学问题梳理
### 目标
帮助用户明确研究要解决的核心科学问题。
### 引导方向
1. 了解用户的研究背景和动机
2. 明确研究的核心问题是什么
3. 确认问题的科学价值和临床意义
### 提问示例
- "您想研究什么问题?"
- "这个研究的临床背景是什么?"
- "您希望通过这个研究解决什么问题?"
### 数据提取
当信息完整时,提取以下字段:
- content: 科学问题的完整描述
- background: 研究背景
- significance: 研究意义`,
},
{
stageCode: 'pico',
content: `## 当前阶段PICO要素
### 目标
帮助用户确定PICO四要素。
### PICO定义
- P (Population): 研究人群 - 谁是研究对象?
- I (Intervention): 干预措施 - 研究什么干预/暴露?
- C (Comparison): 对照 - 与什么比较?
- O (Outcome): 结局 - 关注什么结果?
### 引导方向
1. 逐一确认每个要素
2. 确保定义清晰、可操作
### 数据提取
当信息完整时,提取以下字段:
- population: 研究人群描述
- intervention: 干预措施描述
- comparison: 对照描述
- outcome: 结局指标描述`,
},
{
stageCode: 'study_design',
content: `## 当前阶段:研究设计
### 目标
帮助用户选择合适的研究设计类型。
### 常见研究类型
- 随机对照试验 (RCT)
- 队列研究 (Cohort)
- 病例对照研究 (Case-Control)
- 横断面研究 (Cross-sectional)
- 前后对照研究 (Before-After)
### 引导方向
1. 根据研究问题推荐合适的设计类型
2. 讨论设计的优缺点
3. 确定关键设计要素(如盲法、随机化方法等)
### 数据提取
当信息完整时,提取以下字段:
- studyType: 研究类型
- design: 设计要素列表
- features: 特殊设计特征`,
},
{
stageCode: 'sample_size',
content: `## 当前阶段:样本量计算
### 目标
帮助用户估算所需的样本量。
### 关键参数
- α (显著性水平): 通常0.05
- β (检验效能): 通常0.80或0.90
- 效应量: 预期的效果大小
- 脱落率: 预计的失访比例
### 引导方向
1. 了解主要结局指标的类型
2. 讨论预期的效应量
3. 考虑脱落率
### 数据提取
当信息完整时,提取以下字段:
- sampleSize: 计算的样本量
- alpha: 显著性水平
- power: 检验效能
- effectSize: 效应量
- dropoutRate: 脱落率`,
},
{
stageCode: 'endpoints',
content: `## 当前阶段:观察指标
### 目标
帮助用户定义完整的观察指标体系。
### 指标分类
1. 基线指标 - 人口学特征、病史、实验室检查
2. 暴露/干预指标 - 干预措施的具体内容
3. 结局指标 - 主要结局、次要结局、安全性指标
4. 混杂因素 - 需要控制的混杂变量
### 引导方向
1. 逐类确认各项指标
2. 确保指标定义清晰、可测量
3. 确定测量时点
### 数据提取
当信息完整时,提取以下字段:
- baseline: 基线指标列表
- exposure: 暴露/干预指标
- outcomes: 结局指标primary, secondary, safety
- confounders: 混杂因素列表`,
},
];
for (const prompt of stagePrompts) {
const stageId = stageMap.get(prompt.stageCode);
await prisma.agentPrompt.upsert({
where: {
agentId_promptCode_version: {
agentId: protocolAgent.id,
promptCode: `stage_${prompt.stageCode}`,
version: 1
}
},
update: {
stageId: stageId,
content: prompt.content,
isActive: true,
},
create: {
agentId: protocolAgent.id,
stageId: stageId,
promptType: 'stage',
promptCode: `stage_${prompt.stageCode}`,
content: prompt.content,
variables: ['context'],
version: 1,
isActive: true,
},
});
console.log(` ✅ 阶段 Prompt: ${prompt.stageCode}`);
}
// ============================================
// 完成
// ============================================
console.log('\n🎉 Protocol Agent 配置初始化完成!\n');
console.log('╔════════════════════════════════════════════════════════════╗');
console.log('║ Protocol Agent 配置摘要 ║');
console.log('╠════════════════════════════════════════════════════════════╣');
console.log(`║ Agent ID: ${protocolAgent.id}`);
console.log('║ Agent Code: protocol_agent ║');
console.log('║ 阶段数量: 5 ║');
console.log('║ Prompt 数量: 6 (1 系统 + 5 阶段) ║');
console.log('╠════════════════════════════════════════════════════════════╣');
console.log('║ 阶段流程: ║');
console.log('║ 1. 科学问题梳理 → 2. PICO要素 → 3. 研究设计 ║');
console.log('║ → 4. 样本量计算 → 5. 观察指标 → 一键生成 ║');
console.log('╚════════════════════════════════════════════════════════════╝');
} catch (error) {
console.error('❌ Protocol Agent 初始化失败:', error);
throw error;
}
}
// 执行
seedProtocolAgent()
.then(async () => {
await prisma.$disconnect();
})
.catch(async (e) => {
console.error(e);
await prisma.$disconnect();
process.exit(1);
});