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

Первым делом мы решили воспроизвести G-Designer. В этой работе коммуникационная топология мультиагентной системы оптимизирована с помощью графовой нейросети: агенты представлены вершинами, обмен сообщениями — рёбрами, а итоговый граф должен лучше соответствовать решаемой задаче.

С воспроизводимостью всё оказалось сложнее. Повторить весь заявленный процесс по опубликованному коду не получилось. Но постановка задачи была слишком интересной, чтобы останавливаться. Мы начали писать собственную реализацию, а средой выполнения выбрали LangGraph.

И тут эксперимент про оптимизацию графов неожиданно превратился в эксперимент про ограничения агентных фреймворков.

Коротко: в LangGraph удобно выбирать маршрут внутри заранее описанной схемы, но нам требовалось менять сам граф агентов во время текущего запуска. Поэтому мы написали gMAS — открытый Python-фреймворк поверх rustworkx, где RoleGraph остаётся изменяемой структурой данных. В опытах с поочерёдным отключением механизмов досрочная остановка сокращала расход токенов на 52,6%, а обучаемое прореживание графа — на 27%. Пакет уже опубликован на PyPI и устанавливается через pip install frontier-ai-gmas. У проекта есть также и визуальный слой — flowMAS: в нём граф можно собрать на рабочем поле, запустить и наблюдать за изменениями топологии без погружения в Python-код. Эту часть покажем ближе к концу статьи.

Маршрутизация — ещё не изменение графа

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

Чтобы дальше не рисовать абстрактные вершины, будем использовать один условный пример. Представим мультиагентную систему для подготовки ответа: router принимает задачу, researcher собирает факты, analyst разбирает альтернативы, critic проверяет результат, editor объединяет материалы, synthesizer готовит итоговую версию, а writer выпускает финальный текст. Этот граф будет переиспользован в следующих схемах — меняются только активный маршрут и топология.

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

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

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

  • удалить ребро или изменить его вес;

  • отключить агента;

  • добавить новую вершину;

  • вставить проверяющего после уже выполненного шага;

  • заменить агента, формирующего финальный ответ;

  • пересчитать план для ещё не выполненных шагов.

Но это уже не маршрутизация, а другое требование к среде выполнения.

Динамическая маршрутизация: выбрать путь внутри заранее заданного графа

Изменение топологии: изменить сам граф и продолжить текущий запуск

В LangGraph структура компилируется перед выполнением. Условные переходы и Command(goto=...) позволяют менять ход выполнения, но выбор всё равно происходит среди заранее описанных узлов и переходов. Если оптимизатор выдаёт новую матрицу смежности, граф приходится собирать и компилировать заново.

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

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

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

Это был хороший момент остановиться.

Почему rustworkx?

Во время работы мы обратили внимание на rustworkx — библиотеку графовых структур и алгоритмов с Python API, где критичные операции реализованы на Rust. Она не пыталась быть агентным фреймворком, и в нашем случае это оказалось преимуществом. Мы получили обычный изменяемый ориентированный граф без заранее заданной модели исполнения. Вершины и рёбра можно было добавлять и удалять, веса — обновлять, а топологию — анализировать прямо в том же объекте, с которым работал оптимизатор.

Поверх rustworkx мы закончили собственное воспроизведение G-Designer. Правда, в наших запусках алгоритм примерно в 95% случаев сворачивал систему в одну вершину. Формально граф становился дешевле, но от мультиагентности в нём почти ничего не оставалось. Почему так происходило и насколько это связано с целевой функцией, — отдельная история.

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

Так появился gMAS.

Что именно мы написали

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

Поэтому в gMAS разделены две сущности:

  • RoleGraph хранит текущее устройство системы: агентов, связи, веса, условия переходов, начальную и конечную вершины;

  • ExecutionPlan описывает, как этот граф должен быть выполнен в конкретном запуске.

