agent runtime lab · 2026 · 技术研究笔记
17. 怎样给 Agent 做一次故障演练
正常路径通过只能证明系统会跑,故障注入才能看到它如何停下和恢复
在工具超时、返回损坏数据和进程中断时观察 Agent 的重试、状态恢复与副作用边界
研究版 · 4 个章节 · 约 5 分钟 · 更新于 2026-08-23
一个订单 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故障演练/
