AI测试-05-Agent Workflow执行多步骤测试任务时怎么做状态管理和失败恢复

一提到 Agent Workflow,最容易先想到的是多步骤规划、自动拆解任务、串联工具调用和减少人工编排。

这些能力当然重要,但只要它开始执行真实测试任务,问题就会立刻从“会不会规划”变成“出了问题怎么收”。

原因很简单。多步骤测试任务通常同时具备下面几种特征:

  • 步骤之间存在顺序依赖
  • 执行动作会改变环境或业务状态
  • 一次失败可能污染后续上下文
  • 工具调用、模型决策和环境异常会交织出现
  • 补跑和恢复如果没有边界,很容易把现场改得更乱

这意味着 Agent Workflow 真正难的部分,并不是把任务拆成 5 步还是 10 步,而是要先回答下面这些更工程化的问题:

  • 当前任务到底执行到了哪一步
  • 哪一步已经真正生效,哪一步只是模型规划过
  • 当前失败属于参数错误、工具错误、环境错误,还是状态漂移
  • 这次失败能不能重试,应该从哪一层恢复
  • 恢复动作会不会覆盖现场、重复写数据或者误伤后续步骤

如果这些问题没有先收稳,Agent Workflow 很快就会变成一种看起来很自动、实际上很难治理的执行方式:

  • 任务失败后只能整条重跑
  • 重跑后问题更难复现
  • 人工接管时说不清哪一步已经真正执行过
  • 报告里只有“失败”,没有失败前的状态变化
  • 环境问题、模型问题、工具问题被混在一起

所以这篇文章只聚焦一个更实际的问题:

Agent Workflow 在执行多步骤测试任务时,状态应该怎么分层记录,失败应该怎么分类,恢复应该怎么设计,才能让整条执行链路真正具备可观察、可补跑、可回放和可收敛的能力。

一、先把边界说清:多步骤测试任务里的状态,不是“成功”或“失败”两个字

多步骤任务最常见的错误,是把状态理解成:

  • 成功
  • 失败
  • 运行中

这类状态在看板上够用,在恢复上完全不够。

因为多步骤测试任务里的“状态”至少有两个维度:

  • 生命周期状态:任务和步骤此刻处于什么阶段
  • 语义状态:这个阶段产生了什么真实影响

例如“下单后校验支付状态”的任务里,某一步可能显示为执行失败,但这一步背后的真实语义可能已经分裂成几种情况:

  • 接口没发出去,业务状态没有变化
  • 接口发出去了,结果没拿到,但订单已经创建
  • UI 点击成功了,但页面跳转没被记录
  • 数据已写入,后置校验失败
  • 工具调用超时,但服务端异步任务仍在继续

如果平台只记录“步骤失败”,恢复动作就会非常危险,因为系统根本不知道:

  • 失败前是否已经造成写入
  • 当前会话还能不能继续
  • 后续步骤是不是已经失去前提
  • 环境是否已经进入脏状态

所以在 Agent Workflow 里,状态管理的第一原则不是“状态枚举多一点”,而是:

把不同层级、不同语义的状态拆开,避免用一个简单结果覆盖整个执行现场。

二、状态分层:至少拆成 5 层,才能支撑恢复

更适合多步骤测试任务的状态模型,通常至少要拆成下面 5 层。

1. 任务层状态

任务层状态回答的是:这一次任务实例整体进行到了哪里。

这一层建议至少包含:

  • PENDING:待执行
  • PLANNING:规划中
  • RUNNING:执行中
  • WAITING_RETRY:等待系统补跑
  • WAITING_MANUAL:等待人工接管
  • FAILED:已失败
  • COMPLETED:已完成
  • CANCELLED:已取消

任务层状态的价值不是展示进度,而是给外部系统一个清晰信号:

  • 调度层知道任务是否还能继续占资源
  • 报告层知道是否应该封板
  • 人工接管层知道现在是补跑还是直接终止

2. 步骤层状态

步骤层状态回答的是:每一个步骤是否真正被规划、执行、确认和收口。