Граф хранит состояние мультиагентной системы, а план описывает её текущее выполнение.

В простейшем случае система собирается так:

graph = build_property_graph(
    agents=[researcher, critic, writer],
    workflow_edges=[
        ("researcher", "critic"),
        ("critic", "writer"),
    ],
    query=query,
)

RoleGraph — не просто список переходов. У вершин и рёбер есть идентификаторы, веса, вероятности, условия и состояние, связанное с выполнением. Граф можно представить в виде матрицы смежности, передать графовому алгоритму или экспортировать в формат PyTorch Geometric.

Когда граф меняется, gMAS синхронизирует его представление, матрицы и данные AdaptiveScheduler. Раньше именно этот код жил у нас в адаптерах вокруг LangGraph.

Как проходит один запуск

Сначала AdaptiveScheduler получает актуальный RoleGraph и составляет ExecutionPlan: определяет достижимые вершины, зависимости, порядок выполнения и группы агентов, которые можно запустить параллельно.

Затем MACPRunner запускает план. После каждого шага он:

  1. сохраняет ответ и статус агента;

  2. учитывает токены и время;

  3. обновляет память и метрики;

  4. отправляет событие обработчикам;

  5. проверяет условия переходов, бюджет и правила изменения топологии.

Если ничего не изменилось, то выполняется следующий шаг. Если маршрут или граф изменились, MACPRunner заново составляет план только для ещё не выполненных шагов. Завершённые агенты не запускаются повторно, а их ответы остаются в контексте.

Так можно менять не прошлое, а ещё не выполненную часть системы. Для оптимизационных экспериментов это принципиально: алгоритм может принимать следующее решение после каждого ответа, а не только перед запуском графа.

Три уровня динамики

Не каждое ветвление требует перестройки топологии. Поэтому в gMAS есть несколько уровней управления.

Первый — условия на рёбрах. router может отправить запрос в разные ветви по ключевому слову, метаданным или результату пользовательской функции. Граф при этом остаётся прежним: меняется активный маршрут.

Второй — готовые условия досрочной остановки:

config = RunnerConfig(
    adaptive=True,
    early_stop_conditions=[
        EarlyStopCondition.on_keyword("FINAL_ANSWER"),
        EarlyStopCondition.on_token_limit(5000),
        EarlyStopCondition.on_agent_count(5),
    ],
)

Для этих случаев не нужно писать собственный обработчик.

Третий уровень — изменение ещё не выполненной части системы. Допустим, исходный граф выглядел так: researcher → critic → writer. researcher уже вернул достаточно подтверждённый результат. Промежуточную проверку можно пропустить, а writer запустить сразу:

return TopologyAction(
    skip_agents=["critic"],
    force_agents=["writer"],
)

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

Через TopologyAction можно пропускать и принудительно запускать агентов, добавлять и удалять рёбра, вставлять цепочки восстановления, менять финального агента или досрочно завершать выполнение. Публичный API RoleGraph при этом остаётся доступен для собственных контроллеров с обучением с подкреплением, графовых политик и алгоритмов планирования.

Именно здесь появляется практический выигрыш. В опытах с поочерёдным отключением механизмов досрочная остановка уменьшала расход токенов на 52,6%, время выполнения — на 45%, а среднее число выполненных агентов — на три. Ниже разберём этот эксперимент подробнее.

Что уже есть из алгоритмов

Когда мы начинали, gMAS был почти тонкой оболочкой вокруг rustworkx. Затем в экспериментах стали повторяться одни и те же задачи: найти слабое ребро, сократить граф, выбрать перспективный маршрут или определить критического агента. Постепенно эти операции переехали в сам фреймворк.

Задача

Что есть в gMAS

Маршрутизация

Топологический и взвешенный топологический обход, жадный и лучевой поиск, поиск k кратчайших путей.

Динамическое прореживание

Пороги по весам, вероятностям и качеству ответа, учёт ошибок и токен-бюджета.

