S11|错误恢复:给主循环装上安全网,先恢复,再继续

在前十章,我们的 Agent 已经拥有循环、工具、计划、子代理、技能、压缩、权限、Hook、记忆、提示词流水线十大核心能力,能稳定执行任务、长期沉淀知识、结构化输入输出。

但只要遇到一点异常 —— 模型截断、上下文超限、网络抖动 —— 系统就会直接崩溃停止。一个真正可用的 Agent,必须能自己处理错误、自动恢复,而不是一遇到问题就卡死。

这一章 S11,我们给系统装上错误恢复机制:把错误变成主循环的正常分支,先分类、再重试、最后才失败,让系统稳如生产线。


本章核心信息

  • 核心原则:先恢复,再继续,错误不是崩溃,而是正常流程分支
  • 工具数量:4 个
  • 核心思想:系统必须清楚自己是在继续、重试,还是进入恢复流程

先看懂本章所有名词

  1. 错误恢复不是隐藏错误,而是识别临时问题 → 执行有限补救 → 恢复执行,无法恢复才明确上报失败。

  2. 重试预算每种错误最多重试几次,防止无限循环,例如续写最多 3 次、网络重试最多 3 次。

  3. 状态机主循环在固定状态间切换:正常执行 → 续写恢复 → 压缩恢复 → 退避重试 → 最终失败。

  4. 恢复决策根据错误类型,决定走哪条恢复路径:继续、压缩、退避、失败。

  5. 续写提示模型输出截断时,专用提示词让模型直接断点续接,不重复、不重启、不总结。

  6. 退避重试网络 / 超时 / 限流错误,等待一小段时间再重试,避免瞬间反复请求加重故障。


这一章到底要解决什么问题?

到 S10,Agent 已经是一个真正能干活的系统,但错误处理几乎为零:

  • 模型输出写到一半被截断 → 直接卡住
  • 上下文太长装不进窗口 → 直接报错
  • 网络抖动 / API 超时 / 限流 → 直接中断

没有错误恢复的系统,只能在 “完美环境” 里运行。而现实是:错误一定会发生。

本章目标只有一个:把 **“报错就崩”升级成“先判断错误类型 → 走对应恢复路径 → 继续执行”**。


最小心智模型:3 类错误 → 3 条恢复路径

LLM 调用发起
    │
┌───┴───────────────────────────────────
│ 1. 输出截断 (max_tokens)               
│    → 注入续写提示 → 重试                
│                                       
│ 2. 上下文过长 (prompt too long)        
│    → 压缩旧上下文 → 重试                
│                                       
│ 3. 临时故障 (超时/限流/网络抖动)        
│    → 退避等待 → 重试                   
└───────────────────────────────────────
    │
无法恢复 → 明确失败

一句话:错误先分类,恢复再执行,失败最后才暴露给用户。


最推荐的 3 条基础恢复路径

1. 输出截断恢复(continue)

  • 触发:模型输出被 max_tokens 截断
  • 动作:追加续写提示,让模型从中断点直接继续
  • 约束:最多重试 3 次

2. 上下文过长恢复(compact)

  • 触发:提示词超出模型窗口长度
  • 动作:用 S06 压缩机制,把历史对话变成摘要
  • 目标:保留任务核心,扔掉冗余,让请求能重新发出去

3. 临时网络故障恢复(backoff)

  • 触发:超时、限流、服务不可用、连接错误
  • 动作:等待一小段时间(指数退避),再重试
  • 目标:避开瞬时拥堵,提高成功率

核心数据结构(本章灵魂)

1. 恢复状态(防无限循环)

recovery_state = {
    "continuation_attempts": 0,  # 续写次数
    "compact_attempts": 0,        # 压缩重试次数
    "transport_attempts": 0       # 网络故障次数
}

2. 恢复决策(统一判断)

{
    "kind": "continue" | "compact" | "backoff" | "fail",
    "reason": "错误原因说明"
}

3. 标准续写提示(避免重复)

CONTINUE_MESSAGE = (
    "Output limit hit. Continue directly from where you stopped. "
    "Do not restart or repeat."
)

最小实现代码(极简可运行)

第一步:错误分类选择器

def choose_recovery(stop_reason: str | None, error_text: str | None) -> dict:
    # 1. 输出截断
    if stop_reason == "max_tokens":
        return {"kind": "continue", "reason": "output truncated"}

    # 2. 上下文过长
    if error_text and "prompt" in error_text and "long" in error_text:
        return {"kind": "compact", "reason": "context too large"}

    # 3. 临时网络/服务故障
    if error_text and any(word in error_text for word in [
        "timeout", "rate", "unavailable", "connection"
    ]):
        return {"kind": "backoff", "reason": "transient failure"}

    # 无法恢复
    return {"kind": "fail", "reason": "non-recoverable error"}

第二步:接入主循环

while True:
    try:
        response = client.messages.create(...)
        decision = choose_recovery(response.stop_reason, None)
    except Exception as e:
        response = None
        decision = choose_recovery(None, str(e).lower())

    # 续写恢复
    if decision["kind"] == "continue":
        messages.append({"role": "user", "content": CONTINUE_MESSAGE})
        continue

    # 压缩恢复
    if decision["kind"] == "compact":
        messages = auto_compact(messages)
        continue

    # 退避重试
    if decision["kind"] == "backoff":
        time.sleep(backoff_delay(attempt))
        continue

    # 彻底失败
    if decision["kind"] == "fail":
        break

三条恢复路径分别在解决什么

1. 输出截断 → 续写

模型没说完,只是空间不够。追加续写提示,直接断点继续,不重复、不重启。

2. 上下文太长 → 压缩

不是任务失败,只是历史太占空间。压缩成摘要,保留任务核心,轻量重启

3. 网络 / 限流 → 退避

不是系统坏了,只是拥堵。等一下再试,避开高峰期,大幅提高成功率。


初学者最容易踩的 5 个坑

  1. 把所有错误混为一谈该续写的去压缩,该等待的去重试,逻辑完全混乱。

  2. 没有重试预算不限制次数,系统会进入无限死循环

  3. 续写提示太模糊只写 “continue”,模型会重复、总结、重启。

  4. 压缩后不告诉模型是续场模型以为是新对话,重新提问,任务断裂。

  5. 恢复过程无日志开发者看不见系统在做什么,出问题无法排查。


S10 → S11 升级了什么?

模块S10S11
错误处理遇到错误直接崩溃错误变成正常流程分支
稳定性只能在完美环境运行可抗截断、超限、网络抖动
主循环执行 → 工具执行 → 错误判断 → 恢复 → 工具
可靠性低,随时可能中断高,具备生产级韧性
架构地位输入结构化系统韧性加固层

本章教学边界

本章不讲:

  • 复杂的分布式错误恢复
  • 全量异常类型捕获
  • 持久化断点恢复
  • 多级降级策略

只牢牢守住一条主线:错误不是例外,是主循环必须预留的正常分支;先恢复,再继续。


一句话总结本章

错误恢复不是给系统打补丁,而是给主循环装上安全网:先分类错误,再走对应恢复路径,有限重试,无法恢复才明确失败。让 Agent 从 “能跑”,真正变成 “稳定可靠、能干活的生产级系统”。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值