Атомарные графы задач: планирование работы агента как граф зависимостей
Как фреймворк Atomic Task Graph разбивает задачи агентов на узлы с определенным типом, имитирует планы и восстанавливает только неудачные подграфы, чтобы помочь небольшим открытым моделям конкурировать.
Источники: This New AI Framework Turned 7B Models Into GPT-4 Competitors (Without Any Training)
Большинство попыток сделать агентов на основе больших языковых моделей более надежными начинаются с использования более крупных моделей. Фреймворк Atomic Task Graph (ATG), предложенный исследователями из Университета Цинхуа и Южного технологического университета Китая, идет другим путем: он меняет способ, которым агент структурирует свою работу. Согласно статье, модели объемом 7B и 8B с открытым исходным кодом, использованные в рамках ATG, превзошли GPT-4, работающий по стандартному циклу ReAct, в двух известных тестах на агентов без какой-либо доработки, обучения с подкреплением или изменения весов. Ниже рассматриваются причины сбоев линейных цепочек рассуждений, как ATG заменяет их графом зависимостей, а также какие идеи можно заимствовать для создания собственных агентов.
Почему линейные циклы агентов терпят неудачу при выполнении длинных задач
Рассмотрим запрос вроде «составить отчет о продажах за 2024 год с диаграммами». Типичный агент в стиле ReAct рассматривает его как одну длинную последовательность шагов, каждый из которых зависит от предыдущего.
Step 1
↓
Find database
↓
Query data
↓
Analyze numbers
↓
Create graphs
↓
Write report
Цепочка действий работает нормально, пока каждый шаг успешен. Проблемы начинаются, когда хотя бы один шаг проваливается. Если запрос к базе данных не удаётся, все последующие шаги основываются на недостающих или неверных данных.
Database query
↓
Everything after it becomes wrong
В такой ситуации агент может либо начать всё заново, либо продолжить работу с тем, что у него уже есть. Многие выбирают второй вариант, что является основной причиной галлюцинаций: модель выдумывает правдоподобные данные, чтобы заполнить пробелы, и каждое последующее решение унаследовывает эту ошибку.
Контекст постоянно растёт
Вторая проблема заключается в том, как эти агенты сохраняют состояние. После каждого действия мысли, вызов инструмента и наблюдения добавляются к постоянно растущему отчёту.
User
↓
Thought
↓
Action
↓
Observation
↓
Thought
↓
Action
↓
Observation
↓
Thought
↓
Action
В конечном итоге модель анализирует огромное количество данных из истории. Контекст становится слишком шумным, а ранние ошибки остаются видимыми, поэтому они продолжают влиять на последующие решения. Подобно игре «телефонная служба», каждый этап немного искажает первоначальный план, пока тот не отклоняется от реальности.
Основная идея: граф вместо цепочки
ATG заменяет одну последовательность действий графом задач. Каждый узел представляет собой единицу работы, а каждая рёбро отражает зависимость между двумя такими единицами.
Report
/ \
Analysis Charts
/ \
Database Statistics
Такая структура делает независимость задач очевидной: не связанные между собой задачи больше не ждут друг друга, а сбой в одной из них не делает бесполезными остальные.
Как ATG создаёт и запускает граф
Фреймворк работает в пяти этапах.
1. Рекурсивное разложение на атомарные задачи
Всё начинается с запроса пользователя.
Create sales report
ATG разделяет эту цель на подзадачи.
Create sales report
↓
Load data
↓
Analyze sales
↓
Create charts
↓
Write summary
Затем происходит дальнейшее разделение любых субзадач, которые всё ещё слишком обширны, например этапа анализа.
Analyze sales
↓
Revenue
↓
Profit
↓
Growth
↓
Regional trends
Разложение прекращается, когда каждая листовая задача соответствует одному вызову инструмента, например:
SQL query
Python calculation
Matplotlib chart
Markdown writer
Эти листовые задачи представляют собой атомарные операции: достаточно маленькие единицы, дальнейшее разделение которых не имеет смысла. Правило остановки важно: расплывчатый узел оставляет слишком много свободы для импровизации, тогда как один SQL-запрос имеет чёткий и проверяемый результат.
2. Явные входные и выходные данные для каждого узла
Каждому узлу присваивается интерфейс, похожий на сигнатуру функции. Вместо инструкции вроде «провести анализ» планировщик описывает, что потребляет узел и что он генерирует.
def analyze_sales(data):
return summary
Этот фрагмент носит иллюстративный характер, а не является кодом фреймворка, но он демонстрирует описанный контракт. Поскольку граф зависит только от этого контракта, узел можно попытаться обработать заново или заменить на другой инструмент, и соседние узлы этого не заметят; это та же самая особенность, которая делает модульный код поддерживаемым.
3. Параллельная обработка независимых веток
Последовательный агент выполняет задачи одну за другой, даже если некоторые из них не связаны между собой.
Task A
↓
Task B
↓
Task C
Если B и C нужен только результат работы A, а не результаты друг друга, ATG может выразить это напрямую.
Task A
/ \
Task B Task C
\ /
Task D
Затем B и C могут выполняться одновременно, в то время как D ждет их обоих. В статье отмечается значительное сокращение времени выполнения во всех протестированных тестах, что естественно следует из преобразования независимых шагов в параллельные.
4. Предварительная проверка перед использованием реальных инструментов
Прежде чем что-либо выполнять, ATG внутренне симулирует всю схему, фактически запрашивая у модели, сработает ли она, если будет реализована в соответствии с написанным планом. В ходе симуляции проверяются:
- отсутствующие шаги
- неправильно назначенный инструмент узлу
- некорректные зависимости между узлами
- несоответствия интерфейсов, когда выходной сигнал одного узла не соответствует входному сигналу следующего узла
- пути выполнения, которые фактически невозможно завершить
- нарушения ограничений задачи
Это аналог тестирования перед развертыванием, причем он дешев, поскольку не требуется использования внешних инструментов. Однако качество проверки зависит от модели, которая её выполняет: модель, составившая план, может иметь свои слабые места, поэтому её следует рассматривать как фильтр, а не гарантию.
5. Целенаправленная коррекция повреждённого подграфа
Самый значимый аспект — это способ, которым ATG справляется с сбоями во время выполнения. Возьмем простую структуру графа:
Database
↓
Analysis
↓
Charts
↓
Report
Предположим, что узел анализа выходит из строя. Обычный агент обычно реагирует на это, отклоняя свои результаты и начиная работу заново.
Database
↓
Analysis
↓
Charts
↓
Report
↓
Start over
ATG, в свою очередь, сохраняет тот же граф и замораживает все узлы, которые уже выдали корректные результаты. Приведенная ниже диаграмма преднамеренно выглядит идентичной оригиналу: структура не меняется, только узел анализа отмечается для повторной обработки, в то время как узлы базы данных, графиков и отчетов остаются прежними.
Database
↓
Analysis
↓
Charts
↓
Report
Перегенерируется только несработавший подграф, и как только он справится со своей задачей, граф продолжит работу с новым результатом.
Database
↓
New Analysis
↓
Charts
↓
Report
Это поэтапная компиляция, применяемая к планированию. Обратите внимание: даже если исправленный анализ даёт другие цифры, узлы нижестоящего уровня, которые им пользуются, всё равно должны перезапуститься; экономятся лишь операции на высоких уровнях и не связанные с этим ветви.
Почему меньший объём данных снижает количество иллюзий
В цикле ReAct каждый шаг учитывает всю историю. В ATG каждый узел получает только те данные, которые указаны в его интерфейсе, поэтому шума меньше, и меньше возможностей для проникновения ранее возникших ошибок.
В статье это подтверждается на примере ALFWorld:
- с использованием ReAct 42,86% траекторий содержали иллюзорные действия
- с использованием ATG этот показатель снизился до 12,14%
Это относительное снижение примерно на 72%, достигнутое без изменения основной модели.
Что показывают тесты
Для оценки использовались три открытые модели:
- Mistral 7B
- Gemma 7B
- Llama 3 8B
и три критерия оценки агентов:
- ALFWorld
- WebShop
- ScienceWorld
В основном сравнении Llama 3 8B с ATG противостоит GPT-4 с ReAct. На ALFWorld базовая версия GPT-4 показала следующие результаты:
GPT-4 + ReAct
41.24
в то время как небольшая модель с ATG показала:
Llama 3 8B + ATG
63.65
На WebShop базовая версия GPT-4 достигла:
GPT-4 + ReAct
64.34
а Llama 3 8B с ATG —:
Llama 3 8B + ATG
68.36
Это цифры, приведенные в статье. Показатели GPT-4 относятся к базовой версии с ReAct, поэтому сравнение показывает, насколько структура может компенсировать размер модели, а не то, что 8B-модель в целом сильнее GPT-4.
Почему эта идея находит отклик у инженеров по программному обеспечению
Стандартной стратегией в этой отрасли было масштабирование моделей, кластеров и бюджетов. ATG же задаётся вопросом о том, как лучше организовать работу, что является вопросом инженерии программного обеспечения, а не машинного обучения. Это связано с концепциями Git, графов зависимостей, систем сборки, планировщиков задач, оптимизации компилятора и распределённых систем. Большинство программного обеспечения уже давно перестало быть строго последовательным; агенты постепенно догоняют этот уровень.
Конкретный пример: создание веб-сайта
Если попросить агента создать веб-сайт, линейный агент, как правило, составит план примерно такой:
Think
↓
Write HTML
↓
Write CSS
↓
Write JavaScript
↓
Debug
↓
Deploy
Планировщик в стиле ATG, напротив, может сгенерировать структуру в виде дерева из независимых элементов:
Website
│
├── HTML
├── CSS
├── Images
├── API
└── Tests
Каждую ветвь можно разрабатывать отдельно. Если CSS выходит из строя, перегенерируется только соответствующий узел CSS. Это кажется очевидным, однако большинство современных агентов работают не так. Связанные защитные паттерны рассматриваются в архитектуре против усугубления галлюцинаций в графах агентов.
Когда граф задач нецелесообразен
Планирование, симуляция и ведение учета узлов добавляют нагрузку. Для задач, требующих двух-трех вызовов инструментов, простой цикл ReAct проще в реализации. Граф оправдывает себя тогда, когда задачи длинные, частично независимые и дорогие в повторном запуске, причем только при разумной структуре планировщика: плохой граф, выполняемый эффективно, по-прежнему остается плохим планом.
Основные выводы
- Линейные циклы позволяют одному неудачному шагу повлиять на всё, что следует за ним, а увеличение объема данных усиливает ранние ошибки.