От простого цикла к сложной системе: как устроена архитектура продвинутого ИИ-агента

Habr AI · оригинал

Материал подготовлен автоматизированной редакционной системой. Факты можно сверить по указанному первоисточнику.

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

Понимание внутренней структуры agentic harness критически важно для разработчиков, стремящихся создать ИИ-системы, которые не просто генерируют ответы, но и планируют действия, эффективно используют ресурсы и могут быть отлажены. Материал раскрывает инженерные решения, стоящие за «магией» современных LLM-приложений.

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

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

Ключевым архитектурным решением является использование типизированных инструментов на базе Pydantic. Вместо ручной валидации аргументов, которая приводит к дублированию кода и трудностям в отладке, каждая функция описывается формальной схемой. Это позволяет LLM видеть точную структуру ожидаемых данных, а системе — отклонять некорректные запросы на этапе валидации, прежде чем они попадут в дорогостоящие операции или базы данных. Такой подход обеспечивает fail-fast поведение и унифицирует интерфейс для разных провайдеров, таких как Anthropic и OpenAI.

Для повышения производительности применяется параллельное выполнение узлов графа. Исполнитель (Executor) использует asyncio для конкурентного запуска всех готовых операций, ограничивая число одновременных вызовов семафором. Это предотвращает превышение лимитов скорости (rate limits) и резкий рост расходов на токены. Синхронные функции инструментов выносятся в пул потоков, что позволяет избежать блокировки асинхронного цикла событий. В результате время выполнения определяется не суммой задержек всех операций, а длиной критического пути графа.

Проблема контекстного окна решается через многоуровневую память. Вместо загрузки всей истории диалога в промпт, система использует рабочую, эпизодическую и семантическую память. Контекст формируется динамически: извлекаются только наиболее релевантные фрагменты (top-k), укладывающиеся в жесткий бюджет символов. Эпизодические воспоминания о прошлых похожих задачах имеют приоритет над общими фактами, что позволяет модели опираться на актуальный опыт без потери фокуса на текущей цели.

Наконец, для обеспечения надежности вводится разделение ролей: Planner формирует план, Worker выполняет действия, а Critic верифицирует результат. Это позволяет отделить логическое планирование от механического исполнения и добавить слой контроля качества. Использование мок-провайдеров вместо реальных LLM при тестировании помогает изолировать ошибки оркестрации от проблем с качеством генерации модели. Итоговая архитектура представляет собой тонкий, но мощный каркас, который превращает хаотичный поток действий в предсказуемый и измеримый процесс.