# AI→行动闭环设计规格 > 日期: 2026-05-01 | 状态: 讨论完成,待实施 > 模块: erp-ai + erp-workflow + erp-health ## 1. 背景与动机 erp-ai Phase 1 MVP 已完成 4 种分析类型(化验单解读、趋势分析、体检方案、报告摘要),支持 Claude SSE 流式输出和自动分析调度器。但 AI 分析结果目前仅是文字——没有创建随访计划、没有预约复查、没有跟踪建议是否被执行。 本设计目标是建立**AI→行动闭环**:让 AI 建议自动转化为可执行的行动,追踪执行效果,形成数据采集→AI 解读→行动→评估→再调整的完整循环。 ## 2. 核心决策 | 决策点 | 选择 | 原因 | |--------|------|------| | 行动类型 | 随访计划 + 智能预约 + 风险预警 | 覆盖主要医患互动场景;用药调整涉及处方权暂不纳入 | | 自动化程度 | 分级(低→自动 / 中→医生审批+超时 / 高→必须确认) | 平衡效率与医疗安全 | | 输出结构 | 双通道(可读文本 + 结构化 JSON) | 人机各取所需 | | 架构模式 | Workflow 引擎编排(BPMN) | 利用现有 erp-workflow,流程可视化+审批关卡+审计轨迹 | | 风险判定 | AI 判定 + 可配置阈值 | 智能判定+租户自定义灵活覆盖 | | 效果评估 | 前后对比分析 | 随访后再分析,对比 baseline 指标快照 | ## 3. 双通道输出 Schema ### 3.1 响应结构 AI 分析响应从纯文本升级为双通道: ```json { "analysis_id": "uuid", "patient_id": "uuid", "text_content": "张三的收缩压在过去 90 天呈上升趋势...", "structured_output": { "risk_level": "medium", "risk_factors": ["收缩压连续7天>140", "心率变异性下降15%"], "suggestions": [ { "id": "uuid", "type": "followup", "priority": 1, "timing": "14天内", "reason": "收缩压趋势异常,需要监测用药效果", "params": { "followup_type": "血压监测", "metrics": ["systolic_bp", "diastolic_bp", "heart_rate"], "interval_days": 14 }, "auto_executable": false } ], "baseline_summary": { "analysis_date": "2026-05-01", "key_metrics": { "systolic_bp": {"value": 148, "trend": "rising"}, "diastolic_bp": {"value": 92, "trend": "stable"}, "heart_rate": {"value": 88, "trend": "rising"} } } } } ``` ### 3.2 字段说明 - `text_content`: 保留现有能力,给医生/患者阅读的文本分析 - `risk_level`: `low` / `medium` / `high`,由 AI 基于临床阈值判定 - `suggestions[]`: 建议数组,每个含 `type`(followup/appointment/alert)、`priority`、`timing`、`params`、`auto_executable` - `baseline_summary`: 分析时的指标快照,用于闭环前后对比 ### 3.3 安全与访问控制 - `structured_output` 存储前必须经过 PII 脱敏(复用现有 `SanitizationService`),`baseline_summary` 不包含患者姓名、身份证号等 PII - `ai_suggestion` 表的 `params` 和 `action_result` JSONB 字段存储前需 AES-256-GCM 加密(复用项目已有 KEK/DEK 模式) - 建议查询 API 必须带 `tenant_id` 过滤 + 权限校验(`ai.suggestion.list` / `ai.suggestion.manage`) - `auto_executable` 由 `risk_level` 决定:`low` = true,`medium`/`high` = false。AI 不可覆盖此规则 ### 3.4 边界情况 - **空建议列表**:AI 未生成任何建议时,不创建工作流实例,记录日志,不通知医生(正常行为) - **所有建议参数不完整**:等同于空建议,降级为纯文本,触发 `ai.suggestion.parse_failed` 事件通知医生 - **闭环对比无变化**:生成"指标稳定"对比报告,不触发新一轮建议流程 ## 4. BPMN 流程定义 > **前置条件**:Phase 2 启动前,需审计 erp-workflow 的 BPMN 功能覆盖度。本流程依赖排他网关(条件分支)、定时器边界事件(超时升级)、用户任务(医生审批)。如审计发现能力缺失,MVP 回退为 erp-health 中的直接服务层编排(Action Registry 模式),不依赖 BPMN。 ### 4.1 通用流程骨架 ``` [AI分析完成] → [风险分级网关] │ ┌─────────┼─────────┐ ↓ ↓ ↓ 低风险 中风险 高风险 │ │ │ ↓ ↓ ↓ [自动执行] [创建待办] [紧急通知] │ ↓ ↓ │ [医生审批] [医生确认] │ ↓ ↓ ↓ │ [批准][拒绝] [确认][拒绝] │ ↓ ↓ ↓ ↓ │ [执行][记录] [执行][记录] ↓ ↓ ↓ [执行完成] ←←←←←←←←←← ↓ [等待随访/复查完成] ↓ [触发再分析] ↓ [生成对比报告] ``` ### 4.2 三个流程变体 **随访流程** (`ai_followup_workflow`): - 自动创建随访计划 + 关联 AI 建议来源 - 医生可修改随访时间/内容后再确认 - 随访到期 → 提醒患者记录体征 → 提醒医生查看 **预约流程** (`ai_appointment_workflow`): - AI 推荐科室 + 时间段(基于排班数据) - 患者收到推送,一键确认或选择其他时段 - 预约前 24h 自动提醒 **预警流程** (`ai_alert_workflow`): - 低风险 → 直接发送(患者 + 医生双通道) - 中风险 → 推送给医生,24h 未读升级 - 高风险 → 即时推送 + 仪表盘标红 + 超时升级到科室主任 ### 4.3 超时与升级策略 | 等级 | 医生响应时限 | 超时动作 | |------|-------------|---------| | 低 | 不需要审批 | — | | 中 | 24 小时 | 自动提醒 + 标记待跟进 | | 高 | 4 小时 | 升级到上级医生 + 通知科室 | ### 4.4 闭环触发 - 随访完成 → 提取随访期间新数据 → 对比 baseline_summary → 生成对比报告 - 趋势好转 → 记录有效 + 降低后续监测频率 - 趋势恶化 → 触发新一轮建议流程(可能升级风险等级) ## 5. 事件流与模块集成 ### 5.1 核心事件链 ``` erp-ai erp-workflow erp-health │ │ │ │ ai.analysis.completed │ │ │──────────────────────────→│ │ │ (payload: structured_ │ │ │ output + risk_level) │ │ │ │ │ │ [风险分级网关] │ │ │ │ │ │ workflow.ai_action.created│ │ │──────────────────────────→│ │ │ (创建待办/随访/预警) │ │ │ │ │ │ [执行行动] │ │ │ │ │ health.ai_action.executed │ │ │←──────────────────────────│ │ │ │ │ [等待随访完成] │ │ │ │ │ ai.reanalysis.requested │ │ │←──────────────────────────│ │ │ │ │ │ [前后对比分析] │ │ │ │ │ │ ai.analysis.completed │ │ │──────────────────────────→│ │ │ (新一轮,带 baseline) │ [对比报告] ``` ### 5.2 新增事件 | 事件 | 发布方 | 消费方 | Payload | |------|--------|--------|---------| | `ai.analysis.completed` | erp-ai | erp-workflow | 已有,扩展 payload 含 structured_output | | `ai.reanalysis.requested` | erp-workflow | erp-ai | `{analysis_id, followup_id, trigger}` | | `workflow.ai_action.created` | erp-workflow | erp-health | `{workflow_id, suggestion_type, params, risk_level}` | | `health.ai_action.executed` | erp-health | erp-workflow | `{action_id, action_type, result}` | | `ai.suggestion.parse_failed` | erp-ai | erp-message | `{analysis_id, patient_id, error}` — 通知医生手动查看 | ### 5.3 数据库扩展 **`ai_suggestion` 表**(erp-ai crate): | 字段 | 类型 | 说明 | |------|------|------| | id | UUID v7 | 主键 | | tenant_id | UUID | 租户 | | analysis_id | UUID | 关联分析记录 | | suggestion_type | ENUM | followup / appointment / alert | | risk_level | ENUM | low / medium / high(对应 Rust `RiskLevel` 枚举) | | params | JSONB | 建议参数(AES-256-GCM 加密存储) | | status | ENUM | pending/approved/rejected/executed/expired/parse_failed(对应 Rust `SuggestionStatus` 枚举) | | workflow_instance_id | UUID | 关联工作流实例 | | action_result | JSONB | 执行结果(AES-256-GCM 加密存储) | | baseline_snapshot | JSONB | AI 分析时的指标快照 | | reanalysis_id | UUID | 闭环后再分析的 ID | | 标准审计字段 | — | created_at, updated_at, created_by, updated_by, version, deleted_at | **`ai_risk_threshold` 表**(erp-ai crate): | 字段 | 类型 | 说明 | |------|------|------| | id | UUID v7 | 主键 | | tenant_id | UUID | 租户 | | metric_name | VARCHAR | 指标名(systolic_bp 等) | | low_threshold | JSONB | 低风险阈值范围 | | medium_threshold | JSONB | 中风险阈值范围 | | high_threshold | JSONB | 高风险阈值范围 | | 标准审计字段 | — | 同上 | 全局默认阈值通过 `config.toml` 配置文件加载(`[ai.risk_thresholds]` section),不使用 `tenant_id = null` 的数据库行。租户级覆盖通过此表按 `tenant_id` 查询,查询优先级:租户配置 > 全局默认。 ### 5.4 Rust 类型定义 新增枚举(与现有 `AnalysisType` 并列,位于 `crates/erp-ai/src/dto.rs`): ```rust enum SuggestionType { Followup, Appointment, Alert } enum RiskLevel { Low, Medium, High } enum SuggestionStatus { Pending, Approved, Rejected, Executed, Expired, ParseFailed } ``` ## 6. Prompt 工程与降级 ### 6.1 Prompt 模板改造 现有模板从"纯文本输出"改为"双通道输出": ``` system: "你是健康趋势分析专家。请同时输出两部分: 1. PATIENT_TEXT:给患者/医生的文字解读 2. STRUCTURED_JSON:系统用的结构化建议 风险等级判定规则: - low: 所有指标在正常范围内,仅有轻微波动 - medium: 有1-2个指标超出正常范围 - high: 多个指标严重异常,需要紧急干预 可执行建议类型:followup / appointment / alert 输出格式: ===PATIENT_TEXT=== (可读文本) ===STRUCTURED_JSON=== (JSON)" user: "{{data}} 参考阈值:{{risk_thresholds}}" ``` ### 6.2 输出解析流程 ``` AI 响应 → 分割(===PATIENT_TEXT=== / ===STRUCTURED_JSON===) ↓ JSON 解析 → Schema 校验(字段完整性、类型正确性) ↓ ┌─ 校验通过 → 存储双通道输出 → 触发 ai.analysis.completed │ └─ 校验失败 → 降级为纯文本分析 suggestion_status = "parse_failed" 触发 ai.suggestion.parse_failed 事件 → erp-message 消费,通知医生手动查看 ``` ### 6.3 降级策略 | 场景 | 降级行为 | |------|---------| | JSON 解析失败 | 保留文本,不触发自动化,通知医生手动查看 | | 风险等级缺失 | 默认 medium(需要医生确认) | | 建议参数不完整 | 只执行有完整参数的建议 | | AI Provider 不可用 | 使用本地规则引擎(预定义临床规则) | ### 6.4 本地规则引擎 当 AI Provider 不可用时,预设临床规则直接生成结构化建议: ```rust struct LocalRule { metric: String, // "systolic_bp" operator: CompareOp, // GreaterThan threshold: f64, // 160.0 risk_level: RiskLevel, // High suggestion_type: SuggestionType, // Alert message_template: String, // "收缩压异常偏高({value}mmHg),请立即就医" } ``` 匹配到的规则直接生成结构化建议,走相同的 Workflow 流程。 ## 7. 前端展示 ### 7.1 Web 管理端 - AI 分析详情页增加「建议面板」:显示结构化建议列表、风险等级标签、执行状态 - 医生工作台增加「AI 待办」区域:中/高风险建议等待审批,显示倒计时 - 随访详情页增加「AI 闭环」标签:显示前后对比报告 ### 7.2 小程序患者端 - 健康页面增加「AI 建议卡片」:显示最新建议摘要和风险等级 - 预约页面增加「AI 推荐时段」:标记 AI 建议的预约时间段 - 消息页面增加「风险预警」通知类型 ## 8. 实施分期建议 | Phase | 内容 | 预计周期 | |-------|------|---------| | Phase 1 | 双通道输出 Schema + Prompt 改造 + 解析校验 + `ai_suggestion` 表 | 1-2 周 | | Phase 2 | BPMN 流程定义 + 事件集成 + `ai_risk_threshold` 表 + 前端建议面板 | 2 周 | | Phase 3 | 闭环对比分析 + 本地规则引擎 + 超时升级 + 前端闭环标签 | 2 周 | | Phase 4 | 前端完整体验(医生工作台 + 小程序卡片)+ 配额管控集成 | 1-2 周 |