Мы поставили AI-агента на рельсы.
В какой-то момент при разработке AI-агентов возникает желание сделать всё максимально детерминированно. Чтобы LLM не импровизировала, не выходила за рамки сценария и всегда возвращала ожидаемый результат.
Мы тоже пошли по этому пути. Начали постепенно оборачивать агента в ограничения: — Structured Output + Pydantic — строгие схемы ответов, валидация типов и обязательных полей. — State Machine / Graph-based Workflow — заранее определённые состояния и допустимые переходы. — Guardrails — дополнительные проверки входных данных, ответов и действий агента. — Retry / Fallback Logic — повторные попытки и запасные сценарии при ошибках.
Всё выглядело логично. Меньше непредсказуемости, проще debugging, лучше observability, понятнее execution flow.
Но постепенно мы столкнулись с обратной стороной такого подхода. Мы начали превращать агента в обычный workflow engine с LLM внутри. Каждый новый use case требовал расширения схем, изменения графа состояний, добавления новых conditional edges и обработки очередных corner cases. Structured Output, который должен был упрощать интеграцию, местами начал ограничивать пространство возможных решений. А избыточные guardrails и validation layers увеличивали latency и усложняли оркестрацию.
В какой-то момент сложность поддержки всей этой инфраструктуры стала расти быстрее, чем функциональность самого агента. И здесь возникает интересный архитектурный конфликт. Мы хотим от LLM адаптивности и автономности, но одновременно пытаемся сделать её поведение полностью детерминированным.
В результате получаем систему, в которой: — Time-to-market новых фич увеличивается. — Автоносность агента постепенно исчезает. — Пространство решаемых задач сужается до заранее предусмотренных сценариев. — Любое нестандартное поведение воспринимается как ошибка и весь workflow падает, даже если оно приводит к правильному результату.
При этом проблема не в Structured Output, Pydantic или LangGraph. Проблема начинается тогда, когда мы используем ограничения не только для контроля контрактов и безопасности, но и для определения каждого шага агента.
Мне всё больше нравится фиксировать инварианты системы, а не каждый шаг её поведения. Потому что если все поведение заранее определёно, возникает закономерный вопрос: А нам действительно нужен AI-агент?
Иногда лучший способ улучшить AI-агента — перестать принимать за него все решения.
А как вы проектируете своих агентов? Больше склоняетесь к строгим workflow или даёте модели свободу самостоятельно выбирать действия? #AIEngineering #AIAgents #LLM #LangGraph #AgentArchitecture
· 29.10
Спасибо за статью, очень близкая тема. Мы строим конвейер, где AI-агенты пишут код по задачам, и упёрлись в похожее: пока ограничения были «прозой» в промпте (какие файлы нельзя трогать), модель их нарушала, а когда мы начали проверять границы механически (список путей, откат лишнего), стало надёжно, но каждый новый случай просит новых правил. Как вы определяете, что именно должно быть инвариантом, а что оставить модели? Есть ли у вас критерий или это решается по инциденту? И как вы проверяете инварианты: до запуска, после действия (с откатом) или в обоих местах?
0
ответить
коммент скрыт — часть юзеров считает его токсичным или некорректным
коммент удалён
· 29.10
В задаче которая решается в нашей команде инвариант можно увидеть строго по инциденту. Но в вашем случае - генерации кода, эти правила могли бы быть строго описаны пользователем (какие файлы можно трогать, а какие нет) так как сложно полностью исключить человека из этой цепочки, это может быть yaml конфиг, который лежит рядом со спекой откуда при инициализации tool подтягивал бы конфиг запретов и правил детерминированно.
0
ответить
коммент скрыт — часть юзеров считает его токсичным или некорректным
ответ удалён