Вы несколько недель строите продукт. Завтра демо. Вы деплоите на стейджинг, запускаете нагрузочный тест, и через тридцать секунд логи заполняются ответами HTTP 429. Claude API решил, что на сегодня хватит. Эта статья существует для того, чтобы такой момент никогда не застал вас врасплох. Мы разберём, как именно устроены rate limits у Anthropic, какие рычаги у вас есть, и как построить систему, которая деградирует грациозно, а не падает.
Haiku у нас есть: в каталоге claude-haiku-5.5 и claude-haiku-4.5, цены на странице моделей. Они работают в канале Premium, в канале Cheap Haiku нет.
Как работают rate limits Claude API
Anthropic применяет ограничения на трёх уровнях, и думать нужно обо всех трёх одновременно:
- Requests per minute (RPM): количество API-вызовов за скользящее окно в 60 секунд. Ограничивает конкурентность независимо от размера промптов.
- Tokens per minute (TPM): суммарное количество входных + выходных токенов, которые API обработает за 60-секундное окно. Один огромный промпт может съесть весь бюджет TPM за один вызов.
- Tokens per day (TPD): дневной потолок общей пропускной способности по токенам. Даже если вы остаётесь в пределах RPM и TPM, при достаточно долгой нагрузке можно исчерпать и его.
У каждой модели свои лимиты. У Haiku самые щедрые: она дешевле всего в обслуживании. У Opus самые строгие: каждый запрос потребляет значительные вычислительные ресурсы. Sonnet находится посередине. Это не баг: так Anthropic сигнализирует, какую модель стоит использовать для высоконагруженных задач.
Rate limits применяются на API-ключ и на модель. Если один ключ шлёт 4000 RPM к Sonnet, а другой шлёт 4000 RPM к Haiku, это независимые корзины. Но два сервиса на одном ключе и одной модели конкурируют за одну и ту же корзину.
Заголовки, которые важны
Каждый ответ Claude API содержит заголовки rate limits:
anthropic-ratelimit-requests-limit: 4000
anthropic-ratelimit-requests-remaining: 3842
anthropic-ratelimit-requests-reset: 2026-04-29T12:01:00Z
anthropic-ratelimit-tokens-limit: 400000
anthropic-ratelimit-tokens-remaining: 312000
anthropic-ratelimit-tokens-reset: 2026-04-29T12:01:00Z
Когда вы превышаете лимит, приходит HTTP 429 Too Many Requests с
заголовком retry-after, указывающим, сколько секунд ждать. В теле
ответа будет объект error с type: "rate_limit_error".
Ошибки HTTP 429
Ответ 429 не сбой, а сигнал. API говорит: «Я вас услышал, но
притормозите». Худшее, что можно сделать: немедленно повторить запрос на
полной скорости. Это удержит вас на лимите. Лучшее: уважать заголовок
retry-after и использовать экспоненциальный backoff.
Вот как выглядит ответ 429:
{
"type": "error",
"error": {
"type": "rate_limit_error",
"message": "Number of request tokens has exceeded your per-model limit..."
}
}
Типичные причины 429 в продакшене:
- Всплеск трафика: очередь разом опустошается после деплоя
- Большие промпты: одно окно контекста на 100K токенов съедает весь TPM
- Отсутствие backoff: циклы повторов без задержек создают обратную связь
- Общие ключи: несколько сервисов на одном ключе без координации
Тарифная система Anthropic
Anthropic делит доступ к API на уровни в зависимости от истории использования и расходов. Каждый уровень открывает более высокие rate limits. По состоянию на начало 2026 года тарифы выглядят примерно так:
| Уровень | Месячный расход | Sonnet RPM | Sonnet TPM | Opus RPM | Opus TPM |
|---|---|---|---|---|---|
| Free | $0 | 50 | 40 000 | 5 | 10 000 |
| Build (T1) | $5+ | 1 000 | 80 000 | 100 | 40 000 |
| Build (T2) | $40+ | 2 000 | 160 000 | 200 | 80 000 |
| Scale (T3) | $200+ | 4 000 | 400 000 | 400 | 200 000 |
| Scale (T4) | $1 000+ | 8 000 | 800 000 | 1 000 | 400 000 |
| Enterprise | Индивидуально | Индив. | Индив. | Индив. | Индив. |
Несколько важных моментов:
- Переход с Free на Build даёт колоссальный скачок: 20× по RPM для Sonnet.
- Разрыв между T3 и T4 требует серьёзных расходов, но удваивает всё.
- Enterprise получает индивидуальные лимиты через переговоры с отделом
продаж Anthropic, часто
>80 000RPM на Sonnet. - Лимиты Haiku обычно в 2–4 раза выше Sonnet на каждом уровне.
Проблема холодного старта
Новые API-ключи начинают с нижнего уровня. Если продукту нужны лимиты T3 с первого дня, подтвердите их у провайдера до запуска. Claudexia не гарантирует более высокий уровень или дополнительную ёмкость.
Стратегии обработки rate limits
1. Экспоненциальный backoff с джиттером
Золотой стандарт логики повторов. При каждом 429 ждём экспоненциально растущее время плюс случайный джиттер, чтобы избежать эффекта «громового стада».
Реализация на Python:
import anthropic
import time
import random
def call_with_backoff(
client: anthropic.Anthropic,
max_retries: int = 5,
base_delay: float = 1.0,
**kwargs,
) -> anthropic.types.Message:
for attempt in range(max_retries):
try:
return client.messages.create(**kwargs)
except anthropic.RateLimitError as e:
if attempt == max_retries - 1:
raise
# Уважаем заголовок retry-after, если он есть
retry_after = getattr(e, "response", None)
if retry_after and retry_after.headers.get("retry-after"):
delay = float(retry_after.headers["retry-after"])
else:
delay = base_delay * (2 ** attempt)
# Джиттер: 0–50% от задержки
jitter = delay * random.uniform(0, 0.5)
time.sleep(delay + jitter)
raise RuntimeError("Unreachable")
Реализация на TypeScript:
import Anthropic from "@anthropic-ai/sdk";
async function callWithBackoff(
client: Anthropic,
params: Anthropic.MessageCreateParams,
maxRetries = 5,
baseDelay = 1000,
): Promise<Anthropic.Message> {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
return await client.messages.create(params);
} catch (err) {
if (
err instanceof Anthropic.RateLimitError &&
attempt < maxRetries - 1
) {
const retryAfter = err.headers?.["retry-after"];
const delay = retryAfter
? parseFloat(retryAfter) * 1000
: baseDelay * 2 ** attempt;
const jitter = delay * Math.random() * 0.5;
await new Promise((r) => setTimeout(r, delay + jitter));
continue;
}
throw err;
}
}
throw new Error("Unreachable");
}
2. Очередь запросов
Вместо того чтобы отправлять запросы с максимальной скоростью, помещаем их в очередь и обрабатываем с контролируемой скоростью. Это особенно важно при пиковом трафике: пользователь загружает 50 документов, и каждый нужно обработать.
import asyncio
from collections import deque
class RateLimitedQueue:
def __init__(self, rpm: int = 1000):
self.interval = 60.0 / rpm
self.queue: deque = deque()
self.semaphore = asyncio.Semaphore(rpm // 10) # потолок конкурентности
async def submit(self, coro):
await self.semaphore.acquire()
try:
result = await coro
await asyncio.sleep(self.interval)
return result
finally:
self.semaphore.release()
3. Пакетная обработка через Batch API
Если ваша нагрузка допускает задержку до 24 часов, Batch API от Anthropic обрабатывает запросы за половину стоимости и с отдельными rate limits. Идеально для задач классификации, извлечения данных, массового реферирования и ночных пайплайнов.
import anthropic
client = anthropic.Anthropic()
batch = client.messages.batches.create(
requests=[
{
"custom_id": f"doc-{i}",
"params": {
"model": "claude-sonnet-5",
"max_tokens": 1024,
"messages": [
{"role": "user", "content": f"Резюмируй: {doc}"}
],
},
}
for i, doc in enumerate(documents)
]
)
# Опрашиваем batch.id для получения результатов, до 24ч
Batch API остаётся одной из самых недоиспользуемых возможностей Claude API. Если хотя бы 30% вашего трафика не критичны по задержке, перенос их в пакеты освобождает RPM и TPM реального времени для запросов, которые действительно важны.
Маршрутизация моделей: главный рычаг
Не каждому запросу нужен Opus. На самом деле большинству запросов не нужен даже Sonnet. Грамотный маршрутизатор моделей может сократить расходы на 60–80% и радикально снизить давление на rate limits, распределяя нагрузку между моделями с разными пулами лимитов.
Принцип прост:
- gpt-5.6-luna: классификация, извлечение, простые вопросы-ответы, валидация, решения по маршрутизации. Быстрая и дешёвая модель для этого класса задач.
- Sonnet: реферирование, генерация кода, многошаговые рассуждения, создание контента. Рабочая лошадка.
- Opus: сложный анализ, работа с длинными документами, агентные циклы, задачи, где точность критична, а стоимость вторична.
Вот продакшен-роутер:
import anthropic
from enum import Enum
class Complexity(Enum):
LOW = "low"
MEDIUM = "medium"
HIGH = "high"
def estimate_complexity(prompt: str, token_count: int) -> Complexity:
"""Маршрутизация по эвристикам. Замените на классификатор для точности."""
# Короткие промпты с чёткими инструкциями → gpt-5.6-luna
if token_count < 2000 and not any(
kw in prompt.lower()
for kw in ["проанализируй", "сравни", "рассуждай пошагово", "architect"]
):
return Complexity.LOW
# Очень длинный контекст или явные требования к рассуждению → Opus
if token_count > 50_000 or "подумай внимательно" in prompt.lower():
return Complexity.HIGH
return Complexity.MEDIUM
MODEL_MAP = {
Complexity.LOW: "gpt-5.6-luna",
Complexity.MEDIUM: "claude-sonnet-5",
Complexity.HIGH: "claude-opus-4.8",
}
def routed_call(client: anthropic.Anthropic, prompt: str, **kwargs):
token_est = len(prompt) // 4 # грубая оценка
complexity = estimate_complexity(prompt, token_est)
model = MODEL_MAP[complexity]
return client.messages.create(
model=model,
messages=[{"role": "user", "content": prompt}],
**kwargs,
)
Версия на TypeScript:
import Anthropic from "@anthropic-ai/sdk";
type Complexity = "low" | "medium" | "high";
function estimateComplexity(prompt: string): Complexity {
const len = prompt.length / 4;
const lower = prompt.toLowerCase();
if (
len < 2000 &&
!["analyze", "compare", "reason step by step"].some((kw) =>
lower.includes(kw),
)
) {
return "low";
}
if (len > 50_000 || lower.includes("think carefully")) {
return "high";
}
return "medium";
}
const MODEL_MAP: Record<Complexity, string> = {
low: "gpt-5.6-luna",
medium: "claude-sonnet-5",
high: "claude-opus-4.8",
};
async function routedCall(
client: Anthropic,
prompt: string,
maxTokens = 4096,
): Promise<Anthropic.Message> {
const complexity = estimateComplexity(prompt);
return client.messages.create({
model: MODEL_MAP[complexity],
max_tokens: maxTokens,
messages: [{ role: "user", content: prompt }],
});
}
Ключевой инсайт: маршрутизация экономит деньги и заодно перераспределяет давление rate limits. Направив 60% трафика на gpt-5.6-luna, вы освобождаете ёмкость Sonnet для запросов, которым она действительно нужна.
Кэширование промптов для снижения потребления токенов
Кэширование промптов: механизм Anthropic для повторного использования одинаковых входных токенов между запросами. Если системный промпт, определения инструментов и few-shot примеры идентичны между вызовами, их можно пометить как кэшируемые и платить за эти токены в 10 раз меньше при последующих запросах.
Влияние на rate limits косвенное, но существенное: кэшированные токены учитываются в TPM с пониженным весом, то есть вы можете уместить больше запросов в то же окно.
import anthropic
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=1024,
system=[
{
"type": "text",
"text": "Вы: агент поддержки клиентов компании Acme Corp...",
"cache_control": {"type": "ephemeral"},
}
],
messages=[{"role": "user", "content": user_query}],
)
# Проверяем эффективность кэша
print(f"Прочитано из кэша: {response.usage.cache_read_input_tokens}")
print(f"Создано в кэше: {response.usage.cache_creation_input_tokens}")
Для системного промпта в 6 000 токенов, вызываемого 10 000 раз в месяц, кэширование снижает эффективный расход входных токенов с 60M по $0.33/M ($19.80) до 60M по $0.05/M ($3). Это сокращение на 90% для кэшированной части.
Использование шлюза с явным выбором канала
Шлюз меняет эндпоинт и аккаунт, через который обращается клиент. Ключ Claudexia выбирает Premium или Cheap, при необходимости разрешая резервный Premium для Cheap по правилам провайдера. API ключей личного кабинета не предоставляет настройки квот для ключа и не гарантирует увеличенный пул запросов. Очереди в клиенте, ограниченные повторы и измерение нагрузки остаются нужны.
Вот что меняется в коде:
import anthropic
# До: напрямую к Anthropic
client = anthropic.Anthropic(api_key="sk-ant-...")
# После: через Claudexia, тот же SDK, другой base URL
client = anthropic.Anthropic(
api_key="your-claudexia-key",
base_url="https://api.claudexia.tech/v1",
)
# Всё остальное идентично
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=1024,
messages=[{"role": "user", "content": "Привет"}],
)
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
apiKey: "your-claudexia-key",
baseURL: "https://api.claudexia.tech/v1",
});
// Совместимый SDK, канал выбран при создании ключа
const response = await client.messages.create({
model: "claude-sonnet-5",
max_tokens: 1024,
messages: [{ role: "user", content: "Привет" }],
});
Перед использованием модели проверьте доступность канала и текущие клиентские цены в каталоге Claudexia. Совместимость шлюза не гарантирует более высокие лимиты или уровень Enterprise у провайдера.
Сравнительная таблица: rate limits у разных провайдеров
| Фактор | Anthropic T1 | Anthropic T3 | Anthropic Enterprise | Claudexia | OpenAI (GPT-4o) | Together.ai |
|---|---|---|---|---|---|---|
| Sonnet/аналог RPM | 1 000 | 4 000 | Индив. | Не доступны в API ключей | 5 000 (GPT-4o) | 600 |
| Sonnet/аналог TPM | 80 000 | 400 000 | Индив. | Не доступны в API ключей | 800 000 | 100 000 |
| Opus/аналог RPM | 100 | 400 | Индив. | Не доступны в API ключей | 500 (o1) | Н/Д |
| Batch API | Да (скидка 50%) | Да (скидка 50%) | Да (скидка 50%) | Не подтверждено | Да (скидка 50%) | Нет |
| Кэширование промптов | Да (экономия 10×) | Да (экономия 10×) | Да (экономия 10×) | Да (проксирование) | Да (частично) | Нет |
| Мульти-ключ пулинг | Вручную | Вручную | Управляемый | Не гарантируется | Вручную | Вручную |
| Время до лимитов T3+ | Недели | Недели | Переговоры | Не гарантируется | Недели | Н/Д |
| Совместимость SDK | Нативная | Нативная | Нативная | Drop-in | Отдельный SDK | OpenAI-совместимый |
Мониторинг и алертинг
Не стоит ждать 429-х, чтобы узнать, что вы приближаетесь к лимитам. Стройте мониторинг вокруг заголовков rate limits:
import anthropic
import logging
logger = logging.getLogger("rate_limits")
def monitored_call(client: anthropic.Anthropic, **kwargs):
response = client.messages.create(**kwargs)
remaining_requests = response._response.headers.get(
"anthropic-ratelimit-requests-remaining"
)
remaining_tokens = response._response.headers.get(
"anthropic-ratelimit-tokens-remaining"
)
if remaining_requests and int(remaining_requests) < 100:
logger.warning(f"RPM на исходе: {remaining_requests} осталось")
if remaining_tokens and int(remaining_tokens) < 50_000:
logger.warning(f"TPM на исходе: {remaining_tokens} осталось")
return response
Настройте алерты при падении оставшейся ёмкости ниже 20% от лимита. Это даст время на троттлинг, перемаршрутизацию или масштабирование до того, как начнутся 429-е.
Собираем всё вместе: продакшен-архитектура
Надёжная продакшен-система комбинирует всё вышеперечисленное:
- Маршрутизатор моделей классифицирует входящие запросы и выбирает gpt-5.6-luna, Sonnet или Opus.
- Очередь запросов обеспечивает максимальную скорость обработки для каждой модели.
- Кэширование промптов снижает потребление токенов для повторяющихся системных промптов.
- Повтор с backoff грациозно обрабатывает транзитные 429-е.
- Шлюз (Claudexia) использует канал ключа; перед нагрузкой проверяйте правила провайдера и доступность модели.
- Мониторинг предупреждает до того, как вы упрётесь в стену, а не после.
- Batch API выгружает несрочную работу в отдельный пул лимитов со скидкой 50%.
Это не overengineering. Каждый продакшен-деплой Claude значимого масштаба рано или поздно упирается в rate limits. Вопрос в том, обработает ли ваша система это прозрачно или разбудит кого-то в 3 часа ночи.
FAQ
Что именно такое rate limit в Claude API?
Rate limit: ограничение на количество запросов (RPM), токенов (TPM) или дневных токенов (TPD), которые ваш API-ключ может потребить в заданном окне. Когда вы превышаете любой из них, API возвращает HTTP 429 до сброса окна.
Как узнать мой текущий тарифный уровень?
Войдите в консоль Anthropic и перейдите к настройкам API-ключа. Ваш
уровень отображается рядом с информацией об использовании. Также можно
проверять заголовки anthropic-ratelimit-* в любом ответе API, чтобы
увидеть текущие лимиты и оставшуюся ёмкость.
Можно ли запросить увеличение rate limits у Anthropic?
Да. Для уровней Build и Scale лимиты растут автоматически с увеличением месячных расходов. Для индивидуальных лимитов сверх T4 нужно связаться с отделом продаж Anthropic и заключить Enterprise-соглашение. Обычно это требует минимального годового обязательства.
В чём разница между RPM и TPM?
RPM (requests per minute) ограничивает количество API-вызовов независимо от размера. TPM (tokens per minute) ограничивает общую пропускную способность по токенам. Можно упереться в TPM одним огромным промптом, даже если RPM в норме. Оба потолка должны соблюдаться одновременно.
У Batch API отдельные rate limits?
Да. Пакетные запросы обрабатываются асинхронно с собственным пулом лимитов и стоят на 50% дешевле. Идеально для любой нагрузки, которая допускает задержку до 24 часов: пайплайны классификации, ночная генерация отчётов, массовое извлечение данных.
Как кэширование промптов помогает с rate limits?
Кэшированные токены обрабатываются быстрее и учитываются в TPM с пониженным весом. Системный промпт в 6 000 токенов, попавший в кэш, означает, что API обрабатывает только динамическую часть каждого запроса, фактически увеличивая пропускную способность в рамках того же окна TPM.
Нарушает ли использование шлюза вроде Claudexia условия Anthropic?
Проверяйте условия, которые относятся к вашему аккаунту и договору провайдера. Настройки ключа Claudexia не подтверждают дополнительные квоты или пропускную способность; совместимость шлюза этого не гарантирует.
Как быстрее всего перестать получать ошибки 429?
Сначала проверьте ошибку и указания провайдера о повторах, если они есть. Используйте ограниченную очередь в клиенте и экспоненциальный backoff с джиттером для временных сбоев. Смена шлюза не гарантирует более высокие лимиты.
Rate limits: факт жизни с любым управляемым API, и Claude не исключение. Но это решаемая проблема. Хорошо с ней справляются команды, которые планируют заранее, а не реагируют после первого инцидента. Claudexia предоставляет совместимые эндпоинты и выбор канала. Проверяйте текущие клиентские цены и правила провайдера; дополнительные квоты или объединённая ёмкость не гарантируются.