--- doc_id: DES-202606-003 feature_id: FEAT-202606-006-agent-semantic-interaction type: design title: 卡片链式架构分阶段实施与单次切换方案 status: reviewing owner: 医梦研发团队 created_at: 2026-06-29 updated_at: 2026-07-01 reviewers: - 架构负责人 - 后端负责人 - 终端负责人 related_docs: - ADR-202606-001 - DDS-202606-004 - API-202606-004 related_modules: - emoon-openplatform - emoon-ai-agent - emoon-ai-card - emoon-ai-mcp - emoon-system tags: - 迁移 - Breaking Change - Card Runtime - Command Runtime --- # 卡片链式架构分阶段实施与单次切换方案 ## 迁移前提 - 当前没有生产环境 Agent 和需要保留的卡片实例数据。 - 允许最终切换时破坏性修改接口、模块名、表名和终端事件。 - 开发阶段保留旧演示链作为对照和回退基线,但不建设可长期运行的 v1/v2 双轨。 - 本文只设计迁移步骤,不在本轮执行。 ## 目标映射 | 旧对象 | 新对象 | 处理 | |---|---|---| | Card 驱动业务流程 | TaskState 驱动任务 | 删除链式语义 | | `AgentResponse.cardKey/cardData` | 后端 `SemanticResponse` | 替换 | | `card_created` | `presentation` 或 `command_prepared` | 拆分 | | `nextCard` | interaction + TaskState | 删除 | | 信息 CardInstance | 无状态 Presentation | 不落实例 | | 卡片写动作 | Command | 迁移 | | `emoon-ai-card` | `emoon-ai-command` | 模块重命名 | | `ai_card_instance` | `ai_command_instance` | 新建,不迁数据 | | `ai_card_action_log` | `ai_command_audit_log` | 新建,不迁数据 | | `ai_card_definition` | MVP 删除;展示 ViewModel 随代码版本管理 | 不迁动作 | | Dify 卡片输出 | FastGPT 文本 + 只读 Tool Call | 替换 | | OpenAPI v1.2 卡片动作 | OpenAPI v2 interaction/commands | 主版本替换 | ## 实施策略 实施分四个可独立验收阶段,只有全部门禁通过后才执行一次性切换。 “分阶段”指开发和验证节奏,不表示生产同时维护 v1/v2 两套协议。 ### 阶段零:FastGPT 能力验证 1. 在隔离分支验证目标 FastGPT 版本的流式输出和工具调用事件。 2. 验证医梦 ToolCatalog 能否通过 MCP ToolSet、HTTP ToolSet 或 Workflow 工具节点下发。 3. 确认工具参数 Schema、超时、错误和 traceId 能被稳定回传。 4. 只注册 Mock 只读工具,不接写工具。 门禁:连续覆盖正常、参数错误、超时和空结果;能力不满足则停止后续开发, 保留旧演示链,不进入切换。 ### 阶段一:查询链验证 1. 批准 ADR、详细设计、接口说明和测试计划。 2. 实现 TaskState 查询上下文、只读 ToolCatalog 和 FastGPT Adapter。 3. 建立 ResultSnapshot 和最小 SemanticResponse DTO。 4. 先只返回纯文本,跑通精确查询、空结果和替代推荐。 门禁:不用卡片即可完成挂号查询;工具参数无效时能澄清且不暴露内部拒绝; 查询链稳定后再进入命令阶段。 ### 阶段二:命令链 1. 将 `emoon-ai-card` 迁移为 `emoon-ai-command`。 2. 建立 Command 状态机、风险策略和审计表。 3. 迁移锁号为 L1,挂号/支付/取消为 L2。 4. 写工具只允许 Command Runtime 内部调用。 5. 终端改消费 `command_prepared/command_completed`。 门禁:锁号实时复核、挂号二次确认、幂等和 UNKNOWN 状态测试全部通过。 ### 阶段三:可选展示与最终切换 1. 使用代码内 `AppointmentSlotCandidatesV1` 生成无状态 Presentation。 2. 终端消费 `presentation`,点击回传 interaction。 3. 验证展示关闭、超时或失败均不影响查询和命令。 4. 完成 v2 端到端回归后执行一次性切换。 切换时清理: 1. 删除 `nextCard` 和卡片流程配置。 2. 删除通用 `card_created` 事件。 3. 删除 `/cards/{id}/actions/*`。 4. 删除旧卡片实例、动作日志和动作型定义表。 5. 删除 Dify/Card 相关硬编码和旧演示种子。 6. 仓库全文检索确认旧语义只保留在历史文档的替代说明中。 ## 数据迁移 不迁移生产数据。实施脚本应: 1. 新建 `ai_result_snapshot`、`ai_command_instance`、`ai_command_audit_log`; 2. 确认测试/演示数据不再引用旧表; 3. 删除旧卡片实例、动作和动作型定义表; 4. 展示 ViewModel 随代码发布,不迁移 `actions_json`。 ## 文档迁移 需要同步: - `FEAT-202606-001`:标记链式卡片与 v1.2 被替代; - `FEAT-202606-002`:FastGPT 只读 MCP 与 Command 边界; - `ODS-202606-001`:增加新架构优先声明; - `STD-202605-001`:更新模块、依赖和红线; - OpenAPI v1.2:保留历史文件,停止作为新实现依据。 ## 回滚原则 本方案不提供长期运行的 v1/v2 双轨。切换前,旧演示版本保持可部署;切换动作必须有 完整发布制品、数据库备份和版本回退点。切换后若验收失败,整体回退到旧发布制品, 不得在同一部署中混用 v1 卡片动作和 v2 Command。 如果 FastGPT 工具调用能力验证失败: - 保留文本只读问答; - 暂停挂号写命令上线; - 不恢复模型直出卡片 JSON; - 单独创建后续引擎能力需求。 ## 完成标准 - 新挂号链路不创建信息 CardInstance; - 所有写操作由 Command Runtime 发起; - 终端不再调用卡片动作接口; - v2 契约和测试全部通过; - 旧链式语义在有效工程约束中清零; - 测试结果文档记录真实执行证据后才能标记迁移完成。 ## 批量智能体建设准入门槛 本专题完成前,不以旧 Card Runtime 为基础继续建设生产业务智能体。只有同时满足以下条件, 后续智能体才能进入规模化开发: 1. FastGPT 能稳定消费经过租户、项目、Agent 和场景过滤的只读 ToolCatalog; 2. Agent 不需要生成 `cardKey/cardData` 即可完成查询、解释和替代推荐; 3. TaskState 的完成条件和状态迁移不依赖 Card 类型、`nextCard` 或渲染结果; 4. 所有写操作均通过 Command Runtime 完成风险控制、确认、幂等和审计; 5. 关闭或破坏 Presentation 后,挂号纵向样板仍能通过文本/语音完成端到端业务; 6. 自然语言选择和 Card 点击统一进入 interaction/Command 校验链路; 7. v2 接口、架构测试、终端回归及 `TST-202606-001` 全部通过并形成测试结果文档; 8. 新智能体设计模板能够独立描述 TaskState、只读工具、Command 和可选 Presentation。 达到门槛后,后续智能体按“只读查询型 → 事务型”的顺序分批建设,但统一遵守同一中台协议; 不得为单个智能体恢复模型直出 Card JSON 或链式 Card 编排。