Введение
Гибридная система LLM-агентов – это программная архитектура, где большие языковые модели (LLM) выступают в роли интеллектуальных агентов, способных решать сложные задачи через рассуждение и вызов внешних инструментов. Цель такой системы – комбинировать рассуждения модели с действиями (вызовом кода, поисковых сервисов, браузера и т.д.) для достижения целей пользователя. В данной архитектуре основная LLM (например, GPT-4) берёт на себя роль координатора, разбивая задачу на подзадачи и поручая их выполнение специализированным агентам или инструментам. Подход ориентирован на прозрачность решений и модульность: легко добавлять новых агентов, хранить и использовать факты из памяти, интегрировать различные модели и API. Поскольку это исследовательская система, приоритет отдаётся гибкости и качеству работы, а не оптимизации скорости или масштаба.
Ниже подробно рассматриваются ключевые принципы и компоненты такой архитектуры, включая парадигму ReAct (Reason+Act) для чередования мыслей и действий, механизм оркестрации наподобие HuggingGPT, организация памяти (кратковременной и долговременной с помощью Redis), взаимодействие агентов с инструментами (поиск, вычисления, веб-браузер и др.), а также альтернативные решения и соответствующие открытые библиотеки (LangChain, LlamaIndex и пр.).
Принцип ReAct (Reason + Act) для агентов
Основой поведения LLM-агентов является принцип ReAct – чередование рассуждения и действия. В подходе ReAct модель не просто сразу выдаёт ответ, она генерирует трассировку рассуждений (reasoning trace), размышляя над задачей, и по ходу этого может совершать действия (act) – вызывать инструменты, делать запросы к внешней среде (ReAct: Synergizing Reasoning and Acting in Language Models) (ReAct: Synergizing Reasoning and Acting in Language Models). После каждого действия агент получает наблюдение (observation) – результат этого действия, который включается в последующий контекст размышлений. Таким образом, решение задачи разбивается на последовательность шагов: мысль → действие → наблюдение → …, что продолжается до получения конечного ответа.
(ReAct: Synergizing Reasoning and Acting in Language Models) Принцип ReAct: (вверху) только рассуждение без взаимодействия с внешней средой, (посередине) только действия без внутреннего планирования, (внизу) объединение Reason + Act – модель чередует рассуждения и действия, получая обратную связь от окружения.
Зачем нужен ReAct? Исследования показали, что такая интеграция рассуждений с действиями даёт существенные преимущества. Во-первых, ReAct-подход превосходит стратегии, где LLM либо только планирует (Chain-of-Thought), либо только действует без глубокого анализа – комбинированная парадигма решает задачи эффективнее и надёжнее (ReAct: Synergizing Reasoning and Acting in Language Models). Во-вторых, поведение агента становится более интерпретируемым и управляемым для человека, так как видна цепочка логики, и можно проследить, какие факты были найдены и как они повлияли на вывод (ReAct: Synergizing Reasoning and Acting in Language Models). Действительно, объединение Reason+Act приводит к «траекториям решения задач, выровненным с человеческой логикой» (human-aligned), что упрощает отладку и контроль работы системы (ReAct: Synergizing Reasoning and Acting in Language Models).
Во-третьих, ReAct даёт модели возможность динамически адаптировать план по ходу выполнения задачи. За счёт чередования шагов агент может, например, сначала наметить план, затем выполнить поиск информации, на основе новой информации пересмотреть свои дальнейшие действия, обработать исключения или неожиданные результаты, скорректировать изначальные предположения (ReAct: Synergizing Reasoning and Acting in Language Models) (ReAct: Synergizing Reasoning and Acting in Language Models). Как отмечают авторы метода, синергия между рассуждением и действием позволяет модели создавать, поддерживать и при необходимости корректировать высокоуровневый план (reason to act), одновременно обогащая свои рассуждения сведениями из внешней среды (act to reason) (ReAct: Synergizing Reasoning and Acting in Language Models). Например, если при поиске выяснился новый факт, опровергающий прежнюю гипотезу, агент на следующем шаге размышления изменит план действий с учётом этой информации. Такая адаптивность крайне важна для сложных задач, где решение не явно известно с самого начала.
Практически реализация ReAct-подхода в Python сводится к организации цикла: LLM-агент получает текущий контекст (включающий историю мыслей и наблюдений), генерирует следующий “Thought” (мысль: чего не хватает или что делать дальше) и соответствующий “Action” (команда инструменту или подзапрос). Формат промпта может быть структурирован: например, можно использовать специальные маркировки вроде Thought: и Action: в сообщении модели, чтобы явно отделять размышления от команд. Многие фреймворки уже поддерживают шаблоны ReAct. В частности, библиотека LangChain включает готовый тип агента, реализующего ReAct-шаблон, где модель может выбирать из списка доступных инструментов и вести “scratchpad” для промежуточных выводов (Using LangChain ReAct Agents to Answer Complex Questions). Таким образом, принцип ReAct закладывает фундамент для прозрачной работы системы: агент обосновывает каждое своё действие и использует действия для обогащения последующих размышлений.
Оркестрация агентов в духе HuggingGPT
При решении комплексных задач один LLM, даже обладая инструментами, может быть недостаточно эффективен. В гибридной системе делается акцент на оркестрации множества агентов, то есть координации работы нескольких специализированных моделей/модулей. Центральный управляющий агент (Controller) анализирует запрос пользователя, разбивает его на части и распределяет между другими агентами-экспертами. Подход аналогичен концепции HuggingGPT, предложенной Microsoft: там в роли диспетчера выступает ChatGPT/GPT-4, который по описанию задачи выбирает подходящие модели из сообщества HuggingFace и последовательно запускает их для решения частей задачи ([2303.17580] HuggingGPT: Solving AI Tasks with ChatGPT and its Friends in Hugging Face). В нашем случае в качестве центрального оркестратора может выступать GPT-4 (или другая сильная LLM), а экспертными агентами – модули для конкретных типов заданий (поиск в интернете, выполнение кода, анализ текста и т.п.).
Как это работает: согласно архитектуре HuggingGPT, общий алгоритм таков:
-
Планирование задачи. Получив запрос, главный LLM-агент планирует необходимые шаги: какие подзадачи возникают и в каком порядке их решать ([2303.17580] HuggingGPT: Solving AI Tasks with ChatGPT and its Friends in Hugging Face). Например, сложный пользовательский запрос может требовать сначала найти информацию, затем проанализировать её и выполнить вычисление.
-
Выбор исполнителей. Для каждой подзадачи оркестратор подбирает соответствующий инструмент или модель. В HuggingGPT это сделано через описание функций моделей: ChatGPT просматривает каталог моделей (например, на HuggingFace) с их возможностями и выбирает подходящую ([2303.17580] HuggingGPT: Solving AI Tasks with ChatGPT and its Friends in Hugging Face). В общем случае, у нас может быть реестр агентов/инструментов с метаданными (название, умение: «поиск в веб», «вычисления», «анализ текста» и т.д.). Например, если нужна информация – выбрать поискового агента, если расчёт – агент-калькулятор и т.д.
-
Выполнение подзадач. Оркестратор делегирует исполнение: отправляет соответствующий запрос выбранному агенту и получает от него результат ([2303.17580] HuggingGPT: Solving AI Tasks with ChatGPT and its Friends in Hugging Face). Это может быть вызов функции Python, HTTP-запрос к API, запуск другой модели и т.д. Главный агент ждёт ответа (наблюдения).
-
Агрегация и синтез ответа. После того как все необходимые подзадачи решены и результаты собраны, главный агент сводит всё вместе – формирует итоговый ответ пользователю с учётом полученных данных ([2303.17580] HuggingGPT: Solving AI Tasks with ChatGPT and its Friends in Hugging Face). Если нужно, он может ещё раз проанализировать все наблюдения и выполнить заключительное рассуждение перед выдачей ответа.
Такой подход обеспечивает модульность, масштабируемость и устойчивость системы (Multi-Agent Systems - Hugging Face Agents Course). Специализированные агенты берут на себя узкие функции, в которых они сильны (по принципу “unix-way” или «каждый делает своё дело хорошо»). А центральный LLM следит за высокоуровневой логикой решения. Исследователи отмечают, что многоагентная система с координацией повышает модульность (каждый компонент можно разрабатывать и отлаживать отдельно, заменять при необходимости), улучшает масштабируемость (можно параллелить выполнение независимых подзадач, или добавлять новых агентов без переписывания ядра), а также повышает надёжность решения сложных задач (Multi-Agent Systems - Hugging Face Agents Course). Если один агент столкнулся с проблемой, центральный модуль может обнаружить это (неполучение ответа, либо анализ содержимого ошибки) и перенаправить задачу другому или попытаться переформулировать запрос.
В иерархии агентов обычно выделяют следующие роли:
-
Оркестратор (менеджер) — центральный агент. Это LLM общего назначения с навыками планирования. Он не выполняет узкоспециализированную работу, а лишь решает, что нужно сделать и кто это сделает. Его «квалификация» – понимание запроса и общая осведомлённость о возможностях системы. Пример: GPT-4 как менеджер.
-
Агенты-инструменты (worker agents). Это исполнители конкретных действий. Они могут быть реализованы разными способами: как вызовы API, как отдельные мелкие модели (например, модель-вопросоответчик, модель-классификатор), как обёртки над внешним сервисом. В контексте HuggingGPT таким агентом может быть любая модель с HF Hub (например, модель распознавания изображений, если задача требует анализ картинки) ([2303.17580] HuggingGPT: Solving AI Tasks with ChatGPT and its Friends in Hugging Face). В нашем случае примеры агентов: модуль поиска (обращается к поисковой системе), модуль выполнения Python-кода, модуль взаимодействия с браузером.
Отношения между агентами можно изобразить в виде дерева вызовов. Например, в туториале от HuggingFace показан простой вариант: Manager-Agent наверху, который может напрямую использовать инструмент «Interpreter» (для исполнения кода) или вызвать Web-Search-Agent, а тот, в свою очередь, уже использует инструменты поиска и загрузки страниц (Orchestrate a multi-agent system ).
(Multi-Agent Systems - Hugging Face Agents Course) Пример иерархии агентов (по материалам HuggingFace🤗): центральный «Manager-agent» делегирует работу либо инструменту исполнения кода («Code-Interpreter-tool»), либо веб-поисковому агенту («Web-Search-agent»). Веб-поисковый агент, в свою очередь, задействует конкретные инструменты: «Web-Search-tool» для отправки поискового запроса и «Visit-webpage-tool» для посещения найденной страницы.
Важно подчеркнуть, что хотя оркестратор принимает решения, сами подзадачи могут выполняться независимо и даже параллельно (если это предусмотрено) – например, несколько запросов поиска одновременно. В нашем случае, ввиду исследовательского характера, можно выполнять шаги последовательно для простоты (невысокие требования к скорости). Но архитектура остаётся открытой для оптимизации: можно параллелить обращения к независимым агентам, кэшировать результаты частых запросов и т.п.
Модульность и динамическое добавление агентов
Один из принципов проектирования системы – открытая архитектура: возможность добавлять новые навыки и инструменты без перестройки всего приложения. Это достигается несколькими приёмами:
-
Единый интерфейс для инструментов. Нужно определить стандарт, по которому оркестратор общается с любым инструментом. Например, каждый агент может представляться функцией с определённой сигнатурой или описанием (название, назначение, требуемые аргументы). В случае LangChain это класс
Toolс методами, в Semantic Kernel – Plugins (наборы функций), в OpenAI API – функции с JSON-описанием. Если все новые инструменты будут регистрироваться через такой интерфейс, главный агент сможет о них узнавать автоматически. -
Регистрация и хранилище агентов. Система может иметь реестр (список) доступных агентов/инструментов. В простейшем случае это статический список объектов. Но при большом числе инструментов возникает проблема: не поместить информацию обо всех сразу в контекст LLM (ограничение размера prompt). Решение – использовать подход «Tool Retriever» (retrieval for tools). Его суть: хранить описания инструментов, например, в векторной базе, и по запросу пользователя искать подходящи (Retrieval-Augmented Agents - LlamaIndex)】. Так, LLM-оркестратор сначала анализирует задачу и формирует краткий описательный запрос для поиска нужных инструментов, получает релевантный поднабор, и уже их описания включает в prompt. Фреймворк LlamaIndex предоставляет такую возможность: через
tool retrieverможно хранить и индексировать сколь угодно много инструментов, не перегружая prompt лишни (Retrieval-Augmented Agents - LlamaIndex)】. Это даёт практически неограниченную расширяемость – новые агенты добавляются в индекс и смогут быть найдены, когда появится задача соответствующего типа. -
Изоляция модулей. Каждый агент реализуется как отдельный модуль (класс/функция или даже микросервис). Главное – минимизировать зависимость агентов друг от друга. Они все «подчиняются» только центральному координатору. Тогда добавление или удаление агента мало влияет на остальные части. Например, можно добавить модуль для обработки изображений – если оркестратор обучен или спроектирован распознавать запросы, требующие обработки картинок, он начнёт вызывать новый модуль, не затрагивая логику текстового анализа или поиска.
-
Описание возможностей агентов. Чтобы динамически задействовать новые компоненты, оркестратор должен знать, что умеет новый агент. Поэтому важно снабдить каждого агента машиночитаемым описанием. В HuggingGPT каждую модель снабдили текстовым пояснением её функционала, доступным ChatGP ([2303.17580] HuggingGPT: Solving AI Tasks with ChatGPT and its Friends in Hugging Face)】. В LangChain инструменты имеют
nameиdescription, которые вставляются в prompt агента, чтобы он мог решать, какой вызвать. Semantic Kernel требует указывать в плагине описание каждой функции (в config, либо через докстринги (Diving into Microsoft Semantic Kernel | by Prarthana Saikia | Medium)】. Эти описания служат своеобразным «API-документированием» для LLM, позволяя ему рассуждать о выборе инструмента. При добавлении нового агента нужно просто добавить его описание в реестр – переписывать код оркестрации не придётся.
Таким образом, архитектура строится модульно и масштабируемо. Если завтра потребуется навык, которого нет (скажем, парсинг юридических документов или взаимодействие с новой БД), достаточно реализовать новый агент-модуль по стандартному шаблону и зарегистрировать его. Центральный LLM при корректном обучении (few-shot примеры, демонстрирующие использование инструментов по описанию) сможет сам решить, когда вызывать новый инструмент. Такой плагинный подход обеспечивает эволюционное развитие системы.
Кроме того, модульность облегчает экспериментирование с разными реализациями. Например, можно иметь два варианта агента-поисковика: один – обращается к API поисковой системы, другой – ищет по локальному индексу документов. Они оба зарегистрированы как инструменты «Поиск», и на этапе разработки можно переключаться, не меняя остальной код.
Стоит упомянуть, что в сообществе уже есть реализации, демонстрирующие принципы модульности:
-
LangChain – обеспечивает модульность через цепочки (Chains) и агенты (Agents). Можно легко менять LLM-модель, векторное хранилище, набор инструментов без больших переделок код (What Is LangChain? | IBM)】.
-
Semantic Kernel – использует понятие Plugins (наборы функций) и умеет автоматически подбирать плагины через Planner. Планировщик SK с помощью встроенной памяти может по описанию задачи подобрать нужные плагины, даже если их мног (Diving into Microsoft Semantic Kernel | by Prarthana Saikia | Medium)】. Это аналогично вышеописанному search по описаниям инструментов.
Память: долговременная и кратковременная
Для интеллектуального агента недостаточно одномоментно обрабатывать вход – важно иметь память, чтобы использовать полученные факты позже и учиться на опыте. В данной архитектуре предусматриваются два уровня памяти: кратковременная (рабочая) и долговременная.
Кратковременная память (Working Memory). Это та информация, с которой агент оперирует в текущем контексте решения задачи. По сути, это содержимое его prompt или диалога в данный момент: формулировка цели, промежуточные выводы, результаты последних действий. В процессе ReAct-контура кратковременная память включает: историю размышлений (Chain-of-Thought), список уже выполненных действий и полученных наблюдений, а также формулировку текущей подзадачи. Эта память ограничена по объёму (контекстное окно модели, например ~8K или 32K токенов для GPT-4). Однако она очень оперативна – модель мгновенно учитывает всё, что помещено в prompt. В реализации кратковременная память может быть представлена объектом истории (например, ConversationBuffer в LangChain) или просто конкатенацией строк. Также сюда относится состояние плана: например, список оставшихся шагов, если планирование вынесено отдельно.
Долговременная память. Это хранилище фактов и опыта, накапливаемых агентами в ходе работы, доступное даже за пределами текущего сеанса или контекстного окна. В нашем проекте предлагается использовать Redis как бекенд для долговременной памяти. Redis – высокопроизводительная in-memory база данных, поддерживающая как обычные ключ-значение, так и структуры для поиска по векторным представлениям (с помощью модуля Redis Stack (Redis | ️ LangChain) (Redis | ️ LangChain)】. Почему выбран Redis: он обеспечивает очень быстрые чтение/запись в памяти, а также достаточно прост в использовании. Кроме того, Redis легко масштабировать и он может выступать «слоем кэша» между агентом и более медленными хранилищами.
В контексте LLM-агентов долговременная память нужна для:
-
Хранения фактов, найденных при поиске. Например, если агент нашёл на веб-странице важную цифру или утверждение, имеет смысл сохранить этот факт в базу знаний, чтобы при формулировании ответа или в будущих запросах не искать его повторно.
-
Запоминания прошлых диалогов и задач. В исследовательском прототипе можно игнорировать многосессионость, но при расширении системы полезно хранить историю взаимодействия с пользователем, предпочтения, контекст. Redis позволяет сохранять хронику диалога и затем восстанавливать её при новом обращении (LangChain, например, предоставляет
RedisChatMemoryдля хранения сообщений чата в Redis (Redis | ️ LangChain) (Redis | ️ LangChain)】. -
Персонализация и обучение на опыте. Агент может со временем пополнять свою базу знаний новыми сведениями: результаты аналитики, сделанные выводы. Это напоминает, как человек записывает выученное. Затем при решении новой задачи можно делать поиск по памяти для извлечения релевантных прошлых знаний.
Реализация памяти с помощью Redis. Два основных подхода к долговременной памяти: символьный и векторный. Символьный – хранить информацию в виде текста (JSON, строки) по определённым ключам. Например, можно индексировать факты по их заголовкам или категориям. Но более универсальный подход – векторное хранилище (Vector Store): перед сохранением факт пропускается через модель эмбеддингов, и его embedding-версия сохраняется. Redis (с модулем Redis Search/Vector Search) может выступать в роли векторной базы данных, позволяя делать семантический поиск по близости эмбеддинго (Redis | ️ LangChain)】. В LangChain есть интеграция: RedisVectorStore превращает Redis в векторное хранилище документов, с возможностью затем получать Retriever для выборки по схожест (Redis | ️ LangChain)】. Это как раз подходит для хранения знаний: можно сохранить текстовые факты или даже целые документы, а при необходимости – запрашивать наиболее похожие по смыслу к текущему вопросу. Такой подход известен как Retrieval-Augmented Generation (RAG): прежде чем генерировать ответ, агент достаёт из памяти несколько наиболее релевантных «воспоминаний» и добавляет их в контекст (кратковременную память).
Помимо фактов, можно хранить и «умения» агентов. Выше описывалась идея хранить описания инструментов – это тоже вид долговременной памяти (база знаний о способностях системы). Её тоже можно держать в Redis, в отдельном пространстве имен. Например, ключи вида tool:{имя} → значение: описание, либо векторное представление описания для семантического выбора.
Практический пример из Auto-GPT: там реализована возможность подключения векторной БД для памяти; в исходном проекте предлагаются Pinecone, Milvus, Weaviate и другие. Суть в том, что агент Auto-GPT может заносить в память результаты своих действий, а потом загружать релевантные куски при следующих итерациях. В частности, разработчики Auto-GPT отмечают, что долговременная память позволяет хранить огромные объёмы знаний, подгружая только нужные в каждую конкретную итераци ([PDF] PDF Guide - AutoGPT) (Giving Auto-GPT Long-Term Memory with Weaviate | Weaviate)】. Это помогает агенту сохранять «контекст» даже при решении задач, требующих десятки шагов (превышающих окно контекста модели).
Использование памяти в ходе работы: Оркестратор перед началом новой задачи может выполнить поиск по долговременной памяти, чтобы извлечь известные факты по теме. Например, если запрос связан с конкретной компанией, агент может вспомнить, что ранее уже искал информацию об этой компании, и сразу загрузить эти сведения. Далее, по мере выполнения шагов, результаты каждого важного действия сохраняются: нашли страницу – ее краткое содержание и ключевые данные сохраняются; завершили вычисление – формула и результат сохраняются и т.п. В конце сессии можно по желанию сохранить финальный вывод (например, выводы анализа) для будущих нужд.
Ограничение памяти: Необходимо продумать, что сохранять, чтобы база не разрасталась бесполезно. Решение – сохранять именно факты/знания, очищенные от временных мыслей. Например, сохранять стоит ответы на конкретные подзапросы, цифры, имена, отношения – то есть структурированную информацию. А вот цепочку reasoning из 50 шагов сохранять целиком нет смысла (можно лишь лог финальный хранить отдельно при отладке).
Итак, сочетание кратковременной и долговременной памяти делает систему более контекстно-ориентированной и обучаемой. Кратковременная память – это то, над чем LLM «размышляет» сейчас, а долговременная – то, что он «знает» из прошлого опыта. С технической стороны, реализации могут опираться на существующие решения: например, Upstash Redis (облачный Redis) уже используется сообществом для сохранения истории чатов LangChai (Add Long-Term Chat Memory to LangChain Applications - YouTube) (LangChain Memory Types: A Comprehensive Guide for Engineers)】, а LlamaIndex имеет средства для интеграции памяти и поиска по ней с помощью индексов различных типо (Memory - LlamaIndex)】.
Агенты и инструменты для выполнения задач
Система спроектирована для выполнения разнородных задач, упомянутых в требованиях: анализ текста, интернет-поиск, вычисления, веб-браузинг, и потенциально других. Рассмотрим, как каждый вид задачи вписывается в архитектуру и какие агенты или инструменты могут её решать:
-
Анализ текста. Сюда относятся задачи NLP: суммирование документа, извлечение ключевых фактов, классификация тональности, перевод и др. Такие задачи сама LLM способна выполнять на высоком уровне без внешних вызовов (это её внутренняя функция). Тем не менее, можно выделить агенты для некоторых подвидов анализа. Например, агент-экстрактор фактов может по запросу выделять из текста имена, даты, отношения и сохранять их (в виде триплетов) в базу знаний. Или агент-классификатор – модель поменьше, обученная на тональность, чтобы не гонять GPT-4 на простую метку. Однако в начальной версии можно считать, что анализ текста выполняется либо главным агентом (если это непосредственно вопрос пользователя: «проанализируй текст и ответь…»), либо суб-агентом, но всё равно с использованием LLM. Фреймворки облегчают это: например, можно подключить библиотеку spaCy или transformers-пайплайн для конкретных задач анализа (в качестве инструментов).
-
Поиск по интернету. Это критически важный тип действия для обеспечения актуальности и фактологичности. Агент-поисковик должен уметь по текстовому запросу вернуть список релевантных результатов (страниц, документов). Реализация: вызвать API поисковой системы (например, Bing Search API, Google Custom Search API) или использовать стороннюю библиотеку (той же LangChain есть инструмент
SerpAPIWrapperилиGoogleSearchAPI). В простейшем случае можно даже обращаться к Bing через неофициальный API или к DuckDuckGo (есть пакет duckduckgo-search). Результатом поиска будет список ссылок с аннотациями. Затем может потребоваться агент для перехода по ссылкам. В примере многоагентной системы от HuggingFace есть Web Search Agent, который использует два инструмента: выполнить поисковый запрос и *открыть веб-страницу (Multi-Agent Systems - Hugging Face Agents Course)】. У нас можно схожим образом: отдельный инструментsearch(query)возвращает ссылки, и инструментvisit(url)качает содержимое страницы (HTML или текст). Оркестратор, исходя из задачи, может несколько раз выполнить поиск с разными уточнениями или обойти несколько ссылок, прежде чем соберёт нужные факты. Все найденные данные идут в память фактов. -
Вычисления. Под этим можно понимать как арифметические расчёты, так и выполнение произвольного кода/скриптов. LLM хорошо умеют считать в пределах, но склонны к ошибкам в длинной арифметике. Поэтому часто агентам дают инструмент калькулятора. В LangChain есть, например,
LLMMathChain, который пытается сначала решить математически, а если не может – вызывает Python для вычислени (Using LangChain ReAct Agents to Answer Complex Questions)】. Мы можем реализовать агент Code Interpreter, позволяя LLM генерировать код (Python) и запускать его, возвращая вывод. Это аналог недавно представленного OpenAI Code Interpreter плагина. В контексте GPT-4, можно ограничиться математическим движком: либо простымeval/execв sandbox (с защитой), либо вызовом специализированных библиотек (Sympy для алгебры, Numpy для статистики и т.д.). Кроме того, выполнение кода нужно не только для чисел: агент может, к примеру, захотеть преобразовать данные – тогда генерация и исполнение кода поможет. Этот инструмент достаточно рискованный (нужно изолировать окружение, контролировать время выполнения), но очень мощный. В упомянутом примере от HuggingFace Code Interpreter tool является одним из модулей, доступных менеджер (Orchestrate a multi-agent system )】. -
Веб-браузер (парсинг страниц). После поиска зачастую нужно получить содержимое страницы и вытащить из него нужное. Здесь нужен инструмент, который по URL возвращает текст. Это может быть простой HTTP GET запрос и затем фильтрация HTML (удаление тегов). Можно использовать библиотеки вроде requests + BeautifulSoup для парсинга. Либо более мощный подход – запуск headless-браузера (Selenium, Playwright) если нужно выполнить JS. Но в большинстве случаев текст доступен без этого. В некоторых проектах, например, Auto-GPT, реализован инструмент
browse_websiteдля чтения страниц. Он обычно возвращает ограниченное количество текста (чтобы не захламлять контекст). Можно использовать эвристики: например, сначала получить оглавление или summary (используя модель суммирования на полученном тексте), или дать LLM самой решить, какой фрагмент страницы читать (посредством поиска по текстру). Этот агент-браузер должен также уметь кликать ссылки или отправлять формы при необходимости. Но на исследовательском этапе можно ограничиться чтением статических страниц. -
Другие потенциальные инструменты. Система открыта для расширения: можно подключать API внешних сервисов по необходимости (например, новостные или финансовые данные), агента для генерации изображений (вызов diffusion-моделей), для распознавания речи (если когда-то потребуется аудио-ввод) и т.д. HuggingGPT демонстрирует, как LLM+инструменты могут охватывать межмодальные задачи – от текста к изображению, от речи к тексту и т.п ([2303.17580] HuggingGPT: Solving AI Tasks with ChatGPT and its Friends in Hugging Face)】. Наша архитектура это не исключает – достаточно добавить соответствующий модуль и дать описания.
Оркестрация выполнения. Главный агент, получив цель, определяет последовательность вызовов этих инструментов. Благодаря ReAct-подходу, он делает это шаг за шагом с проверкой. Например, задача: «Найдите текущий курс евро и постройте график за последний год». Оркестратор сначала думает: нужно найти курс и данные за год. Решает: Action: вызвать поиск «EUR to USD rate history». Получает ссылку на страницу с графиком. Observation: текст страницы или данные. Затем мысль: нужно построить график. Он может вызвать Code Interpreter, передав туда данные для построения графика (например, с помощью matplotlib), и получить картинку. Далее он может вернуть эту картинку или описание. При каждом шаге агент контролирует: получен ли нужный результат? Если нет – повторный поиск или изменение стратегии. Такая итеративная схема (план → действие → проверка) делает систему устойчивой к непредвиденным ситуация (Giving Auto-GPT Long-Term Memory with Weaviate | Weaviate)】: агент убеждается, что шаг выполнен успешно, прежде чем перейти далее, и при необходимости корректирует план действий, если, скажем, первый поиск не дал результата. В Auto-GPT это описано как обязательная проверка выполнения шага 1, прежде чем идти на шаг (Giving Auto-GPT Long-Term Memory with Weaviate | Weaviate)】. Наш оркестратор (GPT-4) будет аналогично анализировать наблюдения: если инструмент вернул ошибку или пустой результат, он попробует другой подход.
Интеграция с фактами. При работе инструментов, результаты сразу отправляются в память фактов. Например, поисковый агент нашёл цифру: «Инфляция в 2023 = 5%». Этот факт сохраняется в Redis (возможно с ключом «инфляция 2023») и параллельно идёт оркестратору. Оркестратор при формировании ответа может напрямую использовать наблюдения (которые в кратковременной памяти), а для увеличения достоверности может дополнительно сделать поиск по долговременной памяти: вдруг там есть связанные факты (скажем, инфляция 2022 для сравнения). Таким образом, инструменты и память работают в связке: инструменты добывают новые данные, память их удерживает для последующего использования.
Примечание по достоверности: Хотя наличие инструментов снижает риск галлюцинаций (LLM обращается за реальными данными), важно, чтобы оркестратор умел цитировать источники или проверять факты. Например, финальный ответ можно составлять, опираясь на контент памяти, и даже вернуть ссылки на источники (если требуется). В плане архитектуры это значит, что помимо основного ответа, оркестратор может собрать список использованных URL и включить их в вывод.
Основная модель (GPT-4) и поддержка различных LLM
В центре системы предполагается использовать GPT-4 (через API) в роли главного интеллектуального агента. GPT-4 обладает продвинутыми возможностями понимания контекста, логического вывода и планирования, что делает его подходящим «мозгом» оркестрации. Он будет выполнять роль как планировщика, так и генератора текстовых результатов. Однако архитектура не ограничивается именно GPT-4 – она задумана модель-агностичной. Это означает, что при необходимости можно подменить модель на другую, без изменения общего дизайна.
Поддержка различных моделей выражается в следующих аспектах:
-
Лёгкая заменяемость LLM. Благодаря использованию библиотек-обёрток (LangChain, aioredis, etc.), сменить модель можно, изменив несколько строк настройки. Например, вместо GPT-4 можно подключить open-source модель (Llama 2, GPT-J, etc.) через API HuggingFace. LangChain предоставляет единый интерфейс для разных LLM-провайдеров, а Semantic Kernel – абстракцию Kernel, куда можно регистрировать разные backends. Таким образом, экспериментально можно пробовать разные LLM (например, для снижения затрат – взять GPT-3.5 или локальный Llama2 70B). IBM описывает LangChain как унифицированную среду разработки почти для любого LLM, где модульный подход позволяет с минимальными изменениями переключаться между моделями и даже использовать *несколько LLM в одном приложении (What Is LangChain? | IBM)】. Последнее может быть актуально: можно использовать GPT-4 на критических шагах (планирование, финальный ответ), а где-нибудь внутри задействовать более дешёвую модель для черновых операций.
-
Использование нескольких моделей одновременно. Наша архитектура по сути это уже подразумевает: кроме основного LLM, задействуются «инструментальные» модели. Например, если анализ изображения – это вызов модели компьютерного зрения; или генерация текста может делегироваться другому LLM, специализирующемуся на стилизации. HuggingGPT именно это и делает – подключает множество моделей-друзей под управлением одного LL ([2303.17580] HuggingGPT: Solving AI Tasks with ChatGPT and its Friends in Hugging Face)】. Мы можем включить, например, отдельный LLM-агент для кодовых задач (например, Codex или StarCoder), если решим, что пусть код пишет специализированная модель. Главное, чтобы оркестратор умел к ней обращаться. Благодаря модульности, это возможно: оркестратор не «знает», GPT-4 или нет выполняет subtask – он получает результат через унифицированный интерфейс. Единственное, надо контролировать формат возврата (но это решаемо на уровне каждого агента-враппера).
-
Выход за пределы GPT. Хотя GPT-4 силён, закрытость модели может быть минусом (например, ограничение на контент, стоимость API). Поэтому архитектура готова к использованию open-source решений. Существуют модели типа Llama 2, GPT-4All, Falcon и др., которые можно развернуть локально. Их можно интегрировать как агентов (например, использовать Llama 2 70B в роли главного, если нет доступа к GPT-4). Также можно комбинировать: например, сделать систему, которая по необходимости вызывает Claude или PaLM API как альтернативу – в зависимости от доступности или цены. Фреймворки, опять же, позволяют это – LangChain поддерживает провайдеров Anthropic, Google, etc.
-
Обучение и тонкая настройка. На исследовательском этапе планируется опираться на существующие LLM (prompt engineering). Но архитектура не препятствует дальнейшему обучению моделей. Можно собрать датасет из траекторий работы системы (последовательности {мысль-действие-наблюдение}), подобно тому как в статье ReAct авторы генерировали такие траектории и дообучали меньшие модели на ни (ReAct: Synergizing Reasoning and Acting in Language Models) (ReAct: Synergizing Reasoning and Acting in Language Models)】. В перспективе, можно будет обучить своего оркестратора, чтобы он лучше справлялся в конкретном домене (например, корпоративные данные). Кроме того, храня данные взаимодействий, можно fine-tune сделать long-term memory подсказки.
Резюме: мы используем GPT-4 как сильную базу, но архитектура открыта к применению различных моделей и легко адаптируется под них. Это согласуется с трендом создания LLM-фреймворков: тот же LangChain декларирует модульность, позволяющую быстро сравнивать разные foundation-модели в одном окружени (What Is LangChain? | IBM)】. Такой гибкий подход защитит систему от зависимости от одного поставщика и позволит воспользоваться прогрессом в сфере open-source LLM.
Взаимодействие модулей: ход выполнения запроса (пример)
Рассмотрим пример, как все описанные компоненты взаимодействуют на практике, выполняя комплексный запрос пользователя. Допустим, пользователь спрашивает: «Проанализируй последние новости о климатических инициативах ООН и посчитай, сколько стран участвует в программе». Эта задача требует и поиска информации, и анализа текста, и простого подсчёта. Пошаговый сценарий работы системы может выглядеть так:
-
Обработка запроса и планирование. Запрос на естественном языке поступает в систему и передаётся главному LLM-агенту (GPT-4). Оркестратор распознаёт, что задача включает несколько частей: (а) найти последние новости о климатических инициативах ООН, (б) проанализировать эти новости, (в) извлечь число стран-участников. Агент размышляет над планом (ReAct Thought): «Вероятно, нужно выполнить поиск новостей, затем найти в тексте упоминание количества стран». Он может сформулировать план: найти новости → извлечь текст → отыскать число стран. Оркестратор обращается к реестру инструментов, выбирает Поисковый агент для первого шага. (Внутренне может происходить семантический подбор инструмента по ключевым словам «новости, ООН» – в итоге выбирается веб-поиск). Затем модель выдаёт команду (ReAct Action):
Search["последние новости климатические инициативы ООН"]. -
Поиск информации (инструментальный агент). Вызванный агент-поисковик (который под капотом обращается к поисковому API) получает запрос, выполняет поиск и возвращает оркестратору список топ-результатов. Например, это могут быть ссылки на статьи или пресс-релизы на сайтах ООН, новости на CNN и т.п. Оркестратор получает их как Observation. Он сохраняет их (в кратковременной памяти и, возможно, сразу в долговременную с меткой). Далее агент размышляет: «Нужно открыть соответствующую статью и вычитать детали». Возможно, он выберет самую релевантную ссылку (например, пресс-релиз ООН) – или несколько по очереди. Решим, что он выбирает одну ссылку и делает Action:
Visit[URL]. -
Извлечение контента (браузерный агент). Инструмент Visit обращается к модулю браузера: делает HTTP GET страницы по указанному URL. Допустим, возвращается HTML-текст новости «ООН объявила климатическую инициативу, присоединились X стран…». Агент-браузер парсит HTML, извлекает видимый текст (может отбросить меню, оставить основной контент). Затем он может вернуть весь текст или ключевые абзацы. Чтобы не перегружать LLM, агент может сам выделить предполагаемый релевантный фрагмент – например, найти в тексте число или словосочетания «страны», «участники». Тем не менее, можно упростить: вернуть 2-3 первых абзаца. Оркестратор принимает текст страницы как Observation. Этот текст также сохраняется (например, в Redis как документ, чтобы не потерять).
-
Анализ текста LLM-агентом. Оркестратор получает текст новости. Теперь его задача – найти в тексте информацию о количестве стран. Он может сделать это двумя путями: а) напрямую сам просканировать текст (в конце концов GPT-4 способен найти число в тексте, тем более текст у него в контексте сейчас), б) вызвать специализированный инструмент (скажем, агент-вопросоответчик или RegEx tool). В простом случае, оркестратор сам прочитает: в цепочке Thought он может написать: «В тексте говорится: “…initiative with participation of 50 countries” – значит 50 стран». Либо, если текст очень большой, можно применить инструмент Question Answering: например, LlamaIndex или LangChain могут построить временный индекс по полученному документу и задать туда вопрос. Но предположим, GPT-4 сам справляется. Он вычленяет число – скажем, находит «50» в контексте. Для надёжности, он может переспросить: Action: search в тексте слова “страна” (это локальный поиск по строке). Получает позиции, видит рядом число. Всё, теперь у него есть факт: 50 стран участвуют.
-
Вычисление (если требовалось). В данном примере особых вычислений нет, кроме как может сложить числа из разных источников. Допустим, если бы новости были две: одна говорит 50 стран, другая – ещё 5 новых присоединились, агент мог бы вызвать Python-код:
50+5. Но опустим этот нюанс. Если бы требовалось построить график или посчитать статистику – тогда бы агент задействовал Code Interpreter. Например, скачал бы данные (черезrequests), затем сгенерировал код для matplotlib и выполнил, вернув изображение. -
Формирование ответа. Оркестратор теперь имеет всю необходимую информацию: он знает, что последние климатические инициативы (из новости) – это про участие 50 стран, возможно у него есть названия инициатив. Он может для полноты открыть пару других ссылок, но предположим, одной достаточно. Теперь LLM генерирует финальный ответ для пользователя, например: «В последней климатической инициативе ООН участвуют 50 стран. Эта инициатива направлена на … (краткое резюме новости).» Чтобы быть фактологичным, агент может включить цитирование источника (если мы это запрограммируем), либо по крайней мере полагаться на сохранённый текст. В памяти у него хранится фраза, он может её перефразировать. Готовый ответ возвращается пользователю.
-
Сохранение в долговременную память. Завершающий этап (не обязательно явно заметный) – обновление базы знаний. Выделенные факты (например, «Инициатива ClimateAction: 50 стран-участников») сохраняются в Redis для использования в будущем. Также можно журналировать сам запрос и ответ для истории. В следующий раз, если придёт вопрос по этой же теме, система уже будет вооружена конкретными данными, возможно, не требуя повторного поиска.
Так выглядит поток данных между модулями. Здесь главный агент несколько раз чередовал мысль и действие: план → поиск → чтение → анализ → вывод. Каждый инструмент сработал по запросу и предоставил результат обратно LLM. Вся сложность «скрыта» внутри orkестратора – то есть GPT-4 получил соответствующие подсказки как форматировать свои мысли и команды. Например, prompt для GPT-4 мог выглядеть как:
Ты – умный помощник, у тебя есть инструменты:
1. Search(query) – искать в интернете информацию.
2. Visit(url) – скачать содержимое веб-страницы.
...
Следуй формату:
Thought: {твои размышления}
Action: {название инструмента}[{аргумент}]
Observation: {результат}
...
Начни.
С помощью такого шаблона GPT-4 генерирует действия, а код Python перехватывает строку Action: Search[...], вызывает соответствующую функцию, получает результат, добавляет в prompt как Observation: ... и снова вызывает GPT-4 с дополненным контекстом. Этот цикл продолжается, пока агент не выдаст ответ (Final Answer:). Подобная реализация есть в открытых фреймворках – например, LangChain Agents предоставляет готовый цикл исполнения агента с инструментами по описанию (ReAct loop).
В итоге, взаимодействие модулей обеспечивает сквозное решение задачи: от понимания запроса до возвращения результата, с привлечением множества разнообразных ресурсов. Ключевое преимущество такого подхода – гибкость: если изменятся условия (новые данные, уточнения от пользователя), агент просто сделает ещё несколько итераций цикла или скорректирует план, как сделал бы человек.
Инструменты и библиотеки для реализации
Реализация описанной системы в Python упрощается за счёт использования ряда открытых библиотек и платформ. Ниже приведены рекомендации по инструментам и краткое сравнение их возможностей:
-
LangChain – популярный фреймворк для оркестрации LLM-процессов. Он предоставляет абстракции для LLM-моделей, инструментов (Tools), памяти и цепочек вызовов. В нашем контексте LangChain полезен тем, что уже реализует логику агента по схеме ReAct, где модель автоматически выбирает и вызывает инструменты из списк (Using LangChain ReAct Agents to Answer Complex Questions)】. Плюсы: большое сообщество, много готовых интеграций (поисковые API, базы знаний, когнитивные услуги), поддержка как синхронного, так и асинхронного выполнения. Также LangChain имеет встроенные классы для памяти – например,
ConversationBufferMemoryдля хранения диалога илиVectorStoreRetrieverMemoryдля интеграции с векторным хранилищем (можно подключить RedisVectorStore (Redis | ️ LangChain)】. Плюсы: Быстрое прототипирование, унификация разных провайдеров LLM, богатая документация. Минусы: Абстракции могут быть сложными для тонкой настройки; добавление очень нестандартных поведений может потребовать вникания в исходный код агентов. -
LlamaIndex (ранее GPT Index) – фреймворк, изначально предназначенный для связи LLM с внешними данными (документами) через индексы. В контексте агентов LlamaIndex тоже стал поддерживать агентные возможности, в том числе имеет Agent API и поддержку множественных инструменто (Agents - LlamaIndex)】. Сильная сторона LlamaIndex – работа с данными: можно создавать индексы разных типов (векторные, графовые) для документов, и делать сложные запросы. Он отлично дополняет LangChain: например, управлять knowledge-base и memory через индексы. В нашем случае LlamaIndex можно использовать для реализации долговременной памяти: хранить факты/документы в индексах и делать retrieval, либо как прослойку между Redis и LLM (например, Index навыков). Также LlamaIndex поддерживает концепцию Composed orchestrator: в их примерах можно строить многослойных агентов, которые сами планируют и выполняют действия с помощью LlamaIndex. Плюсы: продвинутые возможности RAG (retrieval augmented generation), оптимизация работы с большим числом инструментов (через ToolRetriever (Retrieval-Augmented Agents - LlamaIndex)】, интеграция с LangChain (можно использовать индексы в LangChain). Минусы: Немного менее зрелая документация на момент 2024, меньшая экосистема инструментов по сравнению с LangChain; основной упор на работу с данными, поэтому чисто агентные аспекты могут требовать кастомизации.
-
Auto-GPT и подобные (BabyAGI) – это не библиотека, а готовые проекты-агенты, появившиеся в 2023 году, демонстрирующие автономную работу GPT-4. Auto-GPT написан на Python и по сути реализует цикл планирования и выполнения с памятью. Изучение его архитектуры полезно для нашего проекта: Auto-GPT имеет модуль Agent, список Tools (Google search, Python execution, etc. (Giving Auto-GPT Long-Term Memory with Weaviate | Weaviate)】, использует long-term memory (подключаемую через vector DB) и short-term memory (через prompts). Также он разбивает задачи на подзадачи и умеет генерировать новый план по результатам, без помощи человек (Giving Auto-GPT Long-Term Memory with Weaviate | Weaviate)】. Мы можем заимствовать идеи или даже компоненты. Например, можно взять модуль работы с памятью из Auto-GPT (он поддерживает Redis через plug-in) или посмотреть, как у него оформлен prompt (они добились некоторых хаков для стабильности). Плюсы: концепция готова – экономит время на проработку базового цикла; большое сообщество, много форков с улучшениями. Минусы: Auto-GPT как программа довольно монолитен и рассчитан на одну цель (весь цикл – одна большая задача), то есть у него нет явной архитектуры под многомодульность как HuggingGPT; код может оказаться сложным для встроения в другую систему, легче почерпнуть идеи.
-
Hugging Face Transformers / Agents – от сообщества HF есть несколько утилит. Во-первых, сами модели (через
transformersможно подключать локальные LLM или через API). Во-вторых, библиотека Huggingface smolGPT/agents (упомянутая выше в примере) – предоставляет упрощённые классы для агентов, совместимые с HF Inference API. Это может быть полезно, если хотим, например, использовать локальную модель Qwen-7B для исполнения кода, как в их пример (Orchestrate a multi-agent system )】, или взять доступ к репозиторию инструментов HF (Hugging Face имеет множество Spaces с апи, которые тоже можно дергать). Плюсы: открытость, репозитории моделей и датасетов под рукой; можно быстро подключить новую модель для эксперимента. Минусы: к 2025 году HF Agents – скорее набор примеров, не такой всеобъемлющий фреймворк, как LangChain. -
Semantic Kernel (Microsoft) – упомянутый SK представляет SDK (есть на C# и Python) для создания комплексных AI-решений. Он предлагает другой взгляд на оркестрацию: у него есть концепции Plugins (навыки), Memory (встроенное сохранение и поиск по эмбеддингам) и Planner (автоматическое планирование последовательности шагов (Diving into Microsoft Semantic Kernel | by Prarthana Saikia | Medium) (Diving into Microsoft Semantic Kernel | by Prarthana Saikia | Medium)】. По сути SK решает ту же задачу, что и мы – как по задаче пользователя подобрать функции и скомбинировать их. Planner в SK может работать двумя режимами: пошагово (Stepwise, аналог ReAct) или сразу предлагая полный план. Интеграция памяти позволяет Planner’у выбирать действия на основе прошлых данных или подсказок из базы знани (Diving into Microsoft Semantic Kernel | by Prarthana Saikia | Medium)】. Microsoft активно развивает SK, он хорошо интегрируется с Azure (например, можно подключить Azure OpenAI, CognitiveSearch для знаний). Плюсы: Хорошая поддержка от Microsoft, надёжность; возможности для enterprise-интеграции (Graph, Outlook, etc.); поддержка plugin-интерфейсов как в OpenAI (можно описать функции так, что и ChatGPT Planner их поймёт). Минусы: Меньшее сообщество, особенно для Python-версии, многие примеры и фишки на C#; философия немного иная, может быть сложнее реализовать произвольную логику по сравнению с прямым Python-кодом. Тем не менее, SK можно рассматривать как альтернативу LangChain+Custom code для построения прототипа.
-
Redis – как основа для памяти, уже обсуждалось. Из инструментов: библиотека
redis-pyдля прямого взаимодействия, илиredisearch/redis-vectorдля работы с векторами. Есть и интеграции: например, RedisMemory в LangChain (которая может автоматически сохранять истории (Redis | ️ LangChain)】. Также можно использовать ORM-уровень: например, Redis OM или даже простой Python словарь, привязанный к Redis. -
Прочие: В зависимости от деталей реализации могут понадобиться вспомогательные библиотеки:
requestsдля HTTP,beautifulsoup4илиreadabilityдля парсинга HTML (чтобы браузер-агент вытаскивал текст страницы),numpy/pandasдля обработки данных,matplotlibдля визуализаций (если решим генерировать графики как часть ответа),tiktokenдля подсчёта токенов (чтобы не переполнить контекст). Для эмбеддингов – либо API OpenAI (векторные представления текста через модель типа ada-002), либо открытые модели (SentenceTransformers). Кстати, LlamaIndex и LangChain упрощают работу с эмбеддингами и векторными базами, абстрагируя их.
Отдельно про интеграцию GPT-4: будем пользоваться либо официальным OpenAI API (с моделью gpt-4), либо, если это on-premise сценарий, можно задействовать местный аналог (например, gpt4all с локальной моделью, хотя качество ниже). OpenAI API позволяет задать системное сообщение, множество примеров, что помогает обучить оркестратора на правильный формат ReAct. Важный инструмент – мониторинг и логирование. Рекомендуется логировать все шаги (мысли и действия) для отладки. Тут пригодятся либо простое логирование в файл, либо готовые инструменты, как LangChain Trace (телеметрия запусков агентов), либо даже внешние наблюдатели (например, Weight & Biases можно приспособить).
Альтернативные архитектурные решения: сравнение
При разработке подобных агентных систем возможно несколько архитектурных вариантов. Опишем основные альтернативы и их плюсы/минусы по сравнению с выбранным подходом:
1. Единый LLM-агент с инструментами (без явного оркестратора)
Это упрощённая архитектура, где один и тот же LLM выполняет и роль планировщика, и исполнителя всех действий. Собственно, в нашем описании главный агент и так делает почти всё, но отличие здесь в том, что специализированных подагентов нет вовсе. LLM напрямую вызывает примитивные инструменты (поиск, код, браузер) и сама же обрабатывает их результаты. Такой подход реализован, к примеру, в базовом ReAct-agent LangChain или в самом первом примере Auto-GPT.
-
Плюсы: минимальная сложность – не нужно управлять несколькими моделями, весь контекст у одной модели, что упрощает передачу данных (не нужно сериализовать и пересылать между агентами). Проще отлаживать поначалу. Производительность может быть выше, так как избегаем лишних обращений к разным моделям.
-
Минусы: ограниченная модульность – вся логика завязана на одну LLM, трудно заменять части. Нет специализации: одна модель должна быть универсалом во всём, что может быть менее эффективно, чем использование узких экспертов. Масштабируемость ниже: нельзя параллельно выполнять действия (LLM последовательно выводит их). Кроме того, такая система сильнее зависит от контекстного окна LLM – все инструменты и знания должны поместиться ей в prompt.
Когда выбрать: если задача относительно простая или однотипная (например, только веб-ассистент с поиском и одной моделью), то монолитный ReAct-агент будет достаточен. Но для сложных, мульти-модальных задач (как HuggingGPT решает), лучше разнести на несколько агентов.
2. Многоагентная система без централизованного управляющего
Другой вариант – распределённая система, где нет единого «менеджера», а несколько агентов взаимодействуют на равных. Например, два LLM-агента могут вести диалог: один генерирует предложения решения, другой критикует и указывает на ошибки (подход «self-play» или «адвокат-дьявол»). Либо архитектура BabyAGI: там задачи генерируются одним агентом, а выполняются другим, плюс есть агент-приоритизатор. В BabyAGI формально есть центральная петля, но по сути три роли (генератор задач, исполнитель, приоритизатор) работают итеративно без одного главног (BabyAGI - Naptha Docs) (BabyAGI, the Start of Computers Working on Their Own)】.
-
Плюсы: появляется возможность экспертной оценки решений и более творческого подхода. Агенты могут взаимно дополнять друг друга – например, один специализируется на генерации идей, другой – на проверке фактов. В исследованиях OpenAI (про критиков) или Microsoft Autogen такие схемы показали уменьшение галлюцинаций и более надёжные решения. Распределённая система также естественно масштабируется в сторону параллелизма – агенты могут одновременно работать над разными аспектами задачи, общаясь по необходимости.
-
Минусы: сложность координации возрастает многократно. Без единого контроллера трудно гарантировать, что агенты не зайдут в тупик или не будут бесконечно спорить. Требуется протокол общения (формат сообщений, язык коммуникации). Возможны ситуации гонок или противоречий. Отладка сложнее – нужно прослеживать диалог между агентами. В итоге, часто приходится всё же вводить неявный управляющий скрипт или правила. Поэтому полностью децентрализованные LLM-системы пока менее распространены.
Применение: такой вариант интересен для экспериментов с автономным поведением или эмуляции группы агентов (например, «виртуальная команда», где каждый с разной личностью/ролью). В продуктивных решениях чаще придерживаются иерархии с координатором.
3. Открытые API-функции и плагины вместо текстовых команд
Наш проект следует классическому ReAct, где LLM выдаёт текстовые указания, которые парсер интерпретирует как вызов инструмента. Альтернатива – использовать структурированные функции, например, как в OpenAI Function Calling. В этом подходе инструменты регистрируются не через текст в prompt, а через API, и LLM возвращает JSON с именем функции и аргументами. Плагиновый подход ChatGPT тоже похож: модель предсказывает, какую функцию вызвать, и платформа сама вызывает её, возвращая результат в следующий prompt.
-
Плюсы: Более формальное взаимодействие, меньше шансов неправильного парсинга. Модель тратит меньше токенов на описание инструмента (оно передаётся вне основного prompt). Можно строго задавать типы данных, что облегчает последующую обработку. Такой подход снижает «токеновую нагрузку» и может ускорить процесс.
-
Минусы: Пока что эта функциональность доступна в основном через закрытый API OpenAI. Использование JSON функций внутри открытых моделей требует их обучения на соответствующий формат или сложной валидации. Кроме того, теряется часть прозрачности: сложно включить в chain-of-thought объяснение, почему модель решила вызвать функцию – хотя можно её побудить написать комментарий, но сам механизм предполагает скрытый выбор. В ReAct же мы явно видим рассуждение.
В контексте нашего проекта можно сочетать подходы: GPT-4 (через API) может вызывать функции (search, browse) напрямую, а мы параллельно логируем его chain-of-thought. Однако, на исследовательском этапе текстовый ReAct более понятен и контролируем.
4. Различия в планировании: заранее составленный план vs динамический ReAct
Есть два стиля: HuggingGPT и SK Planner стараются сначала получить целый план из нескольких шагов, затем исполняют по порядку. Другое дело – ReAct, где план строится по ходу (модель может не знать заранее, сколько шагов потребуется). Возможен и гибрид: модель примерно планирует, но допускает коррекцию.
-
Плюсы заранее планирования: Оркестратор может глобально оценить структуру решения, что бывает полезно для оптимальности (например, не делать лишних действий). Можно пользователю показать план перед выполнением (для одобрения, если нужно). Минус – модель может ошибиться в плане, и если жестко следовать, будет провал.
-
Плюсы динамического: Высокая гибкость, адаптация к новым данным на лету. Минус – иногда модель может зациклиться или топтаться, если не видит всей картины сразу.
Наш подход в основном динамический (ReAct), но его можно обогатить лёгким первоначальным планированием: попросить LLM сгенерировать список подзадач, затем выполнять их ReAct-стилем. В LangChain, кстати, есть агент Plan-and-Execute, реализующий такую идею: сначала Plan-компонент (LLM) генерирует список действий, потом Execute-компонент выполняет их по одному с возможной корректировкой.
5. Выбор фреймворков и экосистемы
Можно выделить и альтернативы по инструментариям:
-
Использовать LangChain vs писать с нуля. Плюсы LangChain: быстрее собирать, много готового (меньше ошибок на базовых вещах). Минусы: может быть избыточным, и для очень кастомных вещей иногда проще написать свой цикл.
-
Использовать Semantic Kernel vs LangChain. SK более системный подход, хорош в .NET экосистеме. LangChain – более pythonic, с большим комьюнити. Возможно, выбор зависит от того, где будет развёртываться (в Azure среде – SK отлично встанет, в open-source Python – LangChain/LLamaIndex).
-
Базы данных для знаний: у нас Redis – но можно рассмотреть Weaviate, Pinecone, FAISS. Pinecone – облачная специализированная векторная БД (очень хорошая, но внешняя зависимость). FAISS – локальная библиотека от Facebook, можно хранить embeddings на диске, но потребуется свой серверный код. Redis выигрывает простотой и тем, что у нас не огромные данные пока.
-
Выбор моделей: GPT-4 – top-notch качество, но дорого и закрыто. Альтернатива – Llama 2 70B или его потомки (которая может быть размещена на сервере с GPU), либо Claude-instant (Anthropic, хороший контекст 100k, но тоже API). Можно даже комбинировать: например, использовать GPT-4 для сложных рассуждений, а для рутинных ответов – более дешёвый GPT-3.5.
В таблице ниже кратко сведены некоторые варианты архитектур с их сильными и слабыми сторонами:
| Вариант архитектуры | Плюсы | Минусы |
|---|---|---|
| Mono-LLM агент (ReAct) (один LLM делает всё) | - Простота реализации и отладки- Меньше оверхеда между модулями- Все данные в одном контексте | - Нет специализации, нагрузка на одну модель- Сложно добавлять новые навыки модульно- Ограничения контекста и последовательность действий |
| Orchestrator + Tools (наш подход, один LLM + инструменты) | - Прозрачность логики (ReAct)- Гибкость действий, адаптация плана на лет (ReAct: Synergizing Reasoning and Acting in Language Models)】- Относительная простота по сравнению с множеством LLM | - Если оркестратор ошибся, некому его поправить- Последовательное выполнение шагов может быть медленным- Оркестратор должен иметь высокий уровень интеллекта (требует мощной модели) |
| Orchestrator + Multi-Expert LLMs (HuggingGPT, несколько моделей) | - Специализация: каждый саб-агент лучше решает свою задачу (NLP, CV, расчёты ([2303.17580] HuggingGPT: Solving AI Tasks with ChatGPT and its Friends in Hugging Face)】- Возможность параллелить независимые подзадачи- Легко расширять новыми экспертами | - Сложнее инфраструктура (надо вызывать и хранить несколько моделей)- Нужна единая “языковая шина” между ними (формат данных)- Потенциально выше стоимость (много моделей = много вычислений) |
| AutoGPT-подобный автопилот (автономный цикл, задачи сам себе ставит) | - Максимальная автономность, минимум человеческого вмешательств ([Giving Auto-GPT Long-Term Memory with Weaviate | Weaviate](https://weaviate.io/blog/autogpt-and-weaviate#:~:text=ChatGPT%20requires%20humans%20to%20prompt,ability%20to%20chain%20together%20thoughts))】- Может работать над общей целью неопределённо долго, генерируя подцели- Имеет память для обучения на своих же выводах |
| Многоагентное взаимодействие (кооператив) (несколько LLM общаются) | - Каждого агента можно настроить на свою роль (генератор идей, проверяющий и т.д.)- Уменьшает вероятность грубых ошибок – агенты друг друга корректируют- Интересно для исследований (эмерджентное поведение) | - Очень сложная координация, нет гарантии конвергенции- Большие затраты токенов на “разговоры” агентов- Нет широко готовых фреймворков, больше экспериментальный подход |
| Planner + Executor (плагин/планировщик Semantic Kernel) | - Часть работы (план) выполняется эффективно разо ([Diving into Microsoft Semantic Kernel | by Prarthana Saikia |
Как видно, наш выбранный подход (централизованный агент + гибкое привлечение инструментов) находится где-то посередине этих вариантов, сочетая сильные стороны: гибкость, модульность, прозрачность. Более сложные схемы (multi-LLM, multi-agent) потенциально дают выигрыш в специализации и надежности, но добавляют сложности в реализации и отладк (AI Agents: Demystifying the Tradeoffs)】. Простые же схемы (единый агент без памяти или без инструментов) не удовлетворяют всем требованиям задачи. Поэтому гибридный подход с ReAct-оркестратором представляется оптимальным компромиссом на этапе исследования.
Заключение
Подытоживая, архитектура гибридной системы LLM-агентов на Python включает: центральный LLM-агент (GPT-4), действующий по принципу ReAct (чередуя размышления и вызовы модульных инструментов), систему оркестрации а-ля HuggingGPT для делегирования подзадач экспертным агентам, а также подсистемы памяти – кратковременной (контекст решения) и долговременной (база знаний на Redis) – для учёта фактов и опыта. Такая система способна выполнять сложные многоэтапные запросы, требующие поиска информации, её анализа, вычислений и взаимодействия с внешним миром (веб-страницы, API). Она сохраняет фактические данные и способна перестраивать свой план действий динамически, когда получает новую информаци (ReAct: Synergizing Reasoning and Acting in Language Models)】.
Мы рассмотрели и альтернативные подходы, сравнив их достоинства и недостатки. На текущем этапе, опираясь на требования (гибкость важнее скорости), предложенная архитектура выглядит наиболее сбалансированной. Она опирается на современные наработки (ReAct, HuggingGPT, AutoGPT) и активно использует доступные open-source инструменты: LangChain и LlamaIndex для построения агента и интеграции данных, Redis для организации памяти, а также экосистему моделей (от GPT-4 до open-source LLM) для наполнения интеллектом каждого компонента.
Источники и ссылки:
-
Описание парадигмы ReAct (Reason+Act) и её преимуществ (ReAct: Synergizing Reasoning and Acting in Language Models) (ReAct: Synergizing Reasoning and Acting in Language Models) (ReAct: Synergizing Reasoning and Acting in Language Models)】.
-
Концепция HuggingGPT – оркестрация задач центральным LLM через подключение специализированных моделе ([2303.17580] HuggingGPT: Solving AI Tasks with ChatGPT and its Friends in Hugging Face)】.
-
Многоагентные системы и иерархия агентов (менеджер vs рабочие агенты (Multi-Agent Systems - Hugging Face Agents Course) (Multi-Agent Systems - Hugging Face Agents Course)】.
-
Использование Redis для долговременной памяти, векторное хранилище и извлечение знани (Redis | ️ LangChain) (Redis | ️ LangChain)】.
-
Примеры интеграции инструментов (поиск, браузер, код) в существующих решения (Giving Auto-GPT Long-Term Memory with Weaviate | Weaviate)】.
-
Проект Auto-GPT – демонстрация автономного цикла планирования и выполнения с память (Giving Auto-GPT Long-Term Memory with Weaviate | Weaviate)】.
-
Инструментарий: LangChain (оркестрация LLM, инструменты (What Is LangChain? | IBM)】, LlamaIndex (агенты с памятью (Agents - LlamaIndex)】, Semantic Kernel (планировщик с памятью (Diving into Microsoft Semantic Kernel | by Prarthana Saikia | Medium)】 и др.
-
Сравнение простых и сложных LLM-агентов, вопрос модульности vs сложност (AI Agents: Demystifying the Tradeoffs)】.