LLM в продакшене: чек-лист перед запуском функции на нейросети

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

6 мин · · API-ключи · разработка

LLM в продакшене ломается не там, где ломалась в прототипе. В прототипе вопрос «умеет ли модель это делать». В продакшене: что будет, когда провайдер ответит 503, когда ключ упрётся в лимит ночью, когда в логи утекут телефоны клиентов, когда модель сменят и качество поплывёт. Ниже чек-лист из семи блоков с кодом, который можно взять за основу. Он написан для любого проекта на OpenAI-совместимом API; примеры на Python с адресом https://api.zukko.pro/v1.

1. Ключи и лимиты

  • Отдельный ключ на каждое окружение и сервис. Разработка, стейджинг и продакшен не должны делить ключ: утечка и расход тогда не смешиваются. Создаются ключи в кабинете, полный ключ показывается один раз при создании.
  • Дневной и месячный лимит в долларах на каждый ключ. Это последний рубеж против зацикленного кода: когда лимит исчерпан, ключ получает 429 (key_daily_limit_reached или key_monthly_limit_reached), и больше не тратится ни цента. Подробности в документации по лимитам ключей.
  • Список разрешённых моделей (allowed_models). Если функции нужна одна модель, разрешите ей только её: тогда даже украденный ключ не позволит запускать дорогие модели. Отказ придёт как 403 model_not_allowed_for_key.
  • Ключ в секретах, не в коде. Переменные окружения или менеджер секретов; ключ передаётся заголовком Authorization: Bearer fetch_.... Заранее решите, кто и как перевыпускает ключ при утечке: новый ключ создаётся в кабинете, старый отзывается.

2. Таймауты и повторы

Запрос к модели — это сетевой вызов, который может занять секунды или десятки секунд. Без таймаута зависший вызов держит поток и, как следствие, пользователя.

Разные ошибки требуют разной реакции:

КодЧто значитЧто делать
401, 403неверный ключ, модель не разрешена ключуне повторять; ошибка конфигурации, поднять алерт
402не хватает балансане повторять; алерт, пополнение
404неизвестное имя моделине повторять; исправить конфиг
413запрос слишком большойсократить вход
429лимит ключа или ограничение у провайдера моделилимит ключа: не повторять; у провайдера: повтор с паузой
503провайдер недоступен или модель выключенаповтор, затем запасная модель

Важно: у Zukko нет своего общего ограничения частоты запросов, поэтому 429 означает либо лимит вашего ключа, либо ограничение у провайдера модели. Определяйте причину по коду в теле ошибки. Повторять при исчерпанном лимите ключа бессмысленно: до начала нового дня или месяца ничего не изменится.

3. Запасная модель

Модели бывают выключены или недоступны у провайдера. В Zukko это 503 с кодом model_disabled; запрос нужно перенаправить на другую модель из GET /v1/models. Выберите запасную заранее, по цене и контексту не хуже основной, и проверьте на своих данных, что она вообще справляется с задачей.

Код с таймаутом, повтором и запасной моделью:

bash
import os, time, logging
import openai
from openai import OpenAI

log = logging.getLogger("llm")
client = OpenAI(
    base_url="https://api.zukko.pro/v1",
    api_key=os.environ["ZUKKO_API_KEY"],
    timeout=30.0,
    max_retries=0,          # повторы делаем сами, чтобы управлять ими
)

MODELS = ["claude-sonnet-5-5", "gpt-6.1-sol"]   # основная, запасная
KEY_LIMIT_CODES = ("key_daily_limit_reached", "key_monthly_limit_reached")

Код нужно подгонять под вашу архитектуру, главное в нём логика: что повторять, что нет и когда переходить на запасную модель. Шире эта тема раскрыта в статье про retry и запасную модель. Если запросы повторяются, подумайте и о защите от двойной обработки одного и того же события в вашей системе.

4. Логи без персональных данных

Журнал запросов к модели нужен для отладки, но в нём легко накопить чужие телефоны, адреса и содержимое переписок. Правила:

  • В обычные логи пишите метаданные: модель, число токенов входа и выхода, время ответа, код результата, идентификатор запроса в вашей системе.
  • Тексты запросов и ответов сохраняйте только если они нужны для отладки, с маскированием телефонов, e-mail, номеров документов и коротким сроком хранения.
  • Не передавайте модели лишних персональных данных. Если для задачи нужно имя клиента, а номер паспорта нет, не отправляйте номер.
  • Проверьте требования законодательства о персональных данных и политику компании до запуска.

