失败从哪来
Agent 链路包含:模型推理(超时、限流、内容过滤)、工具执行(网络、权限、业务错误)、编排逻辑(状态不一致、解析 JSON 失败)。韧性设计假设每一步都会失败,且失败可观测、可恢复。
重试与超时
import random
import time
def call_with_retry(fn, max_attempts=3, base=1.0):
for attempt in range(max_attempts):
try:
return fn()
except TransientError as e:
if attempt == max_attempts - 1:
raise
sleep = base * (2 ** attempt) + random.uniform(0, 0.5)
time.sleep(sleep)
- 可重试:429、5xx、连接重置、工具只读查询。
- 不可重试:400 参数错误、401 鉴权(修配置)、非幂等写除非有 idempotency key。
- 超时:LLM 与每个工具分别设 deadline,避免单工具拖死整轮。
把错误还给模型
工具层返回统一结构:
{
"ok": false,
"error_code": "TIMEOUT",
"message": "查询超过 10s",
"retryable": true
}
编排器写入 role: tool,模型可改 SQL、缩小范围或告知用户。禁止返回空字符串冒充成功。
熔断与降级
连续失败率超阈值时熔断某工具或某下游,短期直接返回「服务繁忙」。降级路径:
- 换小模型完成摘要类任务;
- 关闭非关键工具,仅保留 FAQ;
- 人工接管队列。
状态与补偿
长任务用检查点持久化:已完成工具调用、中间结果。崩溃后从检查点续跑,配合幂等键防重复执行。
人机协同:低置信或高风险操作(转账、删数据)要求确认,不交给模型自动执行。
checklist
- [ ] 所有外部调用有超时与重试策略
- [ ] 工具幂等与写操作审计
- [ ] 日志含 trace_id、tool_name、error_code
- [ ] 用户可见错误文案与内部堆栈分离