feat(iit): Implement event-level QC architecture V3.1 with dynamic rule filtering, report deduplication and AI intent enhancement

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-02-08 21:22:11 +08:00
parent 45c7b32dbb
commit 7a299e8562
51 changed files with 10638 additions and 184 deletions

View File

@@ -0,0 +1,72 @@
# **CRA Agent 业务逻辑与执行架构书**
**文档目的:** 基于用户定义的 5 大规则体系,构建标准化的 CRA 智能监查工作流。
**适用版本:** IIT Manager Agent V2.9.1
**创建日期:** 2026-02-07
## **🏛️ 一、 规则体系定义 (The 5 Pillars)**
我们将规则分为两类引擎执行,以平衡成本与智能。
| 编号 | 规则类型 | 执行引擎 | 来源方式 | 典型示例 |
| :---- | :---- | :---- | :---- | :---- |
| **1** | **变量质控** | **Hard Engine** (代码) | 自动从 Metadata 同步 | 空值检查、数值范围 (0\<BMI\<50)、逻辑跳转 |
| **2** | **入排标准** | **AI Engine** (LLM) | AI 解析 Protocol \+ 人工确认 | 确诊时间 \< 3个月、实验室指标符合入组线 |
| **3** | **方案偏离 (PD)** | **Hybrid** (混合) | 人工配置逻辑 | 访视超窗 (Date2 \- Date1 \> 28+3)、禁用药物使用 |
| **4** | **AE 事件** | **AI Engine** (LLM) | 预置医学 Prompt | Lab 异常值 vs AE 记录一致性检查 (SAE Reconciliation) |
| **5** | **伦理合规** | **Hard Engine** (代码) | 预置逻辑 | 知情同意书签署日期 \> 访视 1 日期 |
## **🔄 二、 智能监查工作流 (The Workflow)**
### **Step 1: 触发与范围界定 (Trigger)**
* **触发源**
* **自动触发**Webhook (REDCap 数据录入) 或 Cron (每日凌晨)。
* **人工触发**:用户点击“立即监查”。
* **范围优化**:使用 **增量检查 (Incremental Check)**。只对新录入或变更的数据及其相关联规则进行检查。
### **Step 2: 漏斗式质控执行 (Funnel Execution)**
为每个受试者执行以下管道:
1. **Level 1: 阻断性检查 (Blocking)**
* 检查伦理 (ICF) 和 关键变量缺失。
* *如果 Fail*:直接标记为 Critical**中止后续 AI 检查**(省钱)。
2. **Level 2: 基础清洗 (Cleaning)**
* 运行所有变量质控规则 (Hard Rules)。
* 生成基础错误日志。
3. **Level 3: AI 深度监查 (AI Reasoning)**
* 组装 Context (XML+Markdown)。
* 调用 LLM 检查 入排、PD、AE。
* **输出证据链**{ "status": "FAIL", "reason": "...", "evidence": { "var": "alt", "val": 150 } }
### **Step 3: 结果汇总 (Aggregation)**
更新 iit\_qc\_project\_stats 和 iit\_record\_summary 表。
* 生成 **风险热力图 (Risk Heatmap)** 数据源。
### **Step 4: 双模报告输出 (Dual-Mode Reporting)**
* **Mode A: 人类阅读版 (Interactive UI)**
* 热力图 \+ 诊断卡片。
* 支持 **“确认/忽略”** 操作 (Query Loop)。
* **Mode B: LLM 阅读版 (Context Protocol)**
* XML 结构化数据,包含统计摘要 \+ 严重问题清单 \+ 证据链。
### **Step 5: 智能问答 (Q\&A Loop)**
* 用户提问 \-\> ContextBuilder 提取 Mode B 报告 \-\> LLM 回答。
* *场景*:“帮我列出所有疑似未报 AE 的患者。”
## **💡 三、 关键增强点**
1. **SDV 边界声明**:明确系统仅进行“逻辑一致性监查”,无法核对原始病历真伪。
2. **人机回环 (HITL)**:所有 AI 生成的复杂规则(入排/PD必须经过人工 **"Review & Activate"** 才能生效。
3. **三态管理**:质控结果包含 Pending (AI 疑似), Confirmed (人工确认), Ignored (人工忽略)。
## **✅ 结论**
该方案逻辑闭环,技术可行。通过引入 **漏斗执行****人机回环**,可有效解决成本与准确性问题。

View File

@@ -0,0 +1,200 @@
# **基于 Skills 的 CRA 规则配置实施指南**
**文档目的:** 定义如何通过 iit\_skills 表配置化实现 CRA 的 5 大核心工作变量质控、入排、PD、AE、伦理
**适用版本:** IIT Manager Agent V2.9.1
**创建日期:** 2026-02-07
## **🏗️ 核心概念Skill \= 规则容器**
在我们的架构中,**Skill (技能)** 是一个可执行的最小业务单元。它定义了:
1. **触发条件**:什么时候跑?(Webhook/Cron)
2. **执行引擎**:用哪个引擎跑?(Hard/Soft)
3. **配置数据**:具体规则是什么?(JSON/Prompt)
4. **数据依赖**:需要哪些数据?(Tags)
### **数据库模型映射 (iit\_skills)**
我们复用并扩展 V2.6 计划中的 iit\_skills 表设计:
model IitSkill {
id String @id @default(uuid())
projectId String @map("project\_id")
name String // e.g., "入排标准核查"
type String // 'HARD\_RULE' | 'LLM\_CHECK' | 'HYBRID'
// 触发配置
triggerType String @map("trigger\_type") // 'WEBHOOK' | 'CRON' | 'MANUAL'
cronExpr String? @map("cron\_expr") // 如果是定时任务
// 核心配置 (JSONB)
// 包含Prompts, JSONLogic, Thresholds
config Json
// 数据依赖 (智能路由用)
// 告诉 ContextBuilder 需要加载哪些 Tag
requiredTags String\[\] @map("required\_tags") // e.g., \['\#lab', '\#demographics'\]
isEnabled Boolean @default(true)
createdAt DateTime @default(now())
@@map("iit\_skills")
@@schema("iit\_schema")
}
## **🛠️ 五大规则的 Skill 实现方案**
我们通过配置不同类型的 Skill 来覆盖 CRA 的所有工作。
### **1\. 变量质控 Skill (Type: HARD\_RULE)**
**对应需求:** 针对每个变量,构建数据质控规则。
* **场景**:空值检查、数值范围、逻辑跳转。
* **配置来源**Rule Studio (Layer 1\) 自动生成。
* **Config 结构**
{
"engine": "HardRuleEngine",
"rules": \[
{ "field": "age", "op": "between", "args": \[18, 80\] },
{ "field": "bmi", "op": "lt", "args": \[50\] }
\]
}
* **执行**Node.js 直接计算,毫秒级响应。
### **2\. 入排标准 Skill (Type: LLM\_CHECK)**
**对应需求:** 针对是否符合入排标准,建立医学逻辑规则。
* **场景**:复杂的医学判断(如:病理确诊时间 \< 3个月
* **配置来源**Rule Studio (Layer 3\) AI 提取 \+ 人工确认。
* **数据依赖**\['\#demographics', '\#lab', '\#history'\]
* **Config 结构**
{
"engine": "SoftRuleEngine",
"model": "deepseek-v3",
"system\_prompt": "你是一个医学监查员...",
"checks": \[
{
"id": "I-03",
"desc": "肝肾功能正常 (ALT/AST \< 2.5 ULN)",
"prompt\_template": "基于以下实验室数据 {{\#lab}},判断..."
}
\]
}
### **3\. 方案偏离 Skill (Type: HYBRID)**
**对应需求:** 针对是否出现方案偏离,建立核查规则。
* **场景**:访视超窗、漏做检查。
* **配置来源**Rule Studio (Layer 2\) 逻辑构建器。
* **Config 结构**
{
"engine": "HybridEngine",
"logic": {
"if": \[
{ "date\_diff": \["$V2.date", "$V1.date"\] },
{ "\>": 31 }, // 28 \+ 3
"FAIL",
"PASS"
\]
}
}
### **4\. AE 监测 Skill (Type: LLM\_CHECK)**
**对应需求:** 针对是否出现 AE 事件,建立核查规则。
* **场景**SAE ReconciliationLab 异常 vs AE 记录)。
* **数据依赖**\['\#lab', '\#ae'\]
* **Config 结构**
{
"engine": "SoftRuleEngine",
"task": "AE\_RECONCILIATION",
"prompt": "对比 \<lab\_data\> 中的 Grade 3+ 异常值与 \<ae\_data\> 记录,找出未报告的 AE。"
}
### **5\. 伦理合规 Skill (Type: HARD\_RULE)**
**对应需求:** 针对是否出现伦理问题,建立规则。
* **场景**ICF 日期逻辑。
* **Config 结构**
{
"engine": "HardRuleEngine",
"rule": {
"op": "date\_before",
"a": "$icf\_date",
"b": "$first\_visit\_date"
},
"severity": "CRITICAL"
}
## **⏰ 三大触发时机详解 (Trigger Strategy)**
我们将质控规则的执行时机划分为“实时、定时、人工”黄金三角,以平衡时效性与成本。
### **1\. 🟢 实时触发 (Real-time / Webhook)**
* **触发源**REDCap DET (Data Entry Trigger)。CRC 保存任意表单时触发。
* **执行范围****单点切片 (Micro-Batch)**。
* 仅针对 **当前受试者 (Current Record)**
* 仅加载 **与当前表单相关** 的 Skill (通过 formName 过滤)。
* *例如:录入“血常规”单,系统只检查 \#lab 相关规则,不会检查人口学。*
* **核心价值****阻断错误**。在 CRC 记忆犹新时(秒级)推送企微提醒,纠正成本最低。
* **成本策略**:默认优先跑 **Hard Rules**。涉及核心安全指标(如 AE时才触发 Soft Rules (LLM)。
### **2\. 🔵 定时触发 (Scheduled / Cron)**
* **触发源**pg-boss Cron Job。每日凌晨 (e.g., 02:00) 执行。
* **执行范围****全量扫描 (Full Scan)**。
* 针对 **所有活跃受试者**
* 重点运行 **跨表逻辑** (如一致性检查) 和 **时间敏感型规则** (如访视超窗 PD)。
* **核心价值****发现隐患**。捕捉“因时间流逝而产生的问题”(如昨天未超窗,今天超窗)和“漏录问题”。
* **成本策略**:使用 **增量标记**。若数据 Hash 未变且无时间规则,跳过 LLM 检查。
### **3\. 🟠 人工触发 (Manual / On-Demand)**
* **触发源**:管理端 "一键全量质控" 或 "单受试者重跑" 按钮。
* **执行范围****按需全量**。
* 针对选定的受试者范围。
* 运行 **所有启用** 的 Skill。
* **核心价值****合规审计与验证**。用于项目初始化清洗、规则调整后的验证、或上级核查前的自查。
## **🔄 调度与执行Skill Runner**
我们不需要为每个规则写死代码,而是实现一个通用的 **SkillRunner**
### **执行流程**
1. **触发 (Trigger)**
* Webhook 收到数据 \-\> 触发 SkillRunner.runByTrigger('WEBHOOK', projectId, recordId, formName)
* Cron Job 到点 \-\> 触发 SkillRunner.runByTrigger('CRON', projectId)
* 人工点击 \-\> 触发 SkillRunner.runByTrigger('MANUAL', projectId)
2. **加载 (Load)**
* Runner 从 iit\_skills 表加载所有启用的 Skill。
* **过滤**:如果是 WEBHOOK 触发,仅加载与当前 formName 关联的 Skill。
3. **路由 (Route)**
* 根据 Skill 的 type 分发给对应的 Engine (HardRuleEngine 或 SoftRuleEngine)。
4. **上下文构建 (Context)**
* 如果需要 LLM调用 ContextBuilder传入 Skill 定义的 requiredTags只拉取相关数据。
5. **结果聚合 (Aggregate)**
* 收集所有 Skill 的执行结果,存入 iit\_qc\_logs。
## **✅ 结论:对当前计划的影响**
你的 **V2.6 开发计划** 非常稳健,只需要在细节上明确 Skill 的定义即可。
**建议调整:**
1. **Phase 1**:重点设计 iit\_skills 的 JSON Schema确保它能容纳上述 5 种类型的配置。
2. **Phase 2**:实现 SkillRunner作为连接 SOP 和 Engine 的中间件。
**总结**:通过 SKILLS 配置化,你的系统就像一个\*\*“可插拔的乐高玩具”\*\*。
* 如果明天要加一个“肿瘤评估 (RECIST)”规则,你只需要新增一个 Skill完全不用改后端代码。
* 这正是 SaaS 化产品的核心竞争力。