# HMS Copilot 基因化设计规格 > 日期: 2026-05-11 | 状态: Draft | 分支: feat/media-library-banner > 讨论来源: 2026-05-11 发散式互动探讨 --- ## §1 愿景与定位 ### 1.1 问题陈述 当前 erp-ai 模块是一个独立的 AI 分析工具,覆盖 3 个场景(化验单解读、趋势分析、报告摘要),用户需要主动点击"AI 分析"按钮才能触发。AI 与系统的关系是"附加工具"——不用它,系统照常运转。 这带来三个问题: 1. **医护端:被动发现** — 医护需要主动查数据、看报告才能发现异常。高风险患者的风险信号淹没在数据海洋中,依赖医护的经验和注意力。 2. **患者端:沟通空白** — 血透机构无互联网医院资质,医生不能在线与患者对话产生诊断行为。患者离院后的疑问、不适、焦虑没有合规渠道可以解答。 3. **系统层面:AI 价值未被释放** — AI 只在用户主动触发时才工作,99% 的运行时间处于闲置状态,但它本可以持续观察数据、发现模式、生成洞察。 ### 1.2 Copilot 定义 Copilot 将 AI 从"工具"转变为"基因"——一个始终在场、主动观察、适时建议的智能层。 它不是系统的一个器官,而是弥漫在每个交互点的基础能力。就像免疫系统不是一个独立的器官,而是无处不在的防御能力。 **Copilot 不是什么:** - 不是自动决策系统——它不替医护做决定 - 不是诊断工具——它不做医疗诊断 - 不是聊天机器人——它有深度上下文感知能力 - 不是 erp-ai 的替代品——它是 erp-ai 的进化形态 **Copilot 是什么:** - 一个"永远醒着的观察者"——持续监控数据变化 - 一个"适时开口的顾问"——在关键时刻主动提供建议 - 一个"合规的沟通桥梁"——在法律允许范围内连接医护和患者 - 一个"越用越了解你的助手"——基于患者数据提供个性化洞察 ### 1.3 核心价值主张 **医护端:从"查数据发现问题"到"被推送需要关注的风险"** | 现在 | Copilot 之后 | |------|-------------| | 医护每天花 30 分钟逐个查看患者数据 | Copilot 自动筛选高风险患者,推送到仪表盘 | | 异常数据依赖医护经验发现 | 规则引擎 + LLM 自动检测异常并分级告警 | | 随访计划从空白模板开始写 | Copilot 基于风险画像推荐个性化随访方案 | | 咨询时需要手动翻看患者历史 | Copilot 侧边栏实时展示背景和追问建议 | **患者端:合规替代医患在线沟通** 血透机构的核心痛点:想服务好患者、想提高随访率、想增加到院量,但没有互联网医院资质,医生不能在线"看病"。 Copilot 以"AI 健康管家"身份填补这一空白: - 解答患者疑问(在合规边界内) - 提供健康科普和个性化数据解读 - 引导需要关注的症状到院就医 - 驱动患者日常互动(每日问候、健康打卡、积分激励) ### 1.4 业务驱动力 **合规痛点是 Copilot 患者端存在的根本理由:** 血透机构没有互联网医院资质,意味着: - 医生不能在线与患者进行问诊对话 - 不能在线给出诊断或治疗建议 - 不能在线开具处方 但患者离院后确有大量沟通需求:用药疑问、不适咨询、复查提醒、心理支持。这些需求目前没有合规渠道可以满足。 Copilot 作为 AI 客服/管家: - 不做诊断、不开处方、不给治疗建议 - 在合规边界内解答患者疑问 - 智能识别需要就医的情况并引导到院 - 所有输出经过合规审查引擎自动检查 这不仅是功能创新,是解决了一个真实的合规痛点。 ### 1.5 设计原则 1. **Copilot 不替人做决定** — 只建议,医护审批。患者端不诊断,只引导。 2. **规则保底,LLM 拓展** — 规则引擎保证确定性和可解释性,LLM 提供超越规则的洞察。规则是下限,LLM 是上限。 3. **合规第一** — 患者端所有 AI 输出必须经过合规审查引擎。宁可过度保守,不可越界。 4. **渐进式渗透** — 从一个触点(风险画像)开始,逐步扩展到全系统。不追求一步到位。 --- ## §2 架构总览 ### 2.1 分层架构 ``` ┌─────────────────────────────────────────────────────────────────┐ │ │ │ 前端呈现层 │ │ ├─ 医护端: │ │ └─ 患者端:对话式 UI(嵌入小程序消息体系) │ │ │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ Copilot API 层 │ │ ├─ GET /copilot/insights — 获取预计算洞察 │ │ ├─ POST /copilot/chat — 患者端对话(经合规审查) │ │ └─ GET /copilot/patients/{id}/risk — 获取风险评分 │ │ │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ Copilot 引擎层 │ │ ├─ 混合评分引擎(规则引擎 + LLM 补充) │ │ ├─ 意图识别引擎(患者端对话分类) │ │ ├─ 合规审查引擎(关键词 + 语义双层) │ │ └─ 洞察调度器(决定何时/如何生成洞察) │ │ │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ 数据层 │ │ ├─ copilot_insights — 预计算洞察存储(带过期时间) │ │ ├─ copilot_risk_snapshots — 患者风险评分快照 │ │ ├─ copilot_chat_logs — 患者端对话审查日志(合规审计) │ │ └─ copilot_rules — 规则引擎配置(可动态调整) │ │ │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ 触发层 │ │ ├─ 异步:事件总线订阅 → 后台预计算洞察 │ │ └─ 同步:API 请求时 → 合并预计算结果 + 实时补充 │ │ │ └─────────────────────────────────────────────────────────────────┘ ``` ### 2.2 混合触发模型 洞察通过两种机制产生,互相补充: **异步预计算(后台):** 事件总线上的健康数据变更事件触发 Copilot 后台引擎,异步生成洞察并写入存储。医护在打开页面前,相关洞察已经准备就绪。 | 触发源 | 时机 | 延迟 | 示例 | |--------|------|------|------| | 事件总线订阅 | 数据写入后秒级 | < 5s | 血压录入 → 后台更新风险评分 | | 定时任务 | 每日凌晨 | 批量 | 重新计算所有在管患者风险评分 | | 化验报告确认 | 报告确认后 | < 10s | 肌酐异常 → 生成告警洞察 | **同步实时补充(前端请求时):** 医护或患者打开页面时,前端调用 Copilot API。API 先返回预计算的洞察,再根据当前上下文(如正在查看的页面、当前对话内容)实时补充额外建议。 | 触发源 | 时机 | 延迟 | 示例 | |--------|------|------|------| | 页面加载 | 用户请求时 | < 500ms | 打开患者档案 → 返回风险画像 | | 对话消息 | 患者发消息时 | < 2s | 患者提问 → 意图识别 + 合规审查 + 回复 | | 随访创建 | 医护操作时 | < 1s | 创建随访 → 返回推荐方案 | **合并策略:** API 响应中同时包含 `precomputed`(预计算结果,即时返回)和 `realtime`(实时补充,可能稍慢)。前端先渲染预计算部分,实时部分流式追加。 ### 2.3 与现有 erp-ai 的关系 Copilot 不替换 erp-ai,而是在其上构建。现有 erp-ai 的 AI Provider 抽象(OpenAI / Claude / Qwen / Ollama)、Prompt 模板管理、SSE 流式输出能力完全保留。 ``` erp-ai(保持不变) ├─ AI Provider 抽象(4 个 Provider) ├─ Prompt 模板管理(Handlebars) └─ SSE 流式输出 Copilot 引擎层(新增,调用 erp-ai) ├─ 规则引擎 — 纯 Rust 实现,不依赖 AI Provider ├─ LLM 补充分析 — 调用 erp-ai 的 Provider 能力 ├─ 合规审查 — 调用 erp-ai 的 Provider 能力 └─ 意图识别 — 调用 erp-ai 的 Provider 能力 ``` **分层依赖关系:** - 规则引擎:完全离线可用,不依赖任何 AI Provider - LLM 补充 / 合规审查 / 意图识别:依赖 erp-ai 的 Provider 抽象 - AI Provider 不可用时,Copilot 降级为纯规则模式 ### 2.4 降级策略 当 AI 服务不可用时(Provider 宕机、配额用尽、网络故障),Copilot 分层降级: | 降级级别 | 触发条件 | 影响范围 | 表现 | |----------|---------|---------|------| | 正常 | 所有 Provider 可用 | 全部功能 | 规则 + LLM 混合模式 | | 一级降级 | 主 Provider 不可用,备用可用 | LLM 延迟增加 | 自动切换到备用 Provider | | 二级降级 | 所有 LLM Provider 不可用 | 医护端部分降级 | 规则评分正常,无 LLM 补充;患者端仅回答服务类问题,健康类问题使用安全兜底模板 | | 三级降级 | Copilot 引擎整体不可用 | 全部 Copilot 功能 | 静默降级,系统回到无 Copilot 状态,不阻塞任何业务流程 | **关键设计约束:Copilot 的任何故障都不能阻塞 HMS 核心业务流程。** 患者管理、预约、随访、咨询等功能在 Copilot 完全不可用时必须正常运转。 --- ## §3 医护端 Copilot 医护端 Copilot 不改变现有工作流,而是在每个关键节点"旁边"插入智能建议。医护照常操作,Copilot 在适当的时候主动开口。 4 个触点形成闭环:风险画像(基础)→ 异常检测(感知)→ 随访推荐(决策)→ 咨询辅助(执行)→ 回到异常检测。 ### 3.1 触点①:患者风险画像(基础层) **触发时机:** 医护打开任意患者相关页面时(同步 API 调用 + 预计算数据) **呈现方式:** 患者姓名旁的风险等级徽章 + 可展开的 Copilot 洞察卡片 **评分机制(混合):** Layer 1 — 规则引擎(确定性): - 医疗专家定义规则,存储在 `copilot_rules` 表中 - 每条规则包含:条件表达式、风险分值(+1~+5)、严重度、建议文案 - 规则以 JSON 表达式存储,支持动态加载和机构自定义 - 基础风险分 = 所有匹配规则的分值之和 Layer 2 — LLM 补充分析(拓展性): - 输入:患者近期数据 + 规则评分结果 - 输出:自然语言的补充风险描述、建议、相似病例参考 - 非阻塞:LLM 失败时仅展示规则结果 内置规则覆盖 5 大类: | 类别 | 示例规则 | 分值范围 | |------|---------|---------| | 体征异常 | 收缩压连续>140、体重周增幅>2kg | +1~3 | | 化验异常 | eGFR<60、肌酐环比>20%、血钾>5.5 | +2~5 | | 依从性 | 随访失约>2次、药物依从性<80% | +1~2 | | 透析质量 | Kt/V<1.2、透析间期体重增长>5% | +2~4 | | 综合风险 | 多指标同时异常叠加 | 叠加计算 | 风险等级映射:0-2 低 | 3-5 中 | 6-8 高 | 9-10 危急 **规则条件表达式 Schema(JSONLogic 子集):** 采用 JSONLogic 风格的表达式格式,支持嵌套逻辑组合,存储在 `copilot_rules.condition_expr` 字段中。 ```json // 示例:收缩压连续 >140 { "and": [ { ">=": [{ "var": "vital_signs.systolic.latest" }, 140] }, { ">=": [{ "var": "vital_signs.systolic.prev1" }, 140] }, { ">=": [{ "var": "vital_signs.systolic.prev2" }, 140] } ] } // 示例:eGFR < 60 { "<": [{ "var": "lab_reports.egfr.latest" }, 60] } // 示例:肌酐环比 > 20% { ">": [ { "var": "lab_reports.creatinine.change_pct" }, 20 ] } ``` 支持的数据引用路径: - `vital_signs.{指标}.latest` / `.prev1` / `.prev2` — 最近 3 次体征值 - `lab_reports.{指标}.latest` / `.change_pct` — 最新化验值 / 环比变化百分比 - `follow_up.missed_count` — 随访失约次数 - `dialysis.ktv.latest` — 最新透析充分性指标 - `medication.adherence_rate` — 药物依从性百分比 支持的操作符:`>`, `>=`, `<`, `<=`, `==`, `!=`, `and`, `or`, `!`, `in`, `var` 规则引擎在 Rust 中实现为递归下降的 JSONLogic 解释器,不依赖外部 DSL。 ### 3.2 触点②:健康数据异常检测(感知层) **触发时机:** 新体征/化验数据入库时(异步事件驱动) **呈现方式:** - 实时:医护首页仪表盘的 Copilot 告警卡片 - 推送:浏览器通知(严重异常时) **告警分级:** | 级别 | 条件 | 示例 | 呈现 | |------|------|------|------| | 🔴 危急 | 危及生命或需立即干预 | 血钾>6.0、严重低血压 | 首页置顶 + 浏览器通知 | | 🟡 警告 | 需要关注,非紧急 | 收缩压>160、肌酐环比>30% | 首页告警列表 | | 🟢 提示 | 轻度异常或趋势变化 | 体重周增幅>1.5kg、血压趋势上升 | 患者档案内洞察卡片 | **与现有告警系统的关系:** 当前 HMS 已有 `health.alerts` 模块。Copilot 异常检测不替代,而是增强: - 现有告警:基于固定阈值的简单规则(血压>140) - Copilot 告警:基于趋势 + 上下文的智能判断(血压从130快速升到150比稳定在145更值得关注) 两者共存。固定阈值走现有系统,趋势/上下文异常走 Copilot。 ### 3.3 触点③:随访计划智能推荐(决策层) **触发时机:** 医护为患者创建或编辑随访计划时 **呈现方式:** 随访表单右侧的 Copilot 推荐面板 **生成逻辑:** 1. 规则引擎匹配患者疾病类型 → 基础随访模板(如 CKD 4 期标准随访方案) 2. 规则引擎叠加风险因素 → 调整频率和关注指标 3. LLM 补充 → 基于近期数据生成个性化问诊要点 **输出内容:** - 推荐随访频率(如"每 2 周 1 次")及理由 - 关注指标列表(如"肾功能、电解质、甲状旁腺激素") - 建议问诊要点(如"近期是否有恶心、食欲下降、尿量变化") 医护可选择"采纳全部"、"选择性采纳"或"不采纳"。 ### 3.4 触点④:在线咨询实时辅助(执行层) **触发时机:** 医护进入咨询对话时 **呈现方式:** 对话界面侧边栏的 Copilot 面板,不侵入对话区域 **生成逻辑:** 1. 加载患者风险画像(触点①的预计算结果) 2. 实时分析患者消息内容 3. LLM 生成:建议追问方向 + 注意事项提醒 + 过敏/禁忌提示 **输出内容:** - 患者背景摘要(诊断、透析方案、上次关键指标) - 建议追问方向(如"浮肿是双侧还是单侧?") - 注意事项(如"该患者对 XX 药物过敏") 医护可选择"一键插入"追问问题到回复框。 ### 3.5 数据流闭环 ``` ① 风险画像(基础层) │ 输出:风险评分 + 规则匹配结果 + LLM 补充 ▼ ② 异常检测(感知层)← 新数据入库事件触发 │ 输出:分级告警 + 异常指标 ▼ ③ 随访推荐(决策层)← 风险评分 + 异常指标输入 │ 输出:随访方案建议 + 关注指标 + 问诊要点 ▼ ④ 咨询辅助(执行层)← 患者档案 + 对话内容输入 │ 输出:追问建议 + 注意事项 + 过敏提醒 │ └─→ 产生新的健康数据/咨询记录 → 回到 ② ``` 每个触点的输出是下一个触点的输入。数据在闭环中越转越丰富,Copilot 的建议也越来越精准。 --- ## §4 患者端 Copilot ### 4.1 角色定位与行为边界 患者端 Copilot 以"小H 健康管家"的身份存在,是血透机构无互联网医院资质下的合规医患沟通桥梁。 **角色:** AI 客服 + 健康管家,嵌入小程序消息体系 **行为边界:** | 可以做 | 不可以做 | |--------|---------| | 解释化验单指标含义(科普) | 诊断疾病("你得了XX") | | 生活方式建议(饮食、运动) | 开处方("吃XX药") | | 预约引导、流程咨询 | 预测疗效("吃了会好") | | 健康数据通俗解读 | 替代医生评估 | | 紧急情况引导就医 | 推荐特定治疗方案 | | 基于数据的关怀提醒 | 承诺治疗结果 | ### 4.2 产品形态:对话式嵌入消息体系 "小H"作为小程序内的一个"联系人"出现在消息列表中,患者可以像微信聊天一样互动。 **与 erp-message 模块的关系:** 小H 对话**不复用** erp-message 的消息系统。erp-message 管理的是医护之间的通知消息,而小H 对话是 AI 驱动的实时交互,两者的数据模型、推送机制、存储需求完全不同。小H 对话使用独立的 `copilot_chat_logs` 表存储。 **消息列表集成方式:** - 小程序 TabBar 中的"咨询"标签(现有)中新增"小H 健康管家"入口卡片 - 点击进入独立的 Copilot 对话页面(新页面,不属于现有消息列表) - 不修改现有消息 TabBar 的结构和功能 **微信服务号模板消息推送:** 透析日提醒、复查提醒等需要通过微信服务号模板消息推送。这需要: - 机构在微信公众平台注册并认证服务号 - 申请模板消息权限并创建所需模板 - 后端集成微信模板消息 API 此功能作为 Phase 4 后期可选增强,不影响核心对话功能。Phase 4 MVP 仅实现小程序内对话。 交互入口: - "咨询"Tab 中的"小H 健康管家"卡片 → 对话窗口 - 首页 AI 问候卡片 → 点击进入对话 - 各健康数据页面的"问小H"按钮 → 带上下文进入对话 ### 4.3 意图识别引擎 患者消息先过 LLM 意图分类,再路由到不同处理逻辑。5 种意图类型,按优先级排序: | 优先级 | 意图类型 | 示例 | 处理方式 | 合规要求 | |--------|---------|------|---------|---------| | 1 | 紧急情况 | "我胸痛"、"喘不上气"、"出血不止" | 优先响应 + 强制引导就医 + 通知医护 | 必须包含"请立即就医或拨打120" | | 2 | 健康咨询 | "头晕是不是血压高了"、"这个指标什么意思" | 科普式回答 + 基于患者数据的个性化解读 | 禁止诊断性语言,必须附"建议到院评估" | | 3 | 服务咨询 | "怎么预约"、"透析时间"、"收费多少" | 规则库直接匹配回答 | 无特殊合规要求 | | 4 | 情感关怀 | "我不想透析了"、"好累啊"、"谢谢小H" | 共情回应 + 自然过渡到健康话题 | 不做健康承诺 | | 5 | 闲聊 | "今天天气怎么样"、"你好" | 友好回应 + 巧妙关联健康 | 保持角色一致性 | **分类策略:** 单次 LLM 调用完成分类(低 token 消耗的快速分类 prompt),延迟 < 500ms。分类结果缓存到对话上下文中,连续同类消息可跳过重复分类。 ### 4.4 对话上下文管理 每次对话自动注入患者上下文,使"小H"真正"认识"患者: ``` 上下文结构(后端自动组装,前端不可篡改): { "patient": { "name": "张三", "age": 62, "diagnosis": "CKD 4期", "dialysis_schedule": "每周二、四、六 下午", "allergies": ["青霉素"], "medications": ["硝苯地平", "碳酸氢钠"] }, "recent_data": { "last_bp": "135/85", "last_weight": "68.5kg", "last_dialysis": "2026-05-09", "next_dialysis": "2026-05-13", "next_checkup": "2026-05-15" }, "risk_summary": { "score": 7, "level": "中高", "top_risks": ["eGFR快速下降", "血压趋势上升"] }, "conversation_summary": "最近5轮对话摘要..." } ``` **设计约束:** - 上下文由后端自动组装,前端不可篡改 - 对话历史保留最近 5 轮摘要(控制 token 消耗) - 敏感字段(详细诊断、具体用药剂量)不注入患者端上下文,只在医护端可见 - 上下文随每次请求刷新,确保数据时效性 ### 4.5 引导到院策略 "引导到院"不是生硬的"请去医院",而是基于上下文的自然引导。通过规则 + LLM 配合实现: **规则驱动引导(确定性):** - 患者提到任何身体不适 → 触发引导 - 患者问药物相关问题 → 触发引导 - 患者数据持续异常(后台检测)→ 主动推送提醒 - 患者表达消极情绪("不想来了")→ 共情 + 正面引导 **引导话术模板(可配置):** - 症状类 → "XX可能有多种原因,建议让医生当面评估。要不要帮您预约?" - 用药类 → "用药调整需要医生评估。我帮您看看最近有没有门诊?" - 消极类 → "理解您可能有些疲惫。规律透析很重要,要不看看有没有更方便的时间段?" --- ## §5 合规审查引擎 ### 5.1 双层审查架构 患者端 Copilot 的每一条 AI 输出都必须经过合规审查。审查不通过则自动修正,不阻断对话流程。 **Layer 1 — 关键词过滤(规则层,< 5ms):** 使用 Aho-Corasick 多模式字符串匹配(精确子串匹配),扫描预定义的违规词表。不使用正则表达式——Aho-Corasick 只做子串匹配,不支持模式,因此违规词表需列举具体词组而非模式。 | 扫描维度 | 违规关键词(示例,非穷举) | 严重度 | |---------|---------|--------| | 诊断类 | "确诊为"、"诊断为"、"你得了"、"诊断结果是" | CRITICAL | | 处方类 | "建议你吃"、"开点"、"处方"、"调整药量" | CRITICAL | | 疗效类 | "吃了会好"、"可以治愈"、"保证能好" | HIGH | | 评估类 | "我判断"、"我认定" | HIGH | | 承诺类 | "肯定没问题"、"绝对不会出问题" | MEDIUM | | 误导安慰类 | "完全不用担心"、"绝对没事" | MEDIUM | 命中违规 → 标记违规片段 → 进入修正流程。 未命中 → 进入 Layer 2。 **Layer 2 — 语义审查(LLM 层,< 200ms):** 通过低 token 消耗的快速分类 prompt 进行语义级审查,捕捉绕过关键词的隐性违规: ``` Prompt: "以下AI回复是否存在医疗合规问题? A.无问题 B.含诊断 C.含处方建议 D.含疗效承诺 E.其他违规 只输出字母。" 实现:调用 erp-ai Provider(优先本地 Ollama 降成本) ``` 返回 A → 放行。返回 B/C/D/E → 标记违规类型 → 进入修正流程。 ### 5.2 审查规则配置 合规过滤规则与风险评分规则(§3.1 的 `copilot_rules` 表)是不同的数据结构,使用独立的内存加载方式: - **风险评分规则** → 存储 `copilot_rules` 表(含 condition_expr、score),通过事件驱动执行 - **合规过滤规则** → 使用 Rust 代码内嵌的静态词表 + 可选的 `copilot_compliance_rules` 表(机构自定义扩展词) 机构自定义合规词表在 Phase 4 MVP 中不实现。MVP 使用代码内嵌的固定词表,覆盖 §5.1 中列出的标准违规关键词。后续版本可通过管理后台动态管理词表。 ```json { "rule_id": "no_diagnosis", "category": "diagnosis", "severity": "critical", "keywords": ["确诊为", "诊断为", "你得了", "诊断结果是", "可以确诊"], "replacement_template": "这个情况建议让医生当面评估一下", "auto_fix": true } ``` 内置规则分类:CRITICAL(诊断/处方)→ 自动修正,不可跳过;HIGH(疗效/评估)→ 自动修正;MEDIUM(绝对化/误导)→ LLM 重写。 ### 5.3 修正策略 三级修正,逐级升格: **策略 1 — 模板替换(关键词违规,确定性高):** - 直接用预设安全模板替换违规片段 - 例:"可能是高血压引起的头晕" → "头晕可能有多种原因,建议到院让医生评估" **策略 2 — LLM 重写(语义违规,需理解上下文):** - Prompt:"将以下回复改写为合规版本,移除诊断/处方语言,改为引导到院,保持关怀语气" - 重写后再次过 Layer 1 审查 **策略 3 — 兜底降级(两次修正仍不通过):** - 使用预设安全模板: - "感谢您的提问,这个问题建议您下次来的时候直接跟医生聊聊。要不要我帮您预约?" ### 5.4 降级策略(AI 不可用时) 当 LLM 服务不可用时,合规审查降级为纯规则模式(Layer 1 only): - 仅回答服务咨询类问题(预约、流程、地址等) - 健康类问题统一使用安全兜底模板 - 不尝试生成个性化健康解读 - 对话 UI 显示"小H 暂时只能回答预约和流程类问题,健康问题建议直接咨询医生" ### 5.5 审计追踪 每条患者端对话的审查记录持久化存储到 `copilot_chat_logs` 表: | 字段 | 说明 | |------|------| | user_message | 患者原文 | | intent_classification | 意图分类结果 | | ai_raw_response | AI 原始输出(修正前) | | layer1_result | 关键词审查结果 | | layer2_result | 语义审查结果 | | violations_found | 违规项列表 | | fix_strategy | 修正策略类型 | | final_response | 最终发给患者的文本 | **数据保留策略:** - 审查日志保留 3 年(医疗数据合规要求) - 原始输出与最终输出的对比可用于持续评估审查准确性 - 机构可定期审查 AI 对话是否有违规漏过 --- ## §6 技术设计 ### 6.1 Crate 架构 扩展现有 erp-ai crate,在其内部新增 `copilot/` 子模块。不新建独立 crate。 理由:Copilot 的 AI 调用复用 erp-ai 的 Provider 抽象层,无需重复实现。规则引擎虽不依赖 AI,但作为子模块放在 erp-ai 内部更内聚。如未来 Copilot 发展到需要独立部署,再拆分为微服务。 ``` crates/erp-ai/src/ ├── copilot/ (新增) │ ├── mod.rs — 模块入口 │ ├── engine.rs — 洞察调度器 │ ├── rules.rs — 规则引擎(条件解析 + 评分) │ ├── scoring.rs — 混合评分(规则分 + LLM 补充) │ ├── intent.rs — 患者端意图识别 │ ├── compliance.rs — 合规审查引擎 │ └── context.rs — 对话上下文组装 ├── handler/ (新增) │ ├── insight_handler.rs — 洞察查询 API │ ├── chat_handler.rs — 患者对话 API │ └── risk_handler.rs — 风险评分 API ├── entity/ (新增) │ ├── copilot_insights.rs │ ├── copilot_risk_snapshots.rs │ ├── copilot_chat_logs.rs │ └── copilot_rules.rs ├── service/ (新增) │ ├── insight_service.rs │ ├── risk_service.rs │ ├── chat_service.rs │ └── compliance_service.rs └── event/ (新增) └── copilot_consumer.rs — 订阅 health 模块事件 ``` ### 6.2 数据库设计 4 张新表,均包含标准字段(id, tenant_id, created_at, updated_at, created_by, updated_by, deleted_at, version)。 **跨 crate 外键策略:** copilot_insights 和 copilot_risk_snapshots 中的 `patient_id` 使用逻辑关联(无外键约束),不直接引用 erp-health 的 `patients` 表。理由:根据架构铁律"模块间只通过事件总线和 trait 通信",erp-ai 不应直接依赖 erp-health 的表结构。数据一致性通过事件驱动保证——patient.created 事件触发初始化,patient 数据变更通过事件通知。 **copilot_rules — 规则配置** ```sql CREATE TABLE copilot_rules ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), tenant_id UUID NOT NULL, name VARCHAR(200) NOT NULL, category VARCHAR(50) NOT NULL, -- vital_signs/lab/adherence/dialysis/composite condition_expr JSONB NOT NULL, -- 规则条件表达式 score SMALLINT NOT NULL, -- +1 ~ +5 severity VARCHAR(20) NOT NULL, -- info/warning/critical suggestion TEXT, enabled BOOLEAN DEFAULT true, sort_order INT DEFAULT 0, created_at TIMESTAMPTZ DEFAULT now(), updated_at TIMESTAMPTZ DEFAULT now(), created_by UUID, updated_by UUID, deleted_at TIMESTAMPTZ, version INT DEFAULT 1 ); ``` **copilot_insights — 洞察存储** ```sql CREATE TABLE copilot_insights ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), tenant_id UUID NOT NULL, patient_id UUID NOT NULL, -- 逻辑关联 patients 表,无外键约束(跨 crate) insight_type VARCHAR(50) NOT NULL, -- risk_score/anomaly/follow_up_hint/consult_hint source VARCHAR(20) NOT NULL, -- rule/llm/hybrid severity VARCHAR(20), title VARCHAR(500) NOT NULL, content JSONB NOT NULL, rule_matches JSONB, llm_supplement TEXT, expires_at TIMESTAMPTZ NOT NULL, is_read BOOLEAN DEFAULT false, is_dismissed BOOLEAN DEFAULT false, created_at TIMESTAMPTZ DEFAULT now(), updated_at TIMESTAMPTZ DEFAULT now(), created_by UUID, updated_by UUID, deleted_at TIMESTAMPTZ, version INT DEFAULT 1 ); ``` **copilot_risk_snapshots — 风险评分快照** ```sql CREATE TABLE copilot_risk_snapshots ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), tenant_id UUID NOT NULL, patient_id UUID NOT NULL, -- 逻辑关联 patients 表,无外键约束(跨 crate) risk_score SMALLINT NOT NULL, -- 0-10 risk_level VARCHAR(20) NOT NULL, -- low/medium/high/critical rule_details JSONB NOT NULL, llm_summary TEXT, computed_at TIMESTAMPTZ NOT NULL, data_freshness JSONB, created_at TIMESTAMPTZ DEFAULT now(), updated_at TIMESTAMPTZ DEFAULT now(), created_by UUID, updated_by UUID, deleted_at TIMESTAMPTZ, version INT DEFAULT 1 ); ``` **copilot_chat_logs — 对话审查日志** ```sql CREATE TABLE copilot_chat_logs ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), tenant_id UUID NOT NULL, patient_id UUID NOT NULL, session_id UUID NOT NULL, user_message TEXT NOT NULL, intent_classification VARCHAR(30), ai_raw_response TEXT, layer1_result JSONB, layer2_result JSONB, violations_found JSONB, fix_strategy VARCHAR(30), final_response TEXT NOT NULL, created_at TIMESTAMPTZ DEFAULT now(), updated_at TIMESTAMPTZ DEFAULT now(), created_by UUID, updated_by UUID, deleted_at TIMESTAMPTZ, version INT DEFAULT 1 ); ``` ### 6.3 API 设计 **医护端 API(需 JWT 认证 + 权限码):** | 方法 | 路径 | 权限码 | 说明 | |------|------|--------|------| | GET | `/api/v1/copilot/insights` | copilot.insights.list | 查询洞察列表(支持按患者/类型/严重度过滤) | | GET | `/api/v1/copilot/insights/{id}` | copilot.insights.list | 获取单条洞察详情 | | POST | `/api/v1/copilot/insights/{id}/dismiss` | copilot.insights.manage | 标记洞察已处理/忽略 | | GET | `/api/v1/copilot/patients/{id}/risk` | copilot.risk.view | 获取患者风险画像 | | GET | `/api/v1/copilot/patients/{id}/followup-hint` | copilot.risk.view | 获取随访推荐建议 | | GET | `/api/v1/copilot/patients/{id}/consult-hint` | copilot.risk.view | 获取咨询辅助建议 | | GET | `/api/v1/copilot/rules` | copilot.rules.list | 列出规则 | | POST | `/api/v1/copilot/rules` | copilot.rules.manage | 创建规则 | | PUT | `/api/v1/copilot/rules/{id}` | copilot.rules.manage | 更新规则 | **患者端 API(需患者 JWT):** 患者端与医护端共享同一套 JWT 认证体系(erp-auth)。小程序通过微信登录获取 token(见 `apps/miniprogram/src/services/` 的现有 auth 流程),该 token 包含 `user_id` 和 `tenant_id`。Copilot API 通过 `user_id` 关联 `patients` 表确定患者身份。 `copilot.chat.patient` 权限码在角色初始化时自动赋予"患者"角色(非管理后台角色),无需手动分配。 | 方法 | 路径 | 说明 | |------|------|------| | POST | `/api/v1/copilot/chat` | 发送消息,返回合规审查后的回复 | | GET | `/api/v1/copilot/chat/history` | 获取对话历史(分页) | | GET | `/api/v1/copilot/chat/daily-greeting` | 获取今日个性化问候 | **权限码汇总:** ``` copilot.insights.list — 查看洞察列表 copilot.insights.manage — 处理/忽略洞察 copilot.risk.view — 查看风险画像 copilot.rules.list — 查看规则 copilot.rules.manage — 管理规则 copilot.chat.patient — 患者端对话(患者角色自带) ``` ### 6.4 事件订阅 Copilot 引擎订阅以下 erp-health 模块事件。事件名称已对齐 `crates/erp-health/src/event/mod.rs` 中的实际常量: **已有事件(可直接订阅):** | 事件常量 | 触发动作 | |---------|---------| | `daily_monitoring.created` | 体征数据录入 → 异常检测 + 风险评分刷新 | | `lab_report.reviewed` | 化验报告审核 → 化验异常检测 + 风险评分刷新 | | `follow_up.completed` | 随访完成 → 更新随访依从性 | | `follow_up.overdue` | 随访失约 → 风险评分 +1 + 生成告警 | | `patient.created` | 患者建档 → 初始化风险基线 | **需新增事件(在 erp-health 中添加发布点):** | 事件常量 | 发布时机 | 触发动作 | |---------|---------|---------| | `appointment.completed` | 预约状态变为已完成 | 更新依从性数据 + 风险评分刷新 | 事件消费流程:EventBus 收到事件 → copilot_consumer 匹配事件类型 → 调用规则引擎评估 → 生成/更新洞察 → 写入 copilot_insights → 如有异常告警则通知医护端。 ### 6.5 前端组件设计 **医护端 React 组件(apps/web/src/components/Copilot/):** ``` ├── CopilotBadge.tsx — 风险等级徽章(嵌入患者列表/详情页) ├── CopilotCard.tsx — 洞察卡片(风险画像/异常告警) ├── CopilotAlert.tsx — 告警通知(仪表盘/首页) ├── CopilotPanel.tsx — 侧边栏面板(随访推荐/咨询辅助) ├── CopilotInsightList.tsx — 洞察列表页 └── hooks/ ├── useCopilotInsights.ts — 洞察数据 hook └── useCopilotRisk.ts — 风险评分 hook ``` **患者端小程序组件(apps/miniprogram/src/pages/copilot/):** ``` ├── index.tsx — 对话主页 └── components/ ├── ChatBubble.tsx — 消息气泡 ├── QuickActions.tsx — 快捷入口 └── InputBar.tsx — 输入框 ``` --- ## §7 实施阶段 总体策略:自下而上,每个阶段交付可验证的价值。 ### Phase 0:基础设施(地基) **目标:** 搭建 Copilot 引擎骨架,让它能"跑起来" | 任务 | 产出 | 依赖 | |------|------|------| | 数据库迁移 | 4 个迁移文件(copilot_rules, copilot_insights, copilot_risk_snapshots, copilot_chat_logs) | 无 | | 规则引擎核心 | `copilot/rules.rs` — 条件解析 + 评分计算 | 无 | | 洞察存储 CRUD | `insight_service.rs` — 写入/查询/过期清理 | 迁移文件 | | 风险评分基础框架 | `scoring.rs` — 规则评分逻辑(纯规则,无 LLM) | 规则引擎 | | Copilot API 骨架 | 3 个 handler + 路由注册 | 洞察存储 | | 预置规则种子数据 | 10-15 条内置规则(体征/化验/依从性) | 迁移文件 | **验收标准:** - `cargo check` 通过 - 内置规则对患者数据跑通评分逻辑 - API 可查询风险评分和洞察列表 ### Phase 1:医护端风险画像(第一个可见价值) **目标:** 医护打开患者档案时,能看到 Copilot 风险徽章和洞察卡片 | 任务 | 产出 | 依赖 | |------|------|------| | 事件消费者 | `copilot_consumer.rs` — 订阅体征/化验事件 | Phase 0 | | 风险评分刷新(异步) | 事件触发 → 规则评估 → 写入风险快照 | 事件消费者 | | LLM 补充分析集成 | 规则评分结果 → 调用 erp-ai → LLM 补充洞察 | erp-ai Provider | | 前端 CopilotBadge | 患者列表/详情页风险徽章 | API | | 前端 CopilotCard | 可展开的洞察卡片 | API | | 每日风险快照批量刷新 | 定时任务:凌晨重算所有在管患者 | 评分逻辑 | **验收标准:** - 录入新体征数据后,风险评分自动更新 - 医护端患者详情页显示风险徽章和洞察卡片 - LLM 补充分析正常返回(非阻塞,失败降级为纯规则) ### Phase 2:异常检测 + 告警推送 **目标:** 健康数据入库时自动检测异常,推送告警给医护 | 任务 | 产出 | 依赖 | |------|------|------| | 异常检测规则扩展 | 新增趋势类/复合类规则 | Phase 1 | | 告警洞察生成 | 异常 → 生成洞察 → 推送通知 | 事件消费者 | | 前端 CopilotAlert | 仪表盘告警卡片 + 浏览器通知 | API | | 告警处理工作流 | 标记已处理 / 忽略 / 升级 | API | **验收标准:** - 危急值(如血钾 >6.0)入库后秒级生成告警 - 医护仪表盘显示分级告警列表 - 告警可标记处理状态 ### Phase 3:随访推荐 + 咨询辅助 **目标:** Copilot 在医护创建随访/咨询时提供智能建议 | 任务 | 产出 | 依赖 | |------|------|------| | 随访推荐逻辑 | 基于风险画像 + 疾病模板 → 推荐随访方案 | Phase 1 风险数据 | | 咨询辅助逻辑 | 患者档案 + 对话内容 → 追问建议 | Phase 1 + 对话上下文 | | 前端 CopilotPanel | 随访/咨询页面侧边栏 | API | | 一键采纳/插入 | 医护可将建议直接填入表单 | 前端组件 | **验收标准:** - 创建随访计划时 Copilot 面板显示个性化建议 - 咨询对话时侧边栏显示患者背景和追问建议 - 建议可一键插入到表单/回复框 ### Phase 4:患者端 Copilot(AI 客服/管家) **目标:** 患者小程序内可与小H对话,合规解答、引导到院 | 任务 | 产出 | 依赖 | |------|------|------| | 意图识别引擎 | `intent.rs` — 5 类意图分类 | erp-ai Provider | | 合规审查引擎 | `compliance.rs` — 双层审查 + 自动修正 | 意图识别 | | 对话上下文组装 | `context.rs` — 患者数据 + 对话历史自动注入 | 风险画像数据 | | 对话 API | `chat_handler.rs` — 消息收发 + 审查 | 合规引擎 | | 小程序对话页面 | 聊天 UI + 快捷入口 | API | | 每日问候生成 | 基于患者数据的个性化推送 | 风险画像 + 定时任务 | | 审计日志 | 对话审查记录持久化 | 合规引擎 | **验收标准:** - 患者可发送消息,获得合规审查后的回复 - 诊断性/处方性提问被自动修正为引导到院 - 对话记录完整可审计 - 每日个性化问候正常推送 ### Phase 5:日活引擎(小程序游戏化) **目标:** 积分体系 + AI 问候驱动患者日常互动 | 任务 | 产出 | 依赖 | |------|------|------| | 每日任务系统 | 打卡/录入/阅读任务定义 + 积分规则 | Phase 4 | | 积分经济扩展 | 分层兑换:服务特权 + 实物商品 | 现有积分模块 | | 连续打卡 + 勋章 | streak 追踪 + 成就系统 | 任务系统 | | AI 问候与任务联动 | 问候消息嵌入任务入口 | Phase 4 + 任务系统 | | 小程序首页改版 | 任务入口 + 积分展示 + AI 问候卡片 | 前端 | **验收标准:** - 患者每日可完成健康任务获得积分 - 积分可兑换服务特权/实物商品 - 连续打卡有加成奖励 - AI 问候与当日任务关联 ### 阶段依赖总览 ``` Phase 0(基础设施) │ ▼ Phase 1(风险画像)← 第一个可见价值 │ ├─────────────────┐ ▼ ▼ Phase 2(异常检测) Phase 3(随访/咨询辅助) │ │ └────────┬────────┘ ▼ Phase 4(患者端 Copilot)← 合规 AI 客服 │ ▼ Phase 5(日活引擎)← 游戏化闭环 ``` ### 预估工作量 | 阶段 | 后端 | 前端 | 数据库 | 核心挑战 | |------|------|------|--------|---------| | Phase 0 | 5-7 天 | — | 2 天 | 规则引擎的条件表达式设计 | | Phase 1 | 5-7 天 | 3-5 天 | — | LLM 集成的稳定性与降级 | | Phase 2 | 3-5 天 | 2-3 天 | — | 告警分级与推送策略 | | Phase 3 | 5-7 天 | 3-5 天 | — | 随访模板与疾病类型的映射 | | Phase 4 | 7-10 天 | 5-7 天 | 1 天 | 合规审查的准确性与延迟 | | Phase 5 | 5-7 天 | 5-7 天 | 1 天 | 积分经济平衡 |