Оптимизация топологии

Реализация AgentPrune с обучением весов и удалением рёбер.

Анализ графа

Центральности, сообщества, критические вершины, циклы и поиск путей.

Автопостроение

AutoGraphBuilder, предлагающий состав агентов и связи под задачу.

Обучаемая маршрутизация

Экспорт в PyG и компоненты для GCN, GAT и GraphSAGE.

Простое прореживание встроено в AdaptiveScheduler. Через PruningConfig можно не запускать ветви с низким весом или вероятностью, учитывать оценку качества, исключать агентов после нескольких ошибок и не давать системе разрастаться после исчерпания бюджета.

Отдельный модуль agentprune оптимизирует веса рёбер по результатам запусков, а затем удаляет часть наименее полезных связей. Полученный граф не нужно преобразовывать обратно в исполняемую схему: это тот же RoleGraph, который можно сразу передать исполнителю и сравнить с исходной версией.

Полноценная замена LangGraph?

gMAS не требует обучать router или запускать прореживание. На нём можно собрать обычную мультиагентную систему и выполнять её как статический граф. MACPRunner поддерживает синхронный, асинхронный и потоковый запуск, параллельные ветви и разные модели для разных агентов. Из инструментов доступны Python, поиск по файлам, командная строка, веб-поиск и MCP. Есть повторные попытки с нарастающей задержкой, запасные агенты и ограничения по токенам, времени, шагам и итерациям.

Память разделена на рабочую, долговременную и общую. Записи могут иметь срок жизни, приоритеты и теги; для общей памяти отдельно задаётся, какие сведения видят несколько агентов. Это позволяет не превращать весь запуск в один бесконечно растущий журнал диалога.

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

запустить граф

    → собрать метрики

        → изменить веса или топологию

            → запустить снова

PyTorch Geometric нужен только для обучаемой маршрутизации: RoleGraph экспортируется в PyG, после чего можно применять GCN, GAT, GraphSAGE или собственную графовую нейросеть. Обычные условия, бюджеты, пороговое прореживание и TopologyAction работают без заранее обученной модели.

Почему контрольные точки не стали ядром системы?

У gMAS сейчас нет аналога langgraph-checkpoints с надёжным возобновлением, историей состояния и возвратом к предыдущим состояниям. Это сознательный пробел. Контрольная точка связана не только с сообщениями агентов, но и с конкретной версией графа, журналом применённых изменений и позицией внутри плана.

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

Если для проекта важнее контрольные точки, прерывания и длительное выполнение с участием человека, то LangGraph сейчас объективно сильнее. Если объектом исследования является топология, то нам удобнее gMAS.

А теперь — работает ли это быстрее?

Удобный API ещё ничего не доказывает. Можно написать отличный интерфейс для удаления рёбер, а потом выяснить, что в реальных задачах он только добавляет накладные расходы.

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

Поэтому мы разделили оценку на несколько вопросов:

  1. Создаёт ли среда выполнения заметные накладные расходы при одинаковой работе?

  2. Сколько можно сэкономить, если не выполнять ненужную работу?

  3. Может ли обучаемое прореживание найти граф лучше исходного?

  4. Что произойдёт в задачах с инструментами?

Как сравнивали

Базовой реализацией для сравнения стал LangGraph. Для обеих систем мы зафиксировали одинаковые роли, промпты, модели, серверы моделей, параметры генерации, условия остановки и ограничения параллелизма.

В парное сравнение вошли 68 сочетаний модели, набора данных и топологии:

  • три набора задач на рассуждение: BIG-Bench Hard, GSM8K и MMLU-Pro;

  • четыре топологии: один агент, цепочка из трёх агентов, схождение и расхождение ветвей;

  • шесть обозначений моделей: qwen3.5-35-A3B, qwen3.5-9b, qwen3.5-4b, gemma-12b, gpt-oss-20b и gpt-oss-120b;

  • по 50 задач в каждом срезе; gpt-oss-120b запускали только на GSM8K и MMLU-Pro.

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

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

