# Protocol Agent 数据库设计 > 版本:v1.0 > 创建日期:2026-01-24 --- ## 一、Schema规划 ``` ┌─────────────────────────────────────────────────────────────────────────┐ │ 数据库Schema架构 │ ├─────────────────────────────────────────────────────────────────────────┤ │ │ │ agent_schema (通用Agent框架 - 可复用) │ │ ├── agent_configs Agent配置表 │ │ ├── agent_stages 阶段配置表 │ │ ├── agent_tools 工具注册表 │ │ ├── action_cards Action Card配置表 │ │ ├── reflexion_rules 反思规则表 │ │ ├── agent_sessions Agent会话表 │ │ └── agent_traces 追踪日志表 │ │ │ │ protocol_schema (研究方案Agent专用) │ │ ├── protocol_contexts 研究方案上下文表 │ │ ├── protocol_versions 版本历史表 │ │ └── protocol_exports 导出记录表 │ │ │ │ knowledge_schema (知识库 - Phase 2) │ │ ├── knowledge_docs 知识文档表 │ │ ├── knowledge_chunks 知识块表 │ │ └── knowledge_embeddings 向量嵌入表 │ │ │ │ aia_schema (已有 - 复用) │ │ ├── conversations 对话表 │ │ └── messages 消息表 │ │ │ │ capability_schema (已有 - 复用) │ │ └── prompt_templates Prompt模板表 │ │ │ └─────────────────────────────────────────────────────────────────────────┘ ``` --- ## 二、agent_schema - 通用Agent框架表 ### 2.1 agent_configs (Agent配置表) ```prisma /// Agent配置表 - 定义每个Agent的基础信息 model AgentConfig { id String @id @default(uuid()) agentId String @unique @map("agent_id") agentName String @map("agent_name") agentDescription String? @map("agent_description") baseSystemPrompt String @map("base_system_prompt") @db.Text // 全局配置 toneOfVoice String? @map("tone_of_voice") globalKnowledge String[] @map("global_knowledge") memoryStrategy String @default("full") @map("memory_strategy") maxHistoryTurns Int @default(20) @map("max_history_turns") // LLM配置 defaultModel String @default("deepseek-v3") @map("default_model") temperature Float @default(0.7) maxTokens Int @default(4096) @map("max_tokens") // 状态 isActive Boolean @default(true) @map("is_active") version Int @default(1) createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") // 关联 stages AgentStage[] @relation("AgentConfigStages") tools AgentTool[] @relation("AgentConfigTools") reflexionRules ReflexionRule[] @relation("AgentConfigReflexion") @@index([agentId, isActive]) @@map("agent_configs") @@schema("agent_schema") } ``` **字段说明**: | 字段 | 类型 | 说明 | |------|------|------| | agentId | string | Agent唯一标识,如 `protocol_agent` | | baseSystemPrompt | text | 基础系统Prompt | | toneOfVoice | string | 语气风格,如"专业但亲和" | | memoryStrategy | string | 记忆策略:full/sliding_window/summary | | maxHistoryTurns | int | 最大保留对话轮数 | ### 2.2 agent_stages (阶段配置表) ```prisma /// 阶段配置表 - 定义Agent的各个阶段 model AgentStage { id String @id @default(uuid()) agentConfigId String @map("agent_config_id") stageId String @map("stage_id") stageName String @map("stage_name") stageOrder Int @map("stage_order") // Prompt配置 instruction String @db.Text extractionSchema Json @map("extraction_schema") completionCriteria String? @map("completion_criteria") @db.Text // 流转配置 nextStageId String? @map("next_stage_id") transitionMode String @default("user_confirm") @map("transition_mode") transitionCondition Json? @map("transition_condition") // 工具配置 availableToolIds String[] @map("available_tool_ids") isActive Boolean @default(true) @map("is_active") createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") agentConfig AgentConfig @relation("AgentConfigStages", fields: [agentConfigId], references: [id], onDelete: Cascade) actionCards ActionCard[] @relation("StageActionCards") @@unique([agentConfigId, stageId]) @@index([agentConfigId, stageOrder]) @@map("agent_stages") @@schema("agent_schema") } ``` **extractionSchema 示例** (PICO阶段): ```json { "type": "object", "properties": { "P": { "type": "object", "properties": { "value": { "type": "string", "description": "研究人群" }, "details": { "type": "string" }, "confidence": { "type": "number" } } }, "I": { ... }, "C": { ... }, "O": { ... } } } ``` ### 2.3 agent_tools (工具注册表) ```prisma /// 工具注册表 - 定义Agent可用的工具 model AgentTool { id String @id @default(uuid()) agentConfigId String? @map("agent_config_id") toolId String @unique @map("tool_id") toolName String @map("tool_name") toolDescription String @map("tool_description") @db.Text toolType String @map("tool_type") // Function定义 functionSchema Json? @map("function_schema") // 执行配置 handlerType String @map("handler_type") handlerConfig Json @map("handler_config") // 权限和限制 requiresAuth Boolean @default(false) @map("requires_auth") rateLimit Int? @map("rate_limit") timeout Int @default(30000) isActive Boolean @default(true) @map("is_active") createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") agentConfig AgentConfig? @relation("AgentConfigTools", fields: [agentConfigId], references: [id], onDelete: Cascade) @@index([agentConfigId, isActive]) @@index([toolType]) @@map("agent_tools") @@schema("agent_schema") } ``` **toolType 枚举值**: - `internal`: 内部计算工具 - `external`: 外部API工具 - `deep_link`: 深度链接跳转 - `rag`: RAG知识检索 ### 2.4 action_cards (Action Card配置表) ```prisma /// Action Card配置表 model ActionCard { id String @id @default(uuid()) stageId String @map("stage_id") cardId String @map("card_id") title String description String? @db.Text iconType String? @map("icon_type") // 触发配置 triggerType String @map("trigger_type") triggerCondition Json? @map("trigger_condition") // Action配置 actionType String @map("action_type") actionPayload Json @map("action_payload") // 回调配置 onCompleteAction String? @map("on_complete_action") resultMapping Json? @map("result_mapping") displayOrder Int @default(0) @map("display_order") isActive Boolean @default(true) @map("is_active") createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") stage AgentStage @relation("StageActionCards", fields: [stageId], references: [id], onDelete: Cascade) @@unique([stageId, cardId]) @@map("action_cards") @@schema("agent_schema") } ``` **actionPayload 示例** (Deep Link): ```json { "targetAgent": "sample_calculator", "targetPath": "/aia/sample-calculator", "params": { "studyType": "{{studyDesign.type}}", "primaryEndpoint": "{{endpoints.primary[0].name}}" }, "openMode": "modal" } ``` ### 2.5 reflexion_rules (反思规则表) ```prisma /// Reflexion规则表 model ReflexionRule { id String @id @default(uuid()) agentConfigId String @map("agent_config_id") ruleId String @map("rule_id") ruleName String @map("rule_name") ruleDescription String? @map("rule_description") @db.Text // 触发配置 triggerStageId String? @map("trigger_stage_id") triggerTiming String @map("trigger_timing") // 规则内容 ruleType String @map("rule_type") promptTemplate String? @map("prompt_template") @db.Text ruleLogic Json? @map("rule_logic") // 失败处理 severity String @default("warning") failureAction String @map("failure_action") isActive Boolean @default(true) @map("is_active") priority Int @default(0) createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") agentConfig AgentConfig @relation("AgentConfigReflexion", fields: [agentConfigId], references: [id], onDelete: Cascade) @@unique([agentConfigId, ruleId]) @@index([triggerStageId, triggerTiming]) @@map("reflexion_rules") @@schema("agent_schema") } ``` ### 2.6 agent_sessions (Agent会话表) ```prisma /// Agent会话表 - 扩展conversation的Agent状态 model AgentSession { id String @id @default(uuid()) conversationId String @unique @map("conversation_id") agentId String @map("agent_id") userId String @map("user_id") // 状态管理 currentStageId String @map("current_stage_id") stageStatus String @default("in_progress") @map("stage_status") // 元数据 sessionMetadata Json? @map("session_metadata") // 生命周期 startedAt DateTime @default(now()) @map("started_at") lastActiveAt DateTime @default(now()) @map("last_active_at") completedAt DateTime? @map("completed_at") createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") @@index([agentId, userId]) @@index([currentStageId]) @@index([lastActiveAt]) @@map("agent_sessions") @@schema("agent_schema") } ``` ### 2.7 agent_traces (追踪日志表) ```prisma /// Agent追踪日志表 - 可观测性 model AgentTrace { id String @id @default(uuid()) conversationId String @map("conversation_id") messageId String? @map("message_id") traceId String @map("trace_id") // 步骤信息 stepType String @map("step_type") stepOrder Int @map("step_order") // 输入输出 stepInput Json? @map("step_input") stepOutput Json? @map("step_output") // LLM信息 llmModel String? @map("llm_model") llmPromptTokens Int? @map("llm_prompt_tokens") llmCompletionTokens Int? @map("llm_completion_tokens") // 性能 durationMs Int? @map("duration_ms") // 状态 status String @default("success") errorMessage String? @map("error_message") @db.Text createdAt DateTime @default(now()) @map("created_at") @@index([conversationId, traceId]) @@index([traceId, stepOrder]) @@index([createdAt]) @@index([stepType, status]) @@map("agent_traces") @@schema("agent_schema") } ``` --- ## 三、protocol_schema - 研究方案专用表 ### 3.1 protocol_contexts (研究方案上下文表) ```prisma /// Protocol上下文表 - 研究方案的结构化数据存储 model ProtocolContext { id String @id @default(uuid()) sessionId String @unique @map("session_id") conversationId String @unique @map("conversation_id") userId String @map("user_id") // ===== Phase 1 核心字段 ===== /// 阶段1:科学问题 scientificQuestion Json? @map("scientific_question") @db.JsonB /// 阶段2:PICO pico Json? @db.JsonB /// 阶段3:研究设计 studyDesign Json? @map("study_design") @db.JsonB /// 阶段4:样本量 sampleSize Json? @map("sample_size") @db.JsonB /// 阶段5:终点指标 endpoints Json? @db.JsonB // ===== Phase 2 扩展字段 ===== /// 入选标准 inclusionCriteria Json? @map("inclusion_criteria") @db.JsonB /// 排除标准 exclusionCriteria Json? @map("exclusion_criteria") @db.JsonB /// 统计分析计划 statisticalPlan Json? @map("statistical_plan") @db.JsonB // ===== Phase 3 扩展字段 ===== /// 伦理考量 ethicsConsiderations Json? @map("ethics_considerations") @db.JsonB /// 研究时间线 timeline Json? @db.JsonB /// 预算估算 budget Json? @db.JsonB // ===== 元数据 ===== /// 总体进度 0-100 overallProgress Float @default(0) @map("overall_progress") /// 已完成阶段 completedStages String[] @map("completed_stages") /// 版本号 version Int @default(1) createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") versions ProtocolVersion[] @relation("ProtocolContextVersions") @@index([userId]) @@index([conversationId]) @@map("protocol_contexts") @@schema("protocol_schema") } ``` **各字段JSON结构**: #### scientificQuestion ```json { "content": "探究新型降糖药X对2型糖尿病患者的降糖效果及安全性", "clinicalBackground": "2型糖尿病患病率逐年上升...", "researchGap": "目前缺乏针对中国人群的大规模临床研究", "significance": "填补该领域空白,为临床用药提供依据", "confidence": 0.95, "sourceMessageIds": ["msg_123", "msg_125"], "lastUpdated": "2026-01-24T10:30:00Z" } ``` #### pico ```json { "P": { "value": "2型糖尿病患者", "details": "年龄18-70岁,HbA1c 7.0-10.0%", "confidence": 0.9 }, "I": { "value": "新型降糖药X", "details": "口服,每日一次,剂量10mg", "confidence": 0.95 }, "C": { "value": "二甲双胍", "details": "口服,每日两次,剂量500mg", "confidence": 0.88 }, "O": { "value": "HbA1c变化", "details": "治疗12周后HbA1c相对基线的变化值", "confidence": 0.92 }, "sourceMessageIds": ["msg_130", "msg_132"], "lastUpdated": "2026-01-24T11:00:00Z" } ``` #### studyDesign ```json { "type": "RCT", "phase": "III", "blinding": "双盲", "randomization": "中心随机", "allocationRatio": "1:1", "controlType": "阳性对照", "multiCenter": true, "centerCount": 20, "duration": "12周治疗期 + 4周随访期", "confidence": 0.9, "sourceMessageIds": ["msg_140"], "lastUpdated": "2026-01-24T11:30:00Z" } ``` #### sampleSize ```json { "total": 500, "perGroup": 250, "groups": 2, "calculationMethod": "优效性检验", "assumptions": { "alpha": 0.05, "power": 0.8, "effectSize": 0.5, "dropoutRate": 0.15, "standardDeviation": 1.2 }, "justification": "基于既往研究,预期效应量0.5%...", "toolUsed": "sample_calculator", "confidence": 0.95, "sourceMessageIds": ["msg_150"], "lastUpdated": "2026-01-24T12:00:00Z" } ``` #### endpoints ```json { "primary": [{ "name": "HbA1c变化值", "definition": "治疗12周后HbA1c相对基线的变化", "measurementMethod": "高效液相色谱法", "timePoint": "第12周", "analysisMethod": "ANCOVA" }], "secondary": [{ "name": "空腹血糖", "definition": "...", "measurementMethod": "...", "timePoint": "第4、8、12周" }], "safety": [{ "name": "低血糖发生率", "definition": "血糖<3.9mmol/L的事件" }], "exploratory": [], "sourceMessageIds": ["msg_160", "msg_162"], "lastUpdated": "2026-01-24T12:30:00Z" } ``` ### 3.2 protocol_versions (版本历史表) ```prisma /// Protocol版本历史表 - 支持回溯 model ProtocolVersion { id String @id @default(uuid()) contextId String @map("context_id") version Int changeType String @map("change_type") changedFields String[] @map("changed_fields") previousSnapshot Json @map("previous_snapshot") @db.JsonB changeReason String? @map("change_reason") changedBy String @map("changed_by") createdAt DateTime @default(now()) @map("created_at") context ProtocolContext @relation("ProtocolContextVersions", fields: [contextId], references: [id], onDelete: Cascade) @@unique([contextId, version]) @@index([contextId, createdAt]) @@map("protocol_versions") @@schema("protocol_schema") } ``` ### 3.3 protocol_generations (研究方案生成表) ```prisma /// Protocol生成记录表 - 一键生成研究方案 model ProtocolGeneration { id String @id @default(uuid()) contextId String @map("context_id") userId String @map("user_id") // 生成内容 generatedContent String @map("generated_content") @db.Text // 生成的研究方案全文 contentVersion Int @default(1) @map("content_version") // 版本号(重新生成时递增) // 使用的Prompt和参数 promptUsed String @map("prompt_used") @db.Text generationParams Json? @map("generation_params") @db.JsonB // 生成参数 // LLM调用信息 modelUsed String @map("model_used") tokensUsed Int? @map("tokens_used") durationMs Int? @map("duration_ms") // 导出记录 wordFileKey String? @map("word_file_key") // Word文件OSS Key pdfFileKey String? @map("pdf_file_key") // PDF文件OSS Key lastExportedAt DateTime? @map("last_exported_at") // 用户编辑(如有) userEditedContent String? @map("user_edited_content") @db.Text isEdited Boolean @default(false) @map("is_edited") status String @default("completed") // generating, completed, failed errorMessage String? @map("error_message") createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") @@index([contextId]) @@index([userId, createdAt]) @@map("protocol_generations") @@schema("protocol_schema") } ``` **字段说明**: | 字段 | 类型 | 说明 | |------|------|------| | generatedContent | text | LLM生成的完整研究方案 | | contentVersion | int | 版本号,重新生成时递增 | | promptUsed | text | 使用的Prompt(便于复现和调试) | | userEditedContent | text | 用户编辑后的内容(可选) | | wordFileKey | string | 导出的Word文件在OSS中的Key | ### 3.4 protocol_exports (导出记录表) ```prisma /// Protocol导出记录表 model ProtocolExport { id String @id @default(uuid()) contextId String @map("context_id") userId String @map("user_id") exportType String @map("export_type") exportVersion Int @map("export_version") fileKey String? @map("file_key") status String @default("pending") errorMessage String? @map("error_message") createdAt DateTime @default(now()) @map("created_at") completedAt DateTime? @map("completed_at") @@index([contextId]) @@index([userId, createdAt]) @@map("protocol_exports") @@schema("protocol_schema") } ``` --- ## 四、knowledge_schema - 知识库表 (Phase 2) ### 4.1 knowledge_docs (知识文档表) ```prisma /// 专家知识文档表 model KnowledgeDoc { id String @id @default(uuid()) agentId String? @map("agent_id") docType String @map("doc_type") title String description String? @db.Text content String @db.Text source String? author String? publishDate DateTime? @map("publish_date") tags String[] status String @default("active") isPublic Boolean @default(true) @map("is_public") createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") chunks KnowledgeChunk[] @relation("DocChunks") @@index([agentId, docType]) @@index([status, isPublic]) @@map("knowledge_docs") @@schema("knowledge_schema") } ``` ### 4.2 knowledge_chunks (知识块表) ```prisma /// 知识块表(用于RAG检索) model KnowledgeChunk { id String @id @default(uuid()) docId String @map("doc_id") chunkIndex Int @map("chunk_index") content String @db.Text contentHash String @map("content_hash") metadata Json? @db.JsonB createdAt DateTime @default(now()) @map("created_at") doc KnowledgeDoc @relation("DocChunks", fields: [docId], references: [id], onDelete: Cascade) embedding KnowledgeEmbedding? @relation("ChunkEmbedding") @@unique([docId, chunkIndex]) @@index([contentHash]) @@map("knowledge_chunks") @@schema("knowledge_schema") } ``` ### 4.3 knowledge_embeddings (向量嵌入表) ```prisma /// 向量嵌入表(pgvector) model KnowledgeEmbedding { id String @id @default(uuid()) chunkId String @unique @map("chunk_id") embedding Unsupported("vector(1536)") embeddingModel String @map("embedding_model") createdAt DateTime @default(now()) @map("created_at") chunk KnowledgeChunk @relation("ChunkEmbedding", fields: [chunkId], references: [id], onDelete: Cascade) @@map("knowledge_embeddings") @@schema("knowledge_schema") } ``` --- ## 五、数据库迁移计划 ### 5.1 迁移步骤 ```bash # 1. 创建新Schema CREATE SCHEMA IF NOT EXISTS agent_schema; CREATE SCHEMA IF NOT EXISTS protocol_schema; CREATE SCHEMA IF NOT EXISTS knowledge_schema; # 2. 更新Prisma schema.prisma中的schemas配置 schemas = ["...", "agent_schema", "protocol_schema", "knowledge_schema"] # 3. 生成迁移 npx prisma migrate dev --name add_agent_framework # 4. 应用迁移 npx prisma migrate deploy ``` ### 5.2 初始数据 ```sql -- 插入Protocol Agent配置 INSERT INTO agent_schema.agent_configs ( id, agent_id, agent_name, base_system_prompt, memory_strategy, max_history_turns, default_model, is_active ) VALUES ( gen_random_uuid(), 'protocol_agent', '研究方案制定助手', '你是一位经验丰富的临床研究方法学专家,正在帮助研究者制定研究方案...', 'full', 20, 'deepseek-v3', true ); -- 插入阶段配置(示例:科学问题阶段) INSERT INTO agent_schema.agent_stages ( id, agent_config_id, stage_id, stage_name, stage_order, instruction, extraction_schema, next_stage_id, transition_mode ) VALUES ( gen_random_uuid(), (SELECT id FROM agent_schema.agent_configs WHERE agent_id = 'protocol_agent'), 'scientific_question', '科学问题澄清', 1, '引导用户明确研究的核心科学问题...', '{"type": "object", "properties": {...}}', 'pico', 'user_confirm' ); ``` --- ## 六、ER关系图 ``` agent_schema ┌───────────────────┐ │ AgentConfig │ │ (agent_configs) │ └────────┬──────────┘ │ ┌────┴────┬─────────────┐ │ │ │ ▼ ▼ ▼ ┌─────────┐ ┌─────────┐ ┌─────────────┐ │AgentStage│ │AgentTool│ │ReflexionRule│ └────┬────┘ └─────────┘ └─────────────┘ │ ▼ ┌─────────────┐ │ ActionCard │ └─────────────┘ ┌─────────────┐ ┌─────────────┐ │AgentSession │ ───────→│ AgentTrace │ └─────────────┘ └─────────────┘ │ │ conversationId ▼ aia_schema ┌─────────────┐ ┌─────────────┐ │Conversation │────────<│ Message │ └─────────────┘ └─────────────┘ protocol_schema ┌─────────────────┐ ┌─────────────────┐ │ProtocolContext │────<│ProtocolVersion │ └─────────────────┘ └─────────────────┘ ```