这一层不能只用“成功/失败”,更稳的做法是拆成:

  • PLANNED:已规划,尚未执行
  • READY:依赖满足,准备执行
  • EXECUTING:正在执行
  • APPLIED:动作已生效,但结果尚未完全确认
  • VERIFIED:动作结果已确认
  • FAILED_RETRYABLE:失败但可补跑
  • FAILED_TERMINAL:失败且应终止链路
  • SKIPPED:前置条件不满足,被跳过
  • ROLLED_BACK:已执行回滚

这里最关键的是 APPLIEDVERIFIED 不能混。

例如:

  • 页面按钮点下去了,不代表结果页已经正确出现
  • 调接口返回 200,不代表异步任务已经真正完成
  • 发起删除动作成功,不代表数据已经在读链路里消失

这层拆开以后,恢复时才能知道是:

  • 补确认
  • 补观察
  • 重试动作
  • 还是直接终止

3. 会话与上下文层状态

这一层回答的是:任务当前依赖的执行上下文是否仍然可信。

常见内容包括:

  • 当前登录态是否仍然有效
  • 当前页面或路由是否仍然正确
  • 当前测试账号是否已被占用
  • 当前浏览器、设备、会话 ID 是否发生变化
  • 当前中间变量是否仍然可用于后续步骤

这层状态非常容易被忽略,但它决定了“能不能继续在原地恢复”。

很多恢复失败,不是恢复动作设计错了,而是上下文已经变了:

  • 页面被强制跳转
  • Token 已过期
  • 会话被别的流程踢掉
  • 临时数据被后台清理
  • 设备或 Pod 已经重建

如果这层状态没有单独记录,平台就会在错误上下文里继续执行,造成更大污染。

4. 环境与资源层状态

这一层回答的是:任务外部依赖当前是否可用,以及资源是否还被正确占用。

常见对象包括:

  • 测试环境实例
  • 账号池和租约
  • 浏览器实例或移动设备
  • 数据库连接、消息队列、存储桶
  • 依赖服务和第三方接口

这层状态如果不单独管理,就很容易把环境问题误判成模型或步骤问题。

例如一次“步骤 4 无法确认订单状态”的失败,真正根因可能是:

  • 读库延迟
  • 测试账号被其它任务复用
  • 环境发布中途滚动
  • 队列积压导致异步结果未回写

这时直接从步骤层重试,通常只会重复报错。

5. 证据层状态

这一层回答的是:当前现场有没有足够证据支撑回放、归因和恢复决策。

建议至少记录:

  • 任务级时间线
  • 步骤输入与输出
  • 模型规划结果
  • 工具调用参数
  • 截图、录屏、DOM 或控件树快照
  • 关键日志片段
  • 环境版本、会话 ID、租约 ID

证据层不是为了写报告更好看,而是为了避免恢复动作建立在猜测上。

没有证据层,恢复就会变成:

  • 看起来像没执行过,那就重跑
  • 看起来像网络问题,那就重试
  • 看起来像页面问题,那就重开浏览器

这种恢复方式在短链路里还能勉强工作,放到复杂任务里几乎一定会把现场越修越乱。

三、失败分类:先判断失败类型,再决定恢复方式

Agent Workflow 最怕的一种实现,是所有失败都走同一条路:

  • 失败
  • 重试
  • 还失败
  • 整条任务终止

这类实现通常不是“恢复策略简单”,而是“根本没有失败分类”。

更适合多步骤测试任务的失败分类,至少应该拆成下面 5 类。

1. 参数与规划类失败

这一类通常发生在动作真正执行之前,例如:

  • 模型规划了不允许的动作
  • 参数缺字段
  • 参数类型错误
  • 资源 ID、环境 ID 不合法
  • 本步骤引用了上一步不存在的输出

这类失败的特点是:

  • 尚未真正改变业务状态
  • 适合在工具执行前就被拦住
  • 恢复重点是重新规划或补参数,不是重启环境

更合适的做法是:

  • 标记为 FAILED_RETRYABLE
  • 重新生成该步骤规划
  • 对参数做二次约束
  • 保留原始规划供后续审计

2. 工具执行类失败

