已经是最新一篇文章了!
已经是最后一篇文章了!

agent runtime lab · 2026 · 技术研究笔记

17. 怎样给 Agent 做一次故障演练

正常路径通过只能证明系统会跑,故障注入才能看到它如何停下和恢复

在工具超时、返回损坏数据和进程中断时观察 Agent 的重试、状态恢复与副作用边界

研究版 · 4 个章节 · 约 5 分钟 · 更新于 2026-08-23

版本 A · 中文
SCROLL

一个订单 Agent 调用支付工具时,工具已经扣款,但响应在回传途中超时。运行时只看见“没有收到结果”,于是再调一次。

正常测试不会暴露这个问题。请求成功、结果正常回传时,状态机和重试策略看起来都没有异常。只有在“副作用已发生,确认丢失”这个位置主动中断,重复扣款才会出现。

故障注入是在可控环境中主动制造超时、损坏数据或进程中断,观察系统能否停在正确状态并安全恢复。

故障要注入到精确的边界

“让工具随机报错”可以测到一部分异常处理,但无法回答故障发生在哪个状态边界。工具调用可以拆成五个观察点:

参数校验 -> 记录调用意图 -> 执行副作用 -> 记录结果 -> 回填模型

中断发生在“记录调用意图”之前,运行时可以当作这次调用从未开始。如果发生在“执行副作用”之后,系统就不能凭本地状态判断外部动作是否完成。

每个观察点都要有独立的故障开关。否则一次“测试超时”只能证明某个地方失败了,不能证明恢复逻辑覆盖了最危险的窗口。

先用一个小程序复现丢失确认

下面的脚本模拟一个具有副作用的工具。副作用指修改文件、扣款或发送消息这类会改变外部状态的动作。idempotency_key 是幂等键,多次提交同一个键时,外部系统只执行一次。

from dataclasses import dataclass, field


class LostAcknowledgement(Exception):
    """外部动作已完成,但确认信息丢失。"""


@dataclass
class PaymentService:
    """用内存模拟支持幂等键的支付服务。"""

    charges: dict[str, int] = field(default_factory=dict)

    def charge(
        self,
        idempotency_key: str,
        amount: int,
        lose_ack: bool = False,
    ) -> int:
        """
        扣款并返回金额。

        idempotency_key: 业务调用的唯一标识。
        amount: 本次扣款金额,单位为分。
        lose_ack: 为 True 时,在扣款后模拟回传中断。
        """

        if idempotency_key not in self.charges:
            self.charges[idempotency_key] = amount

        if lose_ack:
            raise LostAcknowledgement("扣款已完成,但回传中断")

        return self.charges[idempotency_key]


service = PaymentService()
key = "order-20260823-001"

try:
    service.charge(key, 5000, lose_ack=True)
except LostAcknowledgement:
    # 恢复时使用原键查询或重试,不生成新键。
    charged = service.charge(key, 5000)

assert charged == 5000
assert service.charges == {key: 5000}
print(service.charges)

典型输出:

{'order-20260823-001': 5000}

如果恢复时使用新键,模拟服务会留下两条扣款记录。因此,幂等键应在运行时接受工具调用时就生成并持久化,不能在每次尝试前重新生成。

三类故障应分开测

工具报错、响应超时和运行时崩溃在界面上可能都显示为“任务失败”,恢复方式却不同。

  • 工具明确返回参数错误时,原样重试没有价值,需要修正参数或终止。
  • 读取类工具超时时,可以在有次数和总时间上限的前提下重试。
  • 写入类工具在回传前中断时,要用幂等键查询原操作,不能直接当作未执行。

故障演练应记录注入点、当时状态、重试次数、外部系统回执和最终恢复方式。只保留一张“演练成功”截图,后续无法判断系统是自动恢复,还是测试人员手动修改了状态。

在测试环境中保持可控

故障注入不等于在生产环境中随机终止进程。起步阶段应使用独立账号、模拟外部服务和专用数据。注入条件要由明确的测试标识触发,不使用随机数决定是否对真实请求制造故障。

等到恢复路径在隔离环境中可重复,再考虑范围很小的生产演练。那时仍需要停止条件、值班人员和恢复方案,而不是让 Agent 自行决定演练边界。

正常路径说明系统在条件充足时能完成任务。故障演练回答的是另一个问题:条件不再充足时,系统是否知道自己停在哪里。

版权声明: 如无特别声明,本文版权归 sshipanoo 所有,转载请注明本文链接。

(采用 CC BY-NC-SA 4.0 许可协议进行授权)

本文标题:17. 怎样给 Agent 做一次故障演练

本文链接:https://www.sshipanoo.com/blog/ai/agent-runtime-lab/17-Agent故障演练/