# S11 Error Recovery 代码讲解 这一节只讲相对 S10 新增的内容: **Agent 调用模型时可能失败,所以需要恢复策略,而不是一报错就退出。** --- ## 1. 本节新增内容 - `RecoveryState`:记录恢复状态。 - `retry_delay()`:计算指数退避等待时间。 - `with_retry()`:包装 LLM 调用,处理 429 / 529。 - `is_prompt_too_long_error()`:识别上下文过长错误。 - `reactive_compact()`:上下文过长时做应急压缩。 - `max_tokens` 恢复路径:输出被截断时升级 token 或要求续写。 --- ## 2. `RecoveryState` `RecoveryState` 是一个状态对象: ```python state = RecoveryState() ``` 内部字段: ```python { "has_escalated": False, "recovery_count": 0, "consecutive_529": 0, "has_attempted_reactive_compact": False, "current_model": PRIMARY_MODEL } ``` 它记录当前 Agent 已经尝试过哪些恢复动作。 --- ## 3. 三类错误恢复 第一类:`max_tokens` ```python response.stop_reason == "max_tokens" ``` 说明模型输出被截断。 处理方式: ```python 第一次:把 max_tokens 从 8000 升到 64000 之后:追加“请继续”的用户消息 超过次数:停止 ``` 第二类:`prompt_too_long` 说明上下文太长。 处理方式: ```python messages[:] = reactive_compact(messages) 重新请求 ``` 第三类:`429 / 529` 说明请求太频繁或服务过载。 处理方式: ```python 等待一段时间 再重试 连续 529 太多时切换备用模型 ``` --- ## 4. `retry_delay(attempt)` 作用:指数退避。 大概规律: ```text 第 1 次等短一点 第 2 次等更久 第 3 次再更久 ``` 代码里还加了随机抖动 `jitter`,避免多个请求同时重试。 --- ## 5. `with_retry(fn, state)` `fn` 是一个“暂时不执行的函数”。 调用时传入: ```python lambda: client.messages.create(...) ``` `with_retry()` 内部真正执行: ```python result = fn() ``` 如果遇到 429 / 529,就等待后继续。 如果不是瞬时错误,就抛给外层处理。 --- ## 6. Agent Loop 中的变化 S10 直接调用模型: ```python response = client.messages.create(...) ``` S11 改成: ```python response = with_retry( lambda: client.messages.create(...), state ) ``` 外层再根据错误类型选择恢复路径。 --- ## 7. 本节课堂重点 生产级 Agent 必须能处理失败: ```python 输出被截断 -> 升级或续写 上下文太长 -> 压缩后重试 服务限流/过载 -> 退避重试 多次失败 -> 给出明确错误 ``` 错误恢复是 Agent Harness 的重要工程能力。