Ошибки Moonshot API нельзя оценивать только по коду состояния. Один и тот же 429 может означать перегрузку кластера, ограничение аккаунта или нехватку средств; один и тот же 401 — неверный ключ или смешивание китайского и международного сайтов. В 2026 году перенос точки входа платформы и вывод старых моделей добавили заметное число 404.

Ниже разобраны пять классов проблем — 401, 404, 429, переполнение контекста и тайм-ауты — в порядке «сначала локализовать, потом классифицировать, затем исправлять». Приведены готовый код повторов и чек-лист для обращения в поддержку. Модели и цены — на странице цены на модели.

Примечание: Moonshot и Kimi — товарные знаки соответствующих правообладателей. Типы ошибок, уровни лимитов и даты вывода моделей могут меняться; примеры отражают распространённую ситуацию на октябрь 2026 года, окончательно действует официальная документация.

1. Сначала зафиксируйте три поля

При диагностике соберите три вещи: HTTP-код состояния, error.type и идентификатор запроса. Ответы об ошибках Moonshot обычно содержат error.message и error.type; конкретные поля зависят от текущего ответа интерфейса. Идентификатор запроса может находиться в теле ошибки, заголовках ответа или журналах консоли — в разных версиях по-разному, не предполагайте единственный источник.

В журнал записывайте как минимум: время с часовым поясом, код состояния, error.type, имя модели, сайт, к которому относится Base URL, признак потокового запроса, версию SDK, число повторов, usage и идентификатор запроса. Не записывайте полный ключ и промпты с чувствительными данными.

Только с этими тремя полями можно понять, в чём проблема — в конфигурации, аккаунте или на стороне сервиса. Ниже разбор по классам.

2. 401: сначала сайт, потом ключ

У Moonshot есть китайский и международный сайты: китайский вход — platform.kimi.com, интерфейс https://api.moonshot.cn/v1; международный — platform.kimi.ai, интерфейс https://api.moonshot.ai/v1. Аккаунты, балансы и ключи двух сайтов полностью независимы. Ключ китайского сайта на адресе международного вернёт 401 invalid_authentication_error.

Порядок проверки:

  1. Относится ли ключ к тому сайту, которому соответствует текущий Base URL, а не к другому сайту или аккаунту.
  2. Не смешаны ли ключ открытой платформы и ключ другой продуктовой линейки, например Kimi Code: они не взаимозаменяемы.
  3. Используется ли заголовок Authorization: Bearer <key> и нет ли вокруг значения пробелов, переводов строки или кавычек.
  4. Действительно ли загружена переменная окружения — можно вывести только первые символы ключа.
  5. Не удалён ли ключ, не выполнена ли его ротация, не отозваны ли права проекта.
  6. Не остались ли локально старый прокси, старые переменные или настройки маршрутизации, перекрывающие текущий запрос.

По типам ошибок: invalid_authentication_error чаще указывает на формат ключа или несовпадение сайта, incorrect_api_key_error — на отсутствующий или неверный ключ. В обоих случаях сначала исправляйте учётные данные и не спешите повторять запрос.

3. 404: чаще всего модель выведена, а не исчез интерфейс

Самый незаметный источник 404 в 2026 году — жизненный цикл моделей. В официальном списке моделей есть такие записи о выводе:

  • Вся серия moonshot-v1, включая moonshot-v1-8k, -32k, -128k, -auto и визуальную preview-версию, отключена 31 августа 2026 года; рекомендуется миграция на kimi-k3.
  • Серия kimi-k2, включая kimi-k2-0905-preview, kimi-k2-0711-preview, kimi-k2-turbo-preview и версию с рассуждением, отключена 25 мая 2026 года.
  • kimi-latest отключена 28 января 2026 года, kimi-thinking-preview — 11 ноября 2025 года.

Другие частые причины 404:

  • В OpenAI SDK не задан base_url, запрос ушёл на адрес OpenAI по умолчанию и вернул «модель не найдена».
  • Опечатка в имени модели или у аккаунта нет доступа к этой модели.
  • В пути лишний или недостающий /v1, либо клиент склеил Base URL с полным путём.
  • На китайском и международном сайтах доступны разные имена моделей.

Запросите список моделей тем же ключом и проверьте, что аккаунт реально видит:

curl "https://api.moonshot.cn/v1/models" \
  -H "Authorization: Bearer $MOONSHOT_API_KEY"

Не угадывайте модели, которых нет в списке. Если список возвращается, а чат-интерфейс всё равно даёт 404, проверяйте склейку пути и настройки клиента.

