Перейти к содержимому
AI-агенты

Что нужно ИИ-агенту для продакшена: шесть слоёв и чек-лист

Коротко

Что это меняет

Провал агента почти никогда не про качество модели — он про отсутствующие слои вокруг неё. Проверка прав, лимит итераций и correlation ID решают судьбу проекта сильнее, чем выбор LLM.

Что сделать

Пройти чек-лист из 13 вопросов по своему агенту и честно посчитать «да». Меньше восьми — возвращайтесь к инфраструктуре, промпты не помогут.

Что нужно ИИ-агенту для продакшена: шесть слоёв и чек-лист

Разница между демо и ИИ-агентом в продакшене — не в модели. Модель одна и та же. Демо пишется за вечер: подключил API, объявил три инструмента, вызвал agent.run(), посмотрел, как оно красиво работает. Продакшен от этого отличается количеством скучного кода вокруг модели, и этого кода примерно вчетверо больше, чем самого агента.

IDC в исследовании для Lenovo посчитала конверсию: из 33 запущенных ИИ-пилотов до широкого развёртывания доходят четыре. Остальные 88% умирают между демо и релизом. Оговорка важная — считали пилоты вообще, не агентов отдельно, так что растиражированное «88% агентов не доходят до продакшена» строго говоря неточно. Но порядок величины показательный, и причины IDC называет прямо: незрелость данных, процессов и инфраструктуры. Не «модель недостаточно умная».

Ниже — шесть слоёв, из которых собирается работающий агент, и что конкретно ломается, если слой пропустить.

Откуда взялась разбивка на слои

Честная оговорка: единой утверждённой схемы «шесть слоёв продакшен-агента» не публиковала ни Anthropic, ни Microsoft, ни OpenAI. Это обобщение, которое сложилось у практиков. Но части его подтверждаются независимо.

Anthropic в разборе «Building effective agents» описывает агента предельно скупо: это LLM, которая в цикле вызывает инструменты, опираясь на обратную связь от среды. И тут же добавляет, что автономность означает более высокую стоимость и накопление ошибок, поэтому нужны условия остановки — например, максимальное число итераций — плюс тестирование в песочнице и guardrails.

С другой стороны заходит OWASP: в проекте GenAI Security вышел Top 10 for Agentic Applications 2026, собранный при участии более сотни исследователей и практиков. Отдельный список рисков именно для агентных систем существует не потому, что кому-то захотелось нового документа, а потому что агент, получивший инструменты, ломается иначе, чем чат-бот.

Слой 1. Модель: клиент должен вырываться без боли

Задача слоя — общаться с API, ретраить сбои, парсить ответ. Всё. Никакой бизнес-логики.

Критерий здоровья здесь один: сможете ли вы поменять модель, тронув одну строку. Сегодня у вас Claude, через месяц дообученная open-source модель на своём железе, ещё через месяц роутинг дешёвых запросов на маленькую модель, а сложных — на большую. Anthropic, кстати, приводит такой роутинг как штатный паттерн, а не как экзотику.

Технически это решается контрактом. В Python — Protocol, структурная типизация: любой класс с нужными методами подходит, наследоваться не надо.

class LLMClient(Protocol):
    async def chat(self, messages: list[dict], max_tokens: int = 1024) -> str: ...

Что ломается без этого: привязка к вендору, тихие поломки при изменении API и невозможность прогнать тесты, не заплатив за запросы. Про последнее у нас есть отдельный разбор о тестах агента без API-ключей — там этот же протокол делает всю работу.

Слой 2. Оркестрация: у цикла нет естественного конца

Без оркестрации у вас чат-бот: запрос, ответ, конец. Агентным его делает цикл — подумать, вызвать инструмент, посмотреть на результат, решить, всё ли готово. Паттерн ReAct, reason plus act, стал здесь стандартом просто потому, что он самый простой из работающих.

Проблема цикла в том, что он не знает, когда остановиться. Агент, который не смог получить внятный ответ от инструмента, будет вызывать его снова. И снова. Пятьдесят раз, пока кто-нибудь не посмотрит на счёт за API.

Поэтому жёсткий лимит итераций — не оптимизация, а условие запуска. Пять-семь шагов на задачу, дальше принудительный выход с человекочитаемым сообщением. Плюс circuit breaker: если внешний сервис отвечает ошибкой три раза подряд, перестаём в него долбиться на минуту, а не пытаемся бесконечно.

Слой 3. Инструменты: каждый вызов проходит через шлюз

Инструменты дают агенту руки. Агент без них — дорогой генератор текста, агент с ними и без ограничений — источник инцидентов.

Правило простое: ни один инструмент не выполняется в обход пайплайна. На каждый вызов — проверка прав, валидация входных данных по схеме, принудительный таймаут через asyncio.wait_for() и запись в аудит. Таймаут именно принудительный: без него зависший HTTP-запрос держит весь цикл, и агент выглядит просто «медленным», хотя он мёртвый.

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

