概要设计.md 209 KB


doc_id: ODS-202606-001 feature_id: FEAT-202605-001-ai-future-hospital-platform type: outline-design title: 医梦 AI 未来医院中台二期技术方案与三期商业闭环设计 status: approved owner: 医梦研发团队 created_at: 2026-06-03 updated_at: 2026-06-03 reviewers: [] related_docs:

  • PRD-202605-001 related_modules:
  • emoon-openplatform
  • emoon-ai-agent
  • emoon-ai-card
  • emoon-ai-mcp
  • emoon-ai-device
  • emoon-ai-meter
  • emoon-ai-billing tags:
  • AI中台
  • 二期
  • 三期
  • 商业闭环 ---

医梦 AI 未来医院中台二期技术方案与三期商业闭环设计

项目 内容
文档定位 生产级技术方案设计文档
适用范围 医梦 AI 开放平台、Dify 医疗智能体、统一入口客户端、设备注册与适配、卡片交互、MCP/HIS 集成、三期商业闭环
二期主题 OpenPlatform + Dify Workflow + MCP Server + Card Runtime + Terminal Runtime + Device Registry/Adapter
三期主题 能力值预付账户、设备授权、设备维度计量、额度、账单、统计、运营、审计
计费主粒度 项目 / 医院客户;科室、智能体、用户、设备、场景作为分摊与统计维度
版本 v6.3
更新时间 2026-06-03

1. 结论摘要

二期方案的核心方向仍然合理,但需要按照医院最新确认的“AI 未来医院软硬件一体化建设方案”升级边界:开放平台负责统一入口、租户权限、项目授权、用量记录和卡片运行时;Dify 负责智能体编排、会话推理和流程画布;MCP Server 负责把 HIS / EMR / LIS / PACS / 支付 / 叫号 / 床位 / 护理等院内系统封装成标准工具;统一入口客户端负责把导诊屏、自助机、机器人、叫号屏、诊室屏、医生站插件等门诊终端接入同一套中台,住院护理白板和床头屏只通过迪耐克/鸿蒙病房生态做 AI 嵌入。

需要修正的是职责边界:开放平台不能退化成“只渲染 UI”。在生产环境中,开放平台必须掌握合同、额度、计量、账单、审计、风控、卡片实例状态、租户权限和系统可观测性。Dify 可以做流程总控,但不能成为商业账本和医疗安全责任的唯一来源。

医院确认版方案带来的新增结论是:门诊侧由医梦主导整体入口总包,重点不是医梦生产所有硬件,而是控制门诊软硬件入口标准、统一客户端、设备准入、联调验收和持续运营;住院侧不做硬件总包,应收敛为“AI 大脑层”,与迪耐克 / 鸿蒙病房体系互通,医梦负责智能体、IoMT 预警解释、护理任务、病历质控、出院随访等 AI 闭环。

空海医院最新会议进一步把方案主轴从“多设备统一入口”提升为“动线 + 感知”:感知负责识别患者身份、空间位置、业务状态、设备能力和风险约束;动线负责判断患者当前处于就医流程的哪个阶段、下一步该做什么;AI 中台负责把感知结果转成可确认、可审计、可计量的智能体服务;统一入口客户端负责在机器人、自助机、导诊屏、诊室屏等设备前外显这些服务。该主轴不改变“医梦不做全院物联网硬件平台”的边界,反而要求第一期更克制:先做低门槛、可验收的动线节点感知和服务找人闭环。

三期应优先建设商业闭环,而不是继续堆业务场景。原因是公司商业口径已经明确为“能力值包 + 项目实施费 + 综合运营服务费 / 合理不限量服务包”,且新方案增加了设备集成服务费、统一入口客户端授权费、设备运维服务费、鸿蒙服务找人 POC、机器人场景服务费等收费项。当前工程只有 token 级调用日志,尚不能支撑真实合同、设备维度授权、设备用量统计、预扣款、超量控制、分摊对账和运营报告。

关键架构决策速查:

决策 本方案口径 MVP 落地方式
OpenPlatform 控事实,Dify 控编排 权限、卡片状态、审计、计量、账本都归 OpenPlatform;Dify 只做 Workflow 编排 不改造 Dify 内核,只做 DifyAgentEngine、输出校验和版本映射
门诊统一入口优先 门诊导诊屏、自助机、机器人、叫号屏、诊室屏进入医梦统一入口 先接 P0 设备,P1/P2 只进准入清单
住院 AI 大脑层 医梦不接管床头屏、护理白板和 IoMT 硬件,只接收迪耐克/鸿蒙病房体系标准事件 先做护理预警解释和任务闭环,不做病房硬件运维
设备授权和能力值分流 设备授权费覆盖入口运行,高级 AI 能力按合同进入能力值或服务包 通过 charge_policy 避免重复收费
事件可靠性优先 业务成功不能丢审计、不能漏计量、不能重复扣费 Outbox + 幂等键 + 账本不可变流水
服务找人最小化 主动签到只处理诊室门口到达事件,不保存连续轨迹 BLE/NFC/二维码兜底,患者确认后才签到
动线驱动服务 同一设备面向不同用户、不同动线阶段,展示不同智能体、卡片和工具权限 MVP 不新增复杂规则引擎,先用 VisitTimeline + TaskState + DeviceContext + DeviceEvent 推导 journeyState
感知分级落地 身份、空间、业务、设备、风险五类感知分层接入 P0 用扫码/NFC/刷卡/人工确认,P1 才做 BLE 区域感知,P2 才评估星闪/UWB/鸿蒙高精度

1.1 行业参考与本方案取舍

本方案只引用能在公开资料中找到对应实践的设计,且默认按创业公司资源做裁剪。大厂方案可以证明方向,但不能照搬其平台规模。

参考对象 公开资料可验证能力 对本方案的启发 医梦采用方式 明确不照搬
卫宁 WiNEX 公开资料提出“1 个中台 + X 场景化解决方案”,并以业务中台、数据中台、技术中台支撑智慧医院场景 中台应沉淀共性能力,再支撑场景扩展 OpenPlatform、Card、MCP、计量账本作为最小共性底座 不建设完整医院核心业务中台,不替代 HIS/EMR
科大讯飞智医助理 公开资料强调在不改变基层医生现有诊疗过程的基础上提供辅助诊断建议 AI 医疗应嵌入医生工作流,医生保留最终决策权 诊间病历、CDSS、质控、四诊结果均需医生确认 不承诺 AI 自动诊断、自动处方
医惠智慧病房 公开资料显示智慧病房以物联网共性开放平台为基础,统一感知、管控和管理病房数据与设备 住院物联网应由病房/物联平台统一接入,AI 厂商接标准事件 医梦只接收迪耐克/鸿蒙病房网关或医院物联平台标准事件 不直连住院 IoMT 原始设备,不接管病房硬件运维
华为智慧病房/医疗物联网 公开资料强调物联网平台自动采集和处理海量物联数据,支撑病房上层应用 网络、设备接入、协议适配是重资产能力 只把 IoMT 作为事件输入和 AI 解释对象 不自建医疗物联网络和设备接入平台
Dify Workflow 官方文档已有 Chatflow/Workflow 版本控制、发布、历史版本和恢复能力 编排平台已有能力应复用,不重复造轮子 医梦只做 Dify 版本映射、输出校验、配置灰度和回滚指针 不自研完整 Workflow 发布系统
中医四诊仪公开产品 公开产品通常包含舌诊、面诊、脉诊、问诊和多模态采集/AI 分析 四诊仪不是普通屏幕,必须依赖厂商 SDK/API 或专精模型 首期只做舌/面采集、分析结果卡片和医生确认 不自研四诊硬件,不训练全量四诊模型
《个人信息保护法》 医疗健康、行踪轨迹属于敏感个人信息,处理需特定目的、必要性和严格保护措施 服务找人和医疗数据链路必须最小化 主动签到只保留诊室门口到达事件,支持拒绝授权后降级 不保存患者连续轨迹,不做无感自动签到
空海医院会议反馈 信息科主任认可“系统知道患者是谁、设备是谁、当前位置和下一步业务,主动把签到/结算/导航服务外显出来”的价值,同时强调门槛低、先做一个场景、不能假设全院蓝牙/星闪 动线和感知是本项目差异化表达,但必须按低门槛方案起步 第一阶段只做关键节点感知和服务卡片推送,优先老人、特殊人群、诊区签到、缴费/检查提醒 不把电梯控制、全院无感定位、腕带体系作为 P0

参考来源:

资料 链接 本文使用方式
卫宁 WiNEX 发布报道 CHIMA:卫宁健康正式发布新一代医疗健康科技产品 WiNEX 支撑“中台 + 场景化解决方案”的方向,但不照搬三中台规模
科大讯飞智慧医疗 科大讯飞智慧医疗官网 支撑“AI 辅助医生、不改变医生流程”的原则
东软 5G 智慧医院信息平台 东软5G智慧医院信息平台系统 支撑“统一信息平台集成各子系统”的方向,但医梦只做 AI 入口层
医惠智慧病房 医惠科技智慧病房 支撑病房物联网由专业平台统一感知、管控、管理的边界
华为智慧病房 华为智慧病房解决方案 支撑病房物联网络和平台是重资产能力,医梦不自建
Dify 版本控制 Dify Version Control 支撑复用 Dify 自带发布、历史版本、恢复能力
个人信息保护法 中央网信办:中华人民共和国个人信息保护法 支撑医疗健康、行踪轨迹敏感信息和最小化处理要求
四诊仪公开产品资料 本足智能中医四诊仪高校装备展四诊仪资料 支撑四诊仪多模态采集和厂商 SDK/API 优先策略

1.2 创业公司可执行性分级

以下分级用于约束研发排期。没有进入 MVP 的能力,不允许在第一期以“顺手做一下”的名义扩张。

能力 难度 核心难点 MVP 做法 延后条件
AgentEngine + DifyAdapter 旧引擎迁移、SSE 解析、输出不稳定 复用现有 DifyApiClient,先支持文本 + 单卡片 多模型路由、复杂降级后置
Card Runtime 状态机、幂等、卡片快照、动作回传 只做内置医疗卡片,不开放第三方卡片生态 沙箱、插件市场后置
MCP/HIS Adapter 医院接口差异、写操作幂等、网络和厂商联调 先做科室/医生/排班查询 + 锁号/挂号 Mock,再接真实写操作 多医院通用 Adapter 后置
Device Registry 设备身份、心跳、位置、版本、准入 只管门诊 P0 设备;住院只记映射 P1/P2 设备批量接入后置
Terminal Runtime 多端兼容、扫码/读卡/打印/语音 Bridge、现场升级 首期 Web/H5 + Android WebView 壳,优先导诊屏/自助机/诊室屏 Electron/Harmony 原生能力后置
Scene Orchestrator 场景规则容易复杂化 先做设备到默认场景、默认智能体、UI 模板的静态绑定 动态位置/时间/用户状态规则后置
Journey Context 业务状态来自 HIS/叫号/卡片动作/设备事件,容易变成复杂状态机 P0 不独立建服务,先在 OpenPlatform 里用任务状态和设备事件生成 journeyState 全院患者动线引擎、复杂路径优化后置
Perception Event 中高 身份绑定、近场准确率、授权、误触发、安全合规 P0 只接扫码/NFC/刷卡/人工确认和诊室门口事件 连续轨迹、全院定位、自动化触发后置
服务找人 POC 近场准确率、授权、误触发、叫号/HIS 联动 诊室门口小屏 + BLE/NFC/二维码兜底,只做主动签到 全院定位、路线推送后置
IoMT Event Hub 病房设备边界、事件标准化、护理闭环 只接迪耐克/鸿蒙病房网关标准预警事件 原始体征流、复杂风险模型后置
四诊仪 专用硬件、图像质量、厂商算法、医生采纳 舌/面图片采集 + 结果卡片 + 医生确认 脉诊、多厂商统一后置
三期计量账本 中高 事件归并、幂等、账本一致性、合同规则 ai_meter_event + ai_credit_ledger,先项目主账户 科室硬预算、区域分账后置
运营看板 指标口径、数据质量、设备/业务归因 先做项目、设备、智能体、场景的基础统计 区域驾驶舱、毛利模型后置

1.3 MVP 红线

  1. 第一阶段只做门诊 P0 设备和一个可演示闭环,不做全院设备平台。
  2. 住院只接标准事件,不碰原始设备认证、采集网关和硬件运维。
  3. Dify 只做编排和版本映射,不自研 Workflow 平台。
  4. 四诊仪只集成厂商能力,不自研硬件和模型。
  5. 计量先按项目主账户真实扣费,科室和设备先做统计分摊。
  6. 所有医疗高风险输出必须有医生或患者确认,不做自动诊断、自动处方、自动签到、自动缴费。
  7. 每个上线场景必须有可回放样例:请求、响应、数据库记录、traceId、计量事件、人工确认记录。

1.4 统一入口客户端补充设计采纳结论

本节采纳 docs/initiatives/FEAT-202606-001-unified-entry-client/详细设计.md 的边界,但按创业公司 MVP 做收敛:统一入口客户端后端能力进入 AI 中台统一工程,前端和移动端另起 emoon-terminal-client 工程,不新增一套 Demo 后端。

