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