函数调用看起来简单,真正放到线上后,失败是常态而不是例外。把失败分类处理, 比统一重试三次要靠谱得多。
先给失败分类
- 参数错误:字段缺失、类型不对、取值越界。这类错误重试没有意义。
- 超时:下游响应慢,可能是暂时性的。
- 限流:被对方拒绝,通常带有明确的等待提示。
- 服务端错误:5xx,可以有限重试。
- 语义失败:接口返回成功,但结果不是用户想要的。
重试策略
参数错误应该把校验信息回给模型,让它修正参数后再试一次,而不是原样重发。 超时和服务端错误用指数退避,但要设总次数和总时长上限,避免把用户卡住。 遇到限流时优先读取对方给出的等待时间,没有就按固定间隔退避。
delay = min(base * 2 ** attempt, max_delay)
delay += random.uniform(0, jitter)
降级
重试都失败后要有兜底。可以换用备用工具、返回缓存结果,或者直接告诉用户当前无法完成, 并给出下一步建议。最糟的情况是静默失败,用户以为操作成功了。
参数校验和超时
在调用工具之前先做一次 schema 校验,能挡掉大部分低级错误。超时时间要结合业务来定, 并且整个请求要有一个总预算,避免单次超时叠加后远超用户预期。