隐藏的 SDK 重试机制:为什么你付了两倍的钱却浑然不知
打开 OpenAI Python SDK 的源代码,你会发现一行安静的代码:DEFAULT_MAX_RETRIES = 2。Anthropic SDK 也采用了同样的默认设置。大多数 TypeScript SDK 也是如此。两次重试,指数级退避(exponential backoff),在连接错误、408、409、429 以及任何 5xx 错误时自动触发——这些都在你的代码看到失败之前就执行了。你没有配置它。你没有选择加入。你通常甚至不知道它的发生,因为你的应用记录的指标是 request_count(请求数),而不是 attempt_count(尝试数),并且你的追踪器(tracer)唯一能看到的 span 是 SDK 在最后一次尝试后关闭的最外层 span。
这在大多数情况下都没问题,直到出问题为止。如果在该 SDK 调用之上再添加一个应用级的重试装饰器——那种每个团队在遇到第一个 429 错误后都会写的代码——你就构建了一个 3x3 的风暴:SDK 尝试三次,你的包装层围绕 SDK 又尝试三次,在服务商降级期间,一个单一的用户请求会扇出为九次推理调用。服务商的账单会计算每一次尝试。而你的仪表盘只记录了一次。当最终有人进行账实对账时,那将是一场谁都不会喜欢的季度末谈话。
