# IIT Manager Agent 数据库设计 > **版本:** V2.9 > **更新日期:** 2026-02-05 > **关联文档:** [IIT Manager Agent V2.6 综合开发计划](./IIT%20Manager%20Agent%20V2.6%20综合开发计划.md) > > **V2.9 更新**: > - 扩展 `iit_skills` 表支持 Cron Skill(主动提醒) > - 扩展 `iit_conversation_history` 表增加反馈字段 > - 更新 `iit_project_memory` 内容结构(用户画像) --- ## 1. 数据库表总览 | 表名 | 用途 | Phase | 优先级 | |------|------|-------|--------| | `iit_skills` | Skill 配置存储 | 1 | P0 | | `iit_field_mapping` | 字段名映射字典 | 1 | P0 | | `iit_task_run` | SOP 任务执行记录 | 2 | P0 | | `iit_pending_actions` | 待处理的违规记录 | 2 | P0 | | `iit_conversation_history` | 对话历史(流水账) | 2 | P1 | | `iit_project_memory` | 项目级热记忆(Markdown) | 2 | P1 | | `iit_weekly_reports` | 周报归档(历史书) | 4 | P1 | | `iit_agent_trace` | ReAct 推理轨迹 | 5 | P2 | | `iit_form_templates` | 表单模板(视觉识别) | 6 | 延后 | --- ## 2. Phase 1:基础配置表 ### 2.1 iit_skills - Skill 配置存储 ```prisma model IitSkill { id String @id @default(uuid()) projectId String // 绑定项目 skillType String // qc_process | daily_briefing | general_chat | weekly_report | visit_reminder name String // 技能名称 config Json // 核心配置 JSON(SOP 流程图) isActive Boolean @default(true) version Int @default(1) // V2.9 新增:主动触发能力 triggerType String @default("webhook") // 'webhook' | 'cron' | 'event' cronSchedule String? // Cron 表达式,如 "0 9 * * *" (每天9点) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@unique([projectId, skillType]) @@map("iit_skills") @@schema("iit_schema") } ``` **触发类型说明**: | triggerType | 触发方式 | 示例场景 | |-------------|----------|----------| | `webhook` | 用户消息触发(默认) | 质控任务、问答查询 | | `cron` | 定时触发 | 访视提醒、周报生成 | | `event` | 事件触发(预留) | AE 预警、数据变更通知 | **Skill 配置示例(SOP 流程图)**: ```json { "name": "肺癌研究入组质控", "start_node": "baseline_check", "nodes": { "baseline_check": { "type": "hard_rule", "rules": [ { "field": "age", "logic": { ">=": [{"var":"age"}, 18] }, "message": "年龄<18岁" }, { "field": "age", "logic": { "<=": [{"var":"age"}, 75] }, "message": "年龄>75岁" }, { "field": "ecog", "logic": { "<=": [{"var":"ecog"}, 2] }, "message": "ECOG>2" } ], "on_pass": "history_check", "on_fail": "end_with_violation" }, "history_check": { "type": "soft_instruction", "instruction": "检查既往史,排除间质性肺炎、活动性感染、严重心血管疾病。", "tools": ["read_clinical_data"], "on_pass": "medication_check", "on_fail": "end_review_required" }, "human_review": { "type": "human_review", "description": "需要 CRC 人工复核", "on_approve": "end_success", "on_reject": "end_rejected" } } } ``` **Cron Skill 配置示例(V2.9 新增)**: ```json { "skillType": "visit_reminder", "name": "每日访视提醒", "triggerType": "cron", "cronSchedule": "0 9 * * *", "config": { "start_node": "check_upcoming_visits", "nodes": { "check_upcoming_visits": { "type": "soft_instruction", "instruction": "查询未来 3 天内到期的访视,生成提醒列表", "tools": ["read_clinical_data"], "on_pass": "send_reminder", "on_fail": "end_no_visits" }, "send_reminder": { "type": "soft_instruction", "instruction": "根据用户画像选择合适的通知方式和语气,发送提醒", "tools": ["send_message"], "on_pass": "end_success" } } } } ``` --- ### 2.2 iit_field_mapping - 字段名映射字典 ```prisma model IitFieldMapping { id String @id @default(uuid()) projectId String // 项目级别映射 aliasName String // LLM 可能传的名称(如 "gender", "性别") actualName String // REDCap 实际字段名(如 "sex") createdAt DateTime @default(now()) @@unique([projectId, aliasName]) @@index([projectId]) @@map("iit_field_mapping") @@schema("iit_schema") } ``` **初始化示例**: ```sql INSERT INTO iit_field_mapping (project_id, alias_name, actual_name) VALUES ('project-uuid', 'age', 'age_calculated'), ('project-uuid', '年龄', 'age_calculated'), ('project-uuid', 'ecog', 'ecog_score'), ('project-uuid', '既往史', 'medical_history_text'), ('project-uuid', 'history', 'medical_history_text'), ('project-uuid', '性别', 'sex'), ('project-uuid', 'gender', 'sex'); ``` --- ## 3. Phase 2:SOP 执行与记忆表 ### 3.1 iit_task_run - SOP 任务执行记录 ```prisma model IitTaskRun { id String @id @default(uuid()) projectId String skillId String // 关联的 Skill recordId String? // 关联的患者(如有) triggeredBy String // 触发者 userId status String // RUNNING | SUSPENDED | COMPLETED | FAILED currentNode String? // 当前执行到的节点 trace Json? // 执行轨迹 resumeCallback String? // SUSPENDED 时,恢复后的下一步 rejectCallback String? // SUSPENDED 被拒绝时的下一步 suspendedAt DateTime? resumedAt DateTime? completedAt DateTime? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@index([projectId, status]) @@index([recordId]) @@map("iit_task_run") @@schema("iit_schema") } ``` --- ### 3.2 iit_pending_actions - 待处理的违规记录 ```prisma model IitPendingAction { id String @id @default(uuid()) projectId String taskRunId String // 来源任务 recordId String? // 关联患者 actionType String // violation | warning | review_required field String? // 违规字段 message String // 违规描述 severity String // error | warning | info resolvedBy String? // 处理人 resolvedAt DateTime? resolution String? // 处理结论 createdAt DateTime @default(now()) @@index([projectId, actionType]) @@index([recordId]) @@map("iit_pending_actions") @@schema("iit_schema") } ``` --- ### 3.3 iit_conversation_history - 对话历史(流水账) > **V2.8 设计**:这是原始对话流水,不直接注入 Prompt,只用于生成周报 > > **V2.9 新增**:增加反馈字段,支持用户点赞/点踩 ```prisma model IitConversationHistory { id String @id @default(uuid()) projectId String userId String recordId String? // 关联的患者(如有) role String // user | assistant content String @db.Text intent String? // 识别出的意图类型 entities Json? // 提取的实体 { record_id, visit, ... } // V2.9 新增:反馈循环 feedback String? // 'thumbs_up' | 'thumbs_down' | null feedbackReason String? // 点踩原因:'too_long' | 'inaccurate' | 'unclear' createdAt DateTime @default(now()) @@index([projectId, userId]) @@index([projectId, recordId]) @@index([createdAt]) @@map("iit_conversation_history") @@schema("iit_schema") } ``` --- ### 3.4 iit_project_memory - 项目级热记忆 > **V2.8 核心表**:存储 Markdown 格式的热记忆,每次对话都注入 System Prompt > > **V2.9 扩展**:增加用户画像结构 ```prisma model IitProjectMemory { id String @id @default(uuid()) projectId String @unique content String @db.Text // Markdown 格式的热记忆 lastUpdatedBy String // 'system_daily_job' | 'admin_user_id' | 'profiler_job' createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@map("iit_project_memory") @@schema("iit_schema") } ``` **内容示例(V2.9 增强版)**: ```markdown # 用户画像 (User Profiles) ## 张医生 (user_id: zhangyi) - **角色**: PI - **偏好**: 简洁汇报,只看结论,不要废话 - **关注点**: AE、入组进度 - **最佳通知时间**: 08:30 - **禁令**: 回复不超过 100 字 - **反馈统计**: 👍 12 / 👎 1 ## 王护士 (user_id: wanghushi) - **角色**: CRC - **偏好**: 详细步骤,需要解释 - **关注点**: 访视安排、数据录入 - **最佳通知时间**: 09:00 # 当前状态 (Active Context) - 当前阶段:入组冲刺期 - 重点关注:P005 患者依从性差,需每日提醒 - 本周目标:完成 3 例入组 - P003 SAE 已判定为"可能无关"(2月5日 PI 决策) # 常见问题 (FAQ) - 访视窗口:V1 Day 1±3, V2 Day 28±7 # 系统禁令 (Rules) - 严禁在未授权情况下删除数据 - 写操作必须经过人工确认 ``` --- ## 4. Phase 4:周报归档 ### 4.1 iit_weekly_reports - 周报归档(历史书) > **V2.8 核心表**:存储每周的关键决策、进度、踩坑记录 ```prisma model IitWeeklyReport { id String @id @default(uuid()) projectId String weekNumber Int // 第几周(从项目开始计算) weekStart DateTime // 周起始日期 weekEnd DateTime // 周结束日期 summary String @db.Text // Markdown 格式的周报内容 metrics Json? // 结构化指标 { enrolled: 3, queries: 5, ... } createdBy String // 'system_scheduler' | 'admin_user_id' createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@unique([projectId, weekNumber]) @@index([projectId]) @@map("iit_weekly_reports") @@schema("iit_schema") } ``` **内容示例**: ```markdown ## Week 5 (2026-02-03 ~ 2026-02-09) ### 进度 - 本周新入组:3 例 - 累计入组:15 / 30 例 - 完成率:50% ### 关键决策 - 2026-02-05: PI 会议决定放宽入排标准,允许 ECOG 3 分患者入组 - 2026-02-07: 确认 P003 AE 与研究药物"可能无关" ### 踩坑记录 - 曾尝试自动录入化验单,因 OCR 精度不足失败,已回退为人工复核 ### 待办 - 清理 1 月份遗留的 Query - 准备 2 月底期中分析数据 ``` --- ## 5. Phase 5:ReAct 追踪表 ### 5.1 iit_agent_trace - ReAct 推理轨迹 > 用于调试,不发送给用户,仅在 Admin 后台查看 ```prisma model IitAgentTrace { id String @id @default(uuid()) projectId String userId String query String @db.Text // 用户原始问题 intentType String? // 识别的意图类型 trace Json // ReAct 的完整思考过程 tokenUsage Int? // 消耗的 Token 数 duration Int? // 执行时长(ms) success Boolean createdAt DateTime @default(now()) @@index([projectId, createdAt]) @@index([userId]) @@map("iit_agent_trace") @@schema("iit_schema") } ``` --- ## 6. Phase 6:视觉能力表(延后到 V3.0) ### 6.1 iit_form_templates - 表单模板 ```prisma model IitFormTemplate { id String @id @default(uuid()) projectId String formName String // REDCap 表单名称 fieldSchema Json // 表单字段结构 keywords String[] // 用于匹配的关键词 createdAt DateTime @default(now()) @@map("iit_form_templates") @@schema("iit_schema") } ``` --- ## 7. 数据库迁移命令 ```bash # 生成迁移 npx prisma db push # 生成客户端 npx prisma generate # 查看表结构 npx prisma studio ``` --- ## 8. 索引设计总结 | 表 | 索引 | 用途 | |----|------|------| | `iit_skills` | `[projectId, skillType]` (unique) | 按项目查询 Skill | | `iit_field_mapping` | `[projectId, aliasName]` (unique) | 字段映射查询 | | `iit_task_run` | `[projectId, status]` | 查询运行中/挂起的任务 | | `iit_conversation_history` | `[projectId, userId]` | 按用户查询对话 | | `iit_conversation_history` | `[projectId, recordId]` | 按患者查询对话 | | `iit_conversation_history` | `[createdAt]` | 按时间范围查询 | | `iit_weekly_reports` | `[projectId, weekNumber]` (unique) | 按周查询报告 | | `iit_agent_trace` | `[projectId, createdAt]` | 按时间查询调试日志 | --- **文档维护人**:AI Agent **最后更新**:2026-02-05