日期:2026-07-25
我们内部有一类长任务型智能体:比如"拉销售数据→生成采购建议→写审批单→等人工确认→下单",一条链路跑下来可能跨数小时甚至跨天。早期版本把整个流程写在一个长脚本里,靠内存里的变量传递状态。问题很快暴露:服务发版重启、Pod 被调度走、或某一步调用超时,整条链路的状态全丢,只能从头重跑。重跑意味着重复调用模型、重复写单,既烧钱又可能制造重复单据。更糟的是,人工确认点的上下文也丢了,审批人收到的是"第二次"的请求,完全不知道之前发生了什么。
我们当时判断,核心矛盾不是"智能体不够聪明",而是"任务没有可持久化的状态"。这个项目里,我们采用私有化 AI 底座承载模型调用,并把任务编排从"内存脚本"改为"持久化状态机驱动"。底座确定后,真正的难点是怎么让一条跨天链路在任意时刻被杀死后,都能从断点精确恢复,且每一步都可重入、不重复副作用。
第一类场景是任务状态机建模。每条智能体链路被抽象成一组离散状态(如:fetch→analyze→draft→human_review→submit→done),状态转移由事件驱动,每一步的入参、产出、时间戳都落库。
第二类场景是步骤幂等与断点恢复。任何一步都可被重复触发,但第二次触发若发现该步已完成,则直接复用结果而非重跑。服务重启后,调度器扫"未完成状态"的任务,从最近一次状态继续,而非从头。
第三类场景是失败回退与补偿。某步失败时,状态机进入 retry 或 fallback 分支,必要时做反向补偿(如已写的草稿单在未提交前可撤回),而不是让半完成状态泄漏到下游。
第四类场景是人工确认点插入。在需要人拍板的状态(如提交采购单前),状态机挂起并等待外部事件,人工确认后推动到下一状态,且确认上下文完整保留。
落地过程中我们还补了一块常被忽略的能力:任务可观测。过去一条链路卡住,运维只能看日志猜卡在哪;现在每个任务的状态、停留时长、重试次数都在看板上,哪类任务经常卡在 human_review 一目了然。
第一个挑战是任务状态机建模与持久化。关键不是"存状态字符串",而是把每一步的副作用也建模清楚。我们用一张 task_step 表记录每步状态与产出,状态转移前先写"意图日志",再执行副作用,保证崩溃时可重放。下面是状态与幂等校验的脱敏片段。
-- 任务步骤状态与幂等(已脱敏)
UPDATE task_step t
SET t.status = :next,
t.output = :output,
t.update_at = NOW()
WHERE t.task_id = :task_id
AND t.step = :step
AND t.status = :expect -- 仅当处于预期前态才转移,避免重复执行
AND t.run_id = :run_id;第二个挑战是步骤幂等与断点恢复。我们给每一步定义"幂等键"(如 fetch 步以日期+数据源为键),重跑时先查是否已存在该键的产出,有则直接复用。调度器恢复时按状态升序扫描未完成任务,从最早未完成步续跑。
第三个挑战是失败回退与补偿。我们为带副作用的步骤(如写单)定义"补偿动作",失败时按反向顺序执行补偿,把半完成态清理干净。human_review 这类等待态用事件表接收外部确认,超时则回退到 draft 并告警。
改造前后,我们拉通了四组口径一致的脱敏示意指标:
| 指标 | 改造前 | 改造后 | 说明 |
|---|---|---|---|
| 任务完成率 | 约 88% | 约 99% | 跨天链路最终完成比例 |
| 断点恢复成功率 | 约 0% | 约 98% | 重启后从中断续跑成功比例 |
| 重复执行率 | 约 9% | 降至约 0.3% | 因重跑产生的副作用重复占比 |
| 平均完成时长 | 约 3.2h | 约 2.1h | 含人工确认的全链路时长 |
上表为脱敏示意值,用于说明趋势而非审计口径;不同链路复杂度差异大,此处取加权均值。
第一,状态机先于编排。我们早期把精力花在"怎么让智能体更聪明"上,结果一个重启就全废。先把任务拆成离散、可持久化的状态,编排才站得住脚。
第二,幂等决定可恢复性。断点恢复能不能可靠,全看每步有没有幂等键。没有幂等键的步骤,重跑就是制造重复副作用;有幂等键,重跑就是"查一下结果复用"。
第三,带副作用的步骤必须有补偿。半完成态泄漏到下游比失败更可怕。为写单、发消息这类动作定义反向补偿,失败时能干净回退。
第四,人工确认点要保留上下文。human_review 不是"暂停",而是"带着完整上下文挂起"。审批人看到的应是完整来龙去脉,而非第二次凭空出现的请求。
案例片段(已脱敏):一次底座升级导致分析步 Pod 被重建,当时有 37 条采购建议链路处于 analyze 之后状态。旧架构下这些任务需人工从 fetch 重跑,预计重复调用模型约数百次。新状态机在重启后自动扫描未完成任务,其中 35 条从 analyze 之后续跑、2 条因 analyze 未落库从 analyze 重跑,全程零重复写单,链路在约 20 分钟内全部恢复。
案例片段(已脱敏):一条"生成审批单"链路在 submit 前的人工确认环节停留超 48 小时,触发超时回退。状态机自动将草稿单标记为撤回、回退到 draft 并告警负责人,避免了"无人确认却已提交"的风险,该机制上线后同类超时单零误提交。