Логотип

Статья

Контроль против гибкости: два подхода к созданию AI-агентов

В последнее время внимание инженеров и исследователей привлекают агентные архитектуры — системы, где LLM координирует работу внутренних инструментов и других моделей. Разберем два основных подхода к построению агентных систем: недекларативный — code-first — его исповедуют OpenAI Agents SDK, Crew AI, AutoGen и декларативный — graph-first — реализован, к примеру, в библиотеках LangGraph.

Недекларативный подход: свобода действий

Именно об этом подходе думаешь в первую очередь, когда слышишь об «универсальном агенте, способном решать все задачи пользователя». Философия недекларативного подхода исходит из невозможности предусмотреть алгоритм на каждый сценарий. Значит, нужно дать относительную свободу LLM, чтобы она сама решала, как выполнить задачу пользователя, применяя доступные инструменты.

Для одиночного агента недекларативный подход обычно означает использование ReAct (Reason + Act) или его производных. LLM динамически выбирает инструменты, настраивает параметры, анализирует результаты и определяет очерёдность действий.

Гибкость реализуется через мультиагентные паттерны. Использование нескольких агентов не исключает ReAct — наоборот, эти паттерны описывают, как объединить агентов в общую систему.

Паттерны коммуникации: Handoff, Agent-as-tool и групповой чат

Handoff — это основной паттерн в OpenAI Software Development Kit (SDK). Агент самостоятельно решает, кому передать задачу или делегировать ее часть. В ответе LLM четко описывает адресата передачи управления. Паттерн хорошо подходит для реализации архитектуры «агент менеджер — агент исполнитель».

Agent-as-tool — интересный паттерн, при котором ReAct привлекает другого агента через вызов инструмента. По смыслу он близок к handoff, но отличается реализацией: LLM генерирует в ответе теги <tool> где описывает инструмент вызова и его параметры. Такой подход, например, используется в Cursor, где инструмент <think> запускает дополнительный цикл рассуждений LLM для формирования плана действий.

Групповой чат реализуется в библиотеке AutoGen — в нем агенты видят всю переписку между собой, как в обычном рабочем чате. Коммуникация между ними происходит как по очередности, заданной разными правилами, например, round-robin, так и через handoff.

Минусы недекларативного подхода

Снижение надежности

Сторонники недекларативного подхода, например, OpenAI, утверждают, что для решения сложных задач нужно быть гибкими. Мне это напоминает фразы вроде: «отсутствие плана — это тоже план» и «разберемся по ходу дела». Проблема в том, что при автоматизации бизнес-процессов возникают сложности без следования четкой методологии. Мы же не будем доверять агенту проводить денежные транзакции, просто рассчитывая на хорошо написанные инструкции в промпте. 

Недавний яркий пример, когда агент в сервисе Replit удалил продуктовую базу пользователей, хотя разработчик явно говорил агенту этого не делать. Понятно, что такие ошибки — вопрос эффективности защитных механизмов. Контроль графа выполнения агента — один из таких механизмов. Если процесс уже выстроен с четкой последовательностью шагов, зачем полагаться на простое следование инструкциям LLM. Гораздо надежнее формализовать процесс в виде графа и снять связанные риски.

Масштабирование галлюцинаций

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

Проблема испорченного телефона

При использовании механизма handoff информация проходит через ряд посредников по пути к исполнителю и тут, как в жизни, больше шансов потерять первоначальный смысл. Именно так происходит в паттерне «менеджер-исполнитель». Если агент передает своими словами исполнение задачи пользователя другому агенту — почти наверняка что-то потеряется. Наличие общей памяти (state), хранящей все артефакты, включая изначальный запрос, позволяет избежать этой проблемы.

Тем не менее недекларативные системы поддерживают крупные игроки. Венчурный инвестор Andrew Ng участвовал в раунде финансирования Crew AI, что свидетельствует о доверии сообщества к подобным решениям. Интересно, что фреймворк Crew AI изначально базировался исключительно на недекларативном подходе с паттерном «команда», но сейчас поддерживает и декларативный подход с явным заданием графа.

