LLM в проде — это не чат с игрушкой
Вы когда-нибудь отправляли запрос в GPT-4o (май 2026), получали JSON с лишней запятой, а потом полчаса искали баг в парсинге? Я — да. И знаете, что хуже всего? LLM не обязана следовать формату. Она может выдать "Извините, я не могу ответить на этот вопрос" вместо твоего precious JSON. В production такое — фатально.
Проблема не в модели — проблема в том, что мы доверяем ей напрямую. Контрольный слой (control layer) — это прослойка между пользователем и LLM, которая отсекает мусор, управляет ресурсами и гарантирует, что на выходе — валидные данные. Без него ваш сервис — рулетка.
Я собрал 8 компонентов, которые превращают LLM из капризного гения в предсказуемый production-сервис. Под катом — код, тесты и бенчмарк, где pass rate взлетел с 0% до 100%. По пути я буду ругать некоторые решения и объяснять, почему они бесят. Поехали.
Архитектура слоя: зачем 8 компонентов?
Control layer — это не один класс, а система фильтров. Представьте конвейер: на входе — сырой запрос пользователя, на выходе — структурированный ответ. Каждый компонент отвечает за свою зону:
- InputGuard — санитизация входа и защита от инъекций.
- PromptGuard — проверка, что промпт соответствует политикам.
- TokenBudget — учет и лимитирование токенов.
- OutputValidator — валидация структуры ответа (JSON, enum и т.д.).
- RetryHandler — повторные попытки с умной стратегией.
- CircuitBreaker — автоматическое отключение при лавине ошибок.
- ContextManager — управление историей диалога (чтобы контекст не раздувался).
- MetricsCollector — сбор метрик для мониторинга.
Каждый из них — это отдельный блок, который можно включать/выключать. Все вместе они дают прозрачность и контроль. А теперь — к делу.
Предупреждение: Код ниже — не игрушка. Это production-ready решения, которые я использую в реальных проектах. Но не копируйте вслепую — адаптируйте под свои модели и лимиты.
1 InputGuard: чистим вход, пока не поздно
Первое, что делает control layer — отсекает мусор. Пользователь может отправить что угодно: бинарные данные, SQL-инъекции, промпты с escape-последовательностями. InputGuard проверяет длину, кодировку и наличие подозрительных паттернов.
import re
from typing import Optional
class InputGuard:
MAX_LENGTH = 8192
BLOCKED_PATTERNS = [
r"