Разбор приёмов с кодом: логирование LLM-запросов без утечки данных.

5. Учёт расходов

Ответ содержит usage, по нему можно считать стоимость каждого вызова и складывать в метрики по функциям и клиентам. Для расчёта используйте формулу: свежий вход × цена входа + чтение кэша × цена чтения + запись кэша × цена записи + выход × цена выхода. Для GPT-моделей отдельной записи кэша нет, для Claude скидку за кэш видно только в Anthropic-формате. Пример с цифрами по ценам на 18 октября 2026: один вызов claude-sonnet-5-5 на 4 000 токенов входа и 600 выхода стоит 4 000 × $0,4 / 1M + 600 × $2 / 1M = $0,0016 + $0,0012 = $0,0028, а миллион таких вызовов в месяц — $2 800. Именно поэтому нужны алерты на расход: небольшая цена вызова на масштабе становится заметной суммой.

Что настроить:

  1. Алерт в вашей системе мониторинга при достижении 50% и 80% месячного лимита ключа.
  2. Алерт на баланс: ошибка 402 в продакшене означает отказ функции.
  3. Сверка своих метрик с разделом «Использование» в кабинете и с историей расходов через API (GET /v1/usage).

6. Проверка качества

Перед релизом и перед каждой сменой модели или промпта нужен набор проверочных случаев. Минимум: 30–100 реальных примеров с ожидаемым результатом и скрипт, который прогоняет их через систему и сравнивает ответы. Для структурированных ответов проверяйте автоматически (валидный JSON, нужные поля, значения из допустимого списка), для свободных текстов — выборочно глазами или по явному критерию. Простой каркас показан в статье про тестирование промптов.

Смена версии модели — отдельное событие. Даже если имя то же, поведение может отличаться: прогоняйте набор при каждом переключении. Список доступных моделей и их цены читайте динамически, через GET /v1/models, а не держите в коде навсегда.

7. Защита от злоупотреблений и аварийный выключатель

  • Ограничение на пользователя на вашей стороне: число запросов в минуту и в день. Свой rate limit стоит ввести самому, шлюз общего ограничения не накладывает.
  • Фильтр входа: длина запроса, формат. Огромный вход от одного пользователя не должен стоить вам денег.
  • Prompt injection. Данные пользователя и документы могут содержать инструкции для модели. Не давайте модели прав, которых нет у пользователя; инструменты, меняющие данные, требуют проверки и подтверждения.
  • Флаг отключения. Возможность выключить функцию без выкладки, чтобы остановить расход и ошибки за минуту.

Итоговый чек-лист

  1. Отдельный ключ, дневной и месячный лимит, allowed_models.
  2. Таймаут и политика повторов по кодам ошибок.
  3. Запасная модель проверена на ваших данных.
  4. Логи без персональных данных, срок хранения задан.
  5. Учёт токенов и денег, алерты на лимит и баланс.
  6. Набор проверочных случаев и прогон при каждой смене модели или промпта.
  7. Лимиты на пользователя и аварийный выключатель.

Начните с первого пункта: создайте ключ с лимитом в кабинете. Баланс пополняется по СБП, картой MasterCard или криптой.

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

Нужно ли самому ограничивать частоту запросов?

Да. У Zukko нет общего rate limit, ограничения бывают у провайдера модели и на уровне ключа (дневной и месячный лимит в долларах). Ограничение на пользователя вашего приложения ставьте у себя.

Что делать при ошибке 429?

Сначала определите причину по коду в теле ответа. Если исчерпан лимит ключа, повторять нельзя: поднимите лимит или дождитесь следующего периода. Если ограничение у провайдера модели, повторите с растущей паузой или переключитесь на запасную модель.

Какую запасную модель выбирать?

Модель с похожим контекстом и ценой, лучше из другого семейства, чтобы сбой одного провайдера её не затронул. Обязательно прогоните на своих проверочных случаях: заменой «по имени» не обойтись.

Можно ли логировать запросы целиком?

Только если без этого нельзя отлаживаться, с маскированием персональных данных и коротким сроком хранения. Для повседневного мониторинга достаточно метаданных: модель, токены, время, код ответа.

zukko

Платите в 25×
меньше

за Claude Code & ChatGPT

Один ключ fetch_* и base URL api.zukko.pro — в Cursor, Claude Code, Codex и любом SDK.