第四课:错误恢复

2025-07-02 · 工程治理系列 · 术语表 · ← 第三课

开场场景:AI跑了一夜,醒来发现崩在第3小时

你让AI处理20篇直播稿。睡前启动,期待早上看结果。

早上打开电脑——任务在第3小时就崩了。某个Agent调用超时,后面15个小时全部白等。

你损失的不是3小时。是一整夜

前几课教了怎么防崩。这一课教的是:崩了之后怎么自动站起来。

模式一:重试(Retry)—— 最简单的恢复

一句话:失败了就再来一次。大多数瞬时错误(网络超时、API限流)重试一次就好了。

但重试有坑。看看下面两种做法:

做法效果
失败后立即重试大概率再次失败——API还没恢复。而且可能触发限流更严重
失败后等5秒重试,再失败等15秒,再失败等45秒给服务恢复时间,同时不把自己打入限流黑名单

这个逐级延长的策略叫指数退避(Exponential Backoff)。它是工程治理中最基础也最被低估的模式——简单到只有三行逻辑,但能救回90%的瞬时故障。

指数退避的三要素

最大重试次数:比如3次,不是无限——防止死循环
退避倍数:每次等待时间翻倍(1秒→2秒→4秒→8秒)
抖动(Jitter):在等待时间上加一个随机值——防止多个失败任务同时重试把服务打崩

模式二:断路器(Circuit Breaker)—— 别在死路上反复撞

一句话:如果一个服务连续失败N次,暂时「熔断」它——不再调用,直接返回失败。过一段时间再试探。

想象你在反复调用一个API,每次都超时。指数退避让你在超时之间等待越来越久——但你每次还是在等。100个任务排队等同一个崩掉的API,整个系统被拖死。

断路器就是那个说「够了,先别调了」的机制。

状态行为
关闭(正常)正常调用,记录失败次数
打开(熔断)连续失败≥阈值 → 不再调用,立刻返回失败。所有排队任务跳过等待
半开(试探)等待一段时间后,放行1个请求试探。成功→关闭(恢复);失败→继续打开

应用到你的项目:20个Agent在并行处理,如果某个Agent发现DeepSeek API连续3次超时,断路器打开,所有Agent暂时跳过需要DeepSeek的任务,优先跑其他任务。10分钟后试探一次,恢复了就继续。

模式三:降级(Degradation)—— 半成品比没有好

一句话:某个环节彻底挂了的时候,不要整个系统跟着挂。退一步,给出「部分可用」的结果。

场景:你的知识卡片生成流程有三个步骤——

AI生成概念解释 → AI生成例子 → AI生成常见误解

如果「生成例子」这一步的API崩了(断路器打开),怎么办?

方案A(没有降级)方案B(有降级)
整个卡片生成失败,20张卡片全部空白跳过「例子」字段,先产出有概念解释+常见误解的卡片,标注「例子待补充」。API恢复后只补例子

降级的核心设计:把任务拆成可独立失败的单元。一个单元死了,其他单元继续跑。事后只修复死了的那个单元。

模式四:死信队列(Dead Letter Queue)—— 失败了不丢弃,单独存起来

一句话:重试了N次还是失败的任务,不丢弃,不放回主队列阻塞其他任务——单独放进「死信队列」,人工或定时检查处理。

没有死信队列的系统:一个任务失败3次后被丢弃,你永远不知道它失败了。
有死信队列的系统:失败任务被归档,你能看到「第37张卡片因为原文格式异常处理失败」——然后针对性地修。

应用到你的项目:20篇稿子处理完,你收到一份报告——

✅ 成功处理:18篇
⚠️ 降级处理(缺例子):1篇
❌ 死信队列:1篇 — 错误原因:原文为纯图片,无可提取文本

你知道18篇可用,1篇需要补例子,1篇需要人工处理。而不是面对一个「全崩了」的结局。

四个模式的关系

模式解决的问题触发条件
① 指数退避瞬时故障(网络抖动、限流)单个调用失败,立即触发
② 断路器持续性故障(API挂了)连续失败达到阈值
③ 降级核心功能不可用断路器打开 + 有备选方案
④ 死信队列彻底失败的任务重试耗尽,断路器持续打开

它们层层递进:退避 → 熔断 → 降级 → 归档。不是四个独立的工具,是一条链上的四个节点。


🧠 课后检验(点击选项作答)
第1题 · 你的AI任务调用外部API失败。以下哪种做法是正确的?
不对。立即重试大概率再次失败,而且可能触发更严重的限流。
正确!指数退避:给API恢复时间,同时限制重试次数防止死循环。
太早了。瞬时故障(网络抖动)重试一次往往能成功,直接放弃损失太大。
危险。无限重试 = 死循环,一个卡住的任务会阻塞整个系统。
第2题 · 10个并行Agent同时发现某个API连续超时。断路器打开后会发生什么?
这恰恰是断路器要避免的——10个任务排队等一个崩掉的API,系统被拖死。
正确!断路器打开 = 立刻失败,不等待。跳过这个依赖,继续跑其他任务。
重启不能解决API挂了的问题。断路器的作用是「隔离故障」,不是「消灭故障」。
断路器正是为了避免这种「轮流撞墙」——一次判断就够了,不需要每个人都撞一次。
第3题 · 以下哪种情况最适合用「降级」而不是「死信队列」?
应该进死信队列——彻底无法处理,需要人工介入。
正确!部分功能不可用时,产出半成品(标注待补充),事后只补缺失部分。这就是降级。
重试耗尽应该进死信队列——归档等待人工处理。
格式错误应该回滚重试——不是降级的场景,因为输出不可用。

最后一题用你自己的话来回答——不用选,心里想就行:

第4题:你的知识卡片项目,Designer Agent(负责排版美化的那个)连续崩了。概念提取和知识点拆解都在正常跑。按这节课的四个模式,你应该怎么设计恢复流程?每一步该用什么模式?

推荐一手来源:搜索「circuit breaker pattern」「exponential backoff」「dead letter queue」——这三个概念来自分布式系统领域,已经被各大云服务(AWS SQS、Azure Service Bus)内置支持。AI工程治理大量借用了这些模式。

实操作业:下次用Claude Code跑批处理任务时,留意有没有任务超时或失败的情况。手动模拟指数退避:失败后等5秒重试,而不是立刻重试。记录成功率的变化。

← 返回首页