我第一次遇到 429 错误时,完全不知道发生了什么。API 返回了一个莫名其妙的错误码,代码就卡在那里不动了。后来我才明白,这是 API 服务商在告诉我:兄弟,你请求太快了,歇会儿吧。

今天我就用最通俗的语言,教会你如何处理这个烦人的 429 错误。我们会用到 HolySheep AI 作为示例,它支持 Claude 全系列模型,而且有国内直连 <50ms 的优势,注册就送免费额度,非常适合练手。

什么是 429 错误?

429 是 HTTP 状态码的一种,全称是 "Too Many Requests",翻译过来就是"请求太多了"。你可以把它想象成:

在 API 调用中,HolySheheep AI 和其他 API 服务一样,都有自己的请求频率限制。当你的代码在短时间内发送太多请求时,就会触发这个保护机制。

为什么需要重试机制?

我曾经踩过一个坑:代码遇到 429 就直接放弃了,结果用户看到的是"服务不可用"的提示,体验很差。

其实 429 不是真正的错误,只是告诉你"等会儿再试"。一个好的重试机制应该:

这样可以让成功率从 70% 提升到 99% 以上。

Python 实现带指数退避的重试机制

指数退避是业界标准的重试策略,简单说就是:失败后等 1 秒,不行等 2 秒,再不行等 4 秒,以此类推。这样既不会浪费资源,也不会给服务器太大压力。

import requests
import time
import json

HolySheep API 配置

BASE_URL = "https://api.holysheep.ai/v1" API_KEY = "YOUR_HOLYSHEEP_API_KEY" def call_claude_with_retry(prompt, max_retries=5): """ 带指数退避重试的 Claude API 调用 """ headers = { "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json" } payload = { "model": "claude-sonnet-4-20250514", "max_tokens": 1024, "messages": [ {"role": "user", "content": prompt} ] } for attempt in range(max_retries): try: response = requests.post( f"{BASE_URL}/chat/completions", headers=headers, json=payload, timeout=30 ) if response.status_code == 200: return response.json() elif response.status_code == 429: # 429 错误,使用指数退避 wait_time = 2 ** attempt print(f"触发速率限制,等待 {wait_time} 秒后重试...") time.sleep(wait_time) elif response.status_code == 500: # 服务器内部错误,也重试 wait_time = 2 ** attempt print(f"服务器错误,等待 {wait_time} 秒后重试...") time.sleep(wait_time) else: # 其他错误,直接返回 print(f"请求失败: {response.status_code} - {response.text}") return None except requests.exceptions.RequestException as e: print(f"网络请求异常: {e}") if attempt < max_retries - 1: time.sleep(2 ** attempt) else: return None print(f"已达到最大重试次数 {max_retries},请求失败") return None

测试调用

result = call_claude_with_retry("用一句话解释什么是量子计算") if result: print("成功!响应:", json.dumps(result, ensure_ascii=False, indent=2))

更专业的重试库:tenacity

刚才那个例子是我自己写的,但在生产环境中,我更推荐使用 tenacity 库。它功能更完善,还支持异步编程。

# pip install tenacity
from tenacity import (
    retry,
    stop_after_attempt,
    wait_exponential,
    retry_if_exception_type
)
import requests

BASE_URL = "https://api.holysheep.ai/v1"
API_KEY = "YOUR_HOLYSHEEP_API_KEY"

配置重试策略

@retry( stop=stop_after_attempt(5), # 最多试5次 wait=wait_exponential(multiplier=1, min=2, max=60), # 等待2-60秒 retry=retry_if_exception_type(requests.exceptions.RequestException), reraise=True ) def call_claude_api(prompt): """带重试的 API 调用函数""" headers = { "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json" } payload = { "model": "claude-sonnet-4-20250514", "max_tokens": 1024, "messages": [ {"role": "user", "content": prompt} ] } response = requests.post( f"{BASE_URL}/chat/completions", headers=headers, json=payload, timeout=30 ) # 429 错误时,手动抛出异常触发重试 if response.status_code == 429: raise RateLimitError("触发速率限制") response.raise_for_status() return response.json()

自定义异常类

class RateLimitError(Exception): """速率限制异常""" pass

使用示例

try: result = call_claude_api("解释一下什么是机器学习") print(f"成功: {result}") except RateLimitError: print("请求被限流,请稍后再试") except Exception as e: print(f"请求失败: {e}")

生产环境完整示例

这是我自己在线上项目中使用的一套完整方案,包含了日志记录、缓存、和优雅的错误处理。

import logging
from datetime import datetime, timedelta
from collections import defaultdict
import time

配置日志

logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) class RateLimitedAPI: """带速率限制感知的 API 客户端""" def __init__(self, api_key, base_url="https://api.holysheep.ai/v1"): self.api_key = api_key self.base_url = base_url # 记录每分钟的请求数 self.request_counts = defaultdict(list) self.max_requests_per_minute = 50 # 根据实际限制调整 def _check_local_limit(self): """本地速率检查""" now = datetime.now() minute_ago = now - timedelta(minutes=1) # 清理过期记录 for key in list(self.request_counts.keys()): self.request_counts[key] = [ t for t in self.request_counts[key] if t > minute_ago ] total_requests = sum(len(v) for v in self.request_counts.values()) if total_requests >= self.max_requests_per_minute: wait_time = 60 - (now - minute_ago).seconds logger.warning(f"本地速率限制触发,等待 {wait_time} 秒") time.sleep(wait_time) def _make_request(self, endpoint, payload): """实际发送请求""" import requests headers = { "Authorization": f"Bearer {self.api_key}", "Content-Type": "application/json" } response = requests.post( f"{self.base_url}/{endpoint}", headers=headers, json=payload, timeout=60 ) # 记录请求时间 self.request_counts['total'].append(datetime.now()) return response def chat(self, messages, model="claude-sonnet-4-20250514"): """聊天接口""" payload = { "model": model, "max_tokens": 2048, "messages": messages } max_retries = 3 for attempt in range(max_retries): try: # 本地限流检查 self._check_local_limit() response = self._make_request("chat/completions", payload) if response.status_code == 200: return response.json() elif response.status_code == 429: # 获取服务器返回的等待时间 retry_after = response.headers.get('Retry-After', 30) logger.warning( f"第 {attempt+1} 次请求触发 429,等待 {retry_after} 秒" ) time.sleep(int(retry_after)) elif response.status_code == 500: logger.warning(f"服务器错误,第 {attempt+1} 次重试") time.sleep(2 ** attempt) else: logger.error(f"API 错误: {response.status_code}") response.raise_for_status() except Exception as e: logger.error(f"请求异常: {e}") if attempt == max_retries - 1: raise raise Exception("达到最大重试次数")

