故障要先分类再计数
捕获故障后的第一个判断不是「要不要重试」,而是「值不值得重试」:四层故障各有对策,分类在先,计数和熔断才有含义。
捕获故障后的第一个判断不是「要不要重试」,而是「值不值得重试」。笼统的「出错就重试三次」把限流和参数非法当成同一件事:前者退避几轮就好了,后者原样重试多少次都是同样的失败,还会被一起计进失败率。运行时的分类是所有计数与熔断的前提。
故障发生在四层
| 层 | 典型表现 | 与任务内容有关吗 |
|---|---|---|
| API 层 | 限流 429、服务过载、超时、连接中断、输出触顶截断 | 无关,是基础设施的噪声 |
| 工具层 | 调用不存在的工具、参数不符合约束、执行抛异常 | 部分有关 |
| 上下文层 | 窗口溢出、压缩失败、工具调用缺少配对的结果消息 | 部分有关 |
| 控制流层 | 死循环、死亡螺旋 | 有关 |
按故障发生的位置分四层,每层的对策完全不同:限流退避、缺配对修配对、溢出触发压缩、循环要被打断 ai-agent-book-5。四层共用的动作只有「计数」,但把四层的数字混进同一条失败率曲线,正是错误的起点——工具层报错涨三倍,可能是模型换了版本,也可能只是某个上游服务在限流,一张表看不出区别。
第一判断:值不值得重试
可重试的错误——限流、过载、网络抖动——重试才有意义;不可重试的错误——参数不合法、权限不足、工具不存在——重试只是烧钱,必须改变输入或策略才行 ai-agent-book-5。生产级 Harness 维护一张错误到恢复策略的映射表,而不是「出错就重试」这一条笼统规则。这张表的维护方式是:给每个错误码和异常类型标注所属层、是否可重试、走哪条恢复路径、由哪个计数器跟踪。没有这张表,后面所有的熔断阈值都无从谈起。
计数之前,先看模式
单次错误好办,连环失控靠模式检测。两个信号:一是重复调用指纹——对「工具名 + 参数」计算指纹,相同指纹反复出现就是无进展循环的明确信号;二是连续失败计数——每条恢复路径维护独立计数器,这是下一篇熔断阈值的依据 ai-agent-book-5。为什么要靠结构信号而不是错误信息?分布式容错理论把故障分两类:崩溃故障和拜占庭故障。Agent 的故障天生是拜占庭式的——它很少径直停止运行,而是继续给出看似可信的错误结论,错误不会主动声明自己是错误 ai-agent-book-10。所以运行时的分类不能等错误自己冒出来,要靠指纹、计数器和配对检查。
最危险的故障不报错
流式连接最危险的失败模式不是断开——断开会立即报错——而是静默卡死:连接建立成功、数据流停止,像水管通着但不出水。SDK 的超时机制往往只覆盖初始连接而非传输过程,所以需要独立的空闲看门狗:超过设定时间没有新输出就判定卡死,主动杀死挂起的流再重试。可以推广成一条原则:每个长连接都需要活性信号,不能只依赖连接超时 ai-agent-book-5。轨迹完整性同理——工具调用缺少配对结果时,Harness 在注入上下文前自动修复配对,而不是把结构异常抛给模型或用户。一个值得抄的细节:有的生产级 Agent 同时跑产品模式和训练数据收集模式,产品模式用占位符宽容修补缺失消息,训练模式拒绝修补——合成占位符会污染训练数据。同一处损坏、两套标准,本身就是工程决策。
运行侧和评测侧是一对
上线看什么指标 里的四类冒烟失败——CAPABILITY、INFRA、TEST_DEFECT、NON_DETERMINISTIC——是评测侧的分类,用来决定劲往哪使;本篇的分类在运行侧,用来决定出错之后做什么。两边精神一致:不分类的失败数字指导不了任何动作。检查自己系统的方法很朴素:有没有一张错误到策略的映射表?每条恢复路径有没有独立计数器?长连接上除了连接超时还有没有看门狗?三问有一问答不上,重试策略就还是玄学。
