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). Если функции нужна одна модель, разрешите ей только её: тогда даже украденный ключ не позволит запускать дорогие модели. Отказ придёт как 403model_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. Выберите запасную заранее, по цене и контексту не хуже основной, и проверьте на своих данных, что она вообще справляется с задачей.
Код с таймаутом, повтором и запасной моделью:
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. Именно поэтому нужны алерты на расход: небольшая цена вызова на масштабе становится заметной суммой.
Что настроить:
- Алерт в вашей системе мониторинга при достижении 50% и 80% месячного лимита ключа.
- Алерт на баланс: ошибка 402 в продакшене означает отказ функции.
- Сверка своих метрик с разделом «Использование» в кабинете и с историей расходов через API (
GET /v1/usage).
6. Проверка качества
Перед релизом и перед каждой сменой модели или промпта нужен набор проверочных случаев. Минимум: 30–100 реальных примеров с ожидаемым результатом и скрипт, который прогоняет их через систему и сравнивает ответы. Для структурированных ответов проверяйте автоматически (валидный JSON, нужные поля, значения из допустимого списка), для свободных текстов — выборочно глазами или по явному критерию. Простой каркас показан в статье про тестирование промптов.
Смена версии модели — отдельное событие. Даже если имя то же, поведение может отличаться: прогоняйте набор при каждом переключении. Список доступных моделей и их цены читайте динамически, через GET /v1/models, а не держите в коде навсегда.
7. Защита от злоупотреблений и аварийный выключатель
- Ограничение на пользователя на вашей стороне: число запросов в минуту и в день. Свой rate limit стоит ввести самому, шлюз общего ограничения не накладывает.
- Фильтр входа: длина запроса, формат. Огромный вход от одного пользователя не должен стоить вам денег.
- Prompt injection. Данные пользователя и документы могут содержать инструкции для модели. Не давайте модели прав, которых нет у пользователя; инструменты, меняющие данные, требуют проверки и подтверждения.
- Флаг отключения. Возможность выключить функцию без выкладки, чтобы остановить расход и ошибки за минуту.
Итоговый чек-лист
- Отдельный ключ, дневной и месячный лимит,
allowed_models. - Таймаут и политика повторов по кодам ошибок.
- Запасная модель проверена на ваших данных.
- Логи без персональных данных, срок хранения задан.
- Учёт токенов и денег, алерты на лимит и баланс.
- Набор проверочных случаев и прогон при каждой смене модели или промпта.
- Лимиты на пользователя и аварийный выключатель.
Начните с первого пункта: создайте ключ с лимитом в кабинете. Баланс пополняется по СБП, картой MasterCard или криптой.
Частые вопросы
Нужно ли самому ограничивать частоту запросов?
Да. У Zukko нет общего rate limit, ограничения бывают у провайдера модели и на уровне ключа (дневной и месячный лимит в долларах). Ограничение на пользователя вашего приложения ставьте у себя.
Что делать при ошибке 429?
Сначала определите причину по коду в теле ответа. Если исчерпан лимит ключа, повторять нельзя: поднимите лимит или дождитесь следующего периода. Если ограничение у провайдера модели, повторите с растущей паузой или переключитесь на запасную модель.
Какую запасную модель выбирать?
Модель с похожим контекстом и ценой, лучше из другого семейства, чтобы сбой одного провайдера её не затронул. Обязательно прогоните на своих проверочных случаях: заменой «по имени» не обойтись.
Можно ли логировать запросы целиком?
Только если без этого нельзя отлаживаться, с маскированием персональных данных и коротким сроком хранения. Для повседневного мониторинга достаточно метаданных: модель, токены, время, код ответа.
zukko
Платите в 25×
меньше
за Claude Code & ChatGPT
Один ключ fetch_* и base URL api.zukko.pro — в Cursor, Claude Code, Codex и любом SDK.
Похожие статьи
- Свой прокси к нейросети на Node.js: не показывать API-ключ во фронтендеНебольшой сервер на Express между вашим фронтендом и API нейросети: ключ остаётся на сервере, а модели, длина запроса и частота ограничены.
- DeepSeek API на Python: запросы, стриминг, JSON и обработка ошибокГотовый код для DeepSeek V4.1 Flash и V4 Pro на OpenAI SDK: запрос, стриминг, разбор JSON и аккуратная обработка ошибок.
- Gemini API на Python: запросы через OpenAI SDK и OpenAI-форматРабочий пример Gemini API на Python без отдельной библиотеки: меняем base_url в OpenAI SDK, добавляем стриминг и JSON и сравниваем с google-genai.
- Anthropic SDK для Python: base_url, ключ и первый запрос через шлюзОфициальный пакет anthropic для Python нужно только направить на другой адрес. Разбираем base_url, ключ, стриминг, подсчёт токенов, кэш и ошибки.