使用示例

if __name__ == "__main__": client = RateLimitedAPI( api_key="YOUR_HOLYSHEEP_API_KEY" ) try: result = client.chat([ {"role": "user", "content": "写一个冒泡排序算法"} ]) print("成功获取响应!") print(result['choices'][0]['message']['content']) except Exception as e: print(f"最终失败: {e}")

使用 HolySheep AI 的优势

我在多个项目中对比过不同的 API 提供商,HolySheep AI 有几个让我特别满意的地方:

特别是在做批量处理或者长对话场景时,低延迟和低成本的优势就非常明显了。

常见报错排查

我把实际开发中遇到的 429 相关问题整理了一下,希望帮你少走弯路:

错误1:本地限流和服务器限流混淆

错误信息:一直触发重试,但永远不成功

# ❌ 错误做法:没有区分本地限流和服务器限流
for i in range(100):
    response = call_api()  # 每个请求都重试,没有延迟
    

✅ 正确做法:加入适当的延迟

import time for i in range(100): try: response = call_api() break except RateLimitError: wait = 2 ** i # 指数退避 time.sleep(min(wait, 60)) # 最大等待60秒

错误2:没有处理 Retry-After 响应头

错误信息:429 错误后等待时间不准确,有时浪费资源,有时被限流

# ❌ 错误做法:忽略服务器的提示
if response.status_code == 429:
    time.sleep(5)  # 固定等待5秒,可能不够

✅ 正确做法:读取服务器的 Retry-After 头

if response.status_code == 429: retry_after = response.headers.get('Retry-After') if retry_after: wait_time = int(retry_after) else: # 服务器没有明确告知,等待时间加倍 wait_time = min(current_wait * 2, 120) time.sleep(wait_time) print(f"服务器建议等待 {wait_time} 秒")

错误3:并发请求导致瞬时流量过高

错误信息:单次请求没问题,批量请求时大量 429

# ❌ 错误做法:同时发送所有请求
import concurrent.futures

with concurrent.futures.ThreadPoolExecutor(max_workers=50) as executor:
    futures = [executor.submit(call_api, item) for item in items]
    results = [f.result() for f in futures]  # 50个并发全部被限流

✅ 正确做法:控制并发数 + 信号量限流

import asyncio import aiohttp async def rate_limited_call(semaphore, session, url, headers, payload): async with semaphore: # 限制同时只有5个请求 async with session.post(url, headers=headers, json=payload) as resp: if resp.status == 429: await asyncio.sleep(2) # 退避 return await rate_limited_call(semaphore, session, url, headers, payload) return await resp.json() async def batch_call(items): connector = aiohttp.TCPConnector(limit=5) async with aiohttp.ClientSession(connector=connector) as session: semaphore = asyncio.Semaphore(5) tasks = [ rate_limited_call(semaphore, session, "https://api.holysheep.ai/v1/chat/completions", {"Authorization": f"Bearer YOUR_HOLYSHEEP_API_KEY"}, {"model": "claude-sonnet-4-20250514", "messages": [{"role": "user", "content": item}]}) for item in items ] return await asyncio.gather(*tasks)

错误4:没有处理 token 耗尽的情况

错误信息:429 错误一直持续,重试也无法恢复

# ❌ 错误做法:无限重试 429
while True:
    response = call_api()
    if response.status_code != 429:
        break

✅ 正确做法:区分不同类型的 429

def handle_api_error(response): error_body = response.json() if response.text else {} error_type = error_body.get('error', {}).get('type', '') if error_type == 'rate_limit_error': return {'action': 'retry', 'wait': response.headers.get('Retry-After', 60)} elif error_type == 'insufficient_quota': return {'action': 'stop', 'message': '账户额度不足,请充值'} elif error_type == 'invalid_request_error': return {'action': 'stop', 'message': '请求参数错误'} else: return {'action': 'stop', 'message': f'未知错误: {error_type}'}

总结

处理 429 错误的关键就是:理解它不是真正的错误,而是服务器在告诉你"慢一点"。一个好的重试机制应该做到:

如果你还没用过 API 调用,建议从 HolySheep AI 开始,注册送额度,微信支付宝都能充值,国内直连延迟低,非常适合练手和学习。

祝你的代码永远不被 429 困扰!

👉 免费注册 HolySheep AI,获取首月赠额度