--- doc_id: ODS-202606-002 feature_id: FEAT-202606-006-agent-semantic-interaction type: outline-design title: Agent 语义交互与命令治理概要设计 status: reviewing owner: 医梦研发团队 created_at: 2026-06-29 updated_at: 2026-07-02 reviewers: - 架构负责人 - 后端负责人 - 终端负责人 related_docs: - PRD-202606-002 - ADR-202606-001 related_modules: - emoon-openplatform - emoon-ai-agent - emoon-ai-card - emoon-ai-mcp - emoon-system tags: - 语义响应 - 命令治理 - 无状态展示 - FastGPT --- # Agent 语义交互与命令治理概要设计 ## 背景 本设计替代“模型输出 cardData、CardInstance 按 nextCard 推进业务”的链式架构。 MVP 只保留三个核心运行时概念:TaskState、可信 QueryResult 和 Command。 `SemanticResponse`、Presentation 都是传输/展示结构,不升级为独立业务子系统。 ## 架构可视化 ### 改造前:Card 驱动的链式 Agent ![改造前:Card 驱动的链式 Agent](assets/agent-architecture-before.png) 模型需要生成 `cardKey/cardData`,Card Runtime 再通过 `nextCard` 串联科室、医生、时段和确认。 Card 类型同时影响展示、任务推进与业务动作,查询和写操作也混在 Card Action 中。 [SVG](assets/agent-architecture-before.svg) / [可编辑 Excalidraw](assets/agent-architecture-before.excalidraw) ### 改造后:TaskState、Query 与 Command 分层 ![改造后:TaskState、Query 与 Command 分层](assets/agent-architecture-after.png) 新运行时以 TaskState 作为任务事实源;FastGPT 只规划经过 ToolCatalog 过滤的 MCP 只读查询; 查询结果形成 ResultSnapshot,并通过 SemanticResponse 完整返回文本/语音。所有副作用进入 Command Runtime,Card 只保留为可选 Presentation。 [SVG](assets/agent-architecture-after.svg) / [可编辑 Excalidraw](assets/agent-architecture-after.excalidraw) ### 核心差异 | 维度 | 改造前 | 改造后 | |---|---|---| | 流程驱动 | Card 类型与 `nextCard` | TaskState 与业务完成条件 | | 模型输出 | 严格 `cardKey/cardData` | 自然语言流 + 只读 Tool Call | | 查询 | 固定卡片步骤 | ToolCatalog + MCP 灵活查询 | | 写操作 | Card Action 混合执行 | Command Runtime 统一治理 | | Card 定位 | 流程节点和状态信号 | 可选 Presentation | | 后续 Agent | 复制卡片链 | 复用统一任务、查询和命令协议 | ## 总体方案 ```mermaid flowchart TD U["用户文本、语音或 interaction"] --> O["OpenPlatform"] O --> T["TaskStateService"] T --> F["FastGPT Adapter"] F -->|"自然语言流"| A["AgentApplicationService"] F -->|"只读 Tool Call"| M["MCP Gateway"] M --> R["QueryResult / ResultSnapshot"] R --> A A --> S["SemanticResponse DTO"] S --> P["PresentationPolicy"] P -->|"可选"| V["无状态 Presentation"] S -->|"需要副作用"| Q["Command Runtime"] Q -->|"内部写工具"| M S --> E["SSE v2"] V --> E Q --> E ``` 总体原则: 1. 查询不经过 Command Runtime。 2. 展示不决定任务推进。 3. 模型不生成最终展示数据或命令令牌。 4. 写操作只由医梦后端创建并执行。 5. 文本、展示和命令事件相互解耦但共享同一业务事实。 ## 后续智能体统一设计方法 本设计是后续业务智能体的公共运行时基线。新智能体必须从业务目标和状态开始设计,不从页面或 Card 开始设计: ```text 业务目标与完成条件 → TaskState 与约束 → 只读 ToolCatalog/MCP → 有副作用的 Command 与风险策略 → 完整文本/语音交互 → 可选 Presentation/Card ``` 只读型智能体无需定义业务 Command;包含锁号、挂号、缴费、取消等动作的事务型智能体必须进入 Command Runtime。两类智能体都不得创建独立的卡片工作流。 Card 是 Presentation 的一种终端表现,不是中台领域对象或 Agent 编排原语: | Card 可以承担 | Card 不得承担 | |---|---| | 候选结果对比与信息分组 | 定义 Agent 步骤和先后顺序 | | 快捷选择入口 | 作为 TaskState 或完成条件 | | Command 确认摘要的可视化 | 生成或携带可信 Command 参数 | | 执行结果和状态展示 | 成为文本/语音之外的唯一业务通道 | 领域 ViewModel 只能投影 ResultSnapshot 或 Command 摘要。Card 点击必须转换为标准 interaction 或 Command 确认请求,再进入与自然语言相同的后端校验链路。 ## 模块边界 | 模块 | 职责 | 不负责 | |---|---|---| | `emoon-openplatform` | 对外 v2 入口、鉴权、SSE、命令确认入口 | 不保存领域状态,不直连 HIS | | `emoon-ai-agent` | TaskState、FastGPT Adapter、查询结果引用、响应组装、简单展示决策 | 不直接写 HIS,不保存最终账务事实 | | `emoon-ai-command`(目标) | 命令状态机、风险、确认、幂等、过期、审计 | 不做模型推理,不负责普通展示 | | `emoon-ai-mcp` | 只读/写工具注册、权限、调用、审计和 HIS Adapter | 不处理 UI,不决定任务流程 | | `emoon-system` | Agent、工具授权、场景和命令策略配置 | 不执行运行时业务 | | `emoon-terminal-client` | 文本/语音展示、无状态 UI、确认交互 | 不创建命令,不判断风险 | | FastGPT | 自然语言生成、只读工具规划、RAG/Workflow 子流程 | 不持有业务事实,不执行写命令 | 当前 `emoon-ai-card` 在实施阶段一次性迁移为 `emoon-ai-command`。 ## 主调用链路 ### 查询 ```text 用户输入 → TaskState 提取已知约束 → FastGPT 选择只读 MCP 工具 → MCP 返回结构化结果 → 保存短期 ResultSnapshot → 后端生成 SemanticResponse → SSE 先返回文本/semantic_result → PresentationPolicy 可选生成 presentation ``` ### 选择与锁号 ```text 自然语言“选第二个”或点击 candidate → interaction 解析 resultRef/version/candidateId → 校验候选版本、租户、患者、会话 → 实时复核号源 → L1 明确选择即授权 → Command Runtime 创建并执行短期锁号 → command_completed + task_updated ``` ### 最终挂号 ```text 后端根据已锁号 TaskState 准备 L2 REGISTER_APPOINTMENT → command_prepared 返回确认摘要 → 用户通过卡片/文本/语音确认 → Command Runtime 复核身份、版本、有效期和幂等 → MCP 写工具执行 → command_completed + task_updated ``` ## 数据流 | 数据 | 来源 | 保存位置 | 使用者 | 生命周期 | |---|---|---|---|---| | TaskState | 后端验证后的模型建议与命令事实 | `ai_task_instance` | Agent、Command | 任务周期 | | ResultSnapshot | 只读 MCP 结果的最小快照 | `ai_result_snapshot` | 文本、展示、交互解析 | 短期 | | Presentation | ResultSnapshot 的无状态投影 | 不持久化或仅留审计摘要 | 终端 | 单次响应 | | CommandInstance | 后端准备的确定性命令 | `ai_command_instance` | Command Runtime、终端 | 命令周期 | | CommandAudit | 确认、拒绝、执行与结果 | `ai_command_audit_log` | 审计、排障 | 按合规策略 | ## 外部依赖 - FastGPT:首期唯一正式支持的推理和只读工具规划引擎。 - HIS/Mock HIS:科室、医生、号源查询以及锁号、挂号写入。 - 终端客户端:消费 SSE v2、渲染 Presentation、确认或拒绝 Command。 - Device/Scene:提供终端能力、允许的 Agent、展示和命令权限。 ## 关键策略 ### 展示策略 PresentationPolicy 综合终端能力、结果数量、领域类型、数据完整性、风险和用户偏好。 信息展示无状态;只有命令确认会创建 CommandInstance。 MVP 不建设动态模板系统。挂号候选和挂号确认采用代码内版本化的领域 ViewModel; 场景配置只决定是否展示和终端能力,不允许上传任意 Schema 或动作脚本。 ### FastGPT 工具目录 Agent 启动或配置发布时,由医梦后端从 MCP Tool Registry 生成只读 ToolCatalog: ```text MCP Tool Registry → 过滤 riskLevel=READ_ONLY → 校验 tenant/project/agent/scene 授权 → 输出 name/description/inputSchema/timeout/dataClassification → FastGPT Adapter 注册或注入目标 App/Workflow ``` FastGPT 目标版本如何承载 ToolCatalog 必须先通过能力验证确定;无论采用 MCP ToolSet、 HTTP ToolSet 还是 Workflow 工具节点,写工具都不会进入该目录。 ### 查询扩展策略 精确查询为空时,按医院配置的允许范围生成替代查询。替代结果必须显式标注放宽了哪个条件, 且只能推荐,不能自动进入命令。 ### 多任务策略 每个会话只允许一个前台可变更任务。无状态问答可以插入;切换业务任务时暂停原任务。 暂停不延长锁号有效期。 ## 风险 | 风险 | 控制 | |---|---| | FastGPT 工具调用不稳定 | 引擎能力门禁、Schema 校验、只读权限、文本降级 | | 展示与文本不一致 | 两者引用同一 ResultSnapshot | | 号源过期 | 锁号前重新查询,ResultSnapshot 不作为执行凭证 | | 命令重复执行 | commandId + 幂等键 + HIS 状态查询 | | 终端伪造命令 | 命令只能由后端准备,终端只能确认/拒绝 | | 配置降低安全要求 | 平台固定风险下限,租户只能收紧 | ## ADR 本设计改变模块边界、接口主版本、数据模型和 FastGPT/MCP 权限边界,必须由 `ADR-202606-001` 记录并在开发前批准。