限流与重试¶
重试只能用于可能恢复且能够安全重复的请求。收到 429、临时服务错误或网络中断后,先判断请求是否已经产生资源、任务、模型用量或外部动作,再决定等待、查询状态或重试。
收到 429 时¶
检查响应是否提供
Retry-After或等价等待信息。有等待信息时,按客户端支持的格式解析并在等待结束后再发送请求。
没有等待信息时,使用有上限的指数退避并加入随机抖动。
降低同一凭据、工作区或模型的并发,不要让多个进程同时立即重试。
达到调用方的最大重试次数或总等待时间后停止,并保留诊断信息。
Retry-After 不是所有限流响应的固定 Header。只有响应实际提供时才能依赖它;具体 RPM、TPM、并发、额度和等待时间以当前凭据、接口和环境返回的信息为准。
判断是否适合重试¶
情况 |
是否自动重试 |
处理方式 |
|---|---|---|
安全的只读请求收到 |
可以有限重试 |
遵循等待信息,使用有上限退避。 |
认证、权限、路径或参数错误 |
不重试 |
修正凭据、作用域、路径或字段。 |
写请求收到明确业务冲突 |
不原样重试 |
重新读取资源状态,处理版本或幂等冲突。 |
写请求网络超时 |
默认不立即重试 |
先按资源 ID、任务 ID、业务操作 ID 或幂等键确认结果。 |
明确支持幂等的写请求发生临时错误 |
按接口规则有限重试 |
保持相同请求内容和幂等键。 |
流式响应开始前收到临时错误 |
可以按接口规则重试 |
尚未产生流式内容时重新建立请求。 |
已收到部分流式输出后中断 |
默认不自动重试 |
将结果标记为中断;确认恢复或去重能力后再处理。 |
异步任务仍在运行 |
不重新创建任务 |
使用原任务 ID 继续查询状态。 |
配置有界退避¶
退避策略应由调用方明确设置以下边界:
最大尝试次数;
单次等待上限;
总等待时间或业务截止时间;
随机抖动范围;
可重试的 HTTP 状态和业务错误;
用户取消或应用关闭时的停止条件。
下面是算法示意,数值应根据应用时延预算和接口返回信息配置,不代表产品默认值:
delay = min(base_delay × 2^attempt, max_delay)
wait = random(0, delay)
如果响应提供的等待时间超过应用的总截止时间,应停止当前操作并向调用方返回可恢复状态,而不是忽略 Header 或无限等待。
避免重试风暴¶
多个实例同时收到限流时,固定间隔会让它们再次同时请求。除随机抖动外,还应:
在应用入口限制并发,而不是只在失败后等待;
将批量任务放入队列并控制消费者数量;
对相同资源或任务合并重复轮询;
在共享凭据的进程之间协调请求预算;
重试成功后逐步恢复流量,不立即回到峰值。
写操作和异步任务¶
创建、运行、发布、导入、导出、SQL 执行和工具调用可能已经在服务端开始。失败恢复应优先使用:
响应已经返回的资源、任务或运行标识;
调用方保存的业务操作 ID;
接口明确支持的幂等键;
列表或详情接口中的现有结果。
如果无法确认首次请求是否生效,停止自动重试并交给业务层处理。重复请求可能创建第二个资源、重复运行任务、产生额外模型用量或再次触发外部副作用。
SDK 行为¶
Product SDK 默认每个调用只发送一次 HTTP 请求,不会替业务自动重试。调用方添加重试前,应先确认:
SDK 方法对应的 HTTP 操作是否安全;
目标接口是否支持幂等;
错误对象中是否包含 HTTP 状态、业务错误码和请求 ID;
超时后能否查询原任务或资源;
重试是否会改变费用或外部系统状态。
Genesis 兼容 SDK 可能具有各自的重试配置。使用这些选项时,也应遵守目标接口的限流、流式和幂等规则,不把 SDK 默认行为当作 Genesis 的产品承诺。
重试耗尽后记录¶
时间范围和时区;
API、接口路径和模型或资源 ID;
HTTP 状态和脱敏错误码;
响应实际提供的请求 ID 与等待信息;
已执行次数、每次等待时间和总耗时;
是否已经收到资源、任务或部分流式结果。
这些信息用于判断是持续限流、暂时服务异常还是客户端策略问题。不要在诊断信息中包含完整凭据和业务数据。