Повторные попытки с экспоненциальной задержкой
Используйте tenacity для повторения временно неудачных операций с экспоненциально увеличивающимися задержками и случайным разбросом.
«Повторные попытки с экспоненциальной задержкой» — бесплатный урок AI Agents на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения AI Agents, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс AI Agents содержит 4 уроков всего.
Зачем нужны повторные попытки
Внешние вызовы (LLM, поисковые API, векторные базы данных) могут временно завершаться с ошибкой. Простая повторная попытка устраняет большинство сбоев, не беспокоя пользователя.
Чего НЕ следует делать
Не повторяйте попытку немедленно в тесном цикле — Вы перегрузите сервис, а ограничитель частоты запросов заблокирует Вам доступ:
# BAD
for _ in range(10):
try:
return call_api()
except Exception:
passЭкспоненциальная задержка
После каждой ошибки ждите дольше. Показатель степени 2 является общепринятым соглашением:
import time
def call_with_backoff(fn, attempts=5):
for i in range(attempts):
try:
return fn()
except TransientError:
if i == attempts - 1:
raise
time.sleep(2 ** i) # 1, 2, 4, 8, 16 secondsДобавляйте случайное смещение
Без случайного смещения повторные попытки от множества клиентов синхронизируются, создавая лавинообразный поток запросов. Добавляйте случайное смещение:
import random
sleep = (2 ** i) + random.uniform(0, 1)
time.sleep(sleep)Используйте Tenacity
Библиотека tenacity реализует это за Вас:
from tenacity import retry, wait_exponential_jitter, stop_after_attempt, retry_if_exception_type
import requests
@retry(
wait=wait_exponential_jitter(initial=1, max=30),
stop=stop_after_attempt(5),
retry=retry_if_exception_type((requests.Timeout, requests.ConnectionError))
)
def search(query):
return requests.get('https://api.tavily.com/search', timeout=10).json()Повторяйте попытки только для временных ошибок
Никогда не повторяйте попытку при следующих ошибках:
- ошибки 4xx (неверный запрос — повторная попытка не поможет)
- ошибки аутентификации
- ошибки проверки
Повторяйте попытку при следующих ошибках:
- истечение времени ожидания
- ошибки сервера 5xx
- ограничения частоты запросов (с более длительным ожиданием)
Повторные попытки с учётом ограничения частоты
Учитывайте заголовок Retry-After:
if response.status_code == 429:
wait = int(response.headers.get('Retry-After', 5))
time.sleep(wait)
continueОграничивайте общее время повторных попыток
Ограничивайте общую продолжительность повторных попыток — обычно от 30 до 60 секунд для вызова, выполняемого по запросу пользователя:
from tenacity import stop_after_delay
@retry(
wait=wait_exponential_jitter(initial=1, max=10),
stop=stop_after_delay(60)
)
def call_api():
...Заголовки идемпотентности
Для неидемпотентных API (Stripe и других) включайте ключ идемпотентности в каждую повторную попытку, чтобы объединять дубликаты:
headers = {'Idempotency-Key': f'agent-call-{run_id}-{tool_id}'}Повторяйте также вызов LLM
Пакеты SDK OpenAI и Anthropic автоматически выполняют 1–2 повторные попытки. Вы можете настроить:
client = OpenAI(max_retries=5, timeout=30.0)Асинхронные повторные попытки
Для асинхронного кода:
from tenacity import AsyncRetrying
async for attempt in AsyncRetrying(wait=wait_exponential_jitter(), stop=stop_after_attempt(5)):
with attempt:
result = await call_api()Журналируйте повторные попытки
Каждая повторная попытка должна записывать: номер попытки, длительность ожидания и причину ошибки. Иначе отладить вопрос «почему всё так медленно?» невозможно.
Повторные попытки и ограничения времени ожидания
Задайте короткое время ожидания для каждой попытки (например, 10 с) и общий предел с помощью stop_after_delay (например, 60 с). Без обоих ограничений зависшее соединение может ожидаться бесконечно.
Зачем нужно случайное смещение
Зачем добавлять случайное смещение к задержкам между повторными попытками?
Итоги
Экспоненциальная задержка + случайное смещение + ограниченное общее время + повторные попытки только для временных ошибок. Используйте tenacity, чтобы не писать шаблонный код.
Часто задаваемые вопросы
Урок «Повторные попытки с экспоненциальной задержкой» бесплатный?
Да — полный текст урока «Повторные попытки с экспоненциальной задержкой» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс AI Agents, подпишись на CoddyKit PRO. Курс AI Agents содержит 4 уроков всего.
Чему я научусь в уроке «Повторные попытки с экспоненциальной задержкой»?
Используйте tenacity для повторения временно неудачных операций с экспоненциально увеличивающимися задержками и случайным разбросом. Ты практикуешь AI Agents с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать AI Agents?
Предыдущий опыт не требуется. AI Agents на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «Повторные попытки с экспоненциальной задержкой»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке AI Agents?
Да. Каждый урок AI Agents включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Идемпотентные инструменты и побочные эффекты
- Повторные попытки с экспоненциальной задержкой
- Тайм-ауты и автоматические выключатели
- Проверка вывода инструментов (Pydantic)