Декларативный подход: надежность через граф

В декларативных системах, например, LangGraph, разработчик описывает граф: узлы — это агенты или этапы, ребра — возможные переходы между ними. Система выполняет граф, управляя агентами. Такой подход ограничивает свободу модели, но дает предсказуемость и контроль.

На практике декларативность не ограничивается мультиагентными системами. Даже на уровне ReAct можно применить подход Schema-Guided Reasoning (SGR) — задать строгую последовательность шагов и формат вывода, чтобы модель действовала только в рамках заданного алгоритма, а не по интуиции. Иными словами, вы можете заставить LLM идти по if-then логике, будто пишете обычную программу.

Пример: система менеджер–кодер–тестер

В недекларативной схеме менеджер выбирает, кому делегировать задачу. Например, агент-менеджер из-за галлюцинации решит выполнить задачу сам, тогда пользователь получит некорректный результат. В декларативной схеме мы строим граф, менеджер правильно классифицирует задачу и обязывает передать ее дальше на исполнение. За счет использования графа и Structured Output, агент просто не может ошибиться на этом этапе — он всегда будет возвращать ответ в нужном формате, что обеспечит корректные переходы по графу.

Преимущества graph-first

Контроль и прозрачность

Узлы получают доступ к общей памяти (state), а переходы между узлами могут быть детерминированными или содержать логическое условие. Это позволяет отслеживать и ограничивать действия агентов, и делает цепочку выполнения прозрачной.

Структурированный вывод и роутинг

В декларативном workflow критично задать структурированный формат ответа. Structured Output (SO) фиксирует схему данных, например, JSON, и модель должна вернуть результат именно в этом виде. Это особенно важно для логических нод-маршрутизаторов: они работают только с конкретными полями и значениями.

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

Передача состояния без искажений

В декларативном графе все данные хранятся в state, и узлы работают с этим состоянием напрямую. Каждый агент получает исходный текст запроса, а не пересказ предыдущего шага. Это убирает возможные искажения в разных формулировках сообщения менеджером-агентом.

Модульность и разделение ответственности

Разделение агентного приложения на специализированных агентов с заданными переходами между ними повышает прозрачность и надежность системы. Это напоминает переход от монолитных приложений к парадигме микросервисов. Разделение ответственности само по себе — крайне полезный паттерн.

В сообществе активно обсуждают подход 12-Factor Agents, в котором формулируются принципы надежных агентных систем: структурированный вызов инструментов, контроль исполнения, версионирование промптов, управление контекстом. Это еще один сигнал, что индустрия стремится к большей предсказуемости и тестируемости агентных решений.

Декларативный подход хорошо работает там, где процесс можно заранее разложить на шаги. Но если задачу сложно структурировать или пользовательский запрос может быть любым, жесткий граф начинает мешать.

Ограничения декларативного подхода

Сложности проектирования

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

Нет «идеального» графа

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

Неизвестные переходы

В некоторых задачах мы просто не знаем всех возможных переходов заранее. Например, для агента Deep Research жесткая схема «планировщик → поиск → агрегация» плохо работает. Уже после первых запросов может выясниться, что план устарел или не учитывает нюансы, но вернуться к планированию граф не позволяет — обратного перехода нет. Такие задачи требуют динамического планирования. Если обратные связи не предусмотрены, граф приходится перестраивать. Но если добавить слишком много связей между нодами, он теряет жёсткость, и агент рискует уйти в бесконечные циклы из-за галлюцинаций.

Поиски баланса: гибридные системы

Не все современные фреймворки строго попадают в одну из двух категорий. Например, LangGraph изначально предлагал декларативный подход, но сегодня в нем можно собирать недекларативных агентов. Crew AI, наоборот, стартовал с концепции свободных команд агентов, а теперь поддерживает и детерминированные workflow.

