重试

哪些错误该重试、要等多久,以及正确实现重试的代码。

哪些要重试

返回重试?方法
429、503、529是等待 Retry-After-Ms 之后
500、502、504是短暂退避 1 到 2 秒之后
400、401、402、403、404、413否同样的调用会以同样的方式失败。先修正
收到任何返回之前的网络错误是短暂退避之后
流式输出中的错误通常是重新发送整个调用。你只需为已生成的内容付费

网关自己从不重试调用:由你的 SDK 来重试,这样重试次数不会成倍增加。

官方 SDK 已经帮你做了

OpenAI 和 Anthropic 的 SDK 默认会对 429 和 5xx 返回重试两次,并等待 Retry-After-Ms。对于长时间无人值守的任务,请调高次数:

const client = new OpenAI({
  baseURL: "https://binference.io/api/v1",
  apiKey: process.env.BINF_API_KEY,
  maxRetries: 5,
});

自己实现

使用原生 fetch 时,从响应头读取等待时间,再加一点随机性:

async function call(body: unknown, tries = 5): Promise<Response> {
  for (let attempt = 1; ; attempt++) {
    const response = await fetch("https://binference.io/api/v1/chat/completions", {
      method: "POST",
      headers: {
        Authorization: `Bearer ${process.env.BINF_API_KEY}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify(body),
    });
    const retryable = response.status === 429 || response.status >= 500;
    if (!retryable || attempt >= tries) return response;

    const named = Number(response.headers.get("retry-after-ms"));
    const wait = Number.isFinite(named) && named > 0 ? named : 1_000 * 2 ** (attempt - 1);
    await new Promise((resolve) => setTimeout(resolve, wait + Math.random() * 250));
  }
}

时间限制

  • 流式调用:最长 30 分钟。
  • 非流式调用:最长 13 分钟。
  • 到达时间限制时,调用会以一个明确的错误结束,并按已生成的内容扣费。

请把客户端的超时时间设得比这些更长,或者使用流式输出:有些 SDK 会在连接 10 分钟没有任何数据后放弃。

本页目录