Публичная версия на момент публикации — gMAS 0.1.2, тег v0.1.2, ревизия 00af659. API тестируется на Python 3.12 и 3.13. В uv.lock зафиксированы rustworkx 0.18.1, LangGraph 1.2.11, PyTorch 2.13.0, NumPy 2.5.2, SciPy 1.18.0 и datasets 5.0.1.

Минимальная команда для повторения сравнения топологий:

uv sync --extra benchmarks
uv run python -m benchmarks.topology.run \
  --datasets big-bench-hard,gsm8k,mmlu-pro \
  --max-samples 50 \
  --temperature 0.7 \
  --max-tokens 8192 \
  --parallel 50 \
  --runs 1

Код экспериментов и полный протокол находятся в документации gMAS и репозитории.

Одинаковые графы: проверяем среду выполнения

В первом эксперименте топологии и количество вызовов были одинаковыми. Это не проверка динамического прореживания, а измерение накладных расходов дополнительного слоя gMAS.

Топология

Время, gMAS / LangGraph

Токены, gMAS / LangGraph

Изменение точности

Вызовы модели

Single

3,8 / 4,0 с (−4,9%)

518 / 534 (−3,0%)

+0,6 п. п.

1 / 1

Chain-3

15,7 / 15,9 с (−1,4%)

2685 / 2672 (+0,5%)

+2,1 п. п.

3 / 3

Fan-in

18,3 / 20,7 с (−11,6%)

4152 / 4261 (−2,6%)

+3,8 п. п.

3 / 3

Fan-out

32,0 / 39,7 с (−19,6%)

8661 / 9857 (−12,1%)

+5,6 п. п.

5 / 5

gMAS оказался быстрее LangGraph во всех четырёх топологиях. Наибольший выигрыш виден на ветвистых графах: −11,6% времени при схождении ветвей (Fan-in) и −19,6% при расхождении (Fan-out). Точность выросла во всех случаях — от +0,6 до +5,6 п. п., а на Fan-out gMAS одновременно сократил расход токенов на 12,1%.

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

Откуда берётся экономия?

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

Механизм

Изменение числа токенов

Изменение времени

Изменение числа агентов

Изменение точности

Досрочная остановка

−52,6%

−45,0%

−3,0

+1,8 п. п., p = 0,70

Отключён-ные узлы

−44,4%

−32,1%

−2,0

+3,4 п. п., p = 0,002

Проверка достижи-мости

−23,1%

−34,3%

−2,0

+0,5 п. п., p = 0,90

Адаптивное изменение топологии

−21,2%

−18,5%

−1,0

+3,2 п. п., p = 0,251

Скрытые каналы

+6,2%

+7,2%

0,0

−2,9 п. п., p = 0,005

Выбор между моделями

−4,6%

+4,2%

0,0

+9,4 п. п., p = 0,118

Самым эффективным механизмом оказался самый простой: вовремя остановиться. Досрочная остановка сократила среднее число выполненных агентов с пяти до двух, расход токенов — на 52,6%, а время выполнения — на 45%.

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

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

Более общее адаптивное правило дало меньший, но заметный выигрыш: −21,2% токенов и −18,5% времени. Универсальный контроллер решает более сложную задачу, чем правило «ответ готов — остановись», и не каждое его действие уменьшает число вызовов.

Даже неудачные результаты здесь полезны. Скрытые каналы в этой конфигурации ухудшили стоимость и точность. Выбор между несколькими моделями повысил наблюдаемую точность, но увеличил время. Поэтому просто включить все доступные механизмы и поставить adaptive=True — ещё не оптимизационная стратегия.

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

Можно ли научить систему удалять рёбра?

