- T40 UI 审计计划和结果文档(docs/qa/) - wiki 更新:miniprogram 设计系统合规审计记录 + index 关键数字更新 - 审计 V2 完整报告(docs/audits/v2/) - 讨论记录文档(docs/discussions/) - 设计规格和实施计划(docs/superpowers/) - 角色测试计划和结果(docs/qa/role-test-*) - Docker 生产部署配置
42 KiB
HMS Copilot 基因化设计规格
日期: 2026-05-11 | 状态: Draft | 分支: feat/media-library-banner 讨论来源: 2026-05-11 发散式互动探讨
§1 愿景与定位
1.1 问题陈述
当前 erp-ai 模块是一个独立的 AI 分析工具,覆盖 3 个场景(化验单解读、趋势分析、报告摘要),用户需要主动点击"AI 分析"按钮才能触发。AI 与系统的关系是"附加工具"——不用它,系统照常运转。
这带来三个问题:
- 医护端:被动发现 — 医护需要主动查数据、看报告才能发现异常。高风险患者的风险信号淹没在数据海洋中,依赖医护的经验和注意力。
- 患者端:沟通空白 — 血透机构无互联网医院资质,医生不能在线与患者对话产生诊断行为。患者离院后的疑问、不适、焦虑没有合规渠道可以解答。
- 系统层面: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 设计原则
- Copilot 不替人做决定 — 只建议,医护审批。患者端不诊断,只引导。
- 规则保底,LLM 拓展 — 规则引擎保证确定性和可解释性,LLM 提供超越规则的洞察。规则是下限,LLM 是上限。
- 合规第一 — 患者端所有 AI 输出必须经过合规审查引擎。宁可过度保守,不可越界。
- 渐进式渗透 — 从一个触点(风险画像)开始,逐步扩展到全系统。不追求一步到位。
§2 架构总览
2.1 分层架构
┌─────────────────────────────────────────────────────────────────┐
│ │
│ 前端呈现层 │
│ ├─ 医护端:<CopilotCard /> <CopilotBadge /> <CopilotAlert /> │
│ └─ 患者端:对话式 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 字段中。
// 示例:收缩压连续 >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 推荐面板
生成逻辑:
- 规则引擎匹配患者疾病类型 → 基础随访模板(如 CKD 4 期标准随访方案)
- 规则引擎叠加风险因素 → 调整频率和关注指标
- LLM 补充 → 基于近期数据生成个性化问诊要点
输出内容:
- 推荐随访频率(如"每 2 周 1 次")及理由
- 关注指标列表(如"肾功能、电解质、甲状旁腺激素")
- 建议问诊要点(如"近期是否有恶心、食欲下降、尿量变化")
医护可选择"采纳全部"、"选择性采纳"或"不采纳"。
3.4 触点④:在线咨询实时辅助(执行层)
触发时机: 医护进入咨询对话时
呈现方式: 对话界面侧边栏的 Copilot 面板,不侵入对话区域
生成逻辑:
- 加载患者风险画像(触点①的预计算结果)
- 实时分析患者消息内容
- 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 中列出的标准违规关键词。后续版本可通过管理后台动态管理词表。
{
"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 — 规则配置
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 — 洞察存储
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 — 风险评分快照
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 — 对话审查日志
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 天 | 积分经济平衡 |