Выбор подхода зависит от задачи. Чем она абстрактнее и чем меньше у нее заранее известных сценариев — тем больше свободы требуется. Когда процесс формализован и ошибки недопустимы, лучше работает жестко фиксированный граф.

На практике граница между подходами размыта. Эффективнее всего работают гибридные схемы — когда структура задана, но внутри узлов остается пространство для динамики.

Компромисс между надежностью и гибкостью

В реальных проектах почти всегда требуется сочетание двух подходов: фиксированной структуры на уровне графа и гибкости внутри отдельных узлов. Такая стратегия позволяет контролировать общий поток и связанные с ним риски, не ограничивая адаптивность агентов. По сути, декларативность на «верхнем уровне» и свободная логика внутри узлов — рабочий компромисс между надежностью и гибкостью.

Декларируем «каркас», а не детали 

Определяем высокоуровневый бизнес-процесс в виде графа: порядок шагов, ответственных агентов, разрешенные переходы. Например, сначала агент-классификатор определяет проблему пользователя, затем передает ее ответственному агенту, после этого происходит ревью проделанной работы. Это похоже на методологию Domain-Driven Development — сначала проектируется доменная модель и связи, а реализация деталей остается свободной. Переходы между нодами жестко зафиксированы, и требуются строгие форматы ответов, чтобы можно было безошибочно определить, куда поток выполнения пойдёт дальше. В отличие от гибкого handoff, такой подход снижает риск галлюцинаций, которые могут привести к неверным переходам между нодами.

Свобода внутри узлов

Каждый узел может использовать недекларативные паттерны ReAct и инструменты LLM: писать код, запускать поиск, задавать уточняющие вопросы. Порядок действий внутри узла может быть динамическим — пока он не нарушает внешний граф. Это дает нужную гибкость в выполнении задачи.

Прописать граф так подробно, чтобы он охватывал все крайние случаи, особенно в задачах вроде генерации кода, практически невозможно. Лучше вложиться в настройку самого ReAct-агента: управление контекстом, памятью, инструментами и стратегиями вызовов. Это приносит куда больше пользы, чем попытки жестко описать каждый шаг.

Структурированные сообщения

Для передачи задач между узлами требуем структурированный формат (JSON) и используем общий для всего графа state. Это предотвращает искажения при передаче информации между нодами и облегчает отладку.

Аудит и адаптация

Вся последовательность шагов выполнения — execution trace — должна записываться, например, в персистентный state и быть доступной через инструменты анализа. Без trace невозможно отлаживать работу агента: он показывает, какие решения принимались, какие инструменты вызывались и как менялся state. Trace служит и источником контекста, но быстро разрастается, поэтому им нужно управлять: задавать, какие его части учитываются конкретными узлами, когда выполнять суммаризацию и что можно удалять как шум.

Гибкость в «грязных» местах

В задачах, требующих динамического планирования, полезно допускать локальные циклы. Например, связка «планировщик → исполнитель → ревьюер» может иметь обратную петлю, но важно ограничить число итераций и вести четкий лог, чтобы избежать бесконечных зацикливаний

Грамматика задания допустимых ответов

Современные инференс-движки, такие как vLLM, позволяют задавать грамматику для управления допустимым ответом. Например, модели семейства Qwen иногда игнорируют инструкции по выбору языка ответа и могут отвечать на китайском. Для борьбы с этой проблемой можно взять русифицированную версию модели t-lite, либо в грамматике ответа запретить все символы кроме нужного языка с помощью регулярных выражений (regex).

Вывод: во всем важен баланс 

Спор между декларативным и недекларативным подходами не имеет однозначного решения. Недекларативные системы удобны для быстрых экспериментов и дают моделям максимум свободы, но их сложнее контролировать и масштабировать. Декларативные графы требуют больше усилий на проектирование, зато обеспечивают предсказуемость, прозрачный поток данных и меньший риск галлюцинаций.

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