这一类通常发生在工具层,例如:

  • 浏览器操作超时
  • 接口调用失败
  • 数据查询报错
  • 设备连接断开
  • 文件取证动作失败

这类失败能不能重试,关键看两件事:

  • 该动作是否幂等
  • 动作是否可能已经部分生效

如果没有这两层判断,系统就很容易把“可能已生效的写动作”当成普通失败去重试。

3. 环境与依赖类失败

这一类通常不是单个步骤自身能解决的,例如:

  • 测试环境发布中
  • 下游依赖超时
  • 队列积压
  • 数据库只读切换
  • 第三方服务限流

这类失败最常见的误判,是把它当成步骤执行问题继续重试。

更合适的处理是:

  • 暂停任务推进
  • 冻结当前上下文
  • 重新探活环境与依赖
  • 判断是否整体延期、切环境或人工接管

4. 状态漂移类失败

这是 Agent Workflow 最有代表性的一类失败。

它的典型特征是:

  • 当前步骤看起来失败了
  • 但真正原因不是步骤本身
  • 而是前置上下文已经漂移

例如:

  • 当前页面不是预期页面
  • 登录态失效
  • 本该引用的订单号来自过期会话
  • 同一个任务里的中间变量被覆盖

这类失败如果不单独分类,系统很容易一直在错误上下文上重试,最后把所有步骤都跑脏。

5. 结果不确定类失败

这类失败比普通报错更危险,因为它既不是明确成功,也不是明确失败。

典型场景包括:

  • 工具超时,但服务端可能已经处理
  • 页面没回显,但后台状态可能已经变化
  • 结果采集失败,但动作本身可能完成
  • 断言链断在中间,最终状态未知

这类失败不能直接重试,也不能直接判失败。

更稳的做法通常是:

  • 先进入 WAITING_MANUALWAITING_RETRY
  • 启动补确认动作
  • 查日志、查库、查接口、查事件链
  • 确认“是否已生效”之后再决定是否回滚或补跑

四、恢复策略:不是所有失败都要“从头再来”

恢复设计真正要解决的,不是“怎么继续跑”,而是:

在不破坏现场、不重复写入、不丢失证据的前提下,把任务尽量收回到一个可继续、可终止或可人工接管的状态。

更合适的恢复策略,通常可以分成 4 层。

1. 步骤内重试

适用场景:

  • 幂等读操作
  • 纯取证动作
  • 页面元素瞬时不可见
  • 网络瞬断但业务未写入

要求:

  • 有明确最大次数
  • 每次重试前重新确认上下文
  • 重试结果单独记录,不覆盖首错证据

不适合直接走步骤内重试的场景包括:

  • 创建、删除、支付、提交这类可能写状态的动作
  • 会触发异步链路的动作
  • 已经判断为上下文漂移的动作

2. 步骤级补跑

适用场景:

  • 当前步骤失败,但前置步骤状态可信
  • 当前动作可安全重放
  • 上下文可通过少量动作恢复

这类补跑的关键不是“重试这个步骤”,而是先做一个小恢复:

  • 刷新会话
  • 重新打开正确页面
  • 重新获取最新资源 ID
  • 重新确认依赖服务可用

如果这些上下文恢复动作没有先做,步骤级补跑通常只是重复失败。

3. 子流程级恢复

适用场景:

  • 中间步骤失败导致后续上下文整体失效
  • 当前任务可自然拆成多个阶段
  • 已完成阶段的结果可以冻结

例如一个长链路任务可以拆成:

  • 登录与准备阶段
  • 核心业务执行阶段
  • 验证与取证阶段

一旦“核心业务执行阶段”里出现状态漂移,更稳的恢复方式通常不是只重跑单个动作,而是从该阶段入口重新进入,并且复用前一阶段确认过的产物。

4. 人工接管与安全终止

适用场景:

  • 高风险写操作后状态不确定
  • 同一类失败连续触发
  • 环境异常范围过大
  • 证据不足以支撑自动恢复决策

这类场景里,自动恢复继续推进的收益通常已经低于风险。

更合适的做法是:

  • 冻结任务
  • 挂起资源租约
  • 保留全部中间状态和证据
  • 给出建议的人工排查入口
  • 明确“哪些动作已经生效,哪些仍未确认”

