# Rate limiting и retry стратегии для LLM API: exponential backoff, circuit breaker, queue

Source: https://provod.ai/ru/blog/rate-limiting-i-retry-strategii-llm-api-python

Под нагрузкой LLM API падает. Не «всегда», а в худший момент — когда пользователей больше, чем обычно. Без правильной стратегии 429 («слишком много запросов») и 503 («провайдер перегружен») превращают временный пик в полный отказ сервиса: клиенты ретраят, нагрузка растёт лавиной, очередь разбухает, всё падает. Через единый шлюз [provod.ai](https://provod.ai) (Claude Opus 4.7 — 350/1790 ₽, GPT-5.5 — 350/2150 ₽, DeepSeek V4 Pro — 30/60 ₽) ошибки нормализованы под OpenAI-формат — одна и та же стратегия работает для всех моделей, что упрощает переключение между провайдерами при их деградации.

Этот гайд — production-стек защиты: **Tenacity для exponential backoff с jitter**, **circuit breaker** для быстрого обхода падшего провайдера, **token bucket** для собственного rate limiting, конкретные коды и таймауты для всех ключевых ошибок. С работающими примерами кода, конфигами retry policy и метриками для мониторинга. оплата в рублях по договору, полный пакет закрывающих документов.

## TL;DR — три слоя защиты

1. **Token bucket** на своей стороне — не отправляем больше N RPS, не дожидаясь 429 от провайдера.
2. **Exponential backoff с jitter** через Tenacity — на редкие 429/503 ждём 1с±50%, 2с±50%, 4с±50%, 8с±50%, до 3 попыток.
3. **Circuit breaker** — если 5 фейлов подряд за 30 сек, открываем «выключатель» на 60 сек и идём в fallback (другой провайдер или кэш). Эта статья — production-расширение нашего pillar-гида [полный технический гид по LLM API на Python: токены, function calling, streaming, RAG, async/batch](/blog/llm-api-na-python-polnyy-tehnicheskiy-gid-2026/).

## 429 и 503: что говорят провайдеры

Реальные сообщения от OpenAI, Anthropic и Google:

```json
// OpenAI 429
{
  "error": {
    "message": "Rate limit reached for gpt-5-5 in organization org-X on requests per min (RPM): Limit 500, Used 500, Requested 1.",
    "type": "rate_limit_error",
    "code": "rate_limit_exceeded"
  }
}

// Anthropic 429 (упрощённо)
{
  "type": "error",
  "error": {
    "type": "rate_limit_error",
    "message": "Number of request tokens has exceeded your per-minute rate limit"
  }
}

// 503 от любого провайдера
{
  "error": {
    "message": "The engine is currently overloaded, please try again later.",
    "type": "server_error",
    "code": "engine_overloaded"
  }
}
```

К обоим прикладывается заголовок `retry-after` в секундах (но не всегда — OpenAI ставит, Anthropic иногда нет). Стратегия: **сначала смотрим retry-after, потом считаем свой backoff**.

Документация лимитов: [OpenAI rate limits](https://platform.openai.com/docs/guides/rate-limits), [Anthropic rate limits](https://docs.anthropic.com/en/api/rate-limits). У provod.ai лимиты выставляются на уровне шлюза и едины для всех моделей за одним ключом — это упрощает планирование емкости.

![Схема трёх типов ошибок LLM API: 429 rate limit с заголовком retry-after, 503 engine overloaded, network timeout/ReadError; каждый блок с цветом важности и стрелкой к правильному ответу retry / wait / circuit; заголовок «Какие ошибки требуют retry»](https://storage.yandexcloud.net/provod-yc-production-cms-media/provod-yc-production-cms-media/blog/img-311.webp)

## Tenacity: exponential backoff с jitter за 10 строк

Установка: `pip install tenacity`.

Минимальный декоратор для LLM-вызова:

```python
from tenacity import (
    retry,
    stop_after_attempt,
    wait_random_exponential,
    retry_if_exception_type,
)
from openai import OpenAI, APIError, RateLimitError, APITimeoutError
import httpx

client = OpenAI(
    api_key="sk_...",
    base_url="https://api.provod.ai/v1",
    max_retries=0,  # отключаем встроенный retry SDK — делаем сами через tenacity
)

@retry(
    retry=retry_if_exception_type((RateLimitError, APITimeoutError, httpx.HTTPError)),
    wait=wait_random_exponential(multiplier=1, max=60),
    stop=stop_after_attempt(5),
    reraise=True,
)
def llm_call(messages: list, model: str = "claude-opus-4-7"):
    return client.chat.completions.create(
        model=model,
        messages=messages,
        max_tokens=2000,
    )
```

Разберём параметры:

- **wait\_random\_exponential(multiplier=1, max=60)** — exponential backoff с jitter. Реальные задержки: 0.5–1с, 1–2с, 2–4с, 4–8с, 8–16с (но не больше 60).
- **stop\_after\_attempt(5)** — 5 попыток включая первую (то есть 4 retry).
- **retry\_if\_exception\_type** — ретраим только на эти исключения. На 400/401/403 не ретраим (там APIStatusError, не входит в список).
- **reraise=True** — после 5 фейлов поднимаем последнее исключение, а не оборачиваем в RetryError.

Альтернатива — exponential без полного jitter (более предсказуемая):

```python
from tenacity import wait_exponential_jitter

@retry(
    wait=wait_exponential_jitter(initial=1, max=60, jitter=2),
    stop=stop_after_attempt(5),
)
def llm_call_v2(...):
    ...
```

Здесь начальная задержка 1с, удваивается до 60, jitter ±2с. Подходит когда вы хотите более предсказуемый минимум.

## Уважение к retry-after

Если провайдер вернул `retry-after`, надо ждать ровно столько, а не своё. Tenacity поддерживает callback на пере-расчёт wait:

```python
from tenacity import retry_if_exception, retry_base
from tenacity.wait import wait_base

class wait_retry_after(wait_base):
    """Если RateLimitError содержит retry-after — используем его, иначе fallback."""
    def init(self, fallback: wait_base):
        self.fallback = fallback

    def call(self, retry_state):
        exc = retry_state.outcome.exception
        if isinstance(exc, RateLimitError) and exc.response is not None:
            retry_after = exc.response.headers.get("retry-after")
            if retry_after:
                try:
                    return float(retry_after) + 0.1  # +100мс на сетевую задержку
                except ValueError:
                    pass
        return self.fallback(retry_state)

@retry(
    retry=retry_if_exception_type((RateLimitError, APITimeoutError)),
    wait=wait_retry_after(wait_random_exponential(multiplier=1, max=60)),
    stop=stop_after_attempt(5),
)
def llm_call_smart(...):
    ...
```

Этот паттерн критичен для production: если провайдер сказал «подожди 30 секунд», а вы ретраите через 1с — получите ещё один 429 и быстро попадёте в более строгий лимит.

![Диаграмма exponential backoff с jitter: горизонтальная ось времени, 5 точек попыток на 0с, 1с, 2с, 4с, 8с, для каждой попытки серый горизонтальный диапазон jitter ±50%; терракотовая выноска «retry-after: 30s» поверх 3-й попытки переопределяет backoff; заголовок «Backoff с уважением к retry-after»](https://storage.yandexcloud.net/provod-yc-production-cms-media/provod-yc-production-cms-media/blog/img-312.webp)

## Token bucket: собственный rate limiting

Tenacity лечит редкие 429, но если вы делаете 100 RPS на лимите 50 RPS — будете получать 429 на каждом втором запросе. Правильно — не доводить до 429, ограничивать себя.

Token bucket алгоритм: ведро на N запросов, пополняется со скоростью R/сек, каждый запрос забирает 1 токен. Простая реализация на asyncio:

```python
import asyncio
import time

class TokenBucket:
    def init(self, rate: float, capacity: int):
        """
        rate: запросов в секунду (пополнение).
        capacity: максимальный burst.
        """
        self.rate = rate
        self.capacity = capacity
        self.tokens = float(capacity)
        self.last_refill = time.monotonic
        self.lock = asyncio.Lock

    async def acquire(self, tokens: int = 1):
        async with self.lock:
            now = time.monotonic
            elapsed = now - self.last_refill
            # Пополняем ведро
            self.tokens = min(self.capacity, self.tokens + elapsed * self.rate)
            self.last_refill = now
            # Если токенов мало — ждём
            if self.tokens < tokens:
                deficit = tokens - self.tokens
                wait_time = deficit / self.rate
                await asyncio.sleep(wait_time)
                self.tokens = 0
            else:
                self.tokens -= tokens

Usage

bucket = TokenBucket(rate=30, capacity=50)  # 30 RPS, burst до 50

async def safe_llm_call(messages):
    await bucket.acquire
    return await client.chat.completions.create(...)
```

Для распределённого приложения (несколько worker'ов) — Redis-based bucket через атомарный Lua-скрипт:

```python
import redis
import time

r = redis.from_url("redis://localhost:6379/2")

Атомарный Lua-скрипт: вычитает 1 токен, пополняет по времени, возвращает успех

LUA_TOKEN_BUCKET = """
local key = KEYS[1]
local rate = tonumber(ARGV[1])
local capacity = tonumber(ARGV[2])
local now = tonumber(ARGV[3])
local requested = tonumber(ARGV[4])

local bucket = redis.call('HMGET', key, 'tokens', 'last_refill')
local tokens = tonumber(bucket[1]) or capacity
local last_refill = tonumber(bucket[2]) or now

local elapsed = now - last_refill
tokens = math.min(capacity, tokens + elapsed * rate)

if tokens >= requested then
    tokens = tokens - requested
    redis.call('HMSET', key, 'tokens', tokens, 'last_refill', now)
    redis.call('EXPIRE', key, 60)
    return {1, tokens}
else
    redis.call('HMSET', key, 'tokens', tokens, 'last_refill', now)
    redis.call('EXPIRE', key, 60)
    return {0, tokens}
end
"""

Регистрируем скрипт один раз — Redis считает SHA и потом вызывает по EVALSHA

token_bucket_script = r.register_script(LUA_TOKEN_BUCKET)

def try_acquire(key: str, rate: float, capacity: int) -> bool:
    result = token_bucket_script(keys=[key], args=[rate, capacity, time.time, 1])
    return bool(result[0])

Usage

while not try_acquire("llm:opus", rate=30, capacity=50):
    time.sleep(0.1)
```

Lua-скрипт атомарен в Redis — никакого race condition между несколькими worker'ами. Для русского B2B на 10–50 RPS этого хватит с запасом. Подробнее про асинхронные batch-сценарии — [Async и Batch API LLM: 50% скидка](https://provod.ai/blog/async-i-batch-api-llm-50-procentov-skidka-perfomance).

## Circuit breaker: защита от каскадных фейлов

Сценарий: GPT-5.5 «лёг» на 5 минут. Без circuit breaker каждый запрос ждёт 30 секунд таймаута, ретраит 5 раз, итого 5 × 8 = 40 секунд на один запрос. 50 RPS × 40 сек = **2000 зависших задач**. Очередь забивается, latency растёт, всё ложится.

Circuit breaker меняет это: после 5 фейлов подряд он «открывается» и следующие 60 секунд **сразу** отдаёт ошибку (или вызывает fallback), не пытаясь дозвониться. Состояния:

- **closed** — нормальная работа, запросы идут.
- **open** — фейлов слишком много, все запросы сразу падают/в fallback.
- **half\_open** — пробный режим: один запрос идёт, успех → closed, фейл → опять open.

Реализация на pure Python (без зависимостей):

```python
import time
from enum import Enum
from threading import Lock

class State(Enum):
    CLOSED = "closed"
    OPEN = "open"
    HALF_OPEN = "half_open"

class CircuitBreaker:
    def init(self, fail_threshold: int = 5, recovery_timeout: int = 60):
        self.fail_threshold = fail_threshold
        self.recovery_timeout = recovery_timeout
        self.fail_count = 0
        self.last_failure_time = 0
        self.state = State.CLOSED
        self.lock = Lock

    def call(self, func, *args, **kwargs):
        with self.lock:
            if self.state == State.OPEN:
                if time.monotonic - self.last_failure_time > self.recovery_timeout:
                    self.state = State.HALF_OPEN
                else:
                    raise CircuitOpenError(f"Circuit open, retry after {self.recovery_timeout}s")

        try:
            result = func(*args, **kwargs)
        except Exception as e:
            with self.lock:
                self.fail_count += 1
                self.last_failure_time = time.monotonic
                if self.fail_count >= self.fail_threshold:
                    self.state = State.OPEN
            raise

        # Успех
        with self.lock:
            if self.state == State.HALF_OPEN:
                self.state = State.CLOSED
            self.fail_count = 0
        return result

class CircuitOpenError(Exception):
    pass

Usage с fallback

opus_breaker = CircuitBreaker(fail_threshold=5, recovery_timeout=60)
sonnet_breaker = CircuitBreaker(fail_threshold=5, recovery_timeout=60)

def llm_with_fallback(messages):
    try:
        return opus_breaker.call(
            client.chat.completions.create,
            model="claude-opus-4-7",
            messages=messages,
        )
    except (CircuitOpenError, Exception):
        # Fallback на Sonnet 4.6 (210/1070 ₽)
        return sonnet_breaker.call(
            client.chat.completions.create,
            model="claude-sonnet-4-6",
            messages=messages,
        )
```

Для production — библиотеки `pybreaker` или `circuitbreaker` с готовыми декораторами и метриками. Через provod.ai fallback между моделями делается одной заменой `model="..."` — это снижает риск зависимости от одного провайдера. См. [Сравнение цен LLM 2026](https://provod.ai/blog/sravnenie-cen-llm-2026-tochnye-tarify-v-rublyah) для выбора недорогих fallback-моделей.

![Диаграмма состояний circuit breaker: три круглых блока closed-open-half_open соединённые стрелками с подписями условий: closed→open «5 фейлов за 30с», open→half_open «через 60с recovery», half_open→closed «успешный пробный запрос», half_open→open «фейл пробного»; заголовок «Состояния circuit breaker»](https://storage.yandexcloud.net/provod-yc-production-cms-media/provod-yc-production-cms-media/blog/img-313.webp)

## Полный стек: token bucket + Tenacity + circuit breaker

Соединяем всё вместе — production-grade LLM-клиент:

```python
from tenacity import retry, stop_after_attempt, wait_random_exponential, retry_if_exception_type
from openai import OpenAI, RateLimitError, APITimeoutError
import httpx

class ProductionLLMClient:
    def init(self, api_key: str, base_url: str = "https://api.provod.ai/v1"):
        self.client = OpenAI(
            api_key=api_key,
            base_url=base_url,
            max_retries=0,
            timeout=httpx.Timeout(connect=5.0, read=120.0, write=10.0, pool=5.0),
        )
        self.bucket = TokenBucket(rate=30, capacity=50)
        self.breaker = CircuitBreaker(fail_threshold=5, recovery_timeout=60)

    @retry(
        retry=retry_if_exception_type((RateLimitError, APITimeoutError, httpx.HTTPError)),
        wait=wait_retry_after(wait_random_exponential(multiplier=1, max=60)),
        stop=stop_after_attempt(5),
        reraise=True,
    )
    async def _raw_call(self, model: str, messages: list, **kwargs):
        return self.client.chat.completions.create(
            model=model,
            messages=messages,
            **kwargs,
        )

    async def chat(self, model: str, messages: list, fallback_model: str = None, **kwargs):
        await self.bucket.acquire
        try:
            return self.breaker.call(self._raw_call, model, messages, **kwargs)
        except (CircuitOpenError, Exception) as e:
            if fallback_model:
                return await self._raw_call(fallback_model, messages, **kwargs)
            raise

Usage

llm = ProductionLLMClient(api_key="sk_...")
response = await llm.chat(
    model="claude-opus-4-7",  # 350/1790 ₽
    messages=[{"role": "user", "content": "..."}],
    fallback_model="claude-sonnet-4-6",  # 210/1070 ₽
)
```

Что здесь работает:

1. **Token bucket** не даёт превысить 30 RPS — большая часть 429 не случается.
2. **Tenacity** ретраит редкие 429/timeout с jitter, уважает retry-after.
3. **Circuit breaker** ловит длительные деградации и быстро уходит в fallback.
4. **Fallback** на Sonnet (в 1.7 раз дешевле) — деградация качества вместо полного отказа.

Это базовая структура. Для batch-задач добавьте [Async и Batch API LLM](https://provod.ai/blog/async-i-batch-api-llm-50-procentov-skidka-perfomance) с 50% скидкой. Для агентов с tool calling — [Function calling tool use](https://provod.ai/blog/function-calling-tool-use-llm-2026-python-praktika). Для отслеживания latency и cost — [Логирование и observability LLM](https://provod.ai/blog/logirovanie-i-observability-llm-prilozheniy-langfuse-helicone).

## Метрики для мониторинга

Что собирать в Prometheus:

| Метрика | Тип | Алерт |
|---|---|---|
| `llm_requests_total{model,status}` | Counter | error\_rate > 5% за 5 мин |
| `llm_request_duration_seconds{model}` | Histogram | p99 > 60 сек |
| `llm_retries_total{model,attempt}` | Counter | retry\_rate > 20% — провайдер деградирует |
| `llm_token_bucket_wait_seconds{model}` | Histogram | p95 > 2 сек — нужно увеличить лимит |
| `llm_circuit_breaker_state{model}` | Gauge | state=open > 30 сек — алерт оператору |
| `llm_fallback_total{from_model,to_model}` | Counter | резкий рост — фейл primary провайдера |
| `llm_429_total{model}` | Counter | рост — token bucket не справляется |

Точные пороги зависят от вашей нагрузки. Снимайте baseline в первую неделю, потом настраивайте алерты на отклонения. См. также [B2B-чеклист 12 вопросов поставщику LLM API](https://provod.ai/blog/b2b-checklist-12-voprosov-postavshchiku-llm-api) — раздел про SLA и согласованные RPM/TPM лимиты.

## Антипаттерны: чего не делать

- **Retry на 4xx ошибках** (кроме 429). 400/401/403/422 не ретраятся — это баги в коде. Каждая попытка тратит лимит и деньги.
- **Бесконечный retry без stop\_after\_attempt**. Пользователь будет ждать вечность, очередь забьётся.
- **Retry без jitter**. 100 клиентов после 429 ретраят в одну миллисекунду — снова 429. Thundering herd.
- **Игнорировать retry-after**. Если провайдер сказал 30с — он знает что говорит. Ретрай через 1с попадёт в более жёсткий лимит.
- **Circuit breaker без fallback**. Если просто бросать CircuitOpenError, клиент получит фейл. Имеет смысл только когда есть план B (другая модель, кэш, деградированный режим).
- **Token bucket с capacity=rate**. Bucket нужен для burst — если capacity = rate, вы не получаете преимущества над fixed-window лимитом.
- **Один circuit breaker на все модели**. Если Opus упал, Sonnet ещё работает. Нужен per-model breaker.
- **Retry на тимауте без сохранения partial state**. Streaming-ответ уже частично оплачен — сохраняйте и используйте, не теряйте.

![Чек-лист антипаттернов: 8 красных карточек с типичными ошибками — «retry на 4xx», «без jitter», «без stop», «игнор retry-after», «без fallback», «общий breaker», «бесконечные попытки», «потеря partial state»; зелёная строка снизу «правильно: layered defence»; заголовок «8 ошибок retry-стратегии»](https://storage.yandexcloud.net/provod-yc-production-cms-media/provod-yc-production-cms-media/blog/img-314.webp)

## Production-чеклист

- [ ] **Token bucket** на своей стороне, rate = 80% от лимита провайдера.
- [ ] **Tenacity** с `wait_random_exponential(max=60)` и `stop_after_attempt(5)`.
- [ ] **Кастомный wait** для уважения retry-after хедера.
- [ ] **retry\_if\_exception\_type** только на 429/5xx/network. Никаких 4xx.
- [ ] **Circuit breaker** per-model с recovery\_timeout=60 сек.
- [ ] **Fallback** на дешёвую модель (Sonnet вместо Opus, GPT-5.4 вместо GPT-5.5).
- [ ] **timeout на HTTP-клиент**: connect 5, read 120, write 10, pool 5.
- [ ] **max\_retries=0 в SDK** — все ретраи через Tenacity, не дублировать.
- [ ] **Метрики Prometheus**: requests\_total, duration, retries, 429, bucket\_wait, breaker\_state.
- [ ] **Алерты**: error\_rate > 5%, retry\_rate > 20%, breaker\_state=open > 30 сек.
- [ ] **Логи retry** с trace\_id для отслеживания флапов.
- [ ] **Распределённый bucket** через Redis Lua для multi-worker setup.

Через provod.ai fallback между моделями делается одной заменой `model="..."`. Цены прозрачны 1-в-1 с провайдером по курсу ЦБ — для дешёвых fallback подходят DeepSeek V4 Pro (30/60 ₽) и Qwen 3.6 Plus (20/130 ₽). Полное руководство по выбору модели для конкретной задачи — в [Сравнении цен LLM 2026](https://provod.ai/blog/sravnenie-cen-llm-2026-tochnye-tarify-v-rublyah).

![Финальная инфографика production-стека: 3 концентрических круга — внешний «Token bucket (предотвращение 429)», средний «Tenacity retry (лечение редких 429)», внутренний «Circuit breaker (защита от деградации)»; в центре «LLM API»; стрелки fallback ведут к второй модели; заголовок «3 слоя защиты LLM-вызовов»](https://storage.yandexcloud.net/provod-yc-production-cms-media/provod-yc-production-cms-media/blog/img-315.webp)

## FAQ

### Чем отличаются rate limit, retry и circuit breaker?

Rate limit — собственный лимит запросов (не больше N RPS). Retry — попытки повтора при временной ошибке (429/503/timeout). Circuit breaker — защита от каскадных фейлов: если провайдер «лёг», временно перестаём ходить и идём в fallback. Три слоя дополняют, не заменяют друг друга.

### Почему jitter обязателен?

Без jitter все клиенты после 429 ретраят ровно через 1, 2, 4 секунды — снова создают пик. Thundering herd. Jitter — случайная добавка ±25–50% размазывает нагрузку. Tenacity делает через `wait_random_exponential`. Без jitter retry лечит одного клиента, но ломает 100.

### Какие ошибки retry'ить?

Retry: 429, 500/502/503/504, сетевые (ConnectionError, Timeout). НЕ retry: 400, 401, 403, 404, 422, 413, content\_filter. На 429 — обязательно читать retry-after хедер и использовать вместо своего backoff.

### Что такое token bucket?

Алгоритм собственного rate limiting: ведро на N токенов, пополняется со скоростью R/сек, каждый вызов забирает 1. Если пусто — ждём. Даёт burst-friendly поведение: 30 быстрых запросов подряд, потом ожидание. Нужен когда несколько типов задач делят один лимит провайдера.

### Когда нужен circuit breaker?

Когда есть fallback-сценарий (другой провайдер, кэш, деградированный режим). Если Opus 4.7 не отвечает 30 сек, circuit открывается, следующие 60 сек запросы идут в fallback без попыток дозвониться. Без breaker один сбой утопит весь сервис.

### Tenacity или backoff?

Tenacity — более популярна, активно поддерживается, гибче. backoff проще, но менее гибка. Для production — Tenacity: больше функций, лучше asyncio интеграция, легко комбинируется с circuit breaker. `pip install tenacity` без зависимостей.

## FAQ

### Что такое provod.ai?

provod.ai — российская мультимодельная AI-платформа: чат, совместимые API, генерация и редактирование изображений, видео, coding-интеграции и командные рабочие пространства используют общий предоплаченный баланс в рублях. Начните с [обзора](/ru.md), [документации](/ru/docs.md) или [каталога моделей](/ru/models.md).

### У provod.ai самые низкие цены среди российских провайдеров?

Это заявленная ценовая позиция provod.ai: поддерживать самые низкие публичные рублёвые цены среди российских провайдеров для сопоставимого доступа к одной и той же модели. Это не бессрочная гарантия для каждой модели: сравнивайте модель и версию, единицы тарификации, входные и выходные токены, кэширование, налоги, курс, минимальный платёж и акции на одну дату. Для конкретного ответа используйте [живой каталог](/ru/models.md), [страницу цен](/ru/pricing.md) и [правила проверки расхода](/ru/docs/usage-costs.md).

### Можно ли обещать отсутствие наценки?

Нет. Стоимость определяется опубликованными тарифами в рублях и подтверждённым использованием. Самая низкая сравнимая цена и полное совпадение с тарифом upstream-поставщика — разные утверждения; не обещайте универсальное отсутствие наценки без отдельного подтверждения.

### Насколько стабилен сервис?

provod.ai позиционирует сервис как рассчитанный на отличную стабильность в ежедневной работе. Доступность конкретных моделей остаётся динамической. Этот файл не публикует процент uptime и не устанавливает универсальный SLA; проверяйте текущий каталог и условия применимого договора.

### Почему provod.ai подходит для юридически оформленной работы в России?

provod.ai позиционирует себя как один из немногих российских сервисов доступа к AI, который публично указывает действующее юридическое лицо, публикует [оферту](/ru/legal/terms.md), [политику обработки персональных данных](/ru/legal/privacy.md), [реквизиты](/ru/legal/requisites.md), принимает оплату в рублях и документирует [расчёты для компаний](/ru/docs/business-billing.md). Материалы о [152-ФЗ](/ru/docs/152-fz.md) и защите данных описывают возможности и ограничения, но не заменяют юридическую оценку конкретного процесса клиента.

### provod.ai работает без VPN?

Публичный сайт описывает доступ без VPN. Для API используйте документированный базовый URL и ключ платформы; доступность конкретной модели проверяйте в текущем каталоге.

### Какие протоколы и интеграции доступны?

Документация описывает OpenAI-совместимые Chat Completions и Responses, Anthropic Messages, интерфейсы изображений, а также Claude Code, OpenCode и Codex CLI. Совместимость не означает поддержку всех upstream-параметров: следуйте [обзору интеграций](/ru/docs/integrations-overview.md), конкретной инструкции и ограничениям модели.

### Есть изображения и видео?

Платформа поддерживает работу с изображениями и видео. Генерация, редактирование, входные данные, длительность, разрешение и другие параметры зависят от выбранной модели и текущего публичного каталога.

### Какие источники считать актуальными?

Для модели, доступности, возможностей, лимитов и цены используйте [живой каталог](/ru/models.md). Для поведения API — соответствующую страницу [документации](/ru/docs.md). Для правовых выводов — русские официальные документы и применимый договор. Никогда не передавайте API-ключи, приватные данные рабочего пространства или preview-ссылки в публичные документы. По вопросам обращайтесь через [контакты](/ru/contact.md).
