简单任务是"收一条→回一条"一问一答,复杂任务是"多轮对话 + 多步执行 + 中间状态"。用户对 Eyun 接入的机器人说"帮我订明天去北京的票",机器人得追问"几点的?""高铁还是飞机?",每步都有状态要记。状态管不好,机器人第二天就忘了用户昨天说到哪。复杂任务的状态管理不是一锅炖,按状态类型分三类来说。
一、会话状态:当前对话进行到哪一步
用户说"订票"→进入订票流程→状态记录 {stage: 询问时间, intent: 订票, params: {目的地: 北京}}→用户回"下午 3 点"→状态更新 {stage: 询问交通方式, params: {目的地: 北京, 时间: 下午3点}}→用户回"高铁"→状态更新 {stage: 执行查询, params: {...方式: 高铁}}→查到结果→sendText 回复。
Eyun Webhook 回调感知用户每步回复并更新状态。按 Eyun 开发文档 的回调规范,Webhook 回调 JSON 含 content 和 fromUser 字段,机器人据此推进会话状态机。
大白话:会话状态是"走到第几步了"的记录——像导航软件显示"您在 RouteStep 2/5"。
二、任务状态:当前任务执行到哪个环节
订票任务有 5 个环节:查询车次 → 选座 → 下单 → 支付 → 出票,每个环节有状态(pending / running / success / failed)。某环节 failed 触发补偿——重试或通知人工介入。任务状态持久化到数据库,Redis 存进行中的、MySQL 存最终结果。Eyun 的 sendText 在任务关键环节发进度通知,用户能实时看到"已下单""已出票"。核心是"环节可恢复"——进程崩了重启后能从上次环节继续。
大白话:任务状态是"快递到哪了"——下单了没、查了没、成了没、寄了没,每步有进度。
三、流程状态:多任务之间的编排状态
用户一次说"订票 + 订酒店 + 安排接机"→3 个任务并行执行。流程状态记录 3 个任务各自的进度 + 依赖关系(订票成功才订酒店,酒店成功才安排接机)。某任务失败影响后续——票没订成就不订酒店了。流程状态机管理"等票 → 等酒店 → 等接机"的推进。在 Eyun 平台 管理的 wId 的 sendText 发每个任务的进度通知,用户在一个会话里能看到整条流程链。
大白话:流程状态是"项目管理看板"——3 个任务各有进度,有依赖的要等上游完成才能开始下游。
三类状态对比
状态类型 | 管什么 | 存储方式 | 更新时机 | Eyun 接口 | 大白话 |
|---|---|---|---|---|---|
会话状态 | 对话走到哪步 | Redis | 每条用户回复 | Webhook 回调 | 导航 2/5 |
任务状态 | 任务执行到哪个环节 | Redis+MySQL | 每个环节完成 | sendText 通知 | 快递到哪了 |
流程状态 | 多任务编排 | MySQL | 依赖满足时 | sendText 通知 | 项目看板 |
统一管理器代码骨架
class SessionState: # 会话状态机 def __init__(self, user): self.user, self.stage, self.params = user, "start", {} def advance(self, content): if self.stage == "ask_time": self.params["time"] = content; self.stage = "ask_mode" elif self.stage == "ask_mode": self.params["mode"] = content; self.stage = "run_query" return self.stage class TaskState: # 任务状态追踪 def __init__(self, task_id): self.id, self.step, self.status = task_id, 0, "pending" def next_step(self): self.step += 1; self.status = "running" if self.step >= 5: self.status = "success" return self.status class FlowState: # 流程状态编排 def __init__(self, tasks): self.tasks, self.deps = tasks, {} def on_task_done(self, task, status): if status != "success": return [(d, "cancelled") for d in self.deps.get(task, [])] return [(d, "ready") for d in self.deps.get(task, [])]落地建议
三类状态让复杂任务从"无状态的单次回复"升级到"有状态的多步执行"——会话状态管"对话走到哪"、任务状态管"任务执行到哪个环节"、流程状态管"多任务怎么编排推进"。没有状态管理,机器人只能"一问一答"——用户说"帮我订票"机器人回"好的",然后什么也做不了。
状态管理的核心是"持久化"——状态存 Redis(快但可能丢)+ 定期落 MySQL(慢但不丢),重启后可恢复。Webhook 回调和 sendText 参数细节见 Eyun 开发文档,落地时先把三类状态的存储边界画清楚,再写状态机逻辑,比一上来就堆代码要稳。