Пороговое прореживание работает, когда уже есть веса или понятное правило. Исходная задача была сложнее: можно ли подобрать структуру по результатам работы системы?

Для этого мы перенесли в gMAS реализацию AgentPrune и провели отдельный эксперимент на задачах генерации исследовательских идей из MultiAgentBench. В нём работала лаборатория из десяти агентов: coordinator, manager, experts, adversarial_reviewer и final_editor.

Алгоритм обучали на трёх задачах, после чего оценивали на 97 отложенных тестовых задачах. Результаты после прореживания усредняли по 14 независимо полученным графам.

Оптимизировали не саму оценку модели-судьи, а функцию со штрафом за время и токены:

score =
    (innovation + safety + feasibility
     − total_tokens / 8000
     − total_time / 60)
    / 10

Метрика

До прореживания

После прореживания

Изменение

Целевая функция со штрафом за стоимость ↑

0,735 ± 0,208

0,822 ± 0,200

+0,087

Время ↓

78,2 ± 13,5 с

53,0 ± 27,4 с

−32,2%

Токены ↓

17,2k ± 3,2 тыс.

12,6k ± 8,1 тыс.

−27,0%

Новизна ↑

3,30 ± 0,90

3,18 ± 0,94

−0,12

Безопасность ↑

4,50 ± 0,90

4,57 ± 0,79

+0,07

Осуществимость ↑

3,00 ± 0,80

2,92 ± 0,82

−0,08

Среднее изменение целевой функции составило +0,087, а 95%-ный доверительный интервал по 14 прореженным графам — от +0,023 до +0,150.

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

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

Полный протокол находится в разделе эксперимента с AgentPrune.

А если агенты используют инструменты?

Задачи без внешних инструментов удобны для сравнения, но в реальной системе значительная часть времени уходит на поиск, работу с браузером, выполнение кода и неудачные вызовы инструментов. Поэтому отдельно мы прогнали валидационную выборку GAIA: 165 задач уровней 1—3 с одинаковой моделью, поисковой системой и ограничением в пять инструментальных вызовов.

В режиме обычного поиска LangGraph решил 22,4% задач и использовал в среднем 4986 токенов на задачу; среднее время составило 10,78 секунды. Для gMAS те же показатели составили 26,7%, 2714 токенов и 16,26 секунды.

В режиме углублённого поиска LangGraph решил 22,4% задач при 7017 токенах и 14,23 секунды в среднем, а gMAS — 29,1% при 4696 токенах и 16,96 секунды.

Здесь gMAS использовал меньше токенов и решил больше задач, но работал дольше. Такой результат нельзя упаковать в слово «быстрее». В этой конфигурации более экономное использование контекста и инструментов потребовало больше времени.

Эксперименты с инструментами чувствительны к доступности поиска, сетевым ошибкам, версии браузера и поведению сервера модели. Поэтому эти результаты нужно читать вместе с протоколом и исходными журналами выполнения: эксперимент на GAIA.

Так gMAS лучше LangGraph или нет?

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

  • Если нужны контрольные точки, надёжное возобновление, возврат к прошлому состоянию и длительное участие человека, то стоит начинать с LangGraph.

  • Для диалоговых команд и выбора следующего собеседника есть AutoGen.

  • Для ролевой модели команды и готовых схем взаимодействия — CrewAI.

  • Для событийных процессов рядом с RAG-экосистемой — LlamaIndex Workflows.

  • Для передачи задач между агентами, ограничений безопасности, сеансов и встроенной трассировки — OpenAI Agents SDK.

  • Для экспериментов, где объектом управления является сама топология, мы написали gMAS.

Если разложить это сравнение не по брендам, а по возможностям среды выполнения, то картина получается такой:

Возможность

LangGraph

AutoGen

CrewAI / LlamaIndex

OpenAI Agents SDK / Semantic Kernel

gMAS

Состояние выполнения или оркестрация нескольких агентов