这一步看起来像保守处理,但它真正避免的是平台把一次局部失败升级成一次全链路污染事故。

五、最小执行骨架:先把恢复点设计进流程里,而不是失败后再补

如果希望 Agent Workflow 真正可恢复,更稳的做法不是“失败后写一堆兜底逻辑”,而是在执行骨架里预留恢复点。

一套更适合第一阶段落地的最小执行骨架,可以这样设计:

1. 任务初始化

在任务开始前先固定下面这些信息:

  • 任务模板 ID
  • 环境 ID
  • 租约资源 ID
  • 可用工具白名单
  • 关键断言点
  • 恢复策略级别
  • 是否允许自动补跑

初始化阶段的目标不是启动执行,而是先把可恢复边界写清楚。

2. 规划与步骤冻结

规划结果不要直接一边生成一边执行。

更稳的做法是:

  • 先生成步骤草案
  • 对每一步标注类型:读、写、取证、确认、恢复
  • 对每一步标注幂等属性
  • 对高风险写步骤附带恢复约束

这样后面一旦失败,平台才能根据步骤属性决定是重试、补确认、子流程恢复,还是人工接管。

3. 执行前快照

每个关键步骤执行前,至少记录:

  • 当前步骤输入
  • 当前页面或会话状态
  • 环境健康探活结果
  • 上一步关键输出
  • 当前证据引用点

执行前快照的价值,是让恢复决策建立在“这个步骤开始前到底是什么样”之上。

4. 执行动作与即时确认

动作执行后,不要只看工具层返回。

更稳的做法是:

  • 动作执行
  • 即时确认动作是否已落地
  • 判断状态是否不确定
  • 需要时进入补确认
  • 再决定是否推进下一步

这一步能显著减少“把未确认动作当成成功继续推进”的问题。

5. 恢复决策节点

一旦出现失败,不要立即重试。

先做 4 个判断:

  • 失败类型是什么
  • 当前步骤是否可能已生效
  • 上下文是否仍可信
  • 证据是否足够支撑自动恢复

只有这 4 个问题答案清楚,恢复动作才有意义。

6. 收口与报告

任务结束时,报告里至少要明确:

  • 最终停在第几步
  • 哪些步骤仅规划未执行
  • 哪些步骤已执行但结果不确定
  • 哪些恢复动作被触发过
  • 哪些资源已回收,哪些仍需人工清理

如果报告只写“第 6 步失败”,后续接手的人仍然要从头还原现场,平台的恢复能力就没有真正落地。

六、一个更实用的状态与恢复记录表

多步骤任务里,建议至少保留一张这种粒度的记录表:

步骤 动作类型 当前状态 是否已生效 上下文可信 失败类型 恢复方式 证据
1 登录 VERIFIED 截图、会话 ID
2 创建订单 APPLIED 待确认 结果不确定 补确认 接口日志、订单号
3 校验回写 FAILED_RETRYABLE 状态漂移 子流程恢复 截图、DOM、控制台日志

这张表的价值不是展示,而是支撑:

  • 自动恢复判断
  • 人工接管
  • 报告收口
  • 同类故障归类

七、常见坑:状态和恢复最容易写坏的 6 个地方

1. 只记录任务状态,不记录步骤语义状态

结果是任务一失败,系统完全不知道前面哪些写动作已经生效。

2. 把“工具返回成功”当成“业务结果已确认”

接口 200、按钮点击成功、脚本没有报错,都不等于业务状态已经稳定。

3. 把所有失败都交给统一重试器

统一重试器适合瞬时读失败,不适合覆盖写动作、不确定结果和上下文漂移。

4. 恢复时覆盖首错证据

一旦补跑前没有冻结首错现场,后续所有排查都会被污染。

5. 人工接管时没有明确“已执行边界”

最常见的后果是人工又执行了一遍写动作,造成重复创建、重复扣减或重复通知。

6. 环境异常和 Agent 失败没有分流

环境发布、依赖故障、资源租约异常如果都挂在步骤失败下面,报告里看起来像 Agent 不稳定,实际问题根本不在 Agent。

