Files
AIclinicalresearch/docs/03-业务模块/IIT Manager Agent/04-开发计划/01-数据库设计.md
HaHafeng 0c590854b5 docs(iit): Add IIT Manager Agent V2.9 development plan with multi-agent architecture
Features:
- Add V2.9 enhancements: Cron Skill, User Profiling, Feedback Loop, Multi-Intent Handling
- Create modular development plan documents (database, engines, services, memory, tasks)
- Add V2.5/V2.6/V2.8/V2.9 design documents for architecture evolution
- Add system design white papers and implementation guides

Architecture:
- Dual-Brain Architecture (SOP + ReAct engines)
- Three-layer memory system (Flow Log, Hot Memory, History Book)
- ProfilerService for personalized responses
- SchedulerService with Cron Skill support

Also includes:
- Frontend nginx config updates
- Backend test scripts for WeChat signature
- Database backup files

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 22:33:26 +08:00

437 lines
12 KiB
Markdown
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.
# 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 // 核心配置 JSONSOP 流程图)
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 2SOP 执行与记忆表
### 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 5ReAct 追踪表
### 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