Runtime enforcement для агентов: почему middleware надёжнее промпт-гардов
Промпт-гарды — это просьба к модели вести себя хорошо. Runtime middleware — это код, который не даёт ей вести себя плохо. Разбираем архитектуру behavioral enforcement для LLM-агентов.
Промпт — это просьба. Middleware — это закон
Каждый, кто строил агентов на LangGraph или CrewAI, проходил через одну и ту же фазу: добавление строк в системный промпт. «Никогда не удаляй файлы». «Всегда проверяй оплату перед подтверждением бронирования». «Не вызывай API больше трёх раз подряд».
Проблема в том, что это текст. LLM интерпретирует текст. А интерпретация — это вероятностный процесс. Модель может решить, что в конкретном контексте правило неприменимо. Может «забыть» его после длинной цепочки рассуждений. Может проигнорировать из-за конфликта с другой инструкцией.
Исследование ATA (Autonomous Trustworthy Agents, 2024) выделяет три паттерна, которые промпт-инженерия не предотвращает:
- Ошибки параметров: агент вызывает book_hotel(guests=15) при максимуме 10 — хотя ограничение прописано в docstring
- Ошибки полноты: агент подтверждает бронирование без верификации оплаты
- Обход инструментов: агент возвращает «успех» без вызова обязательных проверочных функций
Корневая причина архитектурная: промпты — это текст, который модель решает, следовать ему или нет. Бизнес-правила в docstring'ах становятся рекомендациями, а не ограничениями.
Что такое behavioral runtime middleware
Вместо того чтобы просить модель «будь хорошей», behavioral middleware — это слой между агентным фреймворком и LLM, который принудительно ограничивает поведение на уровне исполнения.
Ключевая абстракция — ExecutionContract. Каждый шаг агента проходит через API-вызов, который возвращает контракт:
- allowed_actions — белый список разрешённых действий
- forbidden_actions — чёрный список запрещённых
- decision_style — параметры принятия решений (уровень риска, темп)
- stress_level — индикатор нагрузки/аномалий
Агент читает контракт и принимает решение в его рамках. Контроль не в промпте — в слое исполнения.
Это классический Design by Contract Бертрана Мейера, перенесённый в мир LLM-агентов. Предусловия, постусловия, инварианты — только проверяются они не компилятором, а runtime-middleware.
Как это работает на практике
Архитектура перехвата
Middleware встраивается в цикл агента на трёх уровнях:
Before — до выполнения действия. Проверка входных параметров, валидация намерения агента, фильтрация запрещённых операций. Если действие нарушает контракт — оно блокируется до того, как дойдёт до инструмента.
Around — обёртка вокруг вызова. Контроль параметров вызова, тайм-ауты, rate limiting. Middleware может модифицировать параметры для приведения к допустимому диапазону.
After — после выполнения. Валидация результата, проверка постусловий, аудит-лог. Если результат нарушает инвариант — откат или повтор с ужесточёнными параметрами.
Пример: защита от несанкционированного подтверждения
Агент для бронирования отелей получает запрос «Подтверди бронирование BK001».
Без middleware: агент вызывает confirm_booking, функция возвращает успех, оплата не была проверена.
С middleware: агент формирует намерение вызвать confirm_booking → middleware проверяет предусловие payment_verified == True → предусловие не выполнено → действие заблокировано → агент получает инструкцию «Сначала вызовите verify_payment». Запрещённое действие никогда не достигло инструмента.
Три подхода к runtime enforcement
К марту 2026 сформировались три чётких подхода.
Hook-based перехват (Strands Agents, LangGraph)
LangGraph поддерживает middleware на уровне фреймворка. Strands Agents от AWS реализует hook-систему: before_tool_call, after_tool_call, before_agent, after_agent. Гарды пишутся как обычные Python-функции. Преимущества: простота, нативная интеграция. Недостаток: правила размазаны по коду.
Декларативные контракты (ABC Framework, AgentSpec)
Agent Behavioral Contracts (ABC) — формальная спецификация с предусловиями, постусловиями, инвариантами. Контракты записываются на DSL (ContractSpec), проверяются runtime-монитором (AgentAssert). Ключевая фишка — Behavioral Drift Score: метрика, которая отслеживает кумулятивное отклонение агента от контракта. AgentSpec экстернализирует правила от LLM, обеспечивая консистентное поведение между запусками и версиями модели.
Внешний API контрактов
Отдельный REST API, один вызов на каждый ход агента. SDK для Python и TypeScript. Адаптеры для LangGraph, CrewAI, OpenAI Agents SDK. Преимущества: языко- и фреймворко-независимость. Недостаток: сетевой вызов на каждом шаге добавляет латентность.
Почему промпт-гарды фундаментально ненадёжны
Промпт-гард = soft constraint. Это рекомендация, закодированная в тексте, которую вероятностная модель интерпретирует. Каждый inference — это новый бросок кубика. На 100 вызовах 99 могут быть корректными, но один пропустит запрещённое действие. В production: если трафик достаточно большой, инцидент гарантирован.
Runtime middleware = hard constraint. Это код, который выполняется детерминированно. if action in forbidden: block() — здесь нет вероятности. Запрещённое действие не пройдёт ни на первом вызове, ни на миллионном.
Что выносить в middleware: чеклист
Однозначно в middleware:
- Финансовые операции: лимиты, подтверждения, проверка баланса
- Доступ к данным: авторизация, PII-фильтрация
- Деструктивные действия: удаление, перезапись, отправка
- Rate limiting: частота вызовов к внешним API
- Обязательные предусловия: оплата перед подтверждением
Можно оставить в промпте:
- Тон и стиль ответа
- Предпочтения формата
- Приоритизация источников информации
- Выбор между равноценными стратегиями
Правило: если нарушение правила приводит к необратимым последствиям — это middleware. Если к некачественному, но безвредному результату — достаточно промпта.
Стоимость и компромиссы
Runtime enforcement не бесплатен: дополнительная проверка на каждом шаге (микросекунды для hook-based, миллисекунды для внешнего API), жёсткость (слишком строгие контракты могут парализовать агента), maintenance (контракты нужно обновлять).
Но сравните это с альтернативой: один пропущенный запрещённый вызов в production может стоить гораздо больше, чем 5 мс дополнительной латентности.
Куда движется индустрия
К марту 2026 тренд очевиден: промпт-гарды уходят на второй план. LangChain документирует middleware как рекомендуемый подход к guardrails. AWS выпускает Strands Agents с нативными хуками. Академия формализует behavioral contracts.
Следующий шаг — стандартизация формата контрактов, чтобы переносить правила между LangGraph, CrewAI и OpenAI Agents SDK.
Для тех, кто строит агентов сегодня: если ваши гардрейлы живут только в промпте — это не гардрейлы. Это надежда. Runtime middleware превращает надежду в гарантию.