4. 429: три типа, и обработка у них разная

429 — самый частый источник ошибочных выводов. Сначала смотрите на error.type:

error.type Значение Можно ли повторять Что делать
engine_overloaded_error Перегрузка кластера, нехватка ёмкости Да Выдержка по Retry-After, снижение параллелизма
rate_limit_reached_error Превышены параллелизм, RPM, TPM или TPD организации Частично Снизить скорость, подождать, повысить уровень аккаунта
exceeded_current_quota_error Задолженность, недостаток средств, истёк ваучер Нет Проверить баланс и пополнить

Уровни лимитов Moonshot делятся от Tier0 до Tier5 по суммарному пополнению аккаунта; бонусные ваучеры обычно не входят в накопленную сумму. Уровень одновременно ограничивает число параллельных запросов, запросы в минуту, токены в минуту и токены в сутки: на низком уровне параллелизм может быть однозначным, на высоком — достигать сотен; RPM — от единиц до сотен, TPM — от сотен тысяч до миллионов. У Tier0 есть суточный лимит токенов, после которого обычно нужно ждать сброса на следующий день.

Несколько типичных ловушек:

  • OpenAI SDK по умолчанию автоматически повторяет 408, 409, 429 и 5xx, всего до трёх раз. На низком уровне одна неудача может превратиться в несколько запросов и быстро исчерпать RPM. В продакшене задавайте max_retries явно.
  • У инструментов вроде веб-поиска отдельный лимит QPS, он считается отдельно от RPM и TPM чат-интерфейса; превышение тоже возвращает 429.
  • Запросы, прерванные 429, обычно не тарифицируются, но успешный повтор тарифицируется как обычный запрос. Не повторяйте бесконечно только потому, что отказ бесплатный.
  • Если лимиты и уровень не сходятся, сначала проверьте, не используется ли ключ другого аккаунта.

5. 400: переполнение контекста и ошибки параметров

Переполнение контекста обычно возвращает 400 invalid_request_error, а сообщение указывает на превышение входных токенов. Важно считать не только вход, а сумму «вход + верхняя граница выхода» относительно окна модели.

Частые причины:

  • История сообщений растёт без ограничений, многораундовый диалог никогда не обрезается.
  • Весь документ помещают в контекст 1M и одновременно задают большой лимит выхода.
  • Через файловый интерфейс загружают файл больше 100MB, пустой файл или указывают purpose вне допустимого списка.
  • Выход попадает под content_filter; такой фильтр может срабатывать и на выходе модели, а не только проверять вход.

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

Кроме того, finish_reason=length — не ошибка, а достижение лимита выхода. Если нужен более длинный результат, запрашивайте его частями или используйте продолжение генерации; не поднимайте лимит выше разрешённого моделью.

6. Тайм-ауты, 499 и потоковая передача

У шлюза Moonshot есть предельное время ожидания для непоточных запросов; в официальной документации упоминается, что 504 может появиться через 900 секунд. Чаще всего это встречается при генерации длинных текстов, анализе больших документов и в кодовых агентах.

Порядок обработки:

  1. Переведите непоточный запрос в потоковый, задайте stream=True, чтобы соединение постоянно получало данные.
  2. Тайм-аут соединения задавайте коротким, тайм-аут чтения — по максимальному времени генерации, не оставляйте значения SDK по умолчанию.
  3. Проверьте, не обрывают ли соединение корпоративный прокси, шлюз или локальный инструмент маршрутизации; такой обрыв может выглядеть как 499 client_closed_request.
  4. Ограничивайте длину одной генерации верхней границей выхода, длинные задачи делите на части.
  5. В потоковом режиме следите за задержкой первого токена: резкий рост TTFT обычно означает перегрузку вышестоящего провайдера или удлинение промпта.
  6. Записывайте идентификатор запроса и длительность каждого тайм-аута, чтобы отличить медленную модель, медленную сеть и медленный прокси.

Потоковая передача не снижает цену за токен, но сокращает повторные затраты на «дождаться тайм-аута и повторить». Не используйте для тайм-аута чтения короткое значение от непоточного режима, иначе клиент оборвёт соединение во время нормальной генерации.

7. Как писать повторы и выдержку

Повторы подходят только для временных ошибок. 401, 403, 404, ошибки безопасности контента и нехватку баланса повторять автоматически нельзя; 429 сначала классифицируйте; 5xx можно повторять с выдержкой. Если операция уже дала побочный эффект, сначала проверьте по идемпотентному ключу или статусу, выполнялась ли она.