八、真实案例:一个下单回归任务为什么越恢复越乱

1. 场景

一次 AI 驱动的回归任务需要完成下面这条链路:

  • 登录后台
  • 创建测试订单
  • 调用支付模拟接口
  • 进入订单详情页校验状态
  • 拉取日志并生成证据包

这条链路被编排成一个 Agent Workflow,允许在单步失败时自动补跑 1 次。

2. 执行

任务前 3 步执行正常:

  • 登录成功
  • 订单创建成功
  • 支付模拟接口返回成功

第 4 步进入订单详情页时,页面长时间未出现“已支付”状态,系统判定为步骤失败,并触发自动补跑。

3. 现象

补跑后问题不但没有消失,反而出现了更多异常:

  • 第二次进入详情页时跳到了登录页
  • 自动恢复重新执行了“创建订单”
  • 报告里出现了两个不同订单号
  • 最后任务被判为“详情页断言失败”

表面上看,这是一次普通 UI 断言失败。

但真正的问题已经不是“第 4 步没断上”,而是恢复过程把原始状态打乱了。

4. 排查

排查按状态层逐层展开:

先看步骤层。
原始执行记录显示第 2 步“创建订单”状态是 APPLIED,但没有被提升到 VERIFIED,因为订单号采集逻辑晚于页面跳转,导致系统没有把订单号冻结到上下文里。

再看会话层。
第 4 步失败前,后台登录态已经接近过期,补跑动作重新打开详情页时被系统重定向到了登录页,但平台没有把“上下文漂移”识别出来。

再看恢复策略。
统一重试器把第 4 步视为“可补跑步骤”,但恢复脚本内部为了拿到订单详情页入口,错误地回调了“创建订单”子流程。

最后看证据层。
首错截图和第一次支付接口回包都在,但第二次恢复把任务主上下文里的订单号覆盖了,导致报告里两个订单号混在一起。

到这里可以确认根因不是“订单状态没更新”,而是三件事叠加:

  • 步骤状态没有把 APPLIEDVERIFIED 分开收口
  • 会话漂移没有独立识别
  • 恢复脚本没有显式声明可重放边界

5. 修复

修复动作分成 4 步:

第一步,重构步骤状态。
创建订单后必须先冻结订单号和接口回包,再把步骤从 APPLIED 提升到 VERIFIED

第二步,补上下文探针。
每次进入需要登录态的页面前,先检查会话状态和当前路由,一旦发现被重定向到登录页,直接判定为“状态漂移”而不是普通步骤失败。

第三步,拆恢复策略。
详情页校验失败只允许做“上下文恢复 + 补确认”,不允许回跳到写订单子流程。

第四步,冻结首错证据。
一旦触发恢复,首错步骤的截图、接口回包、订单号和日志引用必须写入只读证据区,后续恢复不能覆盖。

修复之后,同类任务再遇到类似问题时,报告能直接给出更准确的收口:

  • 订单已创建并支付模拟成功
  • 当前失败属于会话漂移
  • 原始订单号已冻结
  • 建议从“重新登录后进入详情页确认”恢复,而不是重建订单

这时候恢复动作才真正从“碰运气补跑”,变成“基于状态和证据的受控恢复”。

九、结语:Agent Workflow 能不能用,最终看恢复时是不是还知道自己在干什么

多步骤测试任务里,Agent Workflow 的价值不只是自动化执行更多步骤,而是把原本依赖人工串起来的计划、执行、确认、取证和恢复收成一条可治理的链路。

这条链路一旦进入真实平台,最先决定它能不能长期可用的,通常不是模型能拆多少步,而是下面这几件事有没有收稳:

  • 状态是不是分层记录
  • 失败是不是先分类再恢复
  • 恢复是不是有明确边界
  • 首错现场是不是能被冻结
  • 任务结束时是不是说得清哪些动作已经真实生效

如果这些问题没有被认真设计,Agent Workflow 很容易停留在“能跑一遍”的阶段。
只有把状态管理和失败恢复真正做成平台能力,它才有机会从演示链路走到长期可用的工程系统。