Коды ошибок, лимиты и повторные попытки
Ошибки DeepSeek API приходят как обычные HTTP-статусы. Часть из них исправляется в коде запроса, часть — только ожиданием или снижением нагрузки. Ниже разобраны коды, лимиты параллельных запросов и практическая схема повторов.
Коды ошибок
| Код | Значение | Что делать |
|---|---|---|
| 400 | Invalid Format | Неверный формат тела запроса — исправить по тексту сообщения |
| 401 | Authentication Fails | Неверный API-ключ — проверить значение заголовка Authorization |
| 402 | Insufficient Balance | Пополнить баланс аккаунта |
| 422 | Invalid Parameters | Неверные параметры запроса — проверить имена и диапазоны значений |
| 429 | Rate Limit Reached | Слишком частые запросы — снизить темп и повторить позже |
| 500 | Server Error | Повторить после короткой паузы |
| 503 | Server Overloaded | Повторить после короткой паузы |
Формат тела ошибки в официальной документации не описан. Структурированное поле error документировано только для объекта Responses API со статусом failed. Заголовка Retry-After и формальной политики backoff в документации тоже нет: всё, что написано ниже про повторы, — практическая рекомендация, а не требование API. Не завязывайте логику на разбор тела ошибки: ориентируйтесь на HTTP-статус.
Типичные причины 400 при работе с моделями DeepSeek разбираются в других разделах: в thinking mode tool_choice: "required" и выбор конкретной функции дают 400, а при использовании tools поле reasoning_content обязательно возвращать назад в последующих запросах. Подробности — в разделах «Режим рассуждений» и «JSON и инструменты».
Лимиты параллельных запросов
Основной лимит — не количество запросов в минуту, а число одновременных запросов (concurrency). Считается на аккаунт, а не на отдельный ключ: если у вас пять ключей, лимит всё равно общий. Один запрос занимает одно соединение от отправки до завершения ответа. При превышении лимита приходит HTTP 429.
| Модель | Одновременных запросов |
|---|---|
deepseek-flash |
2500 |
deepseek-v4-pro |
500 |
Параметр user_id даёт изоляцию по контексту безопасности, KV-кэшу и планировщику. Для обычных пользователей все значения user_id суммируются в общий лимит; при повышенных квотах лимит действует отдельно на каждый user_id. Формат: [a-zA-Z0-9\-_]+, не длиннее 512 символов.
429 проще предотвратить, чем обрабатывать: держите пул параллельных задач заметно ниже лимита, ограничивайте его семафором и не отправляйте пакет запросов одним залпом. Если стриминг открыт, но ответ не читается до конца, соединение продолжает занимать слот.
Нужен API-ключ сегодня
Регистрация по email или Telegram занимает пару минут, оплата идёт в рублях, VPN не нужен. Один ключ работает и с DeepSeek, и с другими моделями.
Keep-alive и закрытие соединения
Соединение удерживается, пока инференс не начался. В нестриминговых ответах для этого приходят пустые строки, в стриминге — SSE-комментарии : keep-alive. Если инференс не начался за 10 минут, сервер закрывает соединение: для клиента это выглядит как обрыв, и такой запрос нужно повторить.
Повторные попытки: экспоненциальный backoff
Практическая схема: повторять только 429, 500 и 503; паузу увеличивать экспоненциально; добавлять случайный разброс (джиттер), чтобы параллельные задачи не повторяли запрос синхронно; ограничить общее число попыток. Ошибки 400, 401, 402 и 422 повторять бессмысленно — они не исчезнут без изменения запроса или баланса.
import os
import random
import time
from openai import APIStatusError, OpenAI
client = OpenAI(
api_key=os.environ["DEEPSEEK_API_KEY"],
base_url="https://api.deepseek.com",
)
RETRYABLE = {429, 500, 503}
MAX_ATTEMPTS = 6
def chat_with_retry(messages, model="deepseek-flash"):
"""Отправляет запрос и повторяет его при 429/500/503."""
for attempt in range(1, MAX_ATTEMPTS + 1):
try:
return client.chat.completions.create(model=model, messages=messages)
except APIStatusError as exc:
status = exc.status_code
if status not in RETRYABLE or attempt == MAX_ATTEMPTS:
raise
# Заголовок Retry-After в документации DeepSeek не описан.
# Если он всё же пришёл — используем его, иначе считаем паузу сами.
retry_after = exc.response.headers.get("retry-after")
delay = float(retry_after) if retry_after else min(2 ** attempt, 60)
delay += random.uniform(0, delay / 4) # джиттер против синхронных повторов
print(f"HTTP {status}: попытка {attempt}/{MAX_ATTEMPTS}, пауза {delay:.1f} с")
time.sleep(delay)
raise RuntimeError("повторы исчерпаны")
response = chat_with_retry(
[{"role": "user", "content": "Объясни в двух предложениях, что такое backoff."}]
)
print(response.choices[0].message.content)
Повтор должен отправлять тот же набор сообщений, что и исходный запрос. Если в истории диалога есть reasoning_content (а при использовании tools он обязателен), сохраняйте его между попытками — иначе повтор завершится HTTP 400.
Смежные лимиты
- Vision: URL изображения ≤ 8192 символов, тело запроса ≤ 48 MiB, одно изображение ≤ 32 MiB (через Files API по
file_id— ≤ 64 MiB), ≤ 600 изображений на запрос, сторона ≤ 8192 px (4096 px при 15 изображениях и больше). - Files API: файл ≤ 64 MiB, имя ≤ 512 символов, ≤ 25 GiB и ≤ 10 000 файлов на пользователя, срок жизни — от 1 часа до 30 дней или бессрочно.
- max_tokens: от 1 до 393 216; если не задан — 8K в non-thinking, 64K в thinking, 128K при
reasoning_effort: "max".
Нужен API-ключ сегодня
Регистрация по email или Telegram занимает пару минут, оплата идёт в рублях, VPN не нужен. Один ключ работает и с DeepSeek, и с другими моделями.
Читайте также
-
Режим рассуждений
Какие комбинации параметров дают 400 в thinking mode и зачем возвращать
reasoning_content. - Модели и параметры Доступные модели, ограничения контекста и вывода, поддержка vision и бета-функций.
- Цены и расчёт Что будет с балансом и когда запросы упираются в 402.
- Примеры на Python Полный рабочий скрипт с клиентом, повторами и логированием.