代码讲解.md 2.6 KB

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 是一个状态对象:

state = RecoveryState()

内部字段:

{
    "has_escalated": False,
    "recovery_count": 0,
    "consecutive_529": 0,
    "has_attempted_reactive_compact": False,
    "current_model": PRIMARY_MODEL
}

它记录当前 Agent 已经尝试过哪些恢复动作。


3. 三类错误恢复

第一类:max_tokens

response.stop_reason == "max_tokens"

说明模型输出被截断。

处理方式:

第一次:把 max_tokens 从 8000 升到 64000
之后:追加“请继续”的用户消息
超过次数:停止

第二类:prompt_too_long

说明上下文太长。

处理方式:

messages[:] = reactive_compact(messages)
重新请求

第三类:429 / 529

说明请求太频繁或服务过载。

处理方式:

等待一段时间
再重试
连续 529 太多时切换备用模型

4. retry_delay(attempt)

作用:指数退避。

大概规律:

第 1 次等短一点
第 2 次等更久
第 3 次再更久

代码里还加了随机抖动 jitter,避免多个请求同时重试。


5. with_retry(fn, state)

fn 是一个“暂时不执行的函数”。

调用时传入:

lambda: client.messages.create(...)

with_retry() 内部真正执行:

result = fn()

如果遇到 429 / 529,就等待后继续。

如果不是瞬时错误,就抛给外层处理。


6. Agent Loop 中的变化

S10 直接调用模型:

response = client.messages.create(...)

S11 改成:

response = with_retry(
    lambda: client.messages.create(...),
    state
)

外层再根据错误类型选择恢复路径。


7. 本节课堂重点

生产级 Agent 必须能处理失败:

输出被截断 -> 升级或续写
上下文太长 -> 压缩后重试
服务限流/过载 -> 退避重试
多次失败 -> 给出明确错误

错误恢复是 Agent Harness 的重要工程能力。