先记住这个答案
死信任务恢复流程应分为三步:先按错误类别分类(如可重试的瞬时错误与不可重试的上下文错误),再修复根因(如调整工具schema或升级模型),最后以幂等键为约束进行重放,确保不产生重复副作用。同时,要保留完整执行轨迹,支持人工介入重放前的状态校验。
- 死信恢复需先分类错误,区分可重试与不可重试
- 重放必须用幂等键防止重复副作用
- 含外部状态的任务要校验状态后才可重放
死信恢复机制:诊断-修复-重放
死信队列里保存的不仅是消息体,还应包含任务ID、执行历史、失败原因和上下文快照;其中任务ID用于定位任务,而幂等键需按步骤或操作粒度另行设计。恢复时不能盲目重投,因为Agent任务通常有多轮LLM调用和工具副作用,简单重投会重复执行那些已成功的工具调用,造成重复扣款或重复写库。
正确的机制是把重放视作一次新执行,但通过幂等键和检查点状态,让已完成的副作用在执行中保持幂等或跳过。具体做法是:工作流引擎先读取死信消息中的task_id,从检查点仓储恢复已提交的工具结果,然后从失败的节点继续执行,而不是从头开始。
场景:航班改签Agent因下游接口超时进入死信
假设一个航班改签Agent的任务包括查询航班、预订新航班、取消旧航班、发送通知。当取消旧航班的API因下游系统超时连续失败3次后,任务进入死信队列。此时,新航班已预订成功,但取消操作未完成,如果简单重投整个任务,会再次预订同一航班(无座位)或重复扣款。
处理方式是:运维人员先查看死信元数据,发现错误码503属于下游瞬时故障,于是将下游服务扩容并设置重试窗口。然后开发者调用恢复API,传入task_id,工作流引擎从检查点得知“预订新航班”已完成,于是跳过该节点,仅从"取消旧航班"节点开始重放,并使用cancel_order_id作为幂等键。最终任务成功完成,无重复副作用。
失败边界:哪些情况不能自动恢复
以下情况禁止自动重放:一是错误分类为永久失败,比如模型持续输出非法JSON或工具参数schema不兼容,因为不修复配置无法成功;二是任务涉及外部系统且检查点未保存接口返回的事务ID,无法保证幂等,此时重放可能产生重复支付。
处理方式是对永久失败升级为工单,由人工修复提示词或工具定义后重新入队;对不确定幂等性的任务,先进入待人工审批队列,由操作员确认是否重放,且重放时强制使用新的上下文和明确的幂等键。
容易答错的地方
- 死信就是重投
- 许多人以为把死信消息放回原队列即可,但Agent任务是多步骤的,重头执行会重复成功步骤的副作用。纠正:必须追踪任务步骤状态,跳过已完成且幂等的部分。
- 所有错误都可重试
- 例如工具Schema变更导致参数错误,重试多少次都一样失败。正确做法是按错误类别分类,只有瞬时错误(超时、限流)可重试,永久错误需要先修复。
面试官还会怎么问?
如何设计幂等键以支持死信重放?
幂等键应包含任务ID和步骤标识,如task_id + ':' + step_id,并为每个工具调用生成唯一操作ID。当重复执行时,通过此键检测已有结果,直接返回缓存结果,避免副作用。
检查点在死信恢复中起什么作用?
检查点保存了每个节点的输入输出和已完成的副作用ID,恢复时先恢复状态,再从失败点继续,而不是从头开始。
人工审批需要对每个死信都做吗?
不需要,仅当任务涉及不可回滚副作用(如支付、发送邮件)或模型输出反复不合规时才需人工决策,其他可自动恢复。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。