import random
import time
from openai import OpenAI, APIStatusError, RateLimitError

client = OpenAI(
    api_key="ваш-ключ",
    base_url="https://api.moonshot.cn/v1",
    max_retries=0,  # отключаем автоматические повторы SDK
)

RETRYABLE_TYPES = {"engine_overloaded_error", "server_error",
                   "server_unavailable", "client_closed_request"}

def ask(prompt: str, retries: int = 4) -> str:
    for attempt in range(retries):
        try:
            resp = client.chat.completions.create(
                model="kimi-k3",
                messages=[{"role": "user", "content": prompt}],
                max_completion_tokens=1024,
            )
            return resp.choices[0].message.content
        except RateLimitError as exc:
            body = exc.body or {}
            etype = (body.get("error") or {}).get("type", "")
            if etype == "exceeded_current_quota_error":
                raise RuntimeError("Недостаточно средств или квоты, пополните баланс")
            if etype == "rate_limit_reached_error":
                raise RuntimeError("Лимит аккаунта, снизьте параллелизм или повысьте уровень")
            wait = min(2 ** attempt, 20) + random.random()
            print(etype or "overloaded", "ждём", round(wait, 1), "с")
            time.sleep(wait)
        except APIStatusError as exc:
            if exc.status_code in (401, 403, 404):
                raise
            if exc.status_code >= 500:
                time.sleep(min(2 ** attempt, 20) + random.random())
            else:
                raise
    raise RuntimeError("Попытки исчерпаны")

print(ask("Объясни границы применимости повторов"))

Если есть заголовок Retry-After, сначала ждите по нему, затем добавьте случайный разброс, чтобы несколько экземпляров не создали вторичную перегрузку. Число повторов должно быть ограничено, а окончательная неудача — попадать в оповещение.

8. Что подготовить перед обращением в поддержку

  1. Время события с часовым поясом и годом, с точностью до секунды.
  2. Идентификатор запроса, поля ответа id и usage.
  3. Имя модели, Base URL, сайт (китайский или международный), признак потокового запроса.
  4. HTTP-код, error.type и полный текст ошибки.
  5. Версии SDK и клиента, настройки повторов, наличие прокси или шлюза.
  6. Минимальный воспроизводимый запрос — достаточно одной команды curl.
  7. Записи о счёте или расходе, чтобы проверить возможное двойное списание.
  8. Обезличенные журналы без ключей, пользовательских данных и чувствительных промптов.

Сначала воспроизведите проблему прямым curl, затем отправляйте результаты прямого подключения и шлюза отдельно — это заметно сокращает время диагностики.

Частые вопросы

Повторный запрос после 429 списывает деньги дважды?

Запросы, отклонённые с 429, обычно не тарифицируются; успешный повтор тарифицируется как обычный запрос. Реальная опасность — автоматические повторы SDK, которые превращают один бизнес-запрос в несколько и одновременно увеличивают число запросов и расход.

Модель работала вчера, а сегодня возвращает 404. Почему?

Проверьте официальный список выведенных моделей. Серия moonshot-v1 отключена 31 августа 2026 года, серия kimi-k2 и kimi-latest также сняты с поддержки; по официальной рекомендации переходите на kimi-k3.

429 сообщает о нехватке средств — нужна ли выдержка и повтор?

Нет. exceeded_current_quota_error относится к балансу или квоте аккаунта; повтор не восстановит средства. Сначала проверьте баланс, статус задолженности и срок действия ваучера.

Потоковый режим уже включён, почему всё равно тайм-аут?

Потоковый режим сокращает ожидание первого пакета, но не обещает, что соединение не оборвётся. Проверьте idle timeout прокси, тайм-аут чтения, лимит выхода и стабильность сети; возможно, вышестоящий провайдер долго не присылает новый токен, и промежуточное устройство закрывает соединение.

Прямое подключение работает, через шлюз — ошибка. Кто виноват?

Отправьте один и тот же запрос с одним ключом и одной моделью напрямую и через шлюз, сравните код состояния, error.type, идентификатор запроса и длительность. Если напрямую успешно, а через шлюз нет, проверяйте путь, аутентификацию, тайм-ауты и повторы шлюза.

Что дальше

Создайте тестовый ключ в ZSQH AI Gateway, по одному разу отработайте 401, 404, 429 и тайм-аут, затем подключайте продакшен-мониторинг. Доступные модели и тарификация — на странице цены на модели.

Связанные материалы: