API 限流与重试策略:别再裸调大模型接口了

陈老师511 阅读

很多刚接大模型 API 的同学,代码里就是一行 fetch 或 client.chat.completions.create,没有重试、没有限流。线上并发一高,429 刷屏,用户体验直接崩。这篇讲讲生产级调用怎么设计。

先区分错误类型

  • 429(限流):请求太多,等一会儿重试通常能成功。OpenAI 的响应头里带 retry-after 字段,告诉你要等多久,优先用这个,别自己瞎猜。
  • 5xx(服务端错误):模型服务暂时挂了,退避重试,但要限次数,别无限重试加重服务负担。
  • 4xx(参数错误):重试也没用,直接抛给上层,记录日志。

重试实现(退避 + 抖动)

Python
import time, random def call_with_retry(fn, max_retries=3): for i in range(max_retries): try: return fn() except RateLimitError as e: wait = e.retry_after or (2 ** i) + random.uniform(0, 1) time.sleep(wait) except APIStatusError as e: if e.status_code >= 500 and i < max_retries - 1: time.sleep(2 ** i) else: raise raise

指数退避 + 随机抖动,避免所有重试同时爆发(惊群效应)。

并发控制

  1. 信号量限流。客户端用 asyncio.Semaphore 或 threading.Semaphore 控制并发数,别一股脑全发出去。

  2. 令牌桶。如果 API 有明确的 RPM(每分钟请求数)限制,用令牌桶平滑速率,别在 1 秒内把 60 次配额打光。

异步与队列: 实时场景用并发控制 + 重试;非实时场景(批量处理)丢进队列,worker 慢慢消费,天然削峰。

可观测性

  • 记录每次调用的:模型、token 数、耗时、错误类型
  • 429/5xx 单独告警
  • 成功率低于阈值自动降级(切备用模型/备用渠道)

  1. 别把重试写在循环里直接睡——异步代码里用 asyncio.sleep,阻塞代码用 time.sleep,用错了会卡死事件循环。

  2. 幂等性:有些调用(如生成任务)重试会重复执行,如果你的操作有副作用(比如扣费、写库),重试要保证幂等。

总结:重试 + 退避 + 并发控制 + 可观测性,是生产调用的基本盘。

评论0

还没有评论,来抢沙发~