结论 正式方案口径 MVP 落地
后端归属 Device Registry、Scene Profile、AgentRouter、TaskStateService、Card Runtime、File Service、HisMockAdapter、TongueDiagnosisAdapter 都归 AI 中台模块 复用 OpenPlatform 对外入口和 Maven 多模块工程,不新建独立终端后端
前端归属 机器人、自助机、导诊屏三端进入独立 emoon-terminal-client 工程 后端只提供 OpenAPI、场景配置、卡片 schema 和设备命令协议
P0 业务链路 机器人导诊导航、自助机建档/分诊/挂号 Mock/舌诊、导诊屏 FAQ/科室介绍/路线/轻分诊 每条链路必须能回放 conversationId、taskId、cardInstanceId、traceId
TaskStateService 任务状态是 AI 中台内部状态,不作为第一期公共 /tasks API 暴露 任务状态通过 /agent/chat/stream/conversations/*/cards/* 返回给终端
AgentRouter 先按设备能力、场景、任务状态和少量规则路由,再少量使用 LLM 意图分类兜底 不在第一期建设复杂规则引擎和在线学习系统
舌诊接入 前端只上传文件和执行卡片动作,后端通过 TongueDiagnosisAdapter 调专精能力 不允许前端直连舌诊底层接口,不把 base64 图片塞进 Dify
HIS 接入 无真实 HIS 前必须显式使用 HisMockAdapter Mock 数据只用于 POC,不得冒充真实支付、真实挂号或真实医保
终端接口白名单 终端只调用设备、SSE 对话、文件、卡片、事件、命令轮询等 P0 接口 终端不得直连 Dify、HIS Tool、计量写接口和舌诊底层接口

该取舍与行业实践一致:东软类智慧医院平台强调统一信息平台集成各子系统,华为/医惠类病房方案强调物联平台统一接入设备,Dify 官方已提供 Workflow 版本能力。医梦作为创业团队,应只做 AI 入口层、卡片闭环、设备场景治理和必要适配,不复制大厂完整医院平台和物联网底座。

1.5 空海会议新增主轴:动线 + 感知

空海会议中甲方真正感兴趣的不是“多接几个设备”,而是设备能理解患者当前处于哪条就医动线、应该外显哪个服务。产品表达应统一为:

医梦 AI 未来医院不是简单接入智能设备,而是通过统一入口客户端和 AI 中台,把患者身份、当前位置、业务状态和设备能力统一感知起来,再基于患者全流程动线主动推送下一步服务,实现“患者少找路、少找窗口、少找设备,医院服务主动找人”。

感知模型分为五类,P0 只做能低成本验证的部分:

感知类型 含义 P0 落地 不做
身份感知 知道当前服务对象是谁 扫码、刷卡、NFC、患者确认后绑定 patientId/visitId/deviceId/terminalSessionId 无授权人脸识别、长期腕带绑定
空间感知 知道患者在哪个服务区域 设备位置 + 诊室门口扫码/NFC/BLE 区域事件 全院连续轨迹、高精度室内定位
业务状态感知 知道患者就医流程状态 HIS/叫号/卡片动作返回:已挂号、待签到、候诊、待缴费、待检查、报告已出 跨系统大数据画像
设备状态感知 知道当前设备能提供什么服务 Device Registry 返回设备能力、场景、允许卡片和允许智能体 未准入设备进入核心业务
风险感知 知道哪些动作必须确认或人工接管 高风险卡片 confirm=true,特殊人群优先提示,失败转人工 自动签到、自动缴费、自动诊断

动线模型不是大型流程引擎,MVP 只做可解释的状态推导:

VisitTimeline + TaskState + DeviceContext + DeviceEvent + CardAction
→ JourneyContext
→ Scene Orchestrator / AgentRouter
→ 智能体、卡片、设备命令
→ 用户确认
→ 状态回写

第一期只实现 4 个可验收动线节点:

动线节点 触发条件 外显服务 验收方式
到院/到诊区 患者扫码/NFC/刷卡或诊区近场事件 建档、签到、候诊提醒 能产生 journeyState=WAITING_CHECKIN/WAITING_CALL
就诊后待缴费 HIS 或 Mock 返回缴费/处置单状态 缴费提醒、窗口/自助机引导 前端展示待办卡片,用户确认后跳转或转人工
待检查/检验 医嘱/检查单状态 + 设备位置 检查导航、注意事项 机器人/屏幕能生成导航命令或路线卡
报告已出/诊后 报告状态或就诊结束状态 报告解读卡、诊后小结/随访提醒 只展示辅助解释,不自动给诊断结论

同一台设备必须按用户和动线阶段动态裁剪能力。例如诊室门口屏对普通患者只展示签到、候诊、缴费提醒;对医护人员可展示队列管理和人工接管;对未授权访客只展示公共导诊和科室介绍。这个差异通过 sceneProfile + userContext + 服务端 journeyState + allowedAgents/allowedCards 决定,前端不得自行放开能力。

1.5.1 SceneOrchestrator 与 AgentRouter 边界

SceneOrchestratorAgentRouter 都使用上下文,但职责不同,不能混成一个“大路由器”。

组件 决策层级 输入 输出 调用时机
SceneOrchestrator 设备/场景级 deviceId/deviceType、设备状态、用户身份、服务端 journeyState、项目配置 homeTemplateallowedAgentsallowedCardsblockedIntentsperceptionCapabilitiesjourneyPolicy GET /devices/{deviceId}/scene;每次 /agent/chat/stream 前复核
AgentRouter 对话/任务级 用户输入、TaskState、等待卡片、服务端 journeyStateallowedAgents/blockedIntents 具体 agentId、任务类型、是否创建卡片或设备命令 每次 /agent/chat/stream 内部执行

调用顺序固定为:

Device Registry / SceneOrchestrator
→ 服务端 JourneyContext 推导
→ AgentRouter 在 allowedAgents 范围内路由
→ Dify / Direct / Mock
→ Card Runtime / Device Command

禁止反向依赖:AgentRouter 不得绕过 SceneOrchestrator 放开设备不允许的智能体;前端不得用本地配置覆盖 allowedAgents/allowedCards

1.5.2 感知能力配置与安全模型

perceptionCapabilitiesjourneyPolicy 不是终端自声明字段。MVP 阶段配置来源如下:

配置 来源 维护人 P0 实现
perceptionCapabilities Device Registry 设备能力配置 医梦运维 / 项目交付 管理后台或 SQL 种子配置,终端只读取
journeyPolicy 设备场景绑定配置 医梦运维 / 项目交付 MVP_STATIC,控制是否展示动线区和服务找人入口
allowedAgents/allowedCards 设备场景白名单 医梦运维 / 项目交付 后端强制校验,前端只渲染
身份绑定策略 项目授权和患者确认策略 医院信息科 / 医梦交付 绑定、解绑、过期、拒绝授权降级

感知事件安全链路:

风险 P0 防护
伪造设备事件 只有已注册、已激活、归属当前项目的设备可调用事件接口;请求必须通过 HMAC/Bearer 鉴权
重放事件 eventId + deviceId + projectId 幂等,服务端校验时间窗口和 nonce/signature
伪造动线阶段 客户端请求不得传 journeyState;即使通过扩展字段伪造,服务端也完全忽略
近场误触发 NEARBY_DETECTED 只作为感知事实,必须结合身份授权、HIS/叫号状态和患者确认后才生成卡片
安全校验失败 降级为 L0 扫码、NFC、人工确认,不自动执行业务动作

1.5.3 P0 动线验收标准

P0 验收采用 Given-When-Then,避免“到诊区”“服务找人”等概念不可测试。

场景 Given When Then
到诊区主动签到 患者已挂号,设备已激活并绑定诊区,患者已授权身份绑定 患者在诊室门口屏刷卡/NFC 或扫描签到二维码 SSE 返回 journey_updated.stageCode=WAITING_CHECKIN;创建主动签到卡;用户确认后才调用签到工具
候诊提醒 患者已签到,叫号系统返回候诊状态 患者靠近候诊屏或自助机,或主动询问“还要等多久” 返回 journeyState.stageCode=WAITING_CALL;展示候诊提醒卡,不暴露他人队列隐私
就诊后缴费引导 HIS/Mock 返回待缴费或处置状态 患者靠近自助机/导诊屏或发起缴费咨询 返回 journeyState.stageCode=WAITING_PAYMENT;展示缴费引导卡;P0 不做真实支付
待检查导航 HIS/Mock 返回待检查/检验状态,设备具备路线或导航能力 患者在机器人/导诊屏请求检查路线 返回 journeyState.stageCode=WAITING_EXAM;生成路线卡或机器人导航命令
报告已出解释入口 报告状态已出,患者身份授权有效 患者在受控终端请求解读报告 返回报告解读入口卡;文件和报告内容走 File Service;不自动给正式诊断

医护电梯场景拆分处理:普通患者电梯控制不进入 P0/P1;医护授权电梯可作为 P1 可选试点,前提是医院已有电梯控制 API 或物联平台能力。医梦只通过 MCP/Adapter 调用,不改造电梯系统,不把医护电梯作为门诊 MVP 交付前置条件。

1.5.4 运维配置闭环

为支撑交付,管理后台至少需要形成以下配置能力。MVP 可以先用种子数据或内部配置页实现,但必须有明确归属。

配置页面 关键字段 MVP 要求
设备准入审核 deviceId、设备类型、院区/楼层/区域、activateStatus、准入等级 P0 必须能激活/拒绝设备
设备能力配置 capabilitiesperceptionCapabilities、Bridge 能力、厂商信息 P0 可配置扫码/NFC/刷卡/摄像头/导航
场景绑定配置 homeTemplateallowedAgentsallowedCardsblockedIntentsjourneyPolicy P0 必须支持按设备切换场景
身份绑定策略 授权方式、绑定有效期、解绑规则、拒绝授权降级 P0 可用固定项目配置
动线规则配置 stageCode、触发事件、依赖 HIS/Mock 状态、推荐卡片 P0 可硬编码 + 文档化,P1 再后台化
感知事件审计 eventId、设备、区域、事件类型、处理结果、traceId P0 必须可查询和回放

2. 当前工程基线

2.1 后端工程结构

当前仓库基于 RuoYi-Vue-Plus 改造,核心模块如下:

模块 当前职责
emoon-admin 管理后台启动模块,承载系统管理接口
emoon-openplatform 对外开放平台入口,包含签名鉴权、模型调用、Dify API 客户端、二期对话入口
emoon-infra/emoon-modules-api/emoon-system-api 系统领域 API、DO、Mapper、Service 接口,已加入部分 AI 元数据表
emoon-infra/emoon-modules-api/emoon-mcp-api 二期新增 MCP/卡片/会话相关 API,已包含 AgentEngine 抽象与 Mock 引擎
emoon-infra/emoon-modules/emoon-system 管理后台业务实现,已有引擎配置 CRUD
emoon-infra/emoon-modules/emoon-mcp MCP 业务模块雏形,目前仍偏 CRUD 模板
emoon-infra/emoon-modules-api/emoon-knowledge-api 既有知识库、模型、智能体、质控等能力

2.2 已落地的二期能力

能力 当前状态 说明
AgentEngine 抽象 已有 统一 chat / chatStream,支持按 engineType 路由
Mock 引擎 已有 可返回模拟科室卡片,用于开发联调
OpenPlatform 对话入口 已有 /api/v1/agent/chat 支持同步和 SSE
项目签名鉴权 已有 基于 X-Emoon-* 请求头和项目公私钥
会话记录 已有 ai_conversation 记录开放平台会话与外部会话映射
用量日志 初步已有 ai_usage_log 记录 token 与费用字段,但尚不是计费账本
卡片定义 / 实例表 初步已有 已有 DO/Mapper,缺少完整卡片运行时和动作闭环
引擎配置管理 初步已有 管理后台支持引擎配置 CRUD

2.3 尚未完整落地的关键能力

缺口 影响
DifyAgentEngine 未进入统一 AgentEngine 主链路 二期文档描述的 Dify 统一编排尚未真正闭环
MCP Server 工具协议未形成生产工具集 Dify 调 HIS 的工具层仍需实现和治理
卡片动作回传与状态机不足 用户点击卡片后的业务动作、幂等、审计、结果回传无法生产化
ai_usage_log 不能直接计费 token 日志缺少合同、套餐、能力值、冻结、扣减、冲正、对账语义
项目租户边界不完整 当前 OpenPlatform 鉴权中 tenantId 使用默认值,需要与项目/医院绑定
风控、限额、预警、账单缺失 无法支撑能力值包、合理不限量、区域能力池和运营服务

2.4 工程现实修正

当前代码中存在几类历史包袱。它们不一定马上删除,但必须在二期设计中明确归属,否则初级工程师会把新旧链路混在一起。

2.4.1 两套引擎抽象并存

体系 位置 当前用途 处理策略
新体系 AgentEngine emoon-mcp-api/src/main/java/com/emoon/mcp/engine /api/v1/agent/chat 主链路正在使用 作为二期唯一主链路
旧体系 AIEngine/EngineAdapter/ChatFactory emoon-openplatform/src/main/java/com/emoon/openplatform/engine DifyAdapterClient 仍接在旧体系上 标记为 legacy,迁移可复用转换逻辑
Dify HTTP 客户端 emoon-openplatform/dify/DifyApiClient 已封装 Dify REST/SSE 调用 保留复用,接入新 DifyAgentEngine

决策:二期主链路只认 AgentEngineDifyAgentEngine 应复用现有 DifyApiClient 的协议能力,但不要继续把业务入口接在旧 EngineAdapter 体系上。

初级工程师重点:为什么不能同时维护两套引擎入口?
两套入口会导致权限、日志、卡片、计量都走不同路径。线上排障时会出现“同样是 Dify 调用,有的写会话,有的不写;有的计费,有的不计费”。所以必须确定唯一主链路。

2.4.2 旧 /chat/apisse 巨石控制器迁移

ApiSseController 是遗留入口,包含模型路由、RAG、旧 MCP 概念、SSE、音频、提示词占位符等逻辑。它与 /api/v1/agent/chat 新链路并存时,会产生鉴权、日志、计量和卡片体系不一致。

迁移策略:

遗留能力 迁移目标
直连模型调用 DirectLLMAgentEngine
RAG 检索 Dify 知识库节点或独立 RAG Service
音频模型 AudioService,再作为 Agent 能力或 MCP 工具
提示词占位符 PromptTemplateService
旧 SSE 输出 统一到 /api/v1/agent/chat 的 SSE 协议
旧 MCP 流式代理 与 Model Context Protocol 区分,逐步废弃

兼容期内可保留 /chat/apisse,但必须在网关或文档中标记为 legacy,不再新增能力。

2.4.3 AiAgentAiAgentApp 的关系

当前存在两个智能体实体:

实体 所在模块 定位
AiAgent emoon-knowledge-api 产品/知识侧的复杂智能体定义,包含目标、场景、步骤、输入输出、集成、KPI
AiAgentApp emoon-system-api 开放平台对外运行视图,绑定项目、引擎配置、状态和对外 agentId

建议关系:AiAgent 是“设计态 / 产品态”,AiAgentApp 是“运行态 / 开放平台态”。二期主链路读取 AiAgentApp;需要展示业务目标、流程步骤、KPI 时可关联 AiAgent

可选关联字段:

字段 说明
ai_agent_app.agent_ref_id 关联 ai_agent.id
ai_agent_app.agent_ref_version 关联设计态智能体版本
ai_agent_app.scenario_code 运行态计量和报表使用的场景编码

2.4.4 Card Runtime 代码归属

卡片相关表分散在 system-apimcp-api,需要明确服务边界:

服务 建议位置 说明
CardDefinitionService emoon-system 管理卡片定义、版本、灰度、启停
CardInstanceService emoon-mcp-api 接口,emoon-openplatformemoon-mcp 实现 创建实例、保存快照、查询状态
CardActionService emoon-ai-card 实现,动作编排由 emoon-ai-agent 承接 校验动作、幂等、保存快照、更新状态;不得直接绕过 Agent 调 MCP
CardRenderConfigService 前端配合,后端提供定义查询 前端按 UI 配置渲染

二期对话链路中,AgentChatServiceImpl 在收到 cardKey/cardData 后必须触发 CardInstanceService.createFromAgentResponse() 这类能力,不能只把卡片数据透传给前端。

2.4.5 MCP 命名边界

文档中的 MCP 指 Model Context Protocol 工具协议。当前代码中 emoon-mcp 同时承载 AgentEngine、会话、卡片实例等能力,历史 ApiSseController 里的 “MCP” 又像是外部 LLM 代理。为避免混淆,设计上采用以下命名:

名称 含义
Agent Core AgentEngine、会话、卡片实例等智能体核心能力
MCP Tool Server 真正对 Dify 暴露的工具协议服务
Legacy MCP Proxy /chat/apisse 中的外部代理逻辑,迁移后废弃

物理模块可分阶段调整:短期先在文档和包名中区分概念;中期再考虑把真正 MCP 工具拆到 emoon-mcp-server 或等价模块。

2.4.6 Dify 健康检查与降级

Dify 是二期流程编排核心,需要独立健康检查和降级策略。

能力 说明
健康检查 管理后台展示 Dify baseUrl、应用密钥是否可用、最近调用成功率
超时配置 每个智能体配置 Dify 连接超时、读取超时、SSE 最大空闲时间
熔断策略 连续失败后短时间熔断,避免拖垮 OpenPlatform
降级策略 按智能体配置:返回预设答复、降级 DirectLLM、只展示人工入口或直接失败
告警 Dify 错误率、P99 延迟、SSE 断连率超过阈值时告警

3. 二期目标与边界

二期的目标不是一次性建完整 AI 医院,而是建立可复用的医疗智能体与多终端入口底座:

  1. 对外提供统一智能体调用入口,并承接多设备统一入口客户端。
  2. 支持 Dify Workflow 承载导诊、预问诊、挂号、住院评估等流程。
  3. 通过 MCP Server 将院内系统封装为可审计、可治理的工具。
  4. 用卡片承载挂号、缴费、签到、报告、病历、护理任务等确定性业务交互,避免纯自然语言完成高风险动作。
  5. 建设 Device Registry、Device Adapter、Scene Orchestrator 和 IoMT Event Hub 的最小可用能力,支撑门诊 P0 设备闭环。
  6. 形成会话、设备、卡片实例、调用日志和后续三期计量账本的数据基础。

医院确认版方案下,二期必须明确门诊和住院边界:

区域 二期定位 医梦主责 不应承担
门诊 医梦主导整体入口总包 门诊 P0 设备统一入口、设备准入、统一客户端、Agent 绑定、HIS/支付/叫号/EMR 对接、业务闭环验收 自研所有硬件、替代医院采购流程
住院 医梦 AI 大脑层协同 住院智能体、IoMT 预警解释、护理任务、病历质控、出院随访、与迪耐克/鸿蒙病房互通 接管床头屏/护理白板/病房硬件总包
鸿蒙协同 标杆 POC 与国产化亮点 主动签到、候诊状态同步、检查路线提醒等“服务找人”小闭环 全院所有设备鸿蒙化、无授权自动识别

二期不应承担以下事项:

不建议二期承担 原因
完整计费结算系统 应纳入三期商业闭环统一设计
第三方卡片开放生态 安全、审核、沙箱成本高,优先级低于内置医疗卡片
复杂模型训练平台 与二期 Dify + MCP 主链路不是同一交付焦点
大而全 HIS 数据中台 二期只需要按场景封装必要工具,避免前期失控
住院硬件总包 与迪耐克/既有病房体系边界冲突,医梦应做 AI 层互通
全院鸿蒙化 技术和设备生态不确定,第一期只做可演示、可验收的 POC

4. 二期总体架构

flowchart TD
    Client["门诊统一入口客户端<br/>患者端 / 医生站 / 机器人 / 自助机 / 大屏"]
    WardEmbed["住院 AI 嵌入端<br/>护理白板 / 床头屏<br/>通过迪耐克/鸿蒙生态接入"]
    Device["Device Registry / Adapter<br/>设备身份 / 能力 / 心跳 / 厂商 SDK"]
    Scene["Scene Orchestrator<br/>设备-位置-场景-智能体绑定"]
    Journey["Journey Context<br/>动线阶段 / 下一步任务 / 服务找人"]
    Perception["Perception Event<br/>身份 / 空间 / 业务 / 设备 / 风险感知"]
    WardGateway["迪耐克/鸿蒙病房网关<br/>床头屏 / 护理白板 / IoMT 标准事件"]
    OpenAPI["OpenPlatform API<br/>签名鉴权 / 租户项目授权 / 限流 / 审计"]
    Engine["AgentEngine 路由层<br/>Dify / Direct / Mock"]
    Dify["Dify Workflow<br/>意图识别 / 分支 / RAG / 工具调用 / 响应组装"]
    MCP["emoon-mcp<br/>MCP Tool Server / HIS Adapter / 幂等 / 熔断"]
    HIS["HIS / EMR / LIS / PACS / 排班 / 支付 / 叫号 / 床位 / 护理 / 随访"]
    Card["Card Runtime<br/>卡片定义 / 实例 / 动作 / 状态"]
    Event["IoMT Event Hub<br/>设备事件 / 护理预警 / 服务找人"]
    Data["AI Metadata<br/>智能体 / 会话 / 用量 / 卡片 / 审计"]
    Meter["三期计量账本<br/>能力值 / 额度 / 账单"]

    Client --> Device
    Device --> Scene
    Device --> Perception
    Perception --> Journey
    Scene --> Journey
    Journey --> OpenAPI
    Client --> OpenAPI
    WardEmbed --> WardGateway
    WardGateway --> Event
    WardGateway --> OpenAPI
    OpenAPI --> Engine
    Engine --> Dify
    Dify --> MCP
    MCP --> HIS
    Device --> Event
    Event --> Perception
    Event --> OpenAPI
    Dify --> OpenAPI
    OpenAPI --> Card
    OpenAPI --> Data
    OpenAPI -.调用事件.-> Meter
    MCP -.工具事件.-> Meter
    Card -.动作事件.-> Meter
    Device -.设备维度事件.-> Meter
    Event -.业务闭环事件.-> Meter
    Journey -.动线服务事件.-> Meter

4.1 组件职责

组件 核心职责 不负责
OpenPlatform 对外入口、项目授权、租户隔离、调用编排、卡片运行时、审计、三期计量入口 复杂业务流程画布
Terminal Runtime 门诊多设备统一入口客户端、UI 模板、虚拟形象、语音/触控/扫码/打印 Bridge、远程升级和异常上报;住院侧只做嵌入或协议适配 医疗业务规则、合同账本;不承担住院床头屏/护理白板硬件责任
Device Registry 设备身份、型号、位置、能力、状态、版本、智能体绑定、SLA 等级 直接调用 HIS 写业务
Device Adapter 厂商 SDK/API、屏幕、机器人、自助机、四诊仪;住院侧仅适配迪耐克/鸿蒙病房标准接口 决定临床结果、财务扣费;不直接接管病房硬件设备
Scene Orchestrator 根据设备、位置、时间、用户和业务状态选择 UI、智能体、工具权限 替代 Dify Workflow 的多轮医学编排
Perception Event 接收和归一身份、空间、业务、设备、风险事件,形成可审计的感知事实 采集全院连续轨迹、替代医院物联平台
Journey Context 根据 VisitTimeline/TaskState/DeviceContext/DeviceEvent/CardAction 推导患者当前动线阶段、下一步服务和允许动作 建设复杂路径优化引擎、自动完成高风险业务
Dify Workflow 多轮对话、意图识别、条件分支、RAG、工具编排、自然语言回复 合同账本、额度扣减、财务结算
MCP Server 院内系统工具封装、协议适配、幂等、熔断、降级、工具审计 UI 渲染、合同管理
Card Runtime 卡片定义、卡片实例、动作状态机、交互结果回传 直接绕过 MCP 操作 HIS
HIS Adapter 对接医院厂商接口、响应格式标准化、错误码映射 业务定价与计费策略
IoMT Event Hub 接收迪耐克/鸿蒙病房网关或医院物联平台输出的标准事件,做事件归一、护理预警、服务找人事件入口 直接认证和采集住院 IoMT 原始设备数据;把设备心跳直接作为客户扣费事实
Metering/Billing 三期能力值计量、预扣、账单、分摊、报表 直接参与医疗诊断决策

4.2 统一调用方向与安全边界

二期/三期融合后,最容易出错的是调用方向。生产方案采用“OpenPlatform 掌控入口和事实记录,Dify 掌控流程编排,MCP 掌控院内工具”的模式。

flowchart LR
    Client["客户端 / 终端<br/>患者端 / 医护端 / 机器人 / 自助机 / 屏幕"]
    Device["Device Context<br/>设备身份 / 场景 / 能力"]
    Open["OpenPlatform<br/>鉴权 / 会话 / 卡片 / 计量入口"]
    Engine["AgentEngine<br/>Dify / Direct / Mock"]
    Dify["Dify Workflow<br/>流程编排"]
    MCP["MCP Tool Server<br/>院内工具网关"]
    HIS["医院系统<br/>HIS / EMR / LIS / PACS"]
    Meter["Metering/Billing<br/>三期账本"]

    Client -->|"1. heartbeat / scene resolve"| Device
    Device -->|"2. device profile / scene profile"| Open
    Client -->|"3. chat / card action"| Open
    Open -->|"4. route by engineType"| Engine
    Engine -->|"5. Dify API"| Dify
    Dify -->|"6. tool call"| MCP
    MCP -->|"7. adapter call"| HIS
    HIS -->|"8. standardized result"| MCP
    MCP -->|"9. tool result"| Dify
    Dify -->|"10. answer / card output"| Engine
    Engine -->|"11. unified response"| Open
    Open -->|"12. response / SSE / card"| Client
    Open -. "business event" .-> Meter
    MCP -. "tool event" .-> Meter
    Device -. "device event" .-> Meter
调用段 发起方 接收方 是否可信 关键控制
客户端到 OpenPlatform 外部端 OpenPlatform 不可信 签名、时间戳、项目授权、幂等键、限流
终端到 Device Registry 医梦客户端 / 第三方设备 OpenPlatform / Device Registry 不可信 设备证书、设备密钥、医院/科室绑定、心跳、版本校验
OpenPlatform 到 Dify 平台内服务 Dify 半可信 Dify App 授权、超时、熔断、输出校验
Dify 到 MCP Dify MCP Tool Server 半可信 工具白名单、项目工具授权、患者授权、幂等
MCP 到 HIS MCP Adapter 医院系统 受控内网 厂商鉴权、短超时、结果确认、审计
OpenPlatform 到 Metering 平台内服务 计量账本 可信但必须可重放 Outbox、幂等、状态机

初级工程师重点:为什么 Dify 不是“可信后端”?
Dify 是流程编排平台,流程画布可能被运营人员调整,输出结构也可能变化。它可以决定下一步问什么、调用什么工具,但不能直接决定扣费、越权访问、写 HIS 或绕过卡片确认。所有安全和账务判断都必须回到 OpenPlatform/MCP 的强校验链路。

4.3 MCP 部署形态决策

MCP Tool Server 可以先嵌入现有工程,也可以独立部署。选择依据不是“哪个更高级”,而是医院网络、交付阶段和治理要求。

部署形态 适用阶段 优点 风险 必须满足
嵌入 emoon-openplatform 二期早期联调、小型试点 少一个服务,开发和部署简单 与对外 API 耦合,内外网边界不清 工具包名和服务边界必须独立,后续可拆
嵌入 emoon-mcp 模块同进程 二期正式试点 保留模块边界,部署复杂度适中 仍与主应用共享资源 独立线程池、超时、熔断、工具审计
独立 MCP 服务 L3 项目交付、院内私有化、区域平台 网络隔离清晰,便于院内部署和扩容 部署、监控、版本治理成本更高 服务鉴权、工具注册、健康检查、灰度

推荐路线:二期先允许同进程落地,但接口和数据模型按独立服务设计;进入 L3 项目建设版后,把 MCP Tool Server 独立部署到医院内网或专属区。

初级工程师重点:同进程不等于可以省略 Outbox。
只要业务成功和计费/审计事件不是同一张表,就存在“业务写成功但事件丢失”的风险。即使 MCP 和 OpenPlatform 在同一个 JVM,仍要用 Outbox 保证业务事实能被后续可靠处理。

4.4 C4 Context:系统上下文

这张图用于回答“医梦 AI 中台在医院项目中和谁交互”。初级工程师先看这张图,明确系统边界,不要把外部系统职责写进中台。

C4Context
  title System Context - 医梦 AI 中台

  Person(patient, "患者", "通过小程序、APP、自助机或机器人使用 AI 服务")
  Person(doctor, "医生 / 护士", "在医生站、护士站使用 AI 辅助功能")
  Person(operator, "医院管理员 / 医梦运营", "配置项目、查看用量、处理账单和运营报告")

  System(emoon, "医梦 AI 中台", "统一智能体入口、多终端入口、Dify 编排、MCP 工具、卡片交互、设备治理、计量账本")
  System_Ext(dify, "Dify 平台", "Workflow、LLM 节点、RAG、工具调用")
  System_Ext(his, "医院业务系统", "HIS、EMR、LIS、PACS、排班、支付、叫号、床位、护理、随访")
  System_Ext(device, "门诊终端与设备", "导诊屏、自助机、机器人、叫号屏、诊室屏、四诊仪")
  System_Ext(harmony, "鸿蒙 / 迪耐克病房体系", "近场感知、床头屏、护理白板、IoMT、病房设备")
  System_Ext(model, "模型与语音图像服务", "大模型、ASR、TTS、舌诊/面诊模型")

  Rel(patient, emoon, "发起咨询、问诊、挂号、随访")
  Rel(doctor, emoon, "使用病历、质控、CDSS、报告解读")
  Rel(operator, emoon, "配置、监控、对账、运营")
  Rel(device, emoon, "注册、心跳、场景加载、设备事件")
  Rel(harmony, emoon, "服务找人、病房事件、住院 AI 互通")
  Rel(emoon, dify, "调用 Workflow", "HTTPS/SSE")
  Rel(dify, emoon, "调用 MCP 工具", "MCP/HTTP")
  Rel(emoon, his, "读取/写入业务数据", "MCP Adapter")
  Rel(emoon, model, "调用模型能力", "OpenAI-compatible/API")

4.5 C4 Container:工程容器视角

这张图用于回答“代码应该放在哪个工程模块”。实现时优先遵守这个边界,避免把计费逻辑写进 Dify Adapter,或者把 HIS 调用写进前端卡片。

C4Container
  title Container Diagram - 医梦 AI 中台

  Person(user, "患者 / 医护 / 管理员", "系统使用者")

  System_Boundary(emoon, "医梦 AI 中台") {
    Container(admin, "emoon-admin", "Spring Boot", "管理后台入口,加载 system/mcp 等模块")
    Container(open, "emoon-openplatform", "Spring Boot", "对外 API、签名鉴权、Agent 调用、Dify 客户端")
    Container(systemApi, "emoon-system-api", "Java API", "系统域 DO、Mapper、Service 接口")
    Container(system, "emoon-system", "Java Module", "系统管理、引擎配置、后续合同账单管理")
    Container(mcpApi, "emoon-mcp-api", "Java API", "AgentEngine、会话、卡片实例、MCP 域接口")
    Container(mcp, "emoon-mcp", "Java Module", "MCP 工具、HIS Adapter、工具审计")
    Container(deviceCore, "Device Core", "Java Module", "设备注册、设备能力、场景绑定、设备事件接入")
    Container(terminal, "Terminal Runtime", "Web / Android / Harmony / Electron", "多终端统一入口客户端、UI 模板、设备 Bridge")
    Container(knowledge, "emoon-knowledge-api", "Java API", "知识库、提示词、质控、既有 AI 资产")
    ContainerDb(mysql, "MySQL", "Relational DB", "元数据、会话、卡片、账本、账单")
    ContainerDb(redis, "Redis", "Cache", "限流、幂等、热点配置、短锁")
  }

  System_Ext(dify, "Dify Platform", "Workflow")
  System_Ext(his, "Hospital Systems", "HIS/EMR/LIS/PACS")
  System_Ext(devices, "Outpatient Devices", "门诊屏幕 / 自助机 / 机器人 / 四诊仪")

  Rel(user, terminal, "使用统一入口客户端", "Touch/Voice/Web")
  Rel(terminal, open, "调用智能体、卡片和场景 API", "HTTPS/SSE/WebSocket")
  Rel(devices, deviceCore, "注册、心跳、设备事件", "HTTPS/MQ/SDK")
  Rel(user, admin, "使用管理后台", "HTTPS")
  Rel(open, mcpApi, "使用 AgentEngine / 会话 / 卡片接口")
  Rel(open, systemApi, "查询项目、智能体、引擎配置")
  Rel(open, deviceCore, "解析设备上下文和场景绑定")
  Rel(open, dify, "调用 Dify 应用", "HTTPS/SSE")
  Rel(dify, mcp, "调用 MCP 工具", "HTTP/MCP")
  Rel(mcp, his, "适配院内系统接口", "HTTP/DB/Vendor API")
  Rel(system, systemApi, "实现管理域服务")
  Rel(mcp, mcpApi, "实现 MCP 域服务")
  Rel(system, mysql, "读写合同、配置、账单")
  Rel(open, mysql, "读写会话、日志、卡片实例")
  Rel(mcp, redis, "幂等、短锁、熔断状态")

4.6 二期组件实现拆解

实现单元 建议位置 输入 输出 关键注意事项
对外智能体 Controller emoon-openplatform 签名请求、agentId、用户消息 统一响应 / SSE 只做参数、鉴权、响应封装,不写复杂业务
项目鉴权服务 emoon-openplatform 或 system API publicKey、签名、payload projectIdtenantId、授权范围 签名、时间戳、项目智能体授权必须统一封装
统一入口客户端 独立前端 / Android / Harmony / Electron deviceId、场景配置、UI 模板 多终端页面、语音/触控/扫码/打印能力 先保证 P0 设备可运行,硬件能力通过 Bridge 标准化
设备注册服务 system/mcp API 或新 Device Core 设备注册、心跳、位置、能力 DeviceProfile、在线状态、版本、智能体绑定 设备必须绑定医院/科室/位置,不能匿名接入核心闭环
设备适配服务 Device Core + 厂商 Adapter SDK/API/驱动事件 标准设备能力协议 第三方设备只能通过适配层进入中台
场景编排服务 Device Core / OpenPlatform 设备、位置、时间、用户、业务状态 sceneProfile、UI 模板、Agent 绑定、工具权限 解决“同一设备不同场景加载什么”
动线上下文服务 emoon-openplatform 内部服务,P1 可下沉到 Agent Core TaskState、HIS/叫号状态、设备事件、卡片动作 journeyState、下一步服务、推荐卡片 MVP 不独立建微服务,不做全院路径优化
感知事件接入 Device Core / OpenPlatform 扫码、NFC、刷卡、近场、业务状态回调 标准 perceptionEvent、审计记录 只存业务必要事件,不保存连续轨迹
Agent 编排服务 emoon-openplatform 对话请求、项目上下文 AgentResponse 查智能体、查引擎配置、路由引擎、写会话
Dify 引擎适配器 emoon-openplatformemoon-mcp-api 实现类 AgentRequest AgentResponse 只负责协议转换,不负责计费、不直接调 HIS
卡片运行时服务 emoon-mcp-api + 实现模块 cardKey、卡片数据、动作请求 卡片实例、动作结果 创建快照、校验状态、动作幂等
MCP 工具服务 emoon-mcp Dify 工具请求 / 卡片动作请求 标准工具结果 院内系统访问统一从这里走
HIS Adapter emoon-mcp 标准工具参数 HIS 响应标准对象 每家医院可配置不同 Adapter
IoMT 事件接入 Device Core / emoon-mcp 设备事件、病房事件、护理事件 标准事件、护理工单、Outbox 事件 只把业务闭环事件计入客户侧,心跳进入内部监控
调用日志服务 system/mcp API 调用上下文和结果 ai_usage_log 用于排障,不作为财务账本
计量入口 三期新增 system/mcp 能力 标准调用事件 ai_meter_event 二期可预留接口,三期完整实现

4.7 初级工程师实现顺序

二期不要从“做全链路”开始。建议按以下顺序逐步打通:

  1. 先打通 Mock 对话:确保 /api/v1/agent/chat 能根据 agentId 查配置、路由 Mock 引擎、写会话、返回卡片。
  2. 再接 Dify 文本对话:实现 Dify 引擎适配器,只返回文本和 usage,不处理卡片动作。
  3. 补 Device Registry 最小闭环:设备能注册、心跳、绑定医院/科室/位置、绑定默认智能体和 UI 模板。
  4. 再接统一入口客户端 MVP:导诊屏、自助机、机器人、诊室屏至少能通过同一套协议加载场景并调用 Agent。
  5. 再接 Dify 卡片返回:约定 Dify 输出结构,OpenPlatform 识别 cardKey/cardData 并创建卡片实例。
  6. 再做卡片动作接口:前端点击卡片后,后端能校验实例、更新状态、写动作日志。
  7. 最后接 MCP/HIS 写操作:先从查询类工具开始,再做锁号、建档、挂号、签到、缴费等写操作。
  8. 全链路补审计和幂等:确认每次请求都有 traceId、业务幂等键、设备上下文、状态和错误记录。

每完成一步都应保留可回放样例:请求参数、响应结果、数据库关键记录、日志 traceId。

5. 二期核心链路

5.1 对话链路

  1. 客户端携带 X-Emoon-* 请求头调用 /api/v1/agent/chat
  2. OpenPlatform 根据 publicKey 查询项目,校验签名、时间戳和智能体授权。
  3. OpenPlatform 查询 ai_agent_appai_agent_engine_config
  4. AgentEngineFactoryengineType 路由到 Dify / Direct / Mock。
  5. Dify Workflow 处理意图、调用知识库或 MCP 工具。
  6. Dify 返回文本、结构化卡片数据、外部 conversation/message 标识和 usage。
  7. OpenPlatform 写入会话、调用日志、卡片实例,并向前端返回统一响应。
  8. 三期接入后,同步产生标准计量事件。

5.2 卡片链路

卡片不是简单 UI 组件,而是确定性医疗业务操作的承载单元。

阶段 说明
卡片生成 Dify 返回 cardKeycardData 和业务上下文
实例创建 OpenPlatform 根据 cardKey 查卡片定义并创建 ai_card_instance
前端渲染 前端根据卡片定义渲染科室、医生、时间、确认、建档等卡片
用户操作 用户点击、选择、确认后调用卡片动作接口
动作执行 OpenPlatform 校验实例状态、幂等键、权限、有效期
工具调用 需要操作 HIS 时,通过 MCP Server 调用,不建议前端或卡片绕过 MCP
状态回写 更新卡片实例、会话上下文、动作日志,并把结果作为下一轮对话输入

5.3 MCP 工具链路

MCP Server 是医院系统的唯一工具出口,所有对 HIS / EMR / LIS / PACS 的确定性调用都应经过它。

这里的 MCP 是医梦内部“AI 工具网关”设计,不把它包装成医院行业已经成熟的通用标准。公开行业方案更常见的是信息平台、集成平台、物联网平台对异构系统做统一接入;医梦采用 MCP 思路,是为了让 Dify 工具调用、卡片动作和 HIS Adapter 都进入同一个可授权、可审计、可幂等的工具出口。MVP 阶段可先用 HTTP/JSON Tool Service 实现,不要求一次性实现完整 Model Context Protocol 生态。

工具域 示例工具 生产要求
基础数据 科室、医生、院区、病区、床位 本地缓存、版本同步、数据来源标识
排班号源 医生排班、号源详情、锁号、释放号源 幂等、短锁、超时释放、并发控制
患者档案 查询患者、建档、更新档案 患者授权、敏感字段脱敏、审计
挂号预约 创建预约、取消预约、状态同步 订单幂等、支付状态一致性
住院管理 入院评估、床位预约、护理任务、出院小结 人工确认、高风险拦截
随访管理 随访计划、随访记录、风险分层 触达记录、升级人工
知识检索 指南检索、制度检索、院内 FAQ 引用来源、版本号、召回质量记录

5.4 对话调用时序

sequenceDiagram
    autonumber
    participant C as 客户端
    participant API as OpenPlatform API
    participant Auth as 项目鉴权
    participant Agent as Agent 编排服务
    participant Engine as AgentEngineFactory
    participant Dify as Dify Workflow
    participant Card as Card Runtime
    participant DB as MySQL

    C->>API: POST /api/v1/agent/chat
    API->>Auth: 校验 publicKey、签名、时间戳、agent 权限
    Auth-->>API: projectId、tenantId、授权范围
    API->>Agent: chat(request, projectContext)
    Agent->>DB: 查询 ai_agent_app、ai_agent_engine_config
    Agent->>Engine: getEngine(engineType)
    Engine-->>Agent: DifyEngine / MockEngine
    Agent->>Dify: 发送消息、inputs、conversationId
    Dify-->>Agent: reply、usage、cardKey、cardData
    Agent->>DB: 创建/更新 ai_conversation、ai_usage_log
    alt 返回卡片
        Agent->>Card: 创建卡片实例和快照
        Card->>DB: 写 ai_card_instance
    end
    Agent-->>API: AgentChatResponse
    API-->>C: 文本 + 卡片数据 + conversationId

5.5 卡片动作时序

sequenceDiagram
    autonumber
    participant C as 前端卡片
    participant API as Card Action API
    participant Card as Card Runtime
    participant MCP as MCP Tool Server
    participant HIS as HIS / EMR
    participant DB as MySQL
    participant Dify as Dify Workflow

    C->>API: POST /api/v1/card/{instanceId}/actions/{action}
    API->>Card: 校验实例、状态、过期时间、幂等键
    Card->>DB: 写 ai_card_action_log(pending)
    alt 只更新卡片状态
        Card->>DB: 更新 ai_card_instance.state_json
    else 需要业务写操作
        Card->>MCP: 调用标准工具,如 his_lock_schedule
        MCP->>HIS: 调用医院接口
        HIS-->>MCP: 返回业务结果
        MCP-->>Card: 标准工具结果
        Card->>DB: 更新实例状态、动作结果
    end
    Card->>Dify: 可选:把动作结果作为下一轮上下文
    API-->>C: actionResult、nextCard 或 nextMessage

5.6 卡片实例状态机

stateDiagram-v2
    [*] --> active: 创建实例
    active --> submitted: 用户提交动作
    submitted --> processing: 后端执行动作
    processing --> completed: 执行成功
    processing --> failed: 执行失败
    failed --> active: 可重试
    active --> expired: 超时未操作
    active --> cancelled: 用户取消/流程终止
    completed --> [*]
    expired --> [*]
    cancelled --> [*]

状态机实现要求:

状态 允许操作 说明
active submit、cancel、refresh 卡片可交互
submitted none 防止重复点击,等待后端处理
processing query 正在调用 MCP/HIS
completed query 业务已完成,只能查看
failed retry、cancel 失败可重试,但必须复用幂等上下文
expired none 超时失效,前端应提示重新发起
cancelled none 用户或系统终止

5.7 MCP 工具实现模式

每个 MCP 工具都按同一套模式实现,避免不同工具风格混乱。

步骤 实现说明
定义工具契约 明确工具名、输入字段、输出字段、错误码、是否写操作
参数校验 校验必填、格式、项目权限、患者授权
幂等处理 写操作必须接收业务幂等键,如 projectId + instanceId + actionName
HIS 调用 通过医院 Adapter 调厂商接口,不在工具里写死某家医院 URL
结果标准化 把厂商响应转换为统一结构,屏蔽厂商差异
审计记录 记录工具名、耗时、状态、错误、输入输出摘要
熔断降级 HIS 超时或异常时返回可解释错误,必要时走人工

5.8 Dify 集成契约

Dify 接入不是简单 HTTP 转发。OpenPlatform 必须把 Dify 的不稳定输出转换成平台稳定响应,并在转换失败时给出可观测错误。

5.8.1 引擎配置结构

ai_agent_engine_config.config_json 建议按以下逻辑字段管理,敏感字段加密存储,展示时脱敏:

字段 说明
baseUrl Dify 服务地址
appId Dify App 标识
apiKeyRef 密钥引用,不直接明文保存
responseMode blockingstreaming
conversationMode 是否复用 Dify conversation
inputMapping 平台上下文字段到 Dify inputs 的映射
outputSchemaVersion 约定的输出结构版本
timeout 连接、读取、SSE 空闲超时
fallbackPolicy 失败时返回预设答复、DirectLLM 或人工入口

5.8.2 Dify 输出格式

同步和流式最终都要归一成平台响应。Dify Workflow 的最终输出建议固定包含以下逻辑字段:

字段 来源 说明
answer Dify 文本节点 给用户展示的自然语言答复
cards Dify 结构化输出节点 可选,数组;每张卡包含 cardKeycardDatabusinessContext
riskLevel Dify 分支或平台后处理 医疗安全等级
scenarioCode 智能体配置或 Dify 输出 三期计量和报表使用
workflowRunId Dify 返回 排障、审计、版本追踪
usage Dify 返回 原始 token/模型消耗,仅作成本和排障参考

卡片输出必须满足:

要求 说明
cardKey 必须存在 用于匹配平台卡片定义
cardData 必须通过 schema 校验 不通过时不能创建卡片实例
businessContext 只保存必要上下文 不把完整病历、身份证号等敏感信息塞进卡片
actionHints 只能作为建议 后端实际动作仍以卡片定义和项目授权为准

卡片数据的敏感字段边界:

字段类型 是否允许由 Dify 输出到 cardData 说明
卡片结构字段 允许 如字段类型、选项布局、按钮动作名
业务标识 允许 deptIddoctorIdslotIdappointmentTime
患者 PII 预填 禁止 如姓名、身份证号、手机号、住址
医疗原文 禁止 如完整病历、检查报告原文、诊断原文
图像原始引用 禁止 舌诊/面诊原图 fileId 不进入 Dify 卡片输出

患者 PII 只能通过“前端卡片动作 -> AgentActionOrchestrator -> CardActionService -> MCP Tool Service”的加密后端链路提交,不能进入 Dify 的输入、输出或 Workflow 变量。

DifyOutputNormalizer 作为 DifyAgentEngine 的内部输出后处理步骤实现,不新增独立 Maven 模块,也不放在 emoon-openplatform。建议落在 emoon-ai-agent 的 adapter/application 边界内,职责包括:

职责 处理规则
JSON 合法性校验 不合法时降级为普通文本并记录 Dify 输出告警
cardKey 校验 不存在或未注册时拒绝创建卡片
cardData schema 校验 不通过时拒绝创建卡片,并返回可观测错误
风险等级归一 将 Dify 输出映射为平台医疗安全等级
敏感字段拦截 阻止 PII、完整病历原文、舌象原图引用进入卡片输出
SSE 事件归一 将 Dify 流式事件转换为平台 message_deltacard_createdusage_reported 等稳定事件

Normalizer 不执行卡片动作、不调用 HIS、不扣能力值。它只负责把 Dify 的不稳定输出转换成平台可审计、可校验、可降级的稳定事件,避免开发人员把校验逻辑散落到 openplatform、Card Runtime 或前端。

5.8.3 流式响应与卡片时机

SSE 模式下,Dify 可能先输出文本,再在最终节点输出卡片。平台 SSE 协议应区分事件类型:

事件 说明
message_delta 文本增量
message_completed 文本输出结束,包含 Dify message/workflow 标识
card_created 平台已创建卡片实例,前端可渲染
usage_reported 原始 usage 已记录
error 可恢复或不可恢复错误

实现规则:

  1. 卡片实例只在平台校验通过并落库后发 card_created
  2. Dify 流式中途输出的疑似 JSON 不直接给前端当卡片。
  3. SSE 断开后,客户端可用 conversationId 查询最终消息和卡片状态。
  4. 若 Dify 已完成但卡片创建失败,消息仍可展示,但返回“卡片生成失败”的平台错误并记录 traceId。

5.8.4 卡片动作结果回传 Dify

卡片动作执行后,Dify 需要知道用户选择了什么。这里不采用“卡片动作直接回调 Dify 内部状态”的假设,因为 Dify Chat API 主要是消息驱动。

默认方案:

  1. Card Runtime 将动作结果写入 ai_card_action_log 和会话上下文。
  2. 下一轮用户消息进入 Dify 时,OpenPlatform 把最近卡片动作结果放入 Dify inputs
  3. Dify Workflow 根据 inputs.cardActionResult 继续流程。

需要立即续跑时:

  1. Card Runtime 完成动作后请求 Agent 编排服务。
  2. Agent 编排服务向 Dify 发送一条平台生成的 synthetic user message。
  3. 该消息必须标记 synthetic=true,并携带 cardActionResultcardInstanceIdactionId
  4. 平台把 Dify 返回的新文本或卡片继续写入会话。

synthetic message 必须有边界:

控制项 规则
最大深度 单次用户动作触发的 synthetic 链路默认最多 3 轮,超过后必须返回卡片或提示,等待用户下一次主动操作
并发控制 同一个 conversationId 同一时间只能有一个 synthetic 链路运行,防止消息乱序
计量控制 每轮 synthetic message 都是一次平台调用,必须产生独立调用日志、计量事件和额度校验
风险控制 L3+ 写操作不能被 synthetic 链路自动连续执行,必须有用户或医护确认动作
上下文裁剪 Dify inputs 只携带最近 3 轮卡片动作结果和当前业务摘要,历史动作通过 conversationId 查询

synthetic message 的场景和计费归属:

  1. synthetic message 默认继承原始用户请求的 scenarioCodebillingEpisodeId 和合同上下文。
  2. Dify 可以显式返回更具体的 scenarioCode,但平台必须校验该场景在合同范围和智能体授权范围内。
  3. synthetic message 产生独立调用日志和内部成本事件,但默认不作为客户侧独立计费“次”。
  4. 一次用户主动请求触发的原始调用和 synthetic 链路,归入同一个 billingEpisodeId,由计量中心按业务 episode 统一定价。
  5. 若 synthetic 链路触发了新的高价值业务能力,如挂号确认、报告生成、图像分析,则按对应业务事件另行计费,但仍通过 parent_event_id 关联原 episode。

初级工程师重点:为什么不让前端直接把动作结果发给 Dify?
前端不可信,且无法保证动作结果已经通过 HIS/MCP 落库。必须以后端动作日志为准,再把“已确认事实”传给 Dify,否则会出现前端伪造挂号成功、Dify 继续错误流程的问题。

5.8.5 Dify 失败补偿

失败点 处理
Dify 请求超时 记录失败 usage log,释放预冻结额度,按 fallback 策略返回
Workflow 运行失败 记录 workflowRunId 和错误摘要,返回平台统一错误码
Dify 输出结构错误 不创建卡片,保留原始输出摘要,触发 Workflow 输出告警
Dify 已输出文本但后续失败 SSE 标记 partial,按 partial 计量策略处理
Dify 调 MCP 失败 由 MCP 返回标准错误,Dify 可继续降级解释,但写操作不得自动重试

5.9 DirectLLM 与 Mock 引擎定位

AgentEngine 需要同时支持 Dify、DirectLLM、Mock,但三者定位不同。

引擎 用途 生产要求
DifyAgentEngine 主流程编排,承载问诊、导诊、住院等多步骤流程 优先实现,支持同步、SSE、usage、卡片输出
DirectLLMAgentEngine L1 标准能力主引擎、简单问答、提示词模板、Dify 降级、旧 /chat/apisse 能力迁移 必须走同一鉴权、会话、计量、日志链路
MockAgentEngine 本地开发、前端联调、自动化测试 不允许生产项目误用,生产环境默认禁用

L1 客户可以使用 DirectLLM 作为主引擎,不强依赖 Dify。L2/L3 的复杂场景优先由 Dify Workflow 编排,DirectLLM 作为简单能力、降级能力或专用模型调用能力存在。无论哪种模式,DirectLLM 都不能绕过平台治理;即使只是直连模型,也要写入 ai_conversationai_usage_log,并按三期计量规则生成事件。

5.10 典型业务流程拆解

以“智能分诊后挂号”为例,工程实现可以拆成以下业务步骤:

步骤 主责模块 说明
用户描述症状 OpenPlatform 接收消息,写入会话上下文
症状追问与分诊 Dify Workflow LLM 节点和知识检索生成候选科室
获取科室和医生 MCP Server 调 HIS 查询科室、医生、号源
展示科室/医生卡片 Card Runtime + 前端 创建卡片实例,前端渲染
用户选择医生时间 AgentActionOrchestrator + Card Runtime Agent 编排承接动作,Card Runtime 校验状态并写动作日志
锁定号源 MCP Server 写操作,必须幂等和短锁
确认挂号 AgentActionOrchestrator + Card Runtime + MCP 用户确认后由 Agent 编排推进预约或订单创建
返回结果 OpenPlatform 更新会话和卡片状态,返回成功卡片
产生计量事件 三期计量中心 按“智能分诊 / 挂号服务”计量

卡片动作调用 MCP 的路径统一为:

flowchart LR
    Front["前端卡片"]
    API["OpenPlatform Card Action API"]
    Agent["AgentActionOrchestrator"]
    Card["CardActionService"]
    Tool["MCP Tool Service"]
    Adapter["HospitalAdapter"]
    HIS["HIS / EMR / LIS / PACS"]

    Front --> API
    API --> Agent
    Agent --> Card
    Agent --> Tool
    Tool --> Adapter
    Adapter --> HIS

实现时,AgentActionOrchestrator -> MCP Tool Service 在同进程部署时可以是模块内 Service 调用;MCP 独立部署后改为内部 HTTP/RPC。无论哪种部署,前端和 Dify 都不能绕过 OpenPlatform、Agent 编排和 Card Runtime 直接执行卡片动作。

5.10.1 统一入口客户端启动链路

统一入口客户端是医院最新方案中的战略控制点。它不是普通网页,而是优先部署在门诊导诊屏、自助机、机器人、叫号屏、诊室屏、医生站插件等终端上的多设备 AI 场景运行时。

住院侧要单独说明:护理白板、床头屏属于迪耐克/鸿蒙病房生态的终端,医梦只通过 Web/H5 嵌入、SDK/API 或标准事件协议提供 AI 能力,不承担住院屏幕硬件、基础呼叫、病房网关和 IoMT 原始采集的主责。

sequenceDiagram
    participant T as Terminal Runtime
    participant D as Device Registry
    participant S as Scene Orchestrator
    participant O as OpenPlatform
    participant A as Agent Center

    T->>D: 设备启动,提交 deviceId、版本、能力、位置
    D->>D: 校验设备密钥、医院/科室绑定、准入等级
    D->>S: 请求当前设备的场景配置
    S->>A: 查询可用智能体、工具权限、UI 模板
    A-->>S: 返回 agentBindings、cardTemplates、toolScopes
    S-->>T: 返回 sceneProfile、首页模板、默认智能体
    T->>O: 携带 deviceContext 发起对话或卡片动作

设备上下文必须进入每一次调用:

字段 用途
deviceId 设备唯一身份,关联授权、心跳、故障定位
deviceType 区分导诊屏、自助机、机器人、叫号屏、诊室屏等入口
hospitalId / departmentId 设备所属医院和科室,用于权限和统计
location 楼栋、楼层、区域、诊室、床位,用于服务找人和场景编排
capabilities 触控、语音、扫码、读卡、打印、摄像头、导航等能力
sceneProfile 当前加载的业务场景,例如 outpatient_registration
agentBindings 当前设备允许调用的智能体集合
clientVersion 统一入口客户端版本,用于灰度和排障

初级工程师重点:为什么不能让每个设备直接写自己的页面? 医院现场设备多、厂商多、版本多。如果没有统一入口客户端和 Device Registry,后续每个屏幕都会变成项目定制,Agent 绑定、权限、日志、计量和升级都无法统一治理。

5.10.2 设备适配与标准设备能力协议

设备适配层要把第三方 SDK、机器人驱动、自助机读卡打印、四诊仪采集、迪耐克病房接口等差异收敛成医梦标准能力。

能力 标准动作 典型设备
屏幕显示 renderCardshowPageshowAlert 大屏、叫号屏、诊室屏;床头屏仅通过迪耐克生态嵌入
语音采集 startRecordstopRecordsendAudio 机器人、诊室麦克风;床头屏语音由病房生态能力决定
语音播放 playTTSstopTTS 机器人、自助机、导诊屏
摄像头 captureImagescanFacescanQRCode 自助机、机器人、四诊仪
打印 printReceiptprintWristbandprintReport 自助机、护士站
读卡 readIdCardreadMedicalCard 自助机、诊区终端
导航 startNavigationstopNavigationgetLocation 机器人、室内导航
IoMT receiveWardEventackAlertcloseTask 迪耐克/鸿蒙病房网关或医院物联平台输出的标准事件

设备准入按 A/B/C/D 分级治理:

等级 标准 能否进入核心闭环
A 级 支持医梦统一客户端,开放 API/SDK,支持远程运维和日志 可以进入核心闭环
B 级 支持 Web/H5 嵌入或标准接口,能完成基础业务 可进入部分闭环
C 级 只能播放内容或展示页面,不开放接口 不进入核心闭环,只做展示
D 级 无接口、无系统、无法远程管理、稳定性差 不建议采购或接入

中医四诊仪适配采用更保守的 MVP 路径。行业公开产品通常把舌诊、面诊、脉诊、问诊作为多模态采集和辅助分析能力,涉及专用相机、脉象传感器、厂商算法或云端 API,不能按普通屏幕设备处理。

阶段 范围 技术路径 不做
MVP 舌诊 / 面诊图片采集与结果卡片 复用厂商 SDK 或文件上传接口,OpenPlatform 保存 fileId,调用专精模型或厂商 API,返回舌诊/面诊结果卡片 不自研采集硬件,不训练新模型
P1 问诊结构化 + 舌面结果合并 Dify 问诊流程 + 四诊结果卡片,医生确认后进入 EMR 摘要 不自动生成诊断和处方
P2 脉诊 / 多设备联动 仅在厂商提供稳定 SDK、数据格式和验收样例后接入 不承诺首期接入所有四诊能力

四诊仪链路:

flowchart LR
    Device["四诊仪<br/>舌象/面象/脉象/问诊采集"]
    Adapter["FourDiagnosisAdapter<br/>厂商 SDK / 文件上传 / API"]
    File["File Service<br/>fileId / 加密 / 审计"]
    Model["专精模型或厂商分析 API"]
    Card["四诊结果卡片<br/>辅助解释 / 风险提示"]
    Doctor["医生确认"]
    EMR["EMR 摘要写回"]

    Device --> Adapter --> File --> Model --> Card --> Doctor --> EMR

验收以“采集成功、图片质量可判定、结果卡片可解释、医生确认可追溯”为准。第一期不得承诺四诊结论自动诊断、自动处方或跨厂商通用算法。

5.10.3 服务找人主动签到 POC

鸿蒙协同不应写成全院设备自动互联,而应落到“服务找人”的小闭环。第一期推荐主动签到 POC。空海会议后,本节的正式口径应从“某个近场设备触发签到”升级为“感知到患者动线阶段后,把下一步服务外显到当前设备”,但 P0 仍只做诊区/诊室门口的低门槛场景。

sequenceDiagram
    participant P as 患者手机 / 小程序
    participant N as 近场设备 / 诊室门口屏
    participant D as Device Event Hub
    participant O as OpenPlatform
    participant Q as 叫号系统
    participant H as HIS / 签到系统

    P->>N: 到达诊室门口区域
    N->>D: 上报患者靠近事件
    D->>O: 归一为 service_find_patient 事件
    O->>Q: 查询当前队列与患者状态
    O->>H: 查询是否允许签到
    O-->>P: 推送签到服务卡片
    P->>O: 用户确认签到
    O->>H: 调用签到接口
    O->>Q: 同步叫号状态
    O-->>P: 返回候诊提醒

兜底路径必须同时存在:鸿蒙生态设备发现、星闪/近场通信、BLE Beacon、Wi-Fi/院内定位、二维码/NFC、小程序位置授权。签到、支付、挂号等动作都必须由患者确认,不能因为“服务找人”而自动完成高风险操作。

感知能力分级:

级别 能力 适用阶段 医梦职责
L0 二维码、人工确认、终端点选 所有医院可用,P0 必备 提供卡片、接口和审计
L1 NFC 碰一碰、刷卡、手机/手表确认 P0 推荐 提供绑定和解绑流程,不保存长期轨迹
L2 BLE Beacon / Wi-Fi 区域判断 P1 试点 只判断是否进入服务区域,事件需患者确认后生效
L3 星闪 / 鸿蒙近场 / UWB 高精度 标杆 POC 只在医院和设备方已有能力时接入,不作为首期交付前置条件

服务找人触发表:

动线状态 感知事实 推荐服务卡片 必须确认
已挂号未签到 患者到达诊区或诊室门口 主动签到卡、候诊队列提醒
已就诊待缴费 HIS/Mock 产生缴费或处置状态,患者靠近自助机/屏幕 缴费引导卡、窗口/自助机导航
已缴费待检查 检查/检验状态存在,患者靠近机器人/导诊屏 检查导航卡、注意事项卡 否,导航可直接展示
报告已出 报告状态更新,患者再次到院或打开终端 报告解读入口卡 是,涉及个人报告
特殊人群 老人、孕产妇、轮椅、急诊等标签或人工标记 人工协助、优先引导、无障碍路线 是或人工确认

近场设备硬件策略:

方案 定位 适用条件 医梦责任
推荐 MVP:诊室门口小屏 + BLE Beacon / NFC / 二维码 最小可落地方案 医院暂不具备成熟鸿蒙近场生态时 医梦提供设备准入、客户端、场景配置和联调;硬件采购按项目合同确认
标杆 POC:鸿蒙生态近场设备 / 星闪能力 展示“服务找人”亮点 医院和设备方具备鸿蒙生态设备与接口 医梦负责事件接入、卡片推送、签到闭环;不承诺全院覆盖
兜底方案:小程序定位授权 + 二维码签到 低成本兜底 近场设备部署受阻或权限不足时 医梦负责软件流程,体验弱于主动触达

第一期不建议采购复杂定位基站或做全院级精准定位。主动签到只要求判断“患者是否到达诊室门口服务区域”,不需要保存患者全院移动轨迹。

隐私合规规则:

  1. 位置和近场感知属于敏感个人信息相关处理,必须有明确目的、充分必要性和严格保护措施。
  2. 首次使用服务找人时,患者端必须明确告知采集范围、用途和保存时间,并取得授权。
  3. MVP 只采集诊室门口服务区域的到达事件,不保存连续历史轨迹。
  4. 事件日志保存 patientId_hash / visitId / deviceId / eventTime / actionResult,不保存可复原的移动路线。
  5. 患者拒绝授权时,必须可降级为扫码/NFC/人工签到。

5.11 常用医疗场景流程

本节用端到端流程检查方案能否闭环。所有流程都遵守同一原则:OpenPlatform 掌握入口、身份、会话、卡片和计量事实;Dify 负责流程编排;MCP 负责院内系统工具;计量中心按业务事实和合同规则结算。

5.11.1 智能分诊后挂号

flowchart TD
    U["用户描述症状"]
    API["OpenPlatform<br/>鉴权 / 幂等 / 额度检查"]
    Dify["Dify Workflow<br/>意图识别 / 分诊 / RAG"]
    DeptTool["MCP: 查询科室/医生/号源"]
    DeptCard["科室/医生/时间卡片"]
    Action["AgentActionOrchestrator + CardActionService<br/>用户选择"]
    Confirm["确认挂号卡片<br/>L3 二次确认"]
    WriteTool["MCP: 锁号 + 创建预约"]
    HIS["HIS"]
    Meter["计量中心<br/>billingEpisode 统一计费"]

    U --> API --> Dify --> DeptTool --> HIS
    HIS --> DeptTool --> Dify --> DeptCard --> Action
    Action --> Dify
    Dify --> Confirm --> WriteTool --> HIS
    API -.原始调用.-> Meter
    Action -.卡片动作.-> Meter
    WriteTool -.内部工具成本.-> Meter

计费规则:一次用户主动分诊请求和其 synthetic 链路归入同一 billingEpisodeId,按“智能分诊/导诊一次”计费;挂号确认是新的业务事实,按“挂号服务”计费。MCP_TOOL_WRITE 只进入内部成本,除非合同明确把某类写操作单独对客户计费。

5.11.2 患者建档

flowchart TD
    U["用户发起建档"]
    API["OpenPlatform<br/>鉴权 / 患者授权"]
    Dify["Dify Workflow<br/>返回建档卡片结构"]
    Form["前端建档卡片<br/>用户填写 PII"]
    CardAPI["AgentActionOrchestrator + CardActionService<br/>字段校验 / 加密 / 审计"]
    MCP["MCP: his_create_patient"]
    HIS["HIS 患者主索引"]
    Meter["计量中心<br/>建档业务事件"]
    Audit["敏感操作审计"]

    U --> API --> Dify --> Form
    Form --> CardAPI --> MCP --> HIS
    CardAPI --> Audit
    MCP --> Audit
    CardAPI -.CARD_ACTION_CONFIRMED.-> Meter
    MCP -.MCP_TOOL_WRITE 内部成本.-> Meter

安全规则:Dify 只输出建档卡片结构,不预填姓名、身份证、手机号等 PII。PII 从前端提交后,经 Agent 编排、CardActionService 状态校验和后端加密链路进入 MCP/HIS;日志、Outbox、计量事件只保存摘要、字段完整度、HIS patientId 和 traceId。

5.11.3 舌诊

flowchart TD
    Upload["上传舌象图片"]
    FileAPI["FileAPI<br/>鉴权 / 类型 / 大小 / 安全扫描"]
    OSS["对象存储<br/>加密保存"]
    Chat["OpenPlatform Chat<br/>携带 fileId"]
    Engine["AgentEngine<br/>Dify 或 DirectLLM"]
    Model["视觉模型 / 舌诊模型"]
    Result["舌诊结果卡片"]
    Meter["计量中心<br/>IMAGE_ANALYSIS"]
    Audit["文件与分析审计"]

    Upload --> FileAPI --> OSS
    Chat --> Engine --> Model --> Result
    FileAPI --> Audit
    Engine --> Audit
    Chat -.文件类型识别.-> Meter
    Result -.分析完成.-> Meter

计量规则:IMAGE_ANALYSIS 由 OpenPlatform 统一产生。OpenPlatform 在构造 AgentRequest 时识别 files 中的图片数量和类型,在模型调用完成后按文件类型、图片数量和场景生成计量事件。Dify/DirectLLM 只提供 usage 和模型成本信息,不决定客户侧计量项。

5.11.4 面诊

flowchart TD
    Upload["上传面部图片"]
    FileAPI["FileAPI<br/>人脸敏感数据标记"]
    OSS["对象存储<br/>加密 + 访问审计"]
    Chat["OpenPlatform Chat"]
    Model["视觉模型 / 面诊模型"]
    Post["平台后处理<br/>敏感特征裁剪"]
    Card["面诊结果卡片"]
    Meter["计量中心<br/>IMAGE_ANALYSIS"]
    Audit["敏感数据审计"]

    Upload --> FileAPI --> OSS
    Chat --> Model --> Post --> Card
    FileAPI --> Audit
    Post --> Audit
    Chat -.图片计量上下文.-> Meter
    Card -.完成事件.-> Meter

合规规则:面部图片和特征属于个人敏感数据。卡片快照只保存医学解释结论、风险提示、建议动作和必要 traceId,不保存原图引用、面部特征向量或可复原的结构化人脸特征。

5.11.5 诊前预问诊与病历草案

flowchart TD
    Patient["患者端<br/>文本 / 语音 / 点选"]
    API["OpenPlatform<br/>身份 / 授权 / episode"]
    Dify["Dify Workflow<br/>多轮追问 / 问题树"]
    Knowledge["平台 RAG/MCP Tool<br/>问诊模板 / 诊疗规则"]
    Draft["结构化预问诊报告<br/>主诉 / 现病史 / 既往史"]
    Doctor["医生站<br/>医生确认 / 修改"]
    EMR["EMR<br/>写入病历草案"]
    Meter["计量中心<br/>previsit_episode"]
    Audit["审计<br/>AI 输出 + 医生修改"]

    Patient --> API --> Dify --> Knowledge
    Knowledge --> Dify --> Draft --> Doctor --> EMR
    Draft -.预问诊完成.-> Meter
    Doctor --> Audit
    EMR --> Audit

规则:预问诊输出只能作为病历草案,不能直接形成正式病历。写入 EMR 前必须有医生确认或医院明确授权的流程节点。计费按“完整预问诊单”或“预问诊 episode”计算,多轮追问和 synthetic 调用归并到同一 episode。

5.11.6 诊间语音病历与质控

flowchart TD
    Audio["诊间音频"]
    ASR["ASR<br/>说话人分离 / 实时转写"]
    NLP["结构化抽取<br/>症状 / 体征 / 诊断 / 药品"]
    Draft["SOAP / 病历草案"]
    QC["质控服务<br/>完整性 / 逻辑 / 时限"]
    CDSS["CDSS<br/>鉴别诊断 / 用药风险"]
    Doctor["医生确认"]
    EMR["EMR 正式保存"]
    Meter["计量中心<br/>ASR_MINUTE / EMR_DRAFT / QC"]
    Audit["审计<br/>AI 建议 + 医生采纳"]

    Audio --> ASR --> NLP --> Draft --> Doctor --> EMR
    Draft --> QC --> Doctor
    Draft --> CDSS --> Doctor
    ASR -.分钟成本.-> Meter
    Draft -.病历生成.-> Meter
    QC -.质控事件.-> Meter
    Doctor --> Audit

规则:诊间病历、CDSS、用药安全都属于医生主导场景。AI 可生成草案、提示风险、推荐方案,但正式诊断、处方、医嘱必须由医生确认和签名。计量上,ASR 分钟、病历生成、质控/CDSS 可以形成同一个诊中 episode 下的多个业务事件,账单按合同约定展示为单项或组合服务。

5.11.7 住院入院评估、床位与护理闭环

flowchart TD
    Patient["患者 / 医护发起入院评估"]
    API["OpenPlatform<br/>住院 episode"]
    Dify["Dify Workflow<br/>预评估 / 护理等级建议"]
    BedTool["MCP: 床位 / 手术 / 检查资源"]
    Ward["病区护士站 / 床位中心"]
    Confirm["医护确认"]
    HIS["HIS / 住院系统"]
    IoMT["IoMT<br/>体征 / 跌倒 / 输液"]
    Alert["护理风险预警 / 任务派发"]
    Meter["计量中心<br/>inpatient_assessment / IoMT事件"]

    Patient --> API --> Dify --> BedTool --> HIS
    BedTool --> Ward --> Confirm --> HIS
    IoMT --> Alert --> Ward
    Dify -.评估完成.-> Meter
    IoMT -.监测/预警事件.-> Meter

规则:床位、护理等级、出入院安排都属于高影响业务,AI 只能给建议或草案,医护确认后才能写入住院系统。IoMT 预警默认按事件或服务包计量,不能把每一次设备心跳都作为客户侧扣费事件。

5.11.8 出院小结与随访闭环

flowchart TD
    Discharge["医生触发出院意向"]
    Data["病历 / 检查 / 医嘱 / 手术记录"]
    Agent["出院小结 Agent"]
    Summary["出院小结草案 / 康复计划"]
    Doctor["医生审核确认"]
    FollowPlan["随访计划"]
    FollowAgent["AI 随访<br/>电话 / 微信 / 问卷"]
    Risk["风险分层<br/>稳定 / 需关注 / 高危"]
    Workbench["护士 / 医生工作台"]
    Meter["计量中心<br/>文书 / 随访分钟 / 随访次"]

    Discharge --> Data --> Agent --> Summary --> Doctor
    Doctor --> FollowPlan --> FollowAgent --> Risk
    Risk --> Workbench
    Summary -.文书生成.-> Meter
    FollowAgent -.随访计量.-> Meter

规则:出院小结属于正式医疗文书,AI 只能生成草案。随访中识别为高危的患者必须升级人工,不允许 AI 独立完成医疗处置。计费可按出院小结份数、随访分钟、随访次数或合理不限量服务包归集。

5.12 非对话式 AI 管道

不是所有 AI 医院场景都适合走 /api/v1/agent/chat。诊间语音、IoMT 护理预警、AI 外呼随访属于流式、事件驱动或任务调度型能力,需要进入同一个审计和计量体系,但入口形态不同。

5.12.1 流式音频处理管道

flowchart LR
    Mic["诊室麦克风 / 医生站"]
    WS["OpenPlatform Audio Gateway<br/>WebSocket / 音频片段"]
    ASR["ASR Service<br/>转写 / 说话人分离"]
    NLP["结构化服务<br/>医学实体 / SOAP"]
    Agent["AgentEngine<br/>Dify 或 DirectLLM"]
    QC["质控 / CDSS"]
    Doctor["医生确认"]
    EMR["EMR"]
    Meter["计量中心<br/>ASR_MINUTE / EMR_DRAFT / QC"]

    Mic --> WS --> ASR --> NLP --> Agent --> QC --> Doctor --> EMR
    WS -.音频时长.-> Meter
    Agent -.文书事件.-> Meter
    QC -.质控事件.-> Meter

实现规则:

  1. 音频入口必须由 OpenPlatform 建立连接和鉴权,不能由 ASR 服务直接暴露给外部终端。
  2. ASR 可用第三方接口、院内模型或本地服务,但返回结果必须带 traceId/sessionId/durationSeconds
  3. ASR 后的结构化文本可以进入 Dify Workflow,也可以进入 DirectLLM 或质控服务,但都要带同一 billingEpisodeId
  4. ASR 分钟由 OpenPlatform Audio Gateway 或 ASR 返回时长统一产出计量事件。
  5. 病历草案、质控建议、CDSS 建议必须由医生确认后才能写入 EMR。

5.12.2 IoMT 事件处理管道

住院 IoMT 的责任边界必须前置说明:医梦不直接接管床垫、雷达、输液泵、生命体征设备等病房硬件的接入、认证和原始数据采集。住院侧优先由迪耐克/鸿蒙病房体系或医院既有物联平台完成设备接入和数据归一,医梦 IoMT Event Hub 只接收已标准化的业务事件、预警事件或护理任务事件,并在此基础上做 AI 解释、风险分级和闭环审计。

flowchart LR
    Device["IoMT 设备<br/>床垫 / 雷达 / 输液泵 / 生命体征"]
    WardGateway["迪耐克/鸿蒙病房网关<br/>设备认证 / 原始数据归一"]
    Hub["医梦 IoMT Event Hub<br/>标准事件接收 / 患者床位映射 / traceId"]
    Rule["规则与 AI 预警<br/>跌倒 / 离床 / 输液 / 体征"]
    Task["护理建议 / 预警工单"]
    Nurse["护士站 / PDA"]
    Outbox["Outbox / Event Ingestion"]
    Meter["计量中心<br/>IOMT_ALERT / NURSING_TASK"]
    Audit["护理闭环审计"]

    Device --> WardGateway --> Hub --> Rule --> Task --> Nurse
    Task --> Outbox --> Meter
    Task --> Audit

实现规则:

  1. 住院设备认证、原始心跳、连续体征采集默认由迪耐克/鸿蒙病房体系或医院物联平台负责。
  2. 医梦只校验事件来源系统、医院/病区/床位绑定、事件签名和事件幂等键,不直接管理 IoMT 设备硬件生命周期。
  3. 设备原始心跳和连续体征通常只做设备方或医院物联平台内部数据,不作为客户侧能力值扣费事件。
  4. 形成护理预警、任务派发、人工处理闭环时,才生成客户可解释的业务事件。
  5. IoMT 事件进入统一 Outbox 或事件接入表,再进入 Metering,不允许直接写账本。
  6. 高危预警必须有护士或医生处理状态:pending、acknowledged、handled、escalated、closed。

5.12.3 AI 外呼随访管道

flowchart LR
    Plan["随访计划"]
    Job["SnailJob<br/>任务调度"]
    Gateway["语音网关<br/>外呼 / 状态回调"]
    ASR["ASR / 对话理解"]
    Agent["随访 Agent<br/>Dify 或 DirectLLM"]
    Risk["风险分层"]
    Human["人工升级<br/>护士 / 医生"]
    Meter["计量中心<br/>FOLLOWUP_CALL_MINUTE / FOLLOWUP_COMPLETED"]
    Audit["随访审计"]

    Plan --> Job --> Gateway --> ASR --> Agent --> Risk
    Risk --> Human
    Gateway -.通话分钟.-> Meter
    Risk -.随访结果.-> Meter
    Agent --> Audit

实现规则:

  1. 外呼随访由随访计划和 SnailJob 触发,不依赖用户主动打开页面。
  2. 电话号码、患者身份和随访内容按 PII/医疗敏感数据处理,通话录音按合同和医院要求保存或不保存。
  3. 语音网关回调必须带 callId、projectId、patientId/visitId、状态、时长和失败原因。
  4. 随访结果可由 Dify 或 DirectLLM 做风险分层,但“需关注/高危”必须进入人工处理台。
  5. 计量按通话分钟、完成次数或合理不限量服务包归集,失败外呼按合同定义是否计入内部成本。

5.13 场景覆盖矩阵与验收口径

场景 主要入口 核心业务事实 客户侧计费单元 必须人工确认 关键验收指标
导诊问答 导诊大屏 / 患者端 / 机器人 完成一次导诊答复 次 / episode / 设备服务包 答复准确率、转人工率、设备在线率
智能分诊挂号 导诊屏 / 患者端 / 自助机 分诊完成、挂号确认 分诊次 + 挂号服务 L3 挂号确认 分诊命中率、挂号成功率
患者建档 患者端卡片 HIS 创建 patientId 建档成功次 建档成功率、PII 脱敏合规
舌诊 / 面诊 文件上传 + 对话 图像分析完成 图片分析次 医疗建议需医生确认 图片质量通过率、分析完成率
预问诊 患者端 结构化问诊单完成 问诊单 / episode 正式病历需医生确认 问诊完整度、医生采纳率
到院签到 / 叫号 诊室门口屏 / 自助机 / 小程序 签到成功、叫号状态同步 签到服务次 / 入口服务包 签到成功率、误触发率、叫号同步延迟
诊间病历 诊室桌面屏 / 医生站插件 病历草案生成并确认 份 / ASR分钟 病历书写节省时间、修改率
CDSS / 用药审核 医生站 风险提示或建议生成 次 / 事件 预警采纳率、误报率
住院评估 患者端 / 护士站 入院评估报告 次 / episode 评估完整度、床位匹配成功率
护理预警 IoMT / 护理白板 / PDA 高风险预警事件 事件 / 服务包 高危必须人工处理 预警及时率、闭环处理率
出院小结 医生站 文书草案生成并确认 文书生成时间、质控通过率
随访 电话 / 微信 / APP 随访完成或风险升级 分钟 / 次 高危必须人工处理 随访完成率、高危触达率
设备运行 门诊统一入口客户端 / Device Registry 设备在线、版本、异常、场景加载 设备授权 / 运维服务 在线率、故障恢复时间、远程升级成功率

验收时不能只看“接口调用成功”或“设备通电能打开”。每个场景至少要验证:业务事实是否落库、是否可追溯到 traceId、是否携带 deviceId、是否生成正确计量事件、是否按合同计费、是否有人工确认或升级路径、是否进入运营指标。

6. 二期数据模型

二期只保留必要的元数据模型,完整 SQL 不放在方案正文,应放在迁移脚本或实施文档中。

6.1 核心表

角色 关键字段
ai_agent_app 智能体元数据 agent_idproject_idengine_config_idagent_typestatus
ai_agent_engine_config 引擎连接配置 engine_typeconfig_jsonproject_idstatus
ai_conversation 开放平台会话 conversation_idexternal_conversation_idagent_iduser_id
ai_task_instance 多轮业务任务状态 task_idconversation_idtask_typestatuscurrent_stepagent_codecontext_jsondevice_idtrace_id
ai_usage_log 原始调用日志 prompt_tokenscompletion_tokensworkflow_run_idlatency_ms
ai_card_definition 卡片定义 card_keyversionschema_jsonui_config_jsonactions_json
ai_card_instance 卡片实例 instance_idconversation_idmessage_idstate_jsonstatus
ai_card_action_log 卡片动作日志 instance_idaction_nameaction_payloadstatus
ai_device_registry 设备注册中心 门诊设备:device_idhospital_iddepartment_iddevice_typevendormodellocation_jsoncapabilities_jsonstatusclient_versionlast_heartbeat;住院嵌入端:仅记录 external_systemexternal_terminal_idward_id/bed_idinterop_statuslast_event_time
ai_device_scene_binding 设备场景绑定 device_idscene_codeui_templateagent_bindings_jsontool_scopes_jsoneffective_time
ai_device_event 设备事件日志 device_idevent_typeevent_payloadtrace_idoccurred_atstatus
ai_iomt_event IoMT/病房事件 event_iddevice_idpatient_id_hashbed_idevent_typerisk_levelbusiness_status

6.2 关键修正

  1. ai_usage_log 是事实日志,不是财务账本。三期要新增不可变计量账本,避免日志补写、失败重试、异步丢失导致账单不可信。
  2. ai_conversation.agent_id 使用 ai_agent_app.id,对外 API 使用 agent_id 字符串,Service 层完成映射。
  3. ai_card_instance 必须保存 UI 和动作快照,避免卡片定义升级影响历史会话。
  4. ai_agent_engine_config.config_json 可继续存 Dify / Direct / Mock 差异配置,但生产环境应加密敏感字段,不能明文暴露密钥。
  5. project_id 要成为权限、额度、账单的核心维度;tenant_id 不能长期使用默认值,应由项目绑定医院/租户。
  6. ai_device_registry 是门诊总包的基础表。门诊侧导诊屏、自助机、机器人、叫号屏、诊室屏、四诊仪必须有医梦管理的设备身份、位置、能力、状态和心跳监控。住院侧护理白板、床头屏由迪耐克/鸿蒙病房体系管理设备身份和硬件状态,医梦只记录必要映射标识、互通状态和最后事件时间,不承担住院设备心跳监控和硬件管理责任。
  7. ai_device_scene_binding 不能写死在前端。设备在哪个位置、加载哪个 UI 模板、绑定哪些智能体、允许哪些工具,要能由后台配置和灰度。
  8. ai_device_eventai_iomt_event 默认是业务和运维事实,不等于财务账本。只有形成可解释业务事实,例如签到成功、护理预警闭环、设备授权周期,才进入计量中心。

7. 二期接口边界

7.1 对外 API

接口 用途 备注
POST /api/v1/agent/chat 智能体对话,支持同步和 SSE 二期主入口
POST /api/v1/device/register 设备注册或重新激活 统一入口客户端启动时调用
POST /api/v1/device/heartbeat 设备心跳、版本、状态上报 支持故障定位和在线率统计
GET /api/v1/device/{deviceId}/scene 获取设备当前场景配置 返回 UI 模板、默认智能体、工具权限
POST /api/v1/device/{deviceId}/events 上报设备事件 近场、扫码、打印、异常、IoMT 入口
POST /api/v1/conversation/create 创建会话 可选,chat 无会话时也可自动创建
GET /api/v1/conversation/list 查询会话列表 按项目、智能体、用户隔离
GET /api/v1/conversation/{conversationId} 查询会话详情 需校验项目归属
POST /api/v1/card/{instanceId}/actions/{action} 卡片动作执行 建议二期补齐
GET /api/v1/card/{instanceId} 查询卡片实例状态 支持前端恢复、超时、刷新

7.2 管理后台 API

能力 用途
智能体管理 配置智能体、绑定项目、选择引擎配置
引擎配置管理 管理 Dify / Direct / Mock 配置
卡片定义管理 管理内置卡片、版本、状态、灰度
MCP 工具管理 管理 HIS 工具、厂商配置、超时、熔断
设备注册管理 管理设备身份、位置、能力、状态、版本、SLA
场景绑定管理 管理设备、场景、智能体、UI 模板、工具权限
设备准入管理 管理 A/B/C/D 准入等级、厂商测试、联调验收
调用日志查询 排查对话、Dify、MCP、卡片动作链路

7.3 接口设计原则

初级工程师实现接口时应遵守这些规则:

  1. 对外接口稳定,内部模型可演进:API 不直接暴露数据库字段,使用 DTO/VO。
  2. 所有写接口必须幂等:卡片动作、MCP 写工具、账本扣减都必须有幂等键。
  3. 查询接口按项目隔离:任何会话、卡片、账单查询都要校验 projectId
  4. 设备接口按设备证书和项目绑定隔离:设备不能只靠 deviceId 字符串接入,必须校验证书/密钥、医院、科室和准入状态。
  5. 错误码统一:Dify 错误、MCP 错误、HIS 错误、设备 SDK 错误要映射成平台错误码。
  6. 响应携带 traceId:前端、设备、日志、账本、MCP 调用都能通过 traceId 串起来。
  7. 不要把复杂 JSON 当黑盒config_jsonstate_jsoncapabilities_jsonagent_bindings_json 可以存 JSON,但 Service 层要有明确解析对象和校验规则。

7.4 API 幂等设计

所有会产生业务事实的接口都必须支持 X-Emoon-Idempotency-Key。幂等键由调用方生成,平台按项目隔离保存,避免不同医院或不同项目之间误判重复。

接口类型 幂等键建议 重复请求返回
对话请求 projectId + resolvedAgentId/routeKey + clientMessageId 返回第一次会话消息结果;统一入口客户端未传 agentId 时由后端路由结果补齐
设备事件 projectId + deviceId + eventType + clientEventId 返回第一次事件接收结果
卡片动作 projectId + cardInstanceId + actionName + clientActionId 返回第一次动作结果
MCP 写工具 projectId + toolName + businessKey 返回第一次工具调用结果或最终查询结果
能力值冻结 accountId + sourceEventId + freezePurpose 返回第一次 freezeId
能力值结算 accountId + meterEventId 返回第一次结算流水

幂等记录需要保存:

字段 说明
idempotency_key 外部幂等键,项目内唯一
request_hash 请求摘要,用于识别同键不同请求
status processing / succeeded / failed / expired
response_snapshot 首次成功响应摘要
trace_id 首次处理 traceId
expire_at 幂等记录保留到期时间

合并规则:

  1. 同一幂等键、同一请求摘要、首次成功:直接返回第一次结果。
  2. 同一幂等键、不同请求摘要:返回幂等冲突,不执行新请求。
  3. 首次仍在处理中:返回处理中状态,前端轮询或等待 SSE。
  4. 首次失败但属于可重试错误:允许在同一幂等记录下重试,并保留重试次数。
  5. 首次失败但 HIS 写操作状态不明:先查询最终状态,禁止直接重复写。

API 幂等与计量幂等的关系:

  1. API 幂等命中且返回首次结果时,不产生新的业务事实,也不产生新的计量事件。
  2. API 幂等记录中的 trace_id/source_id 用于定位第一次请求生成的计量事件。
  3. 计量幂等键面向“业务事实”,API 幂等键面向“请求处理”,两者可以不同,但必须通过 traceId + sourceId 建立关联。
  4. 如果第一次请求业务成功但计量处理失败,应通过 Outbox 重放修复,不能靠重复 API 请求补扣。

初级工程师重点:幂等不是“加 Redis 锁”。
Redis 锁只能减少并发进入,不能证明业务是否已经成功。真正的幂等要有数据库记录和唯一约束,能在服务重启、Redis 丢失、网络超时后仍然判断“这件事是否做过”。

8. 二期技术合理性评估

8.1 合理设计

设计 评价
Dify Workflow 承载流程编排 合理。适合频繁调整的问诊、导诊、咨询流程
MCP Server 统一对接 HIS 合理。可以降低多厂商 HIS 的适配复杂度
AgentEngine 抽象 合理。Dify、直连模型、Mock 可以共存
卡片承载确定性操作 合理。医疗流程不能完全依赖自然语言
卡片实例快照 必须保留。否则历史卡片会受模板升级影响
统一入口客户端 必须新增。医院最新方案要求所有门诊带屏设备和机器人都能进入医梦统一入口
Device Registry / Adapter 必须新增。设备数量、厂商和能力差异会成为门诊总包交付的主要风险
Scene Orchestrator 必须新增。同一设备在不同位置、时间、患者状态下加载不同智能体和 UI
住院 AI 大脑层 合理。与迪耐克/鸿蒙病房体系互通,避免医梦背负住院硬件总包责任

8.2 需要避免的风险

风险 修正方案
Dify 过度承担业务和账本 Dify 做编排,OpenPlatform 做权限、审计、计量、账本
卡片动作绕过 MCP 直连 HIS 统一经过 MCP Server,保证工具治理和审计
用 token 日志直接生成账单 新增计量账本和能力值扣减流水
每个细节都做第三方插件化 三期前以内置医疗卡片为主,第三方生态后置
HIS 工具无幂等和熔断 所有写操作必须有业务幂等键、超时、补偿和人工兜底
医疗建议不可追溯 记录 Dify workflow run、知识引用、工具输入输出摘要、医生确认动作
设备各自为政 所有 P0 设备必须接入统一入口客户端或标准协议,不能项目现场临时页面堆叠
设备准入失控 建立 A/B/C/D 准入和联合验收,接口不开放的设备不进入核心闭环
住院边界扩散 医梦只负责 AI 服务、事件解释和业务闭环,不承担床头屏/护理白板硬件故障主责
鸿蒙过度承诺 第一阶段只承诺主动签到等 POC,保留 BLE/NFC/二维码/小程序位置授权兜底

9. 三期目标:商业闭环优先

三期目标是把 AI 中台从“可调用”升级为“可收费、可控额、可结算、可运营、可审计”的生产平台。

9.1 商业规则

设计结论
合同主粒度 项目 / 医院客户
额度来源 合同签署时购买能力值包,形成预付账户
分摊维度 科室、智能体、用户、设备、终端类型、场景
扣费方式 调用前校验,高成本任务先冻结,完成后按实际能力值结算
余额不足 软拦截优先,按合同边界、能力风险和审批策略处理
医疗关键链路 不因计费简单中断,但必须记账、预警、审批或事后结算
合理不限量 仍需内部计量,用于风控、成本核算和边界判定
设备授权 统一入口客户端可按设备、场景、年度授权计费
设备集成 设备接入、适配、测试、验收进入项目实施费扩展项
设备运维 设备巡检、远程配置、版本升级、异常告警进入综合运营服务费

9.2 合作模式与工程能力映射

业务文档中的 L1/L2/L3 不是销售标签,它们决定工程交付深度、部署形态、计量方式和运营责任。

合作模式 客户购买的核心价值 工程最小能力 计费与运营要求
L1 标准能力接入版 买单点 AI 能力 API 鉴权、AgentEngine、标准能力接口、用量日志、基础计量 接入开通费 + 能力值包;按能力值扣费,基础用量报表
L2 院级场景建设版 买场景交付结果;门诊总包是 L2 的增强子类型,不单独新增中间编号 Dify Workflow、卡片运行时、MCP/HIS 集成、医生确认、场景验收、运营看板;门诊总包子类型增加统一入口客户端、Device Registry、Device Adapter、设备准入、供应商联调 项目实施费 + 综合运营服务费 + 能力值包或合理不限量;门诊总包子类型增加设备集成服务费、入口客户端授权、运维服务费
L3 区域平台运营版 买多院平台运营能力 区域项目、医院子池、多院权限、多院审计、区域驾驶舱、统一计量与分账、设备运营看板 区域项目实施费 + 区域运营服务费 + 区域能力池 + 设备授权
私有平台共创版 买自主建设能力,作为内部扩展形态,不进入对外 L1/L2/L3 编号体系 平台授权、Builder、Workflow 编排、多模型/知识库/MCP 扩展、域空间隔离 平台授权费 + 运维服务 + 联合运营或分成

工程实现要避免“所有客户都上一套最重方案”。L1 只要求标准能力稳定接入;L2 才需要深度 HIS/EMR/LIS/PACS 集成和场景验收,其中门诊总包只是 L2 的增强子类型;L3 才引入区域能力池、多院监管和统一运营;私有平台共创版作为专项合同处理,不改变 L1/L2/L3 对外口径。

9.3 收费项与系统模块关系

收费项 系统如何支撑 不应混淆的点
接入开通费 项目、公私钥、智能体授权、联调环境、基础验收 不是能力值,不进入用量账本
项目实施费 场景配置、卡片、MCP Adapter、HIS 联调、培训验收、项目里程碑 是交付收入,不随调用量扣减
综合运营服务费 巡检、工单、版本升级、安全审计、运营报告、培训记录 不是简单服务器运维费
能力值包 ai_credit_account + ai_credit_ledger 面向按量服务,支撑超量计费
合理不限量服务包 ai_quota_policy + ai_cost_record + ai_operation_report 客户余额不扣,但内部成本和异常必须计量
设备集成服务费 设备清单、准入测试、Adapter 联调、联合验收、现场培训 是项目交付收入,不按每次调用扣减
统一入口客户端授权费 ai_device_registry + license_policy 支撑按设备/场景/年度授权 不是 AI 能力值,设备离线也可能占用授权
设备运维服务费 心跳监控、远程配置、版本升级、设备异常工单、SLA 报告 不是硬件维修费,硬件故障主责仍按合同归属设备方
鸿蒙服务找人 POC 主动签到、候诊状态同步、近场能力联调、演示验收 不承诺全院鸿蒙化,属于标杆亮点专项
机器人场景服务费 机器人导诊、带路、语音交互、场景配置和运维 硬件采购、AI 能力、运行服务要分开报价

初级工程师重点:为什么实施费不能进能力值账本?
能力值账本记录“客户买了多少服务额度、用了多少”。项目实施费和运营服务费是交付和服务收入,和调用消耗不是同一类财务事实。如果混在一起,账单会无法解释,也无法对齐合同。

9.4 三期模块

flowchart LR
    Contract["合同与套餐中心"]
    Account["能力值账户中心"]
    Meter["计量中心"]
    Rating["定价与折算中心"]
    Billing["账单与结算中心"]
    Allocation["额度分摊中心"]
    DeviceLicense["设备授权与运维计费"]
    Risk["风控与审批中心"]
    Analytics["统计与运营中心"]
    Audit["审计与合规中心"]

    Contract --> Account
    Contract --> Rating
    Contract --> DeviceLicense
    Meter --> Rating
    Rating --> Account
    Account --> Billing
    Account --> Allocation
    Account --> Risk
    DeviceLicense --> Billing
    DeviceLicense --> Analytics
    Meter --> Analytics
    Billing --> Analytics
    Meter --> Audit
    Risk --> Audit

10. 三期功能设计

10.0 计费全景闭环

三期计费不是“每次模型调用都扣费”,而是“把多来源调用事实归并成可解释的业务计费单元”。一个业务计费单元称为 billingEpisode

flowchart LR
    Call["用户主动调用<br/>chat / card action / file analysis"]
    Context["计量上下文<br/>project / contract / scenario / episode"]
    Events["标准计量事件<br/>CHAT / CARD / MCP / IMAGE"]
    Merge["事件归并<br/>billingEpisode / parent_event"]
    Pricing["定价折算<br/>合同快照 / 规则快照"]
    Ledger["能力值账本<br/>freeze / settle / release"]
    Bill["月账单<br/>项目 / 科室 / 智能体分摊"]
    Report["运营报告<br/>成本 / 质量 / 风险"]

    Call --> Context --> Events --> Merge --> Pricing --> Ledger --> Bill --> Report

计费闭环规则:

  1. 用户主动发起的对话、卡片动作、文件分析创建新的 billingEpisodeId,除非它明确属于已有业务链路。
  2. synthetic message、Dify workflow run、MCP 查询、MCP 写操作默认作为 episode 下的子事件或成本明细,不直接形成客户侧“次”计费。
  3. 能产生客户价值的业务完成点才结算客户侧能力值,如分诊完成、挂号确认、建档成功、舌诊/面诊分析完成。
  4. 客户侧计费以 billingEpisode 和业务事件为主,内部成本以 token、图片、分钟、工具调用等 detail 记录。
  5. 账单只汇总已 settled 且未出账的账本流水;账单修正通过 reverse/adjust/correction,不改原流水。

billingEpisode 状态机:

stateDiagram-v2
    [*] --> open: 创建 episode
    open --> completed: 达到业务完成点
    open --> expired: 超时/用户中断
    completed --> settling: 进入定价和账本处理
    settling --> settled: 结算完成
    settling --> failed: 处理失败
    failed --> settling: 重试/重放
    settled --> billed: 进入账单
    expired --> closed: partial 处理完成
    billed --> closed: 归档

episode 边界规则:

场景 episode 处理
用户主动发起新 chat 默认创建新 episode
synthetic message 归入当前 episode
同一 conversation 内短时间卡片动作 默认归入当前 episode,除非动作本身定义为新的业务能力
业务完成点,如挂号确认、建档成功、图像分析完成 当前 episode 进入 completed 或创建子业务 episode
医生站独立触发质控、病历生成、CDSS 创建新 episode
IoMT 预警和外呼随访任务 由事件或任务创建 episode,不依赖 chat
episode 长时间未完成 进入 expired,按 partial 策略结算或不扣客户余额

10.1 合同与套餐中心

管理客户购买了什么、能用什么、在哪些边界内使用。

功能 说明
合同档案 客户、项目、医院、院区、合同周期、合作层级 L1/L2/L3
能力值包 试点包、标准包、深度包、旗舰包、区域包
服务包 合理不限量服务包、综合运营服务费、项目实施费
合同范围 医院、院区、科室、场景、智能体、模型、终端、并发
价格策略 标准价、折扣、超量价、阶梯价、赠送额度
状态管理 草稿、生效、暂停、过期、终止、续签

合同中心不直接扣费,只定义规则和边界。

10.2 能力值账户中心

每个项目默认一个主账户,可按科室或区域拆分子账户。

账户类型 用途
项目主账户 合同购买能力值进入主账户
科室预算账户 从主账户分配预算,不作为财务合同主体
智能体预算 控制单个智能体使用上限
区域总账户 L3 区域项目的总池
医院子账户 区域总池下的医院分配池

账户核心字段包括:

字段 说明
available_credits 可用能力值
frozen_credits 已冻结未结算能力值
used_credits 已使用能力值
granted_credits 合同授予能力值
valid_from / valid_to 有效期
overdraft_policy 超额策略

10.3 计量中心

计量中心采集标准事件,生成不可变流水。它是三期的核心。

计量事件来源

来源 事件
OpenPlatform 对话请求、流式完成、异常结束
DifyAdapter Dify message、workflow run、usage
MCP Server 工具调用、HIS 写操作、失败重试
Card Runtime 卡片展示、卡片确认、卡片动作执行
语音服务 ASR、TTS、随访电话分钟数
图像服务 舌诊、面诊、影像类模型分析
文书服务 病历生成、质控、出院小结、报告解读

标准计量事件

字段 说明
event_id 全局唯一事件 ID
idempotency_key 幂等键,避免重复扣费
billing_episode_id 业务计费单元 ID,用于归并 synthetic、MCP、Card 等子事件
parent_event_id 父事件 ID,用于表达一次业务链路内的事件层级
project_id 计费主对象
dept_id 分摊维度
agent_id 智能体维度
device_id 设备维度,门诊总包和统一入口客户端授权使用
terminal_type 终端类型,如 kiosk、robot、doctor_desktop、waiting_screen
scenario_code 场景,如 triage、previsit、emr_write
meter_item 计量项,如 token、call、minute、image、document
raw_quantity 原始数量
credits 折算能力值
source_type openplatform / dify / mcp / card
source_id messageId / workflowRunId / toolCallId / instanceId
charge_policy customer_charge / license_covered / bundle_included / internal_cost / no_charge
contract_snapshot 合同关键快照,包含适用范围、折扣、套餐、超量规则
status pending / settled / reversed / failed

charge_policy 默认规则:

策略 含义 适用场景
customer_charge 从客户能力值账户扣减 高级 AI 能力、按次服务、超出套餐范围的调用
license_covered 已被设备授权费或场景服务费覆盖,不再扣能力值 设备首页、基础导览、基础 FAQ、设备运行服务
bundle_included 已被合理不限量或运营服务包覆盖,客户侧不扣余额 合同明确包含的场景包
internal_cost 只记内部成本,不对客户单独展示 RAG、MCP 查询、synthetic 调用、模型 token 明细
no_charge 不计费,仅留审计 失败、取消、测试、人工豁免

事件归并规则:

组合 客户侧计费 内部成本
用户主动 CHAT_COMPLETED + synthetic CHAT_COMPLETED 按同一 billingEpisodeId 计一次业务能力 synthetic token 进入 detail
CARD_ACTION_CONFIRMED + MCP_TOOL_WRITE 只对卡片确认业务事件定价 MCP 写操作进入工具成本
IMAGE_ANALYSIS + 模型 usage 对图像分析业务事件定价 token、图片张数、模型成本进入 detail
MCP_TOOL_READ 支撑卡片展示 默认不对客户单独扣费 记录工具查询成本
设备授权 + 基础交互 设备年费/月费覆盖,不重复扣能力值 记录设备活跃、并发和基础 token 成本
设备授权 + 高级 AI 能力 设备授权覆盖入口运行,高级能力按合同继续扣能力值 分别记录设备成本和能力成本
机器人场景服务费 + 导诊问答 场景服务费覆盖机器人运行服务,导诊/分诊能力按合同扣或包内 记录机器人在线、语音分钟、模型成本
失败或取消事件 默认不扣客户余额 可记录内部失败成本

10.4 定价与折算中心

把不同底层成本折算为能力值。

能力类型 建议计量方式
导诊问答 次 + token 阈值修正
智能分诊
预问诊 次 / 完整问诊单
报告解读
舌诊 / 面诊
语音随访 分钟
病历生成
病历质控
CDSS
MCP 写操作 次,通常并入业务能力,不单独对客户展示
RAG 检索 内部成本项,通常并入业务能力
设备授权 台 / 年或台 / 月,覆盖统一入口客户端基础运行
设备运维 台 / 月或项目 / 月,覆盖巡检、升级、告警、SLA
机器人运行服务 台 / 月或场景 / 年,覆盖机器人场景配置、语音交互运行、导航联调和运维
机器人 AI 能力 次 / 分钟 / episode,按导诊、分诊、问答、带路等能力进入能力值或服务包

定价规则应支持:

  1. 按智能体配置标准能力值。
  2. 按模型、token、分钟、图片张数做成本核算。
  3. 按合同覆盖范围决定是否免费、扣费、超量或审批。
  4. 按设备授权、场景服务费和能力值扣费三条线分流,避免一件事重复收费。
  5. 支持版本化,历史账单按当时规则回放。

10.5 额度预扣与结算

不同任务采用不同扣费策略。

任务类型 策略
普通问答 完成后扣费
高成本生成 调用前冻结预估额度,完成后结算
语音电话 分段冻结,按实际分钟结算
图像分析 调用前冻结单次额度,失败自动释放
HIS 写操作 业务成功后结算,失败不扣或按合同定义扣基础成本
合理不限量 不扣客户余额,但仍写内部计量与成本流水

扣费流水必须支持:

操作 说明
freeze 冻结能力值
settle 结算扣减
release 释放未使用冻结额度
reverse 冲正
adjust 人工调整
grant 合同授予或续包

10.6 账单与结算中心

账单按项目生成,支持多维分摊。

账单类型 用途
月度账单 客户对账
超量账单 能力值耗尽后的补费
科室分摊账单 医院内部核算
智能体用量账单 产品运营分析
区域结算账单 L3 区域能力池分配
内部成本账单 模型、语音、图像、硬件成本核算

账单生成后应支持状态流转:

draft -> confirmed -> invoiced -> paid -> archived

10.7 统计与运营中心

统计不是简单图表,而是支撑综合运营服务费的交付物。

看板 指标
项目总览 总用量、余额、预计耗尽日期、活跃智能体、异常调用
能力值消耗 日/月趋势、科室分摊、智能体分摊、场景排行
成本分析 模型成本、语音成本、图像成本、毛利估算
医疗场景效果 分诊命中率、预问诊完整度、病历节省时间、质控问题闭环率
运营服务 工单响应、巡检记录、升级记录、客户培训、版本发布
风险审计 超量、越权、异常峰值、高风险医疗建议、人工确认率

10.7.1 运营交付闭环

综合运营服务费必须有可交付物,否则客户会把它理解为普通运维费。运营中心需要把“系统是否持续产生价值”变成可查询、可导出、可复盘的数据。

flowchart LR
    Usage["用量与成本"]
    Quality["医疗质量指标"]
    Ops["运营服务记录"]
    Risk["风险与审计"]
    Report["月度/季度运营报告"]
    Action["运营动作<br/>培训 / 优化 / 续包 / 扩科"]

    Usage --> Report
    Quality --> Report
    Ops --> Report
    Risk --> Report
    Report --> Action
    Action --> Usage
运营对象 必须沉淀的数据 对应交付物
L1 客户 API 调用量、能力值余额、错误率、超量预警 月度用量简报、续包提醒
L2 单院 场景用量、科室分摊、分诊/预问诊/病历/质控效果、工单记录 月度运营报告、阶段复盘、培训记录
L3 区域 多院用量、医院排行、区域能力池、异常医院、统一审计 区域驾驶舱、监管报表、多院运营报告
合理不限量客户 内部成本、峰值、场景占比、合同边界命中 异常复核报告、边界调整建议

10.7.2 价值验收指标

业务附件中提到的门诊、住院建设目标需要落成可统计指标。以下指标不是全部上线第一天都要具备,但 L2/L3 项目验收必须至少选定一组。

场景 建议指标
AI 门诊 患者平均在院时间、分诊命中率、挂号成功率、预问诊完整度、患者满意度
诊间病历 病历生成耗时、医生修改率、病历甲级率、质控问题闭环率
CDSS / 用药安全 预警覆盖率、医生采纳率、误报率、高风险问题拦截数
舌诊 / 面诊 图片质量通过率、分析完成率、医生确认率、复测一致性
AI 住院 病历书写时间、平均住院日、床位使用率、护理风险闭环率
IoMT / 护理预警 预警及时率、误报率、护士处理时长、不良事件趋势
出院随访 随访完成率、高危识别率、人工升级闭环率、复诊推荐转化率

10.8 风控与审批中心

风控策略按合同、能力、余额、风险等级综合判断。

场景 默认策略
余额低于 20% 预警客户管理员、运营负责人
余额低于 5% 强预警,可触发续包流程
余额为 0 非关键能力审批或停用,关键医疗链路软放行并记超量
超出合同场景 阻断或审批
异常高频调用 限流、冻结、人工复核
高成本模型调用 先冻结额度
合理不限量异常峰值 标记异常,不直接扣客户余额,但进入运营复核

10.9 三期服务分层

三期不要把“计量、扣费、账单”写成一个大 Service。建议按以下服务拆分,职责清楚后初级工程师更容易实现和测试。

服务 职责 依赖 不能做什么
ContractService 查询合同、合同范围、合同状态 合同表、套餐表 不直接扣费
PricingService 根据规则计算能力值 定价计划、定价规则 不修改账户余额
CreditAccountService 管理账户余额、冻结、释放、结算 账户表、账本表 不理解业务场景含义
MeterEventService 接收标准计量事件,保证幂等 计量事件表 不生成最终账单
BillingService 汇总账本生成账单 账本、账单表 不直接调用 Dify/MCP
QuotaPolicyService 判断预警、封顶、审批、停用 合同范围、账户、策略表 不做实际扣费
CostService 记录内部模型和资源成本 成本表、模型价格 不影响客户余额
OperationReportService 生成运营报告 账单、计量、业务指标 不修改原始流水

10.10 能力值扣费时序

sequenceDiagram
    autonumber
    participant API as OpenPlatform
    participant Quota as QuotaPolicyService
    participant Contract as ContractService
    participant Credit as CreditAccountService
    participant Agent as Agent/Dify/MCP
    participant Meter as MeterEventService
    participant Pricing as PricingService
    participant Ledger as CreditLedger

    API->>Contract: 查询项目合同和能力范围
    Contract-->>API: 合同有效、覆盖当前智能体/场景
    API->>Quota: 判断是否需要预扣或审批
    alt 高成本或固定价能力
        Quota->>Credit: freeze(预估能力值, idempotencyKey)
        Credit->>Ledger: 写 freeze 流水
    end
    API->>Agent: 执行 AI / Dify / MCP 调用
    Agent-->>API: 返回结果、usage、工具调用信息
    API->>Meter: 记录标准计量事件
    Meter->>Pricing: 根据事件和合同规则折算能力值
    Pricing-->>Meter: credits
    alt 已冻结
        Meter->>Credit: settle(freezeId, actualCredits)
        Credit->>Ledger: 写 settle / release 流水
    else 未冻结
        Meter->>Credit: settle(actualCredits, idempotencyKey)
        Credit->>Ledger: 写 settle 流水
    end

10.11 账本状态机

stateDiagram-v2
    [*] --> granted: 合同生效/续包
    granted --> available: 额度入账
    available --> frozen: 高成本任务预扣
    frozen --> settled: 任务成功结算
    frozen --> released: 任务失败/未用完释放
    available --> settled: 普通任务完成后扣减
    settled --> reversed: 冲正
    available --> adjusted: 人工调账
    reversed --> [*]
    settled --> [*]
    released --> available

账本实现要求:

流水类型 余额影响 场景
grant 增加可用余额 合同生效、续包、赠送额度
freeze 可用余额减少,冻结余额增加 高成本任务开始前
settle 冻结或可用余额转为已使用 调用完成
release 冻结余额回到可用余额 任务失败、取消、实际消耗低于预估
reverse 生成反向流水 错扣、退款、人工复核
adjust 人工增加或减少 合同外调整、历史修正

10.12 三期数据关系图

erDiagram
    AI_CONTRACT ||--o{ AI_CONTRACT_SCOPE : defines
    AI_CONTRACT ||--o{ AI_CREDIT_ACCOUNT : grants
    AI_PRICING_PLAN ||--o{ AI_PRICING_RULE : contains
    AI_CONTRACT }o--|| AI_PRICING_PLAN : uses
    AI_CREDIT_ACCOUNT ||--o{ AI_CREDIT_LEDGER : records
    AI_METER_EVENT ||--o{ AI_METER_EVENT_DETAIL : has
    AI_METER_EVENT ||--o{ AI_CREDIT_LEDGER : charges
    AI_BILLING_STATEMENT ||--o{ AI_BILLING_STATEMENT_ITEM : includes
    AI_CREDIT_LEDGER }o--o{ AI_BILLING_STATEMENT_ITEM : summarized_by

    AI_CONTRACT {
      bigint id
      bigint project_id
      string contract_no
      string cooperation_level
      string status
    }

    AI_CREDIT_ACCOUNT {
      bigint id
      bigint project_id
      bigint parent_account_id
      decimal available_credits
      decimal frozen_credits
      decimal used_credits
    }

    AI_METER_EVENT {
      string event_id
      bigint project_id
      bigint agent_id
      string scenario_code
      string idempotency_key
      string status
    }

    AI_CREDIT_LEDGER {
      string ledger_id
      bigint account_id
      string event_id
      string ledger_type
      decimal credits
      string direction
    }

10.13 三期从调用到出账的完整链路

阶段 触发点 主责服务 落库对象
合同签署 商务录入或项目初始化 ContractService ai_contractai_contract_scope
能力值入账 合同生效 CreditAccountService ai_credit_accountai_credit_ledger(grant)
调用前校验 用户调用智能体 QuotaPolicyService 可选 freeze 流水
调用执行 Dify/MCP/Card 完成业务 OpenPlatform / MCP ai_usage_logai_card_action_log
计量事件 调用完成或失败 MeterEventService ai_meter_eventai_meter_event_detail
价格折算 事件入库后 PricingService 事件 credits 字段或明细
额度扣减 价格计算后 CreditAccountService ai_credit_ledger(settle/release)
月度汇总 定时任务 BillingService ai_billing_statement、明细
运营报告 月度或季度 OperationReportService ai_operation_report

10.14 三期实现注意事项

  1. 所有金额和能力值用 Decimal:不要用 double,避免账单误差。
  2. 账本更新必须事务内完成:账户余额和账本流水要么一起成功,要么一起失败。
  3. 计量事件先幂等再处理:同一个 idempotency_key 重复上报时返回已有处理结果。
  4. 账单从账本汇总,不从日志汇总:日志用于排障,账本用于财务。
  5. 合理不限量也要写事件:只是客户余额不扣减,内部成本必须记录。
  6. 合同规则要版本化:价格变化不能影响历史账单。
  7. 审批结果也要入审计:谁审批、审批原因、放行范围、有效时间都要记录。
  8. 先做同步账本,再做异步优化:MVP 阶段优先正确性,后续再引入队列和批处理。

10.15 能力值套餐示例

能力值是对外报价和内部计量的统一额度。建议对外口径保持“1 能力值约等于 1 元人民币”的理解,但实际合同可按折扣、赠送额度、套餐价进行换算。

示例:L2 标准能力值包。

示例值
套餐名称 标准包
合同价格 200,000 元 / 年
授予能力值 200,000 credits
有效期 合同生效日起 12 个月
超量单价 1 元 / credit,或按合同阶梯价
适用范围 单院项目,覆盖已授权智能体和科室

能力折算示例:

能力 计量单位 标准 credits 说明
导诊问答 1-3 高频轻量能力,可含 token 上限
智能分诊 3-8 含症状采集、科室推荐、紧急度提示
预问诊 完整问诊单 5-15 多轮追问并输出结构化病史
报告解读 5-20 按报告类型和长度分档
舌诊 / 面诊 5-15 图像专精模型
病历生成 10-30 门诊病历、SOAP 等
病历质控 8-30 规则 + LLM 质控
语音随访 分钟 1-3 按实际通话分钟结算
CDSS 10-30 必须医生主导
机器人导诊问答 次 / episode 1-3 若合同已买机器人基础服务,可按 license_covered 处理基础 FAQ
机器人分诊 / 挂号引导 次 / episode 3-8 属于高级 AI 能力,默认进入能力值或合理不限量服务包
机器人语音带路 次 / 分钟 2-10 机器人运行服务覆盖设备运维,AI 语音和导航按合同定义是否另计

初级工程师重点:credits 不是 token。
token 是底层模型消耗,credits 是商业计量单位。一次“报告解读”可能包含 token、RAG、格式化和审计多个成本项,但对客户只展示为“1 份报告解读消耗 X 能力值”。

10.16 定价规则版本化

定价规则必须支持版本化,避免规则变更后历史账单被重新解释。

字段 说明
pricing_rule_id 规则 ID
version 规则版本
effective_from 生效开始时间
effective_to 生效结束时间
meter_item 计量项
scenario_code 场景编码
calculation_mode fixed / tiered / token_based / minute_based
rule_snapshot_json 规则快照

计量事件生成时必须记录:

  1. 命中的 pricing_rule_id
  2. 命中的 pricing_rule_version
  3. 关键规则快照。
  4. 折算前原始数量和折算后 credits。

账单汇总时优先使用事件内的规则快照,不实时读取最新规则。

10.17 定价优先级与合同折扣

同一个计量事件可能同时命中平台默认价、项目合同价、套餐折扣和人工优惠。生产系统必须有唯一优先级,否则同一事件在不同任务里会算出不同金额。

定价优先级从高到低:

优先级 规则来源 示例 说明
1 合同明细覆盖价 某医院报告解读固定 3 credits/份 最优先,商务合同已明确
2 合同套餐折扣 购买 50 万能力值包享 8 折 作用于合同范围内的计量项
3 项目专属定价规则 区域医联体统一定价 用于多项目统一政策
4 平台版本化定价规则 默认报告解读 5 credits/份 全局默认
5 人工审批调整 运营减免或补扣 必须形成调整流水,不改原事件

实现要求:

  1. PricingService 每次计算都输出 pricing_sourcepricing_rule_idpricing_rule_version 和规则快照。
  2. 账本流水保存折算前数量、折算后 credits、折扣原因和合同条款引用。
  3. 合同价变更后只影响新事件,不重算历史事件。
  4. 历史账单需要修正时,使用 reverse + adjust,不能直接改原流水。
  5. 计量事件必须保存 contract_id 和合同关键快照,至少包含适用范围、折扣、套餐类型、超量规则和合理不限量边界。

10.18 计量事件状态与账本一致性

计量事件不是一生成就扣费。它要经过定价、账户处理和账本落地。

stateDiagram-v2
    [*] --> received: 接收事件
    received --> duplicated: 幂等命中
    received --> pricing_completed: 定价完成
    pricing_completed --> frozen: 需要预冻结
    pricing_completed --> settled: 不需冻结直接结算
    frozen --> settled: 实际结算
    frozen --> released: 失败或取消释放
    pricing_completed --> failed: 定价失败
    settled --> billed: 出账
    failed --> dead_letter: 超过重试
    released --> [*]
    billed --> [*]
    duplicated --> [*]
状态 是否可重试 是否影响余额 说明
received 已接收但未定价
pricing_completed 已确定 credits 和规则快照
frozen 冻结余额 预估额度已占用
settled 扣减余额 已形成正式扣减流水
released 释放冻结 业务失败、取消或超时
failed 可重试技术失败
dead_letter 人工处理 视情况 自动处理失败,需要运营/财务介入
billed 已进入账单周期

一致性规则:

  1. ai_meter_event 负责“事件处理状态”,ai_credit_ledger 负责“账户资金事实”。
  2. 不能只更新事件状态而不写账本,也不能只写账本不更新事件状态。
  3. 同一个 meter_event_id 最多只能有一条正式 settle 流水。
  4. 预冻结超时必须由任务释放,并标记释放原因。
  5. 账单只能读取 settled 且未出账流水,不能读取 received/pricing_completed/frozen
  6. billed 的事件不回退状态;账单错误通过 reverse/adjust/correction 生成新流水和补差账单,保留原账单审计链。

10.19 账户层级与并发控制

本期计费主粒度已确认是项目 / 医院客户。账户层级建议只做两层,避免早期账务复杂度失控。

账户层级 用途 是否真实扣费
项目主账户 合同能力值池、真实余额、真实冻结和扣减
分摊维度账户 科室、智能体、医生、渠道的用量统计和预算提醒 否,默认只做分摊

不建议三期初版做多级资金账户递归扣减。科室预算可以先做软控制:统计、预警、审批,不直接把资金拆成多套真实余额。

账户并发规则:

  1. ai_credit_account 增加 version 字段,扣减时用乐观锁更新余额。
  2. 冻结、结算、释放必须在同一数据库事务内更新账户和账本。
  3. Redis 锁只做前置削峰,数据库乐观锁和唯一约束才是最终一致性保障。
  4. 并发更新失败时使用指数退避 + 随机抖动重试,例如 100ms * 2^retryCount + random(0, 50ms),最多重试 3 次。
  5. 任何人工调整都必须走账本流水,不允许直接改账户余额。
  6. 超过最大重试次数后进入待处理或死信,不返回“已扣费成功”。

初级工程师重点:为什么账户余额不能直接 balance = balance - x
多个请求同时扣同一个账户时,直接更新会丢失扣减。必须用版本号或条件更新确保“读到的余额就是当前余额”。如果更新失败,说明别人已经改过余额,需要重新读取再计算。

10.20 三期服务契约

这里不写 Java 代码,只定义服务输入输出。编码前应先把这些契约固化成接口。

服务 输入 输出
ContractService projectIdagentIdscenarioCode、时间 合同状态、合同范围、定价计划
QuotaPolicyService 项目、账户、场景、预估 credits allow / freeze_required / approval_required / reject
PricingService 计量事件、合同、规则版本 credits、规则版本、规则快照
MeterEventService 标准计量事件、幂等键 accepted / duplicated / failed
CreditAccountService.freeze 账户、预估 credits、幂等键 freezeId、冻结结果
CreditAccountService.settle 事件、实际 credits、freezeId 可选 结算流水
CreditAccountService.release freezeId、原因 释放流水
BillingService 项目、账期、账单类型 账单主表和明细
ApprovalService 审批类型、申请对象、原因 审批单和状态

10.21 审批工作流

风控策略依赖审批,审批必须成为显式模块。

stateDiagram-v2
    [*] --> pending: 触发审批
    pending --> approved: 审批通过
    pending --> rejected: 审批拒绝
    pending --> expired: 超时未处理
    approved --> effective: 生效
    effective --> invalid: 到期/撤销
    rejected --> [*]
    expired --> [*]
    invalid --> [*]
审批类型 审批人 生效范围
余额不足放行 医梦运营 / 医院管理员 项目、智能体、时间窗口
超合同范围调用 项目负责人 / 医梦运营 指定场景或能力
高成本模型调用 医梦运营 单次或批量任务
合理不限量异常峰值 医梦运营 / 商务 复核后继续或限制
账本人工调整 财务 / 管理员 指定账户和流水

审批记录至少包含:申请人、审批人、审批类型、关联对象、原因、结果、有效期、审批意见、审计 traceId。

10.22 超量消费处理

余额不足不是简单停用,按合同和风险处理。

场景 策略
余额低但未为 0 继续使用,触发预警
余额为 0 且合同允许超量 继续使用,写超量流水,生成超量账单
余额为 0 且合同不允许超量 非关键能力阻断,高风险医疗关键链路走审批
合理不限量超出边界 不扣客户余额,标记异常并进入运营复核
现场补购 合同续包后 grant 新能力值,再抵扣后续使用

超量账单触发方式:

  1. 实时记录超量流水。
  2. 月末统一生成超量账单。
  3. 合同要求实时补费的客户,可在余额为 0 时生成补购提醒。

10.23 计量事件枚举

事件类型 默认计量策略
CHAT_COMPLETED 普通对话完成,按智能体或 token 折算
CHAT_STREAM_PARTIAL 流式中断,按 partial 策略
CHAT_FAILED 失败事件,默认不扣客户余额
CARD_DISPLAYED 默认不扣费,仅用于漏斗分析
CARD_ACTION_CONFIRMED 用户确认动作,可触发业务计量
MCP_TOOL_READ 内部计量,通常不对客户单独展示
MCP_TOOL_WRITE 并入业务能力,写操作必须幂等
ASR_MINUTE 按分钟
TTS_MINUTE 按分钟或字符
IMAGE_ANALYSIS 按次或图片张数
DOCUMENT_GENERATED 按份
REPORT_INTERPRETED 按份
FOLLOWUP_CALL_MINUTE 按分钟
MANUAL_ADJUSTMENT 人工调整,必须审批

10.24 运营报告结构

项目月度运营报告建议包含以下字段:

区块 字段
项目概览 项目、医院、账期、合同状态、合作层级
用量概览 总调用次数、总能力值、剩余额度、预计耗尽日期
场景分析 导诊、预问诊、报告解读、病历、质控、随访等用量
科室分摊 科室用量、科室占比、异常增长
智能体排行 调用量、消耗、成功率、失败率
成本分析 模型成本、语音成本、图像成本、毛利估算
质量指标 分诊命中率、预问诊完整度、质控闭环率
风险审计 越权、超量、审批、敏感访问、高风险操作
运营动作 巡检、培训、版本升级、问题处理
下月建议 续包建议、能力优化、科室推广建议

10.25 合同状态与账单触发

合同状态机:

stateDiagram-v2
    [*] --> draft: 创建合同
    draft --> active: 审核并生效
    active --> suspended: 暂停
    suspended --> active: 恢复
    active --> expired: 到期
    active --> terminated: 提前终止
    expired --> renewed: 续签
    renewed --> active: 新合同生效

账单触发规则:

账单类型 触发方式 说明
月度账单 每月 1 日由 SnailJob 生成上月账单 支持人工重算
超量账单 月末汇总,或合同要求时实时提醒 来自超量流水
科室分摊账单 月度账单生成后同步生成 医院内部管理使用
区域账单 按区域项目账期生成 包含医院子池分摊
人工调整账单 审批通过后生成 对应 adjust/reverse 流水

区域能力池初版规则:

  1. 区域总账户和医院子账户只做一层父子关系,不做递归账户树。
  2. 初版不做自动划拨,医院子账户额度由运营人员手动分配并形成 transfer 流水。
  3. 医院子账户余额不足时,不自动透支区域总账户;按项目策略进入预警、审批或超量。
  4. 区域月账单同时提供汇总账单和医院分账明细,但真实扣费仍以项目/区域合同约定为准。
  5. 后续如支持自动划拨,必须增加单独审批策略、划拨上限和审计流水。

10.26 特殊账务场景

场景 处理策略 账本动作
用户取消 业务未完成则释放冻结;已完成则按合同规则结算或冲正 releasereverse
SSE 中断 根据 Dify 最终状态判断是否完成;无法确认则标记 partial settle_partialrelease
Dify 部分失败 已产生成本但未形成客户价值时,可内部记成本、不扣客户余额 成本事件 + 客户 release
MCP 写操作超时 先查 HIS 最终状态;成功则结算,失败则释放 settlerelease
冻结超时 定时任务释放超过 TTL 的冻结记录 release_timeout
能力值到期 合同到期或套餐过期后未使用余额按合同处理 expire
人工减免 审批后生成减免流水,不改原始扣费 adjust_credit
人工补扣 审批后生成补扣流水 adjust_debit

能力值到期需要特别谨慎:如果合同约定可结转,则不能执行 expire;如果合同约定到期作废,expire 也必须生成账本流水,不能直接把余额清零。

批量账务修正用于处理规则配置错误、批量误扣、合同折扣漏配等运营事故。流程必须是:选择事件范围和修正原因,预览受影响事件、账户和账单,通过财务/运营审批后批量生成 correction 流水;已出账账单要触发重算或补差账单,不能直接改历史流水。

11. 三期数据模型

以下为设计级模型,不替代最终迁移 SQL。

说明
ai_contract 合同主表,记录客户项目、合作层级、周期、状态
ai_contract_scope 合同范围:医院、科室、场景、智能体、模型、终端、并发
ai_pricing_plan 套餐和定价计划,如能力值包、合理不限量包
ai_pricing_rule 计量项到能力值的折算规则,支持版本化
ai_credit_account 能力值账户,项目主账户和子账户
ai_credit_ledger 能力值账本,记录 grant/freeze/settle/release/reverse
ai_meter_event 标准计量事件,来自 OpenPlatform/Dify/MCP/Card
ai_meter_event_detail token、分钟、图片、文书等明细
ai_quota_policy 额度、封顶、预警、审批策略
ai_billing_statement 月账单 / 超量账单 / 区域账单
ai_billing_statement_item 账单明细,支持科室和智能体分摊
ai_operation_report 运营报告快照
ai_cost_record 内部成本记录,模型、语音、图像、硬件、人工服务

11.1 账本原则

能力值账本必须满足:

  1. 只追加,不物理删除。
  2. 任何扣减都可追溯到合同、账户、计量事件和源调用。
  3. 重试不能重复扣费,依赖 idempotency_key
  4. 冲正必须产生反向流水,不能覆盖原流水。
  5. 账单以账本为准,ai_usage_log 只作为排障和统计辅助。

ai_meter_event_detail 的规模会随调用量快速增长。初版如果明细只用于排障和少量统计,可以先作为 ai_meter_event.detail_json 保存;如果需要按 token、分钟、图片等维度高频查询,则独立建表并按月分区,至少保留 project_id + event_time 索引。

12. 三期与二期的集成点

12.1 OpenPlatform 调用入口

/api/v1/agent/chat 进入主链路时增加:

  1. 根据 project_id + agent_id + scenario 查询合同范围。
  2. 预估本次调用是否需要冻结额度。
  3. 生成调用 traceId 和计量上下文。
  4. 调用结束后产生标准计量事件。
  5. 异常结束时释放冻结额度或记录失败事件。
  6. 识别请求中的 files 类型,调用完成后由 OpenPlatform 统一生成 IMAGE_ANALYSISDOCUMENT_ANALYSISASR_MINUTE 等文件/多模态计量事件。
  7. 为用户主动调用创建 billingEpisodeId;synthetic message、MCP 工具调用和卡片动作沿用或关联该 episode。

12.2 DifyAdapter

Dify 返回 usage、messageId、conversationId、workflowRunId 时:

  1. 标准化为 ai_meter_event
  2. 保留 Dify 原始 usage,便于排障。
  3. 不直接按 token 扣费,交给定价规则折算。

12.3 MCP Server

每个 MCP 工具调用生成工具事件:

工具类型 是否对客户展示扣费 是否内部计量
查询类 通常不单独展示
写操作 通常并入业务能力
高成本第三方接口 可单独配置
失败重试 不重复扣客户费 是,记录成本

MCP 工具事件必须携带 billingEpisodeIdparentEventId 和可选 cardActionId。当它由卡片动作触发时,计量中心以 CARD_ACTION_CONFIRMED 作为客户侧定价事件,MCP_TOOL_WRITE 只进入内部成本,避免重复扣费。

12.4 Card Runtime

卡片动作应接入计量上下文:

  1. 卡片展示不默认扣费。
  2. 卡片确认产生业务事件。
  3. 触发 HIS 写操作时,以卡片动作 ID 作为幂等源。
  4. 账本可回溯“用户在哪张卡片上点击了什么导致扣费”。
  5. 卡片动作触发 MCP 写操作时,卡片动作 ID 是客户侧业务事件的主幂等源,MCP 工具调用 ID 是内部工具成本事件的幂等源。

12.5 计量上下文对象

二期主链路应尽早携带计量上下文,即使三期账本还没有完全实现。这样后续接入计费时不需要重构所有接口。

字段 来源 用途
traceId OpenPlatform 生成 串联日志、调用、MCP、账本
projectId 项目鉴权 合同和额度主对象
tenantId 项目绑定租户 多租户隔离
agentId 请求参数映射 智能体维度
deptId 智能体、用户或业务上下文 科室分摊
userId 请求参数 用户维度
scenarioCode 智能体配置或 Dify 输出 定价规则匹配
contractId ContractService 查询 合同追溯
idempotencyKey 请求 / 卡片动作 / 工具调用生成 防重复扣费
sourceType openplatform / dify / mcp / card 事件来源

12.6 异常处理策略

异常 二期处理 三期处理
Dify 超时 返回可解释错误,记录调用失败 若已冻结额度则释放
SSE 中断 标记会话未完整完成 按 partial 策略计量或不计量
MCP 查询失败 卡片展示失败或降级为空状态 记录工具失败成本,不扣客户业务费
MCP 写操作超时 查询 HIS 最终状态,避免重复写 冻结保持 pending,人工复核后 settle/release
HIS 返回业务失败 展示失败原因,可重试 不扣或按合同基础成本扣
重复点击卡片 幂等返回第一次结果 不重复生成计量事件
余额不足 二期只记录 三期按软拦截/审批/超量策略

13. 生产级增强设计

本章补齐线上医疗项目必须具备的架构能力。它们不是“后续优化”,而是决定系统能否在医院真实运行、能否被审计、能否结算、能否排障的基础能力。

13.1 主数据边界:客户、合同、项目、医院、科室

主数据边界决定权限、计费、统计和审计能不能对齐。当前设计中 project_id 是合同和额度主粒度,但生产环境还需要把客户主体、医院、院区、科室、智能体之间的关系固定下来。

13.1.1 架构关系

flowchart TD
    Customer["客户主体<br/>医院 / 医疗集团 / 卫健委"]
    Contract["合同<br/>L1 / L2 / L3 / 合理不限量"]
    Project["项目 project_id<br/>计费、授权、账单主对象"]
    RegionPool["区域能力池<br/>L3 可选"]
    Hospital["医院"]
    Campus["院区"]
    Dept["科室 / 病区"]
    Agent["智能体 / AI 能力"]
    User["用户 / 医护 / 患者"]

    Customer --> Contract
    Contract --> Project
    Project --> RegionPool
    Project --> Hospital
    RegionPool --> Hospital
    Hospital --> Campus
    Campus --> Dept
    Project --> Agent
    Dept --> Agent
    User --> Project

13.1.2 模块设计

模块 作用 与现有设计的关系
客户主体管理 记录签约主体,可能是单院、集团或卫健委 合同中心的上游
项目管理 绑定客户、合同、医院范围,是授权和计费主对象 复用当前 sys_project,补充医院/租户绑定
医院组织映射 维护医院、院区、科室、病区 支撑科室分摊、权限和 HIS Adapter
智能体授权 控制项目可使用哪些智能体和场景 当前 project.agentIds 应升级为关系表
科室预算分摊 将项目能力值分配到科室或智能体 三期额度分摊中心使用

13.1.3 核心流程

  1. 商务创建客户主体和合同。
  2. 项目经理创建项目,绑定合同、医院和租户。
  3. 管理员导入医院组织结构:院区、科室、病区。
  4. 管理员给项目授权智能体、Dify 应用、卡片和 MCP 工具。
  5. 合同生效后生成项目主账户,必要时按科室分配预算。
  6. 调用时所有事件都带上 projectId,并尽量补齐 hospitalId/campusId/deptId/agentId

初级工程师重点:为什么不能只用 tenantId?
tenantId 解决的是数据隔离,不等于合同主体。一个租户可能有多个项目,一个区域项目可能覆盖多家医院。计费、账单和审计必须挂在 projectId 上,否则后续无法解释“这笔能力值是谁用的、属于哪份合同、哪个医院或科室消耗”。

13.1.4 具体功能

功能 说明
项目-医院绑定 一个项目可绑定一家或多家医院
项目-智能体授权 控制项目可调用的智能体清单
项目-工具授权 控制项目可调用的 MCP 工具范围
科室预算配置 主账户额度分配到科室或智能体
组织映射同步 从 HIS 或手工维护院区/科室
账单分摊规则 按科室、智能体、场景或用户分摊

13.2 事件可靠性:Outbox 与异步处理

三期计量依赖 OpenPlatform、Dify、MCP、Card 多来源事件。如果只用异步线程写账本,线上会出现“业务成功但没扣费”“重复重试导致重复扣费”“SSE 中断后状态不一致”等问题。

13.2.1 架构设计

flowchart LR
    Biz["业务事务<br/>会话 / 卡片 / MCP"]
    Outbox["本地事件表 Outbox<br/>同事务落库"]
    Dispatcher["事件投递任务<br/>SnailJob / 定时扫描"]
    Meter["计量事件处理器"]
    Ledger["能力值账本"]
    Retry["失败重试 / 死信"]

    Biz --> Outbox
    Outbox --> Dispatcher
    Dispatcher --> Meter
    Meter --> Ledger
    Dispatcher --> Retry
    Retry --> Dispatcher

13.2.2 模块设计

模块 作用
OutboxEventService 在业务事务内写入待处理事件
EventDispatcherJob 使用 SnailJob 扫描待处理事件,投递给计量、审计、报表处理器
MeterEventHandler 将业务事件转换为标准计量事件
DeadLetterService 记录多次失败事件,支持人工重放
EventReplayService 按 traceId 或 eventId 重放事件

13.2.3 核心流程

  1. 对话完成、卡片动作完成或 MCP 工具完成时,在同一个数据库事务内写业务记录和 Outbox 事件。
  2. 投递任务读取 pending 事件。
  3. 处理器按 idempotency_key 去重。
  4. 成功后标记 processed
  5. 失败后增加重试次数,超过阈值进入死信。
  6. 运维或运营可在管理后台重放死信事件。

初级工程师重点:为什么要 Outbox?
因为“业务数据”和“计费事件”必须一致。比如挂号成功了,但计费事件因为网络问题没写到账本,账单就漏了。Outbox 的做法是先把事件和业务结果放在同一个本地事务里,保证至少不会丢,再由后台任务慢慢处理。

13.2.4 具体功能

功能 说明
事件本地落库 所有计量、审计、报表事件先写 Outbox
幂等处理 eventType + idempotencyKey 唯一
自动重试 支持指数退避或固定间隔
死信队列 多次失败后人工处理
事件重放 排障后可重新执行计量
事件查询 按 traceId 查看事件处理状态

13.2.5 Outbox 表设计

字段 说明
event_id 全局唯一事件 ID
event_type 事件类型,如 CHAT_COMPLETEDMCP_TOOL_WRITE
source_type openplatform / dify / mcp / card
source_id 源业务 ID
trace_id 调用链 ID
project_id 项目 ID
idempotency_key 幂等键
payload_json 事件负载
status pending / processing / processed / dead
retry_count 重试次数
next_retry_at 下次重试时间
last_error 最近失败原因
create_time 创建时间
update_time 更新时间

payload_json 不能作为任意自由 JSON 使用。编码前必须定义 OutboxPayload 基类,并按 event_type + source_type 选择具体 payload schema。

source_type payload schema 必填字段
openplatform OpenPlatformCallPayload conversationIdmessageIdagentIdrequestSummaryresponseSummary
dify DifyRunPayload workflowRunIddifyMessageIdusagemodelNameoutputSchemaVersion
mcp McpToolPayload toolNamehospitalIdoperationTypelatencyMsresultStatus
card CardActionPayload instanceIdactionNamecardKeyactionResult
billing BillingPayload accountIdledgerIdamountCreditsledgerType

解析规则:

  1. event_type 决定业务语义,source_type 决定 payload 类型。
  2. payload_schema_version 应进入 payload_json 或单独字段,后续 schema 变更必须兼容旧事件。
  3. MeterEventHandler 只处理已注册 schema,未知事件进入死信,不做静默忽略。
  4. payload 只保存摘要和业务 ID,敏感医疗原文不进入 Outbox。

恢复机制:

  1. 业务事务提交成功后,即使处理器挂了,事件仍在 pending 状态。
  2. SnailJob 定时扫描到期事件。
  3. 处理前把状态改为 processing,防止多节点重复处理。
  4. 处理失败时回到 pending 并设置 next_retry_at
  5. 超过最大次数进入 dead,由人工处理台重放。

13.3 Dify Workflow 版本治理

Dify Workflow 是二期流程编排核心,但生产环境不能让任何人随意改画布后立即影响线上。Workflow 版本会影响业务流程、卡片结构、MCP 工具、计费场景和审计证据。

这里采用轻量治理,不重新实现一套 Dify 发布引擎。Dify 自身负责 Workflow 的草稿、发布版本、历史版本和恢复;医梦平台只维护“平台智能体版本 -> Dify App/Workflow 已发布版本”的映射、发布前探测和配置灰度。这样既能控制线上风险,又不会把小团队拖进重型 DevOps 平台建设。

13.3.1 架构关系

flowchart TD
    Agent["ai_agent_app<br/>智能体"]
    Version["ai_workflow_version<br/>平台版本映射"]
    DifyApp["Dify App / Workflow"]
    Release["轻量发布记录<br/>映射 / 探测 / 配置灰度"]
    CardSchema["卡片 Schema 版本"]
    ToolSet["MCP 工具版本"]
    Pricing["计费规则版本"]

    Agent --> Version
    Version --> DifyApp
    Version --> CardSchema
    Version --> ToolSet
    Version --> Pricing
    Release --> Version

13.3.2 模块设计

模块 作用
WorkflowVersionMappingService 维护平台智能体与 Dify 应用发布版本的映射
WorkflowProbeService 发布前探测 Dify 可用性、输出结构和关键工具是否存在
WorkflowSnapshotService 保存平台侧关键快照:Dify App ID、发布版本、卡片 schema、工具集、计费规则版本
AgentConfigGrayService 通过切换 ai_agent_app.engine_config_id 或版本映射实现按项目/科室灰度
WorkflowDiffNote 只记录人工填写的变更说明和影响范围,不做复杂自动 diff

13.3.3 核心流程

  1. 在 Dify 中调整 Workflow,并使用 Dify 自身能力发布为新版本。
  2. 在医梦管理后台新增或更新版本映射,选择 Dify App、发布版本、版本说明、影响智能体。
  3. 系统做最小探测:能否调用、输出 JSON 是否符合卡片 schema、MCP 工具是否存在。
  4. 通过切换 ai_agent_app.engine_config_id 或版本映射,灰度到指定项目、科室或设备。
  5. 观测错误率、卡片渲染失败率、MCP 失败率和能力值消耗。
  6. 灰度稳定后扩大映射范围。
  7. 出现问题时,把映射切回上一稳定 Dify 发布版本。

初级工程师重点:为什么 Dify 也要版本管理?
Dify 画布虽然不是 Java 代码,但它就是线上业务逻辑。改错一个条件分支,可能会把“咨询”走成“挂号写操作”;改错输出字段,前端卡片就渲染失败;改错工具名,HIS 调用就失败。所以 Dify 版本必须像代码一样发布、灰度、回滚。

13.3.4 具体功能

功能 说明
Workflow 版本映射 agentId -> difyAppId -> difyPublishedVersion
轻量审批 医梦技术负责人或项目负责人确认映射变更
输出结构校验 校验 reply/cardKey/cardData/usage
工具依赖校验 校验 Workflow 用到的 MCP 工具是否授权
配置灰度 按项目、科室、设备或智能体配置灰度,不自研完整发布引擎
快速回滚 切回上一稳定 Dify 发布版本映射
发布审计 记录谁切换了映射、切换到哪个 Dify 版本、影响范围

13.4 患者身份与授权体系

医疗系统中的“用户”不等于“患者”。一个登录用户可能给自己、孩子、老人操作;医生操作患者数据也需要明确就诊上下文。

13.4.1 身份模型

标识 含义 示例
platformUserId 平台登录用户 小程序用户、医生账号
patientId 医院患者主索引 HIS 患者 ID / MPI ID
visitId 一次门诊或住院就诊 门诊流水号、住院号
encounterId 诊疗接触,可兼容门诊/住院/随访 一次诊疗上下文
operatorId 实际操作者 医生、护士、患者本人、家属
relationship 操作者与患者关系 本人、父母、子女、医生、护士
authorizationId 授权记录 患者授权或代办授权

13.4.2 架构关系

flowchart TD
    User["platformUserId<br/>登录用户"]
    Auth["授权记录"]
    Patient["patientId<br/>患者主索引"]
    Visit["visitId / encounterId<br/>就诊上下文"]
    AgentCall["AI 调用"]
    Audit["审计记录"]

    User --> Auth
    Auth --> Patient
    Patient --> Visit
    Visit --> AgentCall
    AgentCall --> Audit
    Auth --> Audit

13.4.3 核心流程

  1. 用户登录后选择就诊人。
  2. 系统校验用户是否有权访问该患者:本人、家属代办、医生诊疗关系、护士护理关系。
  3. 调用 AI 前构造身份上下文:platformUserId + patientId + visitId + operatorId + authorizationId
  4. Dify 和 MCP 只接收必要字段,避免传入过多敏感信息。
  5. HIS 写操作前再次校验授权和就诊上下文。
  6. 审计记录保存操作者、患者、授权、操作目的和结果。

初级工程师重点:为什么 userId 不够?
因为 userId=10001 只能说明是谁登录了系统,不能说明他正在为哪个患者操作、有没有授权、属于哪次就诊。医疗数据访问必须回答“谁在什么场景下,为哪个患者,基于什么授权,做了什么操作”。

13.4.4 具体功能

功能 说明
就诊人选择 患者端调用前选择患者
代办授权 家属为患者操作时记录关系和授权
医护诊疗关系校验 医生/护士只能访问职责范围内患者
授权快照 AI 调用时保存授权状态
最小化传参 Dify/MCP 只接收必要患者摘要
敏感操作二次确认 建档、挂号、支付、写病历前确认

13.5 医疗安全分级

不同 AI 能力的风险不同,不能使用同一套自动化策略。风险分级决定是否允许自动回复、是否必须患者确认、是否必须医生确认、是否允许写入 HIS。

13.5.1 风险等级

等级 示例 默认策略
L0 信息查询 院内 FAQ、科室介绍、流程咨询 可自动回复,记录日志
L1 低风险建议 导诊建议、报告通俗解释、就诊准备 自动回复,但要有来源和免责声明
L2 中风险辅助 分诊、预问诊、病历质控建议 需要用户确认或医护确认
L3 高风险操作 挂号写入、患者建档、用药风险提示、CDSS 必须明确确认,写操作走 MCP 幂等
L4 严肃医疗决策 处方、医嘱、诊断结论、危急值处置 AI 只辅助,必须人工决策和签名

13.5.2 与架构融合

模块 如何使用风险等级
Dify Workflow 根据场景输出 riskLevel 和建议动作
OpenPlatform 根据风险等级决定是否允许自动返回、是否创建确认卡片
Card Runtime L2 及以上场景通过卡片确认,L3 及以上记录明确确认动作
MCP Server L3+ 写操作必须校验确认结果和幂等键
计量中心 高风险能力可使用不同计量项
审计中心 L2 及以上必须保留输入摘要、输出摘要、确认人和时间

13.5.3 高风险流程

flowchart TD
    AI["AI 生成建议或操作意图"]
    Risk["风险等级判断"]
    Low["L0/L1<br/>自动回复"]
    Confirm["L2/L3<br/>卡片确认"]
    Human["L4<br/>人工决策"]
    MCP["MCP 写操作"]
    Audit["审计记录"]

    AI --> Risk
    Risk --> Low
    Risk --> Confirm
    Risk --> Human
    Confirm --> MCP
    Low --> Audit
    Confirm --> Audit
    Human --> Audit
    MCP --> Audit

初级工程师重点:为什么不能让 AI 自动完成所有事?
医疗系统里,AI 输出可能影响患者就医路径、用药安全和医疗责任。系统可以让 AI 提建议,但高风险动作必须有人确认,尤其是写入 HIS、影响病历、医嘱、处方、危急值处理的动作。

13.6 多医院 HIS Adapter 策略

HIS 厂商差异是 L2/L3 最大交付风险。MCP 工具必须稳定,但每家医院的接口字段、鉴权、错误码、网络环境都可能不同。

13.6.1 分层设计

flowchart TD
    Tool["标准 MCP Tool<br/>his_create_appointment"]
    Service["标准业务服务<br/>AppointmentService"]
    Adapter["HospitalAdapter 接口"]
    A["医院 A Adapter"]
    B["医院 B Adapter"]
    C["医院 C Adapter"]
    Map["字段映射 / 字典映射"]
    Mock["联调 Mock Server"]

    Tool --> Service
    Service --> Adapter
    Adapter --> A
    Adapter --> B
    Adapter --> C
    A --> Map
    B --> Map
    C --> Map
    Service --> Mock

13.6.2 模块设计

模块 作用
StandardToolContract 平台标准工具契约
HospitalAdapter 医院适配器接口
HospitalAdapterConfig 每家医院的 URL、鉴权、超时、字段映射
DictionaryMappingService 科室、医生、号别、支付状态等字典映射
HisMockServer 没有真实 HIS 时用于联调
HisCapabilityRegistry 记录某家医院支持哪些接口

13.6.3 核心流程

  1. 平台定义标准工具:如 his_get_departmentshis_lock_schedule
  2. 每家医院实现自己的 Adapter。
  3. 工具调用时根据 projectId/hospitalId 选择 Adapter。
  4. Adapter 调厂商接口并转换为标准响应。
  5. 若医院不支持某接口,则返回标准能力缺失错误。
  6. 联调时使用 Mock Server 和验收用例先跑通。

初级工程师重点:为什么不能在 MCP 工具里直接写医院接口 URL?
因为一个工具会服务很多医院。直接写死 URL 会导致每接一家医院都改主流程代码。正确做法是工具保持标准,医院差异放到 Adapter 和配置里。

13.6.4 具体功能

功能 说明
医院接口配置 URL、鉴权、超时、重试、启停
字段映射 厂商字段和平台标准字段互转
字典映射 科室、号别、医生职称、支付状态
能力探测 判断医院是否支持锁号、建档、取消预约等
Mock 联调 未接真实 HIS 前可模拟返回
验收用例 每个工具有标准输入输出和异常场景

13.7 可观测性与排障闭环

线上医疗项目必须支持快速排障。用户只会说“挂号失败了”,工程上要能定位是签名、Dify、MCP、HIS、卡片、计费还是前端问题。

13.7.1 Trace 模型

flowchart LR
    Trace["traceId"]
    Request["API 请求"]
    Dify["Dify message/workflowRun"]
    Card["Card instance/action"]
    Tool["MCP toolCall"]
    HIS["HIS request"]
    Meter["Meter event"]
    Ledger["Credit ledger"]
    Log["应用日志"]

    Trace --> Request
    Trace --> Dify
    Trace --> Card
    Trace --> Tool
    Trace --> HIS
    Trace --> Meter
    Trace --> Ledger
    Trace --> Log

13.7.2 模块设计

模块 作用
TraceContext 在 API、Dify、MCP、Card、Meter 之间传递 traceId
CallChainQuery 按 traceId 查询完整调用链
FailureWorkbench 展示失败事件、死信、可重试操作
ReplayService 支持重放计量事件或重新查询 HIS 最终状态
AlertService 对超时、错误率、余额、异常峰值告警

13.7.3 排障流程

  1. 客户反馈失败,提供时间、用户、会话或订单。
  2. 管理后台按用户、会话、订单或 traceId 查询调用链。
  3. 判断失败节点:鉴权、Dify、MCP、HIS、卡片、计量。
  4. 若是可恢复失败,执行重试或事件重放。
  5. 若是 HIS 写操作不确定,先查 HIS 最终状态,不允许盲目重试。
  6. 处理完成后补充审计和运营备注。

初级工程师重点:为什么写操作不能随便重试?
查询失败可以重试,但写操作可能已经在 HIS 成功了,只是响应超时。如果直接重试,可能重复挂号、重复建档、重复扣费。所以写操作失败后,要先用幂等键或订单号查询最终状态。

13.7.4 具体功能

功能 说明
调用链查询 一个 traceId 展示 API、Dify、MCP、HIS、账本
失败原因分类 网络、鉴权、参数、HIS 业务失败、超时、计费失败
可重试标记 明确哪些失败可以自动重试
人工处理台 死信、账本异常、HIS pending 状态处理
告警规则 错误率、延迟、余额、异常调用峰值

13.8 数据合规与脱敏策略

医疗数据要默认按敏感数据处理。日志、Dify 输入、计量事件、运营报表都不能无节制保存原文。

13.8.1 数据分类

等级 数据 策略
P0 公开数据 科室介绍、就诊流程 可正常记录
P1 内部数据 系统配置、智能体配置、运营指标 权限控制
P2 个人敏感 姓名、手机号、身份证、住址 脱敏展示、加密存储
P3 医疗敏感 病历、诊断、检验、影像、用药 最小化传输、严格审计
P4 高敏业务 支付、医保、处方、危急值 加密、强审计、人工确认

13.8.2 与架构融合

模块 合规要求
OpenPlatform 请求日志脱敏,不记录完整身份证、手机号、病历全文
DifyAdapter 只传必要患者摘要,避免整份病历无控制进入 Dify
MCP Server 工具输入输出记录摘要,不默认保存完整 HIS 响应
Card Runtime 卡片展示按权限脱敏,历史快照避免保存过多敏感字段;建档卡片不保存 PII 预填,舌诊/面诊卡片不保存原图引用和可复原特征
Metering 计量事件只保存计费用字段,不保存完整医疗内容
Billing 账单展示能力值和场景,不展示患者隐私
OperationReport 运营报告使用聚合数据,不展示个人明细

13.8.3 核心流程

  1. 请求进入 OpenPlatform 后先建立 traceId 和数据分类。
  2. 进入日志前做脱敏。
  3. 传给 Dify 前做字段裁剪,只保留完成任务必须的信息。
  4. MCP 调 HIS 时按最小权限取数。
  5. 存储卡片快照时,只保存渲染和审计需要的字段。
  6. 计量事件只保存 projectId/agentId/scenario/quantity/credits/sourceId 等账务字段。
  7. 管理后台根据角色控制是否能查看敏感明细。
  8. 建档、舌诊、面诊等敏感场景必须做字段白名单:允许保存业务 ID、结论摘要、风险等级和确认动作;禁止保存身份证号明文、手机号明文、原始图像引用、面部特征向量和完整病历原文。

初级工程师重点:为什么不能把完整请求和响应都打日志?
医疗请求里可能有身份证、手机号、病历、诊断、检查结果。完整日志一旦泄漏就是严重合规事故。排障需要的是 traceId、错误码、摘要和必要上下文,不是所有原始隐私数据。

13.8.4 具体功能

功能 说明
日志脱敏工具 手机号、身份证、姓名、地址、病历字段脱敏
字段级加密 密钥、患者身份、支付信息加密
Dify 输入裁剪 将完整病历变成任务所需摘要
审计留痕 谁查看了敏感数据、为什么查看
数据出域开关 院内部署项目可限制 Dify/模型调用边界
报表聚合 运营报告默认不展示患者级明细

13.9 知识模块与 Dify 的关系

当前工程已有 emoon-knowledge-api,Dify 也有知识库节点。两者不能互相替代,需要明确边界。

能力 emoon-knowledge Dify 知识库 / Workflow
知识资产管理 主责,管理文档、标签、适用医院、版本、审核状态 引用已发布知识
提示词模板 主责,沉淀医疗场景 prompt、变量、版本 Workflow 节点使用
RAG 检索 可作为平台统一 RAG Service 可使用 Dify 内置节点快速编排
质控后处理 主责,如病历质控、报告结构化校验 调用平台质控服务或接收结果
工作流编排 不负责 主责
审计和发布治理 主责,知识版本、引用来源、审核人 保存 workflow 运行引用

推荐设计:

  1. 医疗知识的权威来源放在 emoon-knowledge,包括院内制度、指南、FAQ、报告模板、质控规则。
  2. Dify Workflow 可以使用 Dify 知识库节点,但导入内容必须来自已发布知识版本。
  3. 对审计要求高的场景,Dify 不直接检索散乱文档,而是调用平台 RAG/MCP 工具,返回带 knowledgeVersion 和引用来源的结果。
  4. PromptTemplateService 管理提示词变量和版本,Dify 发布时记录使用的模板版本。
  5. 报告解读、病历生成、质控建议等输出,必须经过平台后处理校验,不只依赖 Dify 文本。

    flowchart LR
    Knowledge["emoon-knowledge<br/>知识资产 / Prompt / 质控"]
    Publish["知识发布版本<br/>审核 / 生效 / 回滚"]
    DifyKB["Dify Knowledge<br/>流程内检索"]
    DifyWF["Dify Workflow"]
    RAGTool["平台 RAG Tool<br/>带引用和版本"]
    Quality["质控后处理"]
    Open["OpenPlatform"]
    
    Knowledge --> Publish
    Publish --> DifyKB
    Publish --> RAGTool
    DifyKB --> DifyWF
    DifyWF --> RAGTool
    DifyWF --> Open
    Open --> Quality
    

初级工程师重点:为什么知识库不能只放 Dify?
医疗知识需要审核、版本、适用医院和引用追溯。Dify 适合编排和快速检索,但合同审计、医疗责任和知识发布治理必须由平台掌握,否则无法回答“这次建议引用的是哪版指南,谁审核过,是否适用于这家医院”。

13.10 SSE 生命周期与连接治理

SSE 是二期主入口的重要形态,但它不是普通 HTTP 短请求。必须设计连接生命周期、心跳、断线恢复和资源清理。

阶段 平台动作 失败处理
建连 校验签名、项目权限、并发额度,创建 traceId 失败直接返回错误,不创建会话
发送请求到 Dify 记录外部 message/workflow 标识 超时触发 fallback
流式转发 解析 Dify event,转换为平台 SSE event 非法事件忽略并记录摘要
心跳 平台定期发送 heartbeat,避免网关空闲断开 客户端超时后可查询会话
完成 写会话、usage、卡片、Outbox 事件 卡片失败不影响文本保存
断开 标记连接关闭,清理内存对象 根据 Dify 最终状态决定 partial

SSE 实现规则:

  1. 每个项目配置最大 SSE 并发,避免单项目占满线程。
  2. 使用专用线程池或响应式转发,不与普通 API 线程池混用。
  3. 连接必须有最大持续时间和最大空闲时间。
  4. 服务端维护 conversationId/messageId/traceId 映射,客户端断线后可以查询最终结果。
  5. 客户端主动取消时,平台记录 client_cancelled,Dify 是否可取消按引擎能力处理。
  6. 取消后已经完成的业务事实不能删除;如已冻结额度,需要按最终状态结算或释放。
  7. 若采用 Spring SseEmitter,需要维护活跃连接注册表,定时发送 heartbeat,并在 onCompletion/onTimeout/onError 清理连接。
  8. 同步转发模式下,SSE 长连接会占用容器线程;超过试点并发上限时应切换到 Servlet async 独立线程池或响应式实现。

13.11 缓存、文件与多模态输入

13.11.1 缓存策略

缓存只服务性能和降级,不能作为资金、授权、幂等的唯一依据。

缓存对象 建议 TTL 失效策略 注意事项
项目公钥和状态 5-10 分钟 管理后台变更后主动失效 签名失败时可回源确认
智能体运行配置 1-5 分钟 发布后主动失效 Dify 密钥不明文放 Redis
卡片定义 5-30 分钟 卡片发布后失效 卡片实例使用快照,不受缓存影响
基础科室/医生 10 分钟到 1 天 HIS 同步任务刷新 展示可降级,写操作不可只信缓存
定价规则 5-10 分钟 规则发布后失效 事件内必须保存规则快照
额度概览 30-60 秒 账本变更后刷新 仅展示,不作为扣费依据

合理不限量必须参数化,不能只靠人工感觉判断。建议在 ai_quota_policy 中配置以下监控项:

参数 示例默认值 作用
daily_usage_multiplier 合同隐含日均量的 2 倍 标记异常峰值
single_call_cost_limit 单次内部成本超过指定金额 标记高成本调用
scenario_share_limit 单场景占比超过 60% 识别异常集中使用
monthly_cost_limit 月内部成本上限 触发运营复核
approval_required_after_alert true 告警后继续超阈值需审批

Redis 不可用时:

  1. 鉴权、幂等、账本扣费必须回退到数据库约束和事务。
  2. 限流、热点缓存、短锁可以降级,但要提高告警等级。
  3. HIS 写操作如果无法获取短锁,按风险策略拒绝或进入人工确认,不允许盲写。

13.11.2 文件与多模态输入

门诊/住院场景会涉及报告、图片、语音和附件。文件链路必须独立于对话文本治理。

flowchart LR
    Client["客户端上传"]
    FileAPI["文件服务<br/>鉴权 / 类型 / 大小"]
    Object["对象存储<br/>加密保存"]
    Scan["安全扫描 / 病毒扫描"]
    Extract["解析服务<br/>OCR / ASR / PDF"]
    Agent["Agent 调用<br/>只传 fileRef/摘要"]
    Audit["文件访问审计"]

    Client --> FileAPI
    FileAPI --> Object
    FileAPI --> Scan
    Object --> Extract
    Extract --> Agent
    Object --> Audit

实现规则:

  1. 对话接口不直接接收大文件内容,只接收 fileId/fileRef
  2. 文件上传先校验项目、用户、患者授权、大小、类型、有效期。
  3. 解析后的文本要做脱敏和摘要,再传给 Dify 或 DirectLLM。
  4. 图片、报告、病历等原始文件加密保存,访问走签名 URL 或后端转发。
  5. 计量事件记录文件数量、页数、分钟数等账务字段,不保存原文。
  6. 文件删除、归档、导出按医院合同和合规要求执行。

13.12 生产级增强与现有模块的关系

增强方向 影响二期 影响三期
主数据边界 API 鉴权、智能体授权、HIS Adapter 选择 合同、额度、账单主粒度
事件可靠性 会话、卡片、MCP 事件不丢 计量和账本可靠
Dify 版本治理 Workflow 发布可控 计费规则和场景版本可追溯
患者身份授权 卡片动作、MCP 工具合法 审计和风控有依据
医疗安全分级 确定哪些动作需确认 高风险能力定价和审批
多医院 Adapter MCP 工具可复用 L2/L3 多院落地
可观测性 线上问题可定位 账本和事件可重放
数据合规 日志、Dify、MCP 不越界 账单和报表不泄露隐私
知识治理 Dify 输出可追溯 高价值能力可定价和审计
SSE 与文件治理 流式和多模态可上线 partial 计量和文件类计量可信
设备治理 统一入口客户端、设备事件、设备场景可控 设备授权、运维服务和设备维度分摊

13.13 设备治理与统一入口生产化

医院确认版方案把门诊设备入口提升为战略控制点。生产级增强必须补齐设备治理,否则门诊总包会退化成现场定制项目。

能力 生产要求 验收口径
设备身份 每台设备有全局唯一 deviceId、设备密钥、医院/科室/位置绑定 未注册设备不能进入核心业务闭环
远程配置 UI 模板、默认智能体、工具权限、版本灰度由后台下发 现场切换场景不需要重新发版
心跳监控 设备在线、离线、异常、维护状态可查询和告警 P0 设备在线率进入运营报告
版本治理 统一入口客户端有版本、灰度、回滚和升级记录 线上问题能定位到客户端版本
厂商责任 A/B/C/D 准入等级、接口清单、联调记录、验收记录留痕 C/D 设备不承诺核心业务闭环
设备计量 设备授权、设备运维、设备事件和业务调用分开计量 设备费不混入能力值扣减流水

设备运行状态不等于业务成功。导诊屏在线、机器人在线、自助机在线只能说明入口可用;分诊完成、挂号成功、签到确认、支付完成、病历确认、护理任务关闭才是可计量、可验收的业务事实。

14. 工程交付保障

本章覆盖测试、部署、迁移、安全、监控和灾备。它们不直接产生业务功能,但决定系统能不能稳定上线。

14.1 测试策略

测试层级 重点 Mock 方式
单元测试 Pricing、Quota、Credit、状态机、脱敏工具 纯内存对象
Service 集成测试 账本事务、Outbox、卡片动作、MCP Adapter H2/Testcontainers 或测试库
Dify 集成测试 Dify 请求转换、SSE 解析、usage 解析 Dify Mock Server
HIS 集成测试 科室、医生、锁号、挂号、建档 HIS Mock Server
设备集成测试 设备注册、心跳、场景下发、SDK 错误映射 Device Mock / SDK Mock
端侧兼容测试 导诊屏、自助机、机器人、诊室屏、医生站插件 浏览器矩阵 + Android/Harmony/Electron Mock
端到端测试 对话 → 卡片 → MCP → 计量 → 账本 测试项目 + Mock Dify/HIS
账务回归测试 冻结、结算、释放、冲正、超量 固定账本用例

关键测试场景:

  1. 同一个幂等键重复提交,不重复扣费。
  2. 高成本任务冻结后失败,额度释放。
  3. MCP 写操作超时后,查询 HIS 最终状态再处理。
  4. Dify 返回 cardKey 但 cardData 缺字段,卡片实例创建失败可追踪。
  5. 余额为 0 的医疗关键链路按软拦截策略处理。
  6. 未注册或准入不通过的设备不能进入核心闭环。
  7. 设备离线、版本不匹配、SDK 返回异常时有明确降级路径。
  8. 日志不出现完整身份证、手机号、病历全文。

14.2 数据库迁移策略

二三期会新增大量表,不能依赖手工 SQL 随意执行。

建议策略:

设计
迁移工具 优先 Flyway 或 Liquibase;若暂不引入,也要统一脚本编号
脚本命名 V20260523_001__create_ai_meter_tables.sql
可重复脚本 字典、默认配置、测试种子数据独立
回滚策略 生产不依赖自动 drop,使用补偿迁移
审核 所有表结构变更先评审索引、字段类型、数据量

迁移顺序:

  1. 先建表和索引。
  2. 再发布兼容旧数据的代码。
  3. 后台任务补齐历史必要字段。
  4. 验证无误后启用新能力。

14.3 部署拓扑

flowchart TD
    LB["Nginx / 网关"]
    Admin["emoon-admin<br/>管理后台"]
    Open["emoon-openplatform<br/>对外 API / SSE"]
    MCP["MCP Tool Server<br/>可先同进程,后独立"]
    Dify["Dify Platform"]
    MySQL["MySQL 主库/从库"]
    Redis["Redis / Redisson"]
    Snail["SnailJob Server"]
    HIS["医院内网 HIS/EMR/LIS/PACS"]

    LB --> Admin
    LB --> Open
    Open --> Dify
    Dify --> MCP
    Open --> MCP
    MCP --> HIS
    Admin --> MySQL
    Open --> MySQL
    MCP --> MySQL
    Open --> Redis
    MCP --> Redis
    Snail --> MySQL

部署决策:

组件 MVP 规模化
MCP Tool Server 可嵌入 emoon-openplatformemoon-mcp 独立服务,便于内网部署和隔离
Dify 院内或专属云 按医院安全要求部署
MySQL 单主 + 备份 主从 / 高可用
Redis 单实例或哨兵 集群或哨兵
SnailJob 已有基础设施 用于 Outbox、账单、巡检、报表任务

14.4 API 版本化与兼容

当前存在旧 /chat/apisse 和新 /api/v1/agent/chat

路径 状态 策略
/chat/apisse legacy 只维护兼容,不新增能力
/api/v1/agent/chat 主链路 所有新能力进入 v1
/api/v1/card/** 新增 卡片动作和状态查询
/api/v1/billing/** 三期新增 余额、账单、流水查询

兼容迁移:

  1. 新客户只接 /api/v1
  2. 老客户保留兼容期。
  3. /chat/apisse 增加访问统计,确认是否仍有调用。
  4. 完成迁移后下线 legacy 路径。

14.5 安全算法与密钥管理

当前 MD5 签名可先兼容,但应进入升级计划。

能力 设计
请求签名 新接口使用 HMAC-SHA256;旧 MD5 兼容期保留
密钥存储 API Key、Dify Secret、HIS Secret 加密存储
加密算法 对称加密建议 AES-256-GCM 或国密 SM4-GCM
密钥轮换 项目支持多密钥并行,便于无停机轮换
传输安全 生产强制 HTTPS / 内网专线
日志安全 不打印密钥、签名原文、完整敏感 payload

初级工程师重点:为什么 MD5 要升级?
MD5 已不适合做安全签名。即使短期为了兼容保留,也不能作为新接口长期方案。HMAC-SHA256 能证明请求确实由持有密钥的一方发出,并减少伪造风险。

14.6 数据保留与归档

数据 建议保留 说明
计费账本 按财务合规长期保留 只追加,支持审计
账单 长期保留 合同和对账依据
原始调用日志 6-12 个月热数据,之后归档 排障使用
会话内容 按合同和医院要求 默认脱敏和最小化
卡片实例 保留业务结果和必要快照 避免保存过多医疗明细
敏感数据访问审计 长期保留 满足等保和个人信息保护要求

删除和归档必须走任务,不允许人工直接删生产表。

14.7 并发控制

挂号、锁号、支付、床位预约都是高并发写操作。

场景 锁粒度 说明
锁号 hospitalId + scheduleId + slotId 防止同一号源重复锁定
床位预约 hospitalId + bedId 防止重复占床
支付回写 orderId 防止重复回写
卡片动作 instanceId + actionName 防止重复点击
账本扣费 accountId + idempotencyKey 防止重复扣费

锁使用 Redis/Redisson,写操作还必须有数据库唯一约束或幂等记录兜底。

Redis 锁失败或 Redis 不可用时的降级策略:

场景 降级策略
查询类工具 允许继续访问 HIS 或本地缓存,但记录缓存降级告警
卡片重复点击 依赖数据库幂等表拦截,返回处理中或首次结果
锁号 / 建档 / 挂号 若无法确认互斥条件,优先拒绝或进入人工确认
账本扣费 继续使用数据库事务、唯一约束和乐观锁,不依赖 Redis
限流 降级为本机限流并告警,必要时按项目临时关闭高成本能力

初级工程师重点:Redis 是加速器,不是最终事实。
医疗写操作和账本扣费必须以数据库事务、唯一索引、乐观锁为最终保障。Redis 丢数据、重启、网络分区时,系统仍要能防止重复挂号和重复扣费。

14.8 性能基准

初始上线建议定义最低基准,后续按项目规模调整。

指标 MVP 建议
普通 API P95 < 500ms,不含 Dify/HIS 外部耗时
Dify 对话首 token < 3s,按模型和网络调整
SSE 并发 按医院试点规模压测
MCP 查询类工具 P95 < 1s,HIS 慢接口需缓存
MCP 写操作超时 3-10s,按厂商接口确定
计量事件处理延迟 < 1 分钟
月账单生成 可离线任务,允许分钟级

14.9 灾备与备份

对象 策略
MySQL 每日全量 + 增量 binlog,定期恢复演练
Redis 开启持久化,关键幂等状态仍以数据库为准
Dify 配置 定期导出 Workflow 配置和版本映射
账本数据 重点备份,不允许物理删除
对象存储 医疗附件按医院要求备份和加密

14.10 监控指标

维度 指标
API QPS、错误率、P95/P99、签名失败率
SSE 当前连接数、断连率、平均持续时长
Dify 成功率、超时率、P99、workflowRun 失败率
MCP 工具调用量、成功率、P99、HIS 错误码分布
卡片 展示量、点击量、动作成功率、过期率
计量 Outbox backlog、处理延迟、死信数量
账本 扣费失败、冲正次数、账户余额异常
安全 敏感访问、越权、异常调用峰值

15. 三期实施路线

15.0 与业务交付阶段的关系

工程路线要服务 L2/L3 项目交付。业务文档中的 AI 门诊、AI 住院都建议按“试点 -> 扩展 -> 闭环 -> 运营”推进,技术上对应以下里程碑。

业务阶段 门诊交付重点 住院交付重点 中台必须具备
阶段 0:两周边界锁定 存量设备盘点、P0/P1/P2 设备清单、设备准入标准 迪耐克/鸿蒙病房接口摸底、责任边界确认 统一入口客户端 PRD、DeviceProfile、设备准入分级、主动签到 POC 方案
阶段 1:1-2 个月门诊 MVP 导诊屏、自助机、机器人、叫号屏、诊室屏接入;导诊/分诊/挂号/签到基础闭环 住院接口只做摸底和最小互通准备 AgentEngine、Dify、基础 MCP、Card Runtime、Device Registry、Scene Orchestrator、基础计量
阶段 2:2-4 个月打穿闭环 预问诊、科室推荐、号源推荐、签到叫号、诊间语音病历、四诊仪、诊后小结/随访 通过迪耐克/鸿蒙病房体系接收护理白板、床头屏的标准业务事件和 IoMT 标准化数据,形成护理任务 AI 闭环 MCP 写操作、设备事件、医生/护士确认、IoMT Event Hub、Outbox、设备维度计量
阶段 3:4-6 个月标杆运营 门诊 P0/P1 设备统一运营、鸿蒙主动签到上线、运营看板、供应商生态 住院 AI 大脑层稳定互通,IoMT 预警解释与护理闭环 设备授权、合理不限量、运营报告、设备 SLA、区域/多院扩展准备

因此三期工程不能只做账本。它必须同时为项目验收提供证据:功能是否上线、场景是否跑通、医护是否确认、运营指标是否改善、合同范围内的用量和成本是否可解释。

15.1 第一阶段:计量账本 MVP(2-3 周)

目标:先让每次调用、每个设备入口和每个核心业务事件可计量、可追溯、可避免重复扣费。

交付:

  1. ai_meter_eventai_credit_accountai_credit_ledger 基础表。
  2. 对话完成后写标准计量事件。
  3. 设备注册、设备场景加载、卡片动作完成后可产生标准业务事件。
  4. 项目主账户能力值 grant / settle / reverse。
  5. 简单定价规则:按智能体固定能力值、按 token 折算、按设备授权三种。
  6. 管理后台查询项目余额、扣费流水和设备在线/授权状态。

15.2 第二阶段:额度控制与预扣(3-4 周)

目标:让能力值包可生产使用。

交付:

  1. 调用前额度校验。
  2. 高成本能力冻结 / 释放 / 结算。
  3. 余额预警、月度封顶、智能体限额。
  4. 设备授权校验、设备并发/在线数边界。
  5. 幂等键和重复扣费保护。
  6. 异常调用、异常设备、异常成本限流和审批状态。

15.3 第三阶段:账单与分摊(3-4 周)

目标:支撑客户对账和医院内部科室分摊。

交付:

  1. 月账单生成。
  2. 科室、智能体、场景、用户维度分摊。
  3. 设备、终端类型、准入等级、客户端版本维度分摊。
  4. 超量账单。
  5. 账单确认、导出、归档。
  6. 区域能力池的基础模型。

15.4 第四阶段:运营报告与合理不限量(4-6 周)

目标:支撑综合运营服务费和 L2/L3 长期运营。

交付:

  1. 运营看板。
  2. 合理不限量内部计量和异常边界识别。
  3. 设备运营看板:在线率、故障率、版本分布、远程升级成功率、SLA。
  4. 成本核算和毛利估算。
  5. 项目运营报告。
  6. 区域多院监管看板。

15.5 开发任务拆分建议

以下拆分适合初级工程师领取,每个任务都有清晰边界。

任务 依赖 目标 验收标准
项目鉴权上下文改造 请求后能拿到 projectId/tenantId/agentId 所有对话接口日志包含 traceId 和 projectId
Dify 引擎适配器 项目鉴权上下文 Dify 接入 AgentEngine 同步和流式对话能返回统一 AgentResponse
卡片实例创建 Dify 引擎适配器返回 cardKey/cardData Dify 返回卡片时落库 ai_card_instance 有输入数据和快照
卡片动作接口 卡片实例创建 前端点击后状态流转 能从 active 变为 completed/failed
DeviceRegistry MVP 项目鉴权上下文 注册导诊屏、自助机、机器人、诊室屏 设备有 hospitalId、location、capabilities、heartbeat
SceneOrchestrator MVP DeviceRegistry MVP、智能体配置 按设备返回 UI 模板和 Agent 绑定 同一设备切换场景无需改前端代码
TerminalRuntime MVP DeviceRegistry MVP、SceneOrchestrator MVP P0 设备统一加载入口 导诊屏/自助机/机器人/诊室屏至少跑通一条业务链路
DeviceAdapter 基础协议 TerminalRuntime MVP 标准化语音、扫码、打印、导航;住院侧只接收 IoMT 标准事件 设备 SDK 错误和病房标准事件错误能映射为平台错误码
MCP 查询工具 项目鉴权上下文 科室、医生、排班查询 返回统一结构,失败有错误码
MCP 写工具 卡片动作接口、MCP 查询工具 锁号、建档、挂号 写操作具备幂等键和动作日志
Outbox 事件表 项目鉴权上下文 业务事务内写事件 业务成功后一定有 pending 事件
BillingEpisodeService Outbox 事件表、计量上下文 管理 episode 状态和事件归并 synthetic、MCP、Card 子事件不会重复扣客户余额
计量事件表 Outbox 事件表 调用完成后写事件 重复 idempotencyKey 不重复入库
能力值账户 计量事件表 支持 grant、settle 账户余额和账本流水一致
冻结结算 能力值账户 支持 freeze/release/settle 高成本任务失败能释放额度
月账单汇总 能力值账户、冻结结算 按项目生成账单 账单金额等于账本汇总
运营看板接口 计量事件表、月账单汇总 输出项目用量和余额 支持按项目、科室、智能体筛选
AudioStreamGateway 项目鉴权上下文、ASR 服务 接入诊间音频流 能按 traceId 输出转写文本和 ASR 分钟事件
IoMTEventIngestion 项目/病区/床位映射 接收护理和 IoMT 标准预警事件 标准事件可进入 Outbox 和护理闭环
ServiceFindPatient POC DeviceEventIngestion、叫号/签到工具 主动签到服务找人闭环 患者确认后签到,叫号屏/小程序/医生站状态同步
OutboundFollowupService 随访计划、语音网关 调度 AI 外呼随访 通话状态、分钟数、风险分层和人工升级可追踪

15.6 每个任务的共同验收要求

  1. 有成功、失败、重复请求三类测试用例。
  2. 关键写操作有事务控制。
  3. 日志包含 traceId、projectId、sourceId。
  4. 错误返回不暴露密钥、身份证、手机号等敏感信息。
  5. 新增表有必要索引,至少覆盖项目、时间、状态三个维度。
  6. 设计中声明是否影响计费,不能默认“不知道”。

16. 可行性评估

16.1 技术可行性

可行。现有工程已有多租户、项目、公私钥鉴权、MyBatis-Plus、Redis、定时任务、审计日志、AI 调用入口和用量日志,三期可以在现有基础上增量建设。医院确认版新增的统一入口客户端、Device Registry、Device Adapter、Scene Orchestrator 属于新增产品能力,但可以先按门诊 P0 设备做最小闭环,不需要第一期覆盖所有终端。

关键工程难点不是 CRUD,而是账本一致性、幂等、异步事件可靠性、Dify/MCP/Card/Device 多来源事件归一化,以及设备厂商 SDK 差异、现场网络和版本治理。

16.2 业务可行性

可行。公司附件中的商业模式已经明确能力值包、合理不限量服务包、项目实施费和综合运营服务费。医院确认版进一步增加设备集成、统一入口客户端授权、设备运维、鸿蒙 POC、机器人场景服务等收费项,三期设计与该商业口径一致,能支撑 L1/L2/L3,其中门诊总包作为 L2 增强子类型落地。

16.3 风险与控制

风险 控制
计量规则频繁变化 规则版本化,账单按事件发生时规则计算
Dify usage 不稳定或缺失 以平台事件为主,Dify usage 为补充
流式响应中断 记录 partial / failed,按策略释放或部分结算
重试重复扣费 全链路 idempotency key
合理不限量成本失控 内部计量、峰值预警、合同边界和运营复核
医疗关键链路被计费中断 软拦截、审批、事后结算,不做简单硬停
科室分摊争议 保留原始事件、卡片动作、智能体、用户和时间维度
设备范围爆炸 第一阶段只做门诊 P0 设备,P1/P2 进入准入清单但不承诺闭环
厂商接口不开放 按 A/B/C/D 准入分级,不开放接口的设备只做展示或不进入核心闭环
住院硬件责任被转嫁 合同和方案中明确医梦做 AI 大脑层,床头屏/护理白板硬件由设备方负责
鸿蒙能力不成熟 主动签到 POC 保留 BLE、NFC、二维码、小程序位置授权兜底

17. 文档治理

原文中的大段 Java Controller、Service、SQL、Docker 示例不适合放在主技术方案中。后续建议拆为:

文档 内容
本文档 架构、职责、链路、数据模型、三期方案
docs/ai-platform-implementation-guide.md 已实现内容和联调方式
docs/ai-platform-api-contract.md 对外接口契约
docs/ai-platform-billing-design.md 三期计费账本详细设计,如后续需要可单独拆出
docs/ai-terminal-runtime-design.md 统一入口客户端、设备能力协议、UI 模板和端侧 Bridge
docs/ai-device-registry-design.md 设备注册、准入分级、场景绑定、心跳和远程运维
SQL 迁移脚本 最终表结构和初始化数据

二期 MVP 最小可行路径:

项目 最小要求
主入口 /api/v1/agent/chat 完成项目鉴权、traceId、会话写入
引擎 DifyAgentEngine 接入统一 AgentEngine,支持 blocking 和 SSE
设备 ai_device_registry 支持 P0 设备注册、心跳、场景绑定
统一入口 门诊导诊屏、自助机、机器人、诊室屏可通过同一协议加载场景
卡片 Dify 返回 cardKey/cardData 后创建 ai_card_instance
卡片动作 CardActionService 完成状态机、幂等、动作日志
MCP 至少打通科室、医生、排班查询和锁号/挂号 Mock 写工具
计量基础 Outbox + ai_meter_event 写入,重复幂等键不重复计量
验收链路 对话 -> Dify -> 卡片 -> 卡片动作 -> MCP Mock -> Outbox -> 计量事件
门诊 P0 链路 设备启动 -> 场景加载 -> 导诊/挂号/签到 -> 卡片确认 -> HIS Mock -> 计量事件

18. 术语表

术语 含义
OpenPlatform 医梦 AI 对外开放平台,统一鉴权、会话、卡片、审计和计量入口
Dify Workflow Dify 中配置的智能体流程画布,负责对话和流程编排
MCP Tool Server 对 Dify 和平台暴露的院内工具服务,封装 HIS/EMR/LIS/PACS
Terminal Runtime 统一入口客户端,优先部署在门诊屏幕、自助机、机器人、医生站插件等终端上;住院侧只做 AI 嵌入
Device Registry 设备注册中心,管理设备身份、位置、能力、状态、版本和智能体绑定
Device Adapter 设备适配层,把厂商 SDK/API 收敛为医梦标准设备能力协议
Scene Orchestrator 场景编排器,根据设备、位置、用户和业务状态加载 UI、智能体和工具权限
IoMT Event Hub 设备事件中心,接收迪耐克/鸿蒙病房网关标准事件、护理预警和服务找人事件
HIS Adapter 每家医院系统的接口适配层,负责厂商字段、鉴权、错误码转换
Card Runtime 卡片定义、实例、动作、状态机和动作日志的后端运行时
AgentEngine 平台统一智能体引擎接口,支持 Dify、DirectLLM、Mock
AiAgent 设计态/产品态智能体,偏知识、目标、流程和 KPI
AiAgentApp 运行态智能体,对外暴露 agentId,绑定项目和引擎配置
能力值 credits 面向客户的商业计量单位,不等同于 token
计量事件 从调用、卡片、MCP、文件、语音等来源产生的标准用量事实
能力值账本 项目账户的 grant/freeze/settle/release/reverse/expire 资金事实
Outbox 与业务事务同库落地的待处理事件表,用于可靠异步处理
幂等键 防止重复提交、重复写 HIS、重复扣费的业务唯一键
partial 流式调用或流程中断后的部分完成状态
合理不限量 客户侧不按量扣余额,但平台仍做内部计量、成本和异常复核
服务找人 根据患者身份、位置、预约、叫号等上下文,主动推送签到、提醒、路线等服务

19. ADR 索引

以下决策建议后续拆成独立 ADR,便于团队评审和长期维护。

ADR 决策 建议路径 状态
ADR-001 二期主链路统一使用 AgentEngine,旧 EngineAdapter 标记 legacy docs/adr/ADR-001-agent-engine-unification.md 建议采纳
ADR-002 OpenPlatform 掌握账本、审计、卡片状态,Dify 只做流程编排 docs/adr/ADR-002-openplatform-owns-facts.md 建议采纳
ADR-003 MCP Tool Server 作为 HIS/EMR/LIS/PACS 唯一工具出口 docs/adr/ADR-003-mcp-tool-server-boundary.md 建议采纳
ADR-004 卡片动作结果默认写入平台上下文,下一轮通过 Dify inputs 传回 docs/adr/ADR-004-card-action-result-to-dify.md 建议采纳
ADR-005 三期计费主粒度为项目/医院客户,科室和用户只做分摊统计 docs/adr/ADR-005-project-level-billing-grain.md 已确认
ADR-006 合同签署时预付能力值包,余额不足采用软拦截和审批策略 docs/adr/ADR-006-prepaid-credit-package.md 已确认
ADR-007 ai_usage_log 不作为财务账本,新增 ai_meter_event + ai_credit_ledger docs/adr/ADR-007-meter-event-credit-ledger.md 建议采纳
ADR-008 业务事件通过 Outbox 进入计量处理,避免业务成功但漏计费 docs/adr/ADR-008-outbox-for-metering.md 建议采纳
ADR-009 医疗知识权威来源放在 emoon-knowledge,Dify 引用发布版本 docs/adr/ADR-009-knowledge-governance-boundary.md 建议采纳
ADR-010 账户初版只做项目主账户真实扣费,科室预算为软分摊 docs/adr/ADR-010-credit-account-hierarchy.md 建议采纳
ADR-011 门诊 P0 设备必须接入统一入口客户端或标准设备协议 docs/adr/ADR-011-terminal-runtime-device-entry.md 建议采纳
ADR-012 住院侧采用 AI 大脑层互通,不做硬件总包 docs/adr/ADR-012-inpatient-ai-brain-boundary.md 建议采纳
ADR-013 鸿蒙协同先做主动签到 POC,并保留多技术兜底 docs/adr/ADR-013-harmony-service-find-patient-poc.md 建议采纳

20. 最终建议

  1. 二期先补齐 DifyAgentEngine、MCP 工具、卡片动作闭环、会话/卡片审计,以及 Device Registry、统一入口客户端 MVP。
  2. 门诊按“整体入口总包”设计,但第一期只承诺 P0 设备闭环:导诊屏、自助机、机器人、叫号屏、诊室屏/医生站插件、麦克风、四诊仪、主动签到 POC。
  3. 住院按“AI 大脑层”设计,与迪耐克/鸿蒙病房体系互通,不承担床头屏、护理白板、病房硬件总包责任。
  4. 三期不要等所有业务场景完成后再做计费,计量上下文应尽早接入二期主链路和设备事件链路。
  5. ai_usage_log 保留为原始日志,新增 ai_meter_event + ai_credit_ledger 做商业账本。
  6. 项目/医院是合同和额度主对象,科室、智能体、用户、设备、场景用于预算、分摊和统计。
  7. 合理不限量不是不计量,而是不扣客户余额;仍需做内部计量、成本核算和异常边界识别。
  8. 所有 HIS 写操作必须经过 MCP Server,并具备幂等、熔断、降级、人工确认和审计。
  9. 设备集成费、统一入口客户端授权费、设备运维服务费和鸿蒙 POC 应进入三期合同/账单模型,不能混入能力值账本。
  10. 三期 MVP 应优先交付“能扣、能查、能防重复、能出账、能按设备统计”,再做复杂区域运营和报表。

21. 架构图与核心流程图(大厂技术培训 / 高密度 / 强层级版)

本章用于公司内部技术培训和初级工程师快速理解。阅读顺序建议:先看全局分层,再看主调用链,再看卡片、MCP、计量、Outbox、数据安全和交付路线。

21.1 一图看懂:二期技术架构 + 三期商业闭环

医梦 AI 中台全局分层架构图

读图要点:

  • L0 是不可信输入区,所有入口必须经过 OpenPlatform 的签名鉴权、项目授权、限流和审计。
  • L1 是平台事实层,掌握会话、卡片实例、计量上下文和审计链路。
  • L2 是智能推理层,Dify 负责流程编排,DirectLLM 负责轻量能力或降级能力。
  • L3 是工具执行层,MCP 是院内系统唯一工具出口。
  • L4 是资金事实与可靠性层,Outbox、Metering、Credit Ledger、Billing 共同构成商业闭环。

21.2 主调用链路:从 Chat 到卡片、工具、计量

主调用链路图

读图要点:

  • 一次请求不能只理解成“调用大模型”,而是要经过鉴权、路由、Dify 编排、MCP 工具、卡片实例、Outbox 和计量账本。
  • Dify 的输出不能直接信任,平台必须统一做输出结构校验、卡片实例创建和计量事件生成。
  • 所有链路必须带 traceId,否则线上排障会断链。

21.3 卡片运行时闭环:医疗确定性动作必须走卡片

卡片运行时闭环图

读图要点:

  • 卡片不是前端 UI,而是医疗业务动作的状态机。
  • 任何会改变 HIS、患者档案、预约订单、床位、账本的动作,都必须经过 Agent 编排和 CardActionService 状态校验。
  • 卡片动作产生业务事实,MCP 工具调用多为内部成本事实,二者不能重复向客户扣费。

21.4 MCP Tool Server:医院系统唯一工具出口

MCP 工具网关分层图

读图要点:

  • MCP 的价值不是“多一个服务”,而是将院内系统工具化、标准化、审计化。
  • 写操作必须具备幂等、最终状态查询、熔断和人工兜底。
  • 不同医院的 HIS/EMR/LIS/PACS 差异只能进入 Adapter 层,不能污染 Dify、卡片和计量主链路。

21.5 三期能力值商业闭环:从业务事件到月度账单

能力值商业闭环图

读图要点:

  • 客户侧按业务价值计费,内部按 token、图片、分钟、工具调用等成本计量。
  • billingEpisode 是把原始调用、synthetic message、卡片动作、MCP 成本归并成业务计费单元的关键。
  • 账单只能从 ai_credit_ledger 汇总,不能从 ai_usage_log 汇总。

21.6 Outbox 事件可靠性:业务成功不能丢计量、不能重复扣费

Outbox 事件可靠性图

读图要点:

  • 业务表和 Outbox 必须在同一数据库事务中落库。
  • Dispatcher 可以失败、重试、死信,但不能让业务事实和计量事实失联。
  • 幂等键和唯一约束是防止重复扣费的底线,Redis 锁只能做削峰,不能作为最终幂等依据。

21.7 数据安全与权限边界:医疗数据最小化流转

数据安全与权限边界图

读图要点:

  • Dify 只能接收必要患者摘要,不应接收完整病历、身份证、手机号、舌/面原图等敏感原文。
  • PII 和医疗原文必须走“前端卡片动作 → AgentActionOrchestrator → CardActionService → MCP/HIS”的后端加密链路。
  • 计量、账单、运营报告只保存计费用字段和聚合指标,不保存患者隐私明细。

21.8 初级工程师交付路线地图:先闭环,再扩场景

工程交付路线地图

读图要点:

  • 工程交付顺序应从主链路闭环开始,而不是从业务场景无限扩张开始。
  • 每一阶段都必须满足接口可重放、数据可追踪、失败可解释、权限可证明、账务可审计、医疗可兜底。
  • 二期交付“可调用、可审计、可卡片闭环”,三期交付“可收费、可控额、可出账、可运营”。