Слой 4. Память: границы диалога и границы токенов

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

Наивное решение — складывать всё в промпт — упирается в лимит контекста примерно на десятой реплике. Дальше нужен либо sliding window, либо сжатие: старые сообщения свернуть в резюме, свежие оставить как есть.

Второй вопрос — что вообще можно хранить. История переписки в поддержке — это персональные данные, номера заказов, иногда фрагменты платёжных реквизитов. Продакшен-вариант: шифрование на уровне отдельного диалога с деривацией ключа через PBKDF2, детекция PII на входе, разделение хранилищ по идентификатору диалога. Чтобы утечка одного ключа не открывала всю базу.

Слой 5. Guardrails: слой, который стоит денег ровно один раз

Это проверки прав, ограничения частоты, валидация путей, фильтрация контента и лимиты по стоимости. Всё, что отвечает на вопрос «что агенту вообще разрешено».

Показательный пример — защита от выхода за пределы рабочей директории. Агенту разрешено писать в /tmp/workspace, и наивная проверка сравнивает начало пути с этой строкой. Но /tmp/workspace-evil тоже начинается с /tmp/workspace, и проверка его пропустит. Лечится двумя движениями: сначала Path.resolve(), чтобы развернуть символические ссылки и .., потом сравнение с префиксом, к которому дописан слеш.

base_prefix = str(self.base_dir) + "/"

Ограничение частоты в распределённой системе делается через sliding window на sorted sets в Redis — счётчик в памяти процесса бесполезен, когда у вас три реплики за балансировщиком. И отдельно — потолок расходов на диалог, после которого агент вежливо отказывается продолжать. Плавная деградация вместо падения: лучше ответить «не могу выполнить сейчас», чем уронить процесс.

Тут же живёт то, что с недавних пор стало главной практической угрозой для агентов, — доверие к содержимому, которое агент читает сам. README из репозитория, описание MCP-сервера, страница из выдачи: всё это попадает в контекст и влияет на решения. Как это эксплуатируют на практике, мы разбирали на кампании с поддельными MCP-серверами.

Слой 6. Наблюдаемость: чтобы понять, что было в три ночи

Структурированные логи, аудиторский след, метрики, трейсинг. Ключевая деталь — correlation ID, единый идентификатор, который проходит через всю цепочку: ввод пользователя, вызов модели, выполнение инструмента, проверку прав, ответ. Без него у вас россыпь строк, из которой невозможно собрать один инцидент.

Минимальный рабочий вариант не требует стека на миллион: SQLite с таблицей событий, где есть время, correlation ID, тип действия и уровень значимости, уже даёт восстановимую картину. Дальше можно переезжать на OpenTelemetry, когда объём вырастет.

Отдельно про расходы: отслеживание токенов по диалогам — часть этого слоя, а не бухгалтерии. Аномальный рост расхода на одного пользователя — самый ранний сигнал, что агент зацикливается или что его используют не по назначению.

Как понять, чего не хватает вашему агенту

Пройдите по списку и отвечайте только «да, вот код» или «нет». «Планируем» считается за «нет».

  • Смена LLM-провайдера — это правка одного адаптера или переписывание половины проекта?
  • Есть жёсткий максимум итераций в цикле, и что происходит при его достижении?
  • Есть circuit breaker на внешние вызовы, или агент долбится в упавший сервис бесконечно?
  • Каждый вызов инструмента проходит проверку прав, или права проверяются только на входе в диалог?
  • У инструментов есть принудительный таймаут, а не надежда на таймаут библиотеки?
  • Аргументы инструментов валидируются по схеме до выполнения?
  • Пути к файлам разворачиваются через Path.resolve() и сравниваются с префиксом со слешем?
  • Ограничение частоты работает поверх всех реплик, а не в памяти одного процесса?
  • Есть потолок расходов на диалог и что-то происходит при его достижении?
  • История диалога шифруется, и ключ выводится на диалог, а не один на всю базу?
  • Что происходит при переполнении контекста — сжатие, окно или падение?
  • Логи связаны correlation ID, и можно поднять полную цепочку одного запроса?
  • Тесты прогоняются в CI без обращения к платному API?

Меньше восьми «да» — до продакшена рано, и дело не в промптах.

Про инцидент, с которого обычно начинают такие статьи. В исходном материале, откуда взята разбивка на слои, приводится случай: финтех выкатил агента поддержки в пятницу, к трём ночи в субботу тот оформил 47 000 долларов неавторизованных возвратов пользователю, подобравшему нужные формулировки. История правдоподобная и хорошо иллюстрирует, что бывает без слоёв 3 и 5. Подтверждения ей мы не нашли: ни компании, ни даты, ни отчёта, ни публикации. Считайте это иллюстрацией, а не кейсом, и не ссылайтесь на неё в разговоре с руководством — спросят источник.

Источники