下面把“将所有关键动作设计为‘命令 + 应答 + 状态确认’”落地成一套可直接套用的设计规范。它适用于设备控制、任务调度、API 交互、工单流转、机器人/自动化等场景。

一、核心模型

每个关键动作都拆成三段:

阶段方向作用关键要求
命令 Command发起方 → 执行方表达“要做什么”有唯一指令 ID、目标、参数、超时、幂等键
应答 Ack执行方 → 发起方表达“已收到、是否接受”明确 accepted / rejected,附原因
状态确认 Confirm执行方 → 发起方表达“最终执行结果”终态、影响范围、可追溯证据

一句话:命令负责发起,应答负责接收,状态确认负责闭环。

二、统一交互流程

发起方                     执行方
  |---- Command ------------>|
  |<--- Ack (accepted) ------|   接收确认
  |<--- Status (running) ----|   过程状态(可选)
  |<--- Confirm (done/fail) -|   终态确认
  |---- ConfirmAck --------->|   发起方确认收到终态(可选但推荐)

如果执行方拒绝:

  |---- Command ------------>|
  |<--- Ack (rejected) ------|   附拒绝原因
  |<--- Confirm (aborted) ---|   终态:未执行/已中止

三、字段设计模板

1. 命令 Command

{
  "msg_type": "command",
  "command_id": "CMD-20260521-0001",
  "idempotency_key": "order:123:start",
  "action": "device.start",
  "target": "device-01",
  "params": {},
  "issued_by": "scheduler",
  "issued_at": "2026-05-21T10:00:00Z",
  "deadline": "2026-05-21T10:00:30Z",
  "reply_to": "cmd.result.001"
}

要点:

  • command_id 全局唯一,用于全链路追踪。
  • idempotency_key 防止重复执行。
  • deadline 明确超时,避免悬挂。
  • reply_to 指定应答/确认通道。

2. 应答 Ack

{
  "msg_type": "ack",
  "command_id": "CMD-20260521-0001",
  "ack_id": "ACK-0001",
  "status": "accepted",
  "reason": null,
  "estimated_duration": 10,
  "received_at": "2026-05-21T10:00:01Z"
}

status 建议枚举:

  • accepted:已接收,将执行
  • rejected:拒绝执行,必须给 reason
  • duplicated:重复命令,已忽略
  • expired:超过 deadline,不再执行

3. 状态确认 Confirm

{
  "msg_type": "confirm",
  "command_id": "CMD-20260521-0001",
  "confirm_id": "CFM-0001",
  "final_status": "succeeded",
  "progress": 100,
  "result": {},
  "error": null,
  "evidence": {
    "log_url": "...",
    "snapshot_url": "..."
  },
  "finished_at": "2026-05-21T10:00:09Z"
}

final_status 建议枚举:

  • succeeded
  • failed
  • partially_succeeded
  • aborted
  • timeout

四、状态机

CREATED
  -> SENT
  -> ACKED_ACCEPTED / ACKED_REJECTED / ACKED_DUPLICATED / ACKED_EXPIRED
  -> RUNNING
  -> SUCCEEDED / FAILED / PARTIAL / ABORTED / TIMEOUT
  -> CONFIRMED

关键规则:

  1. 没有 Ack,不得进入 RUNNING。
  2. 没有 Confirm,不得视为完成。
  3. Confirm 必须终态,且不可逆。
  4. 超时未 Ack → 发起方标记 timeout 并告警。
  5. Ack accepted 后超时未 Confirm → 进入 unknown,触发对账/补偿。

五、关键动作分类与设计示例

动作类型命令应答状态确认
设备启动device.startaccepted/rejectedsucceeded/failed
订单支付order.payaccepted/rejectedpaid/failed
任务下发task.dispatchaccepted/rejectedcompleted/failed
文件删除file.deleteaccepted/rejecteddeleted/failed
工单关闭ticket.closeaccepted/rejectedclosed/reopened
配置变更config.applyaccepted/rejectedapplied/rolled_back

六、可靠性增强

1. 幂等

执行方按 idempotency_key 去重;重复命令返回 duplicated,不重复执行。

2. 重试

  • 仅对“未收到 Ack”重试。
  • 收到 rejected 不自动重试,除非人工/策略变更。
  • 重试必须复用同一 command_id 或标记 retry_count

3. 超时与对账

  • 命令超时:deadline 后无 Ack → 标记失败。
  • 确认超时:Ack 后无 Confirm → 进入 unknown,由对账任务查询真实状态。

4. 顺序与并发

  • 同一目标的关键动作可加 lock_key 串行化。
  • 并发命令需在 Ack 中返回 conflict 或排队信息。

5. 可观测性

每次交互记录:

  • command_id
  • 各阶段时间戳
  • 发起方、执行方
  • 状态迁移
  • 失败原因与证据

七、反模式

反模式问题修正
只发命令不等待不知道是否执行必须等 Ack
有 Ack 就当成功接收 ≠ 完成必须等 Confirm
Confirm 非终态状态反复终态唯一且不可逆
无 command_id无法追踪全链路唯一 ID
无幂等键重复执行加 idempotency_key
拒绝无原因无法排障rejected 必须附 reason

八、最小落地清单

  1. 定义统一消息结构:Command / Ack / Confirm。
  2. 为每个关键动作分配 action 名和状态机。
  3. 强制 command_id + idempotency_key
  4. 实现 Ack 超时、Confirm 超时与对账。
  5. 日志与监控按 command_id 串联。
  6. 测试:正常、拒绝、重复、超时、部分成功、乱序。

如果你告诉我具体场景(比如 HTTP API、MQTT 设备、工单系统、Agent 工具调用),我可以直接把上面的模板改成该场景的接口定义和状态机。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