稳定调用 GPT 和 Claude:超时、重试退避与故障降级的实战写法
很多人跑通第一个请求后就以为"接好了",一上生产才发现问题:网络抖一下请求就挂死、偶发 429 直接报错、上游异常整条链路瘫痪。所谓"稳定调用",靠的不是运气,而是几段并不复杂的工程代码。本文把它拆成超时、重试退避、故障降级三件事,示例全用占位符,替换成自己的即可。
一、先约定环境变量
export API_KEY="你的key"
export BASE_URL="你的base_url" # 可选,不用则不填
二、超时:第一道保险
裸调不设超时是新手最常见的坑。一次网络抖动就能让请求一直挂着,把连接池占满,新请求全排队。所有调用都必须设超时:
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["API_KEY"],
base_url=os.environ.get("BASE_URL") or None,
timeout=30.0,
)
三、重试退避:把偶发错误吃掉
429(限流)和 5xx(瞬时错误)在生产里是常态,不该直接抛给用户。正确做法是带指数退避的重试,给上游喘息时间:
import time, random
def call_with_retry(messages, model, max_retries=3):
for i in range(max_retries):
try:
return client.chat.completions.create(model=model, messages=messages)
except Exception:
if i == max_retries - 1:
raise
# 指数退避 + 抖动,避免同时重试再次压垮上游
time.sleep((2 ** i) + random.random())
注意加一点随机抖动,避免多个请求踩着同一个节奏重试,反而形成二次冲击。还有一点常被忽略:不是所有错误都值得重试。429 和 5xx 这类瞬时错误重试有意义,但 401(鉴权失败)、400(参数错误)这类确定性错误重试多少次都不会成功,反而白白拖长响应、浪费额度。正确做法是先判断错误类型,只对可恢复的错误重试,把不可恢复的直接抛出去让上层处理。把"可重试错误"列成一个白名单,是让重试逻辑真正有用的关键一步。
四、故障降级:别把鸡蛋放一个篮子
想要"稳定",还得有备选路径。把地址、密钥、模型名都抽成配置,准备一个主入口和一个备用入口,主入口连续失败就切到备用:
ENDPOINTS = [
{"base_url": os.getenv("PRIMARY_URL"), "key": os.getenv("PRIMARY_KEY")},
{"base_url": os.getenv("FALLBACK_URL"), "key": os.getenv("FALLBACK_KEY")},
]
至于主备入口从哪来,官方直连、第三方统一接入、云厂商服务几类各有取舍,可按可达性和稳定性自己实测后填。
五、加个健康探针
生产里最好定时用一个轻量请求探活各入口,成功率掉下来提前告警,别等用户先发现。探针记录成功率和 P95 延迟,比平均值更能反映高峰体验。探针本身要轻,用最短的请求、最小的 token,别让健康检查自己变成负担;探测频率也要适中,太密会额外增加成本和上游压力,太疏又发现得慢,几十秒到一两分钟一次通常够用。把探针数据接进你已有的监控告警,异常时能第一时间通知到人,这套"稳定"才算真正闭环。
六、小结
“稳定调用"不是玄学,是超时兜底、退避重试、故障降级、健康探针这几件工程事叠起来的结果。把这套模板套进项目,GPT 和 Claude 的调用就能从"能通"变成"扛得住线上流量”。key 和 base_url 从哪来是另一回事,实测后按可达性决定即可。
更多推荐




所有评论(0)