Заранее описанная условная маршрутизация или передача задачи

Трассировка, сохранение состояния или наблюдаемость

Пропускать или принудительно запускать агентов по состоянию текущего запуска

Добавлять или удалять вершины и рёбра в том же запуске

Вставлять структуру восстановления без перезапуска текущего запуска

Менять финального отвечающего, сохраняя уже выполненную работу

Записывать изменения топологии как воспроизводимые ревизии графа

Экспортировать графовые тензоры или интерфейс PyG для обучаемой маршрутизации

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

gMAS закрывает базовый сценарий оркестрации: состояние, маршрутизацию, параллельные ветви, инструменты, память, ограничения бюджета и наблюдаемость. Но его главное преимущество не в том, чтобы повторить LangGraph один в один, а в том, чтобы добавить следующий уровень управления.

В обычной среде выполнения система выбирает следующий узел внутри уже описанного графа. В gMAS объектом исполнения остаётся сам изменяемый RoleGraph. После ответа любого агента можно пропустить шаг, удалить ребро, вставить цепочку восстановления, заменить writer или перестроить оставшуюся часть ExecutionPlan — и продолжить тот же запуск с сохранением уже выполненной работы.

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

flowMAS: если не хочется начинать с Python

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

Поэтому поверх SDK появился flowMAS — визуальная студия, которая использует gMAS как отдельную зависимость. В ней можно собрать граф на рабочем поле, назначить модели и инструменты, посмотреть порядок выполнения, следить за вершинами во время запуска и разбирать изменения топологии в обозревателе трасс.

Реальный интерфейс flowMAS: слева библиотека ролей, в центре исполняемый граф. После запуска события и изменения топологии можно разбирать в Runs и Trace Explorer.
Реальный интерфейс flowMAS: слева библиотека ролей, в центре исполняемый граф. После запуска события и изменения топологии можно разбирать в Runs и Trace Explorer.

Если хочется просто посмотреть интерфейс, то есть демонстрационная версия. Для локального запуска исходники и Docker-конфигурация лежат в репозитории flowMAS.

flowMAS — не отдельная среда выполнения и не визуальная копия Langflow. Граф из интерфейса выполняется тем же gMAS, который можно импортировать как Python-библиотеку. Интерфейс нужен для проектирования, наблюдения и демонстрации; оптимизационные алгоритмы остаются в SDK.

Что в итоге

Мы не планировали писать ещё одну систему оркестрации. Хотели воспроизвести один алгоритм и попробовать собственные методы оптимизации графа, но самым сложным в итоге оказалась инфраструктура вокруг него.

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

Сейчас gMAS — ранняя версия проекта с открытым исходным кодом. API протестирован на Python 3.12 и 3.13, но часть исследовательских компонентов ещё будет меняться, поэтому для серьёзных экспериментов лучше фиксировать версию.

Пакет опубликован на PyPI. Текущий релиз устанавливается обычным pip:

python -m pip install "frontier-ai-gmas==0.1.2"

На PyPI дистрибутив называется frontier-ai-gmas, а в Python импортируется как gmas. Проверить установку можно одной командой:

python -c "import gmas; print(gmas.__version__)"

Ссылки:

Будем рады, если вы попробуете gMAS или flowMAS и поделитесь обратной связью: что получилось, где возникли проблемы и каких возможностей не хватает. Особенно интересны реальные примеры, идеи для оптимизации графов и предложения по развитию проекта.

Виталий Витальевич Белов

Ai Research, команда FrontierAI

Комментарии (1)


  1. Devpiligrim
    18.09.2026 12:24

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

    По цифрам не хватает второй оси. -52,6% токенов на досрочной остановке - сильно, но что с качеством ответа на тех же прогонах? Таблица "механизм x токены x качество" сказала бы больше, чем каждая метрика по отдельности: экономия без деградации и экономия ценой двух процентов точности - разные истории для продуктового решения.