Краткий обзор и перевод исследования Large Language Model-Based Agents for Software Engineering: A Survey, которое посвящено применению интеллектуальных агентов на основе больших языковых моделей (LLM) в разработке. Авторы анализируют 106 работ, классифицируя их по задачам и архитектуре.
Примечание: в тексте LLM-агенты представлены в виде названия и номера в квадратных скобках, например CodeAct [85]. В разделе References оригинальной статьи можно найти названия исследований по каждому агенту по номеру.
Большие языковые модели демонстрируют впечатляющие результаты, все быстрее приближаясь к человеческому уровню интеллекта. В последние годы разработчики активно применяют их в различных задачах:
Генерация кода
Тестирование ПО
Отладка
Улучшение кода
Интеллектуальные агенты – это автономные сущности, способные воспринимать окружающую среду и взаимодействовать с ней для достижения поставленных целей. Развитие концепции агентов прошло долгий путь от ранних моделей, основанных на символической логике и обучении с подкреплением, до современных агентов на основе LLM.
Агенты на основе LLM – это новый класс интеллектуальных агентов, использующих LLM в качестве центрального контроллера. В отличие от автономных LLM, агенты обладают расширенными возможностями:
Восприятие внешних данных и использование инструментов
Решение сложных задач путем коллаборации нескольких агентов
Взаимодействие с человеком
Агенты на основе LLM обычно состоят из четырех ключевых компонентов: планирования, памяти, восприятия и действия. Планирование и память составляют основу «мозга» агента, управляемого LLM, который взаимодействует с окружающей средой через компоненты восприятия и действия для достижения поставленных целей.
1. Планирование:
Разбивает сложные задачи на подзадачи и определяет их последовательность для достижения конечной цели.
Может генерировать план заранее или корректировать его на основе обратной связи (от среды или человека).
2. Память:
Хранит историю действий, решений и наблюдений агента.
Позволяет агенту использовать предыдущий опыт для более эффективного решения задач.
Методы управления памятью (представление, чтение/запись, поиск) напрямую влияют на эффективность агента.
3. Восприятие:
Получает информацию из окружающей среды для оптимизации планирования.
Способно воспринимать различные типы данных: текстовые, визуальные, аудио.
4. Действие:
Выполняет конкретные действия во взаимодействии с окружающей средой на основе плана, созданного «мозгом» агента.
Важный механизм – использование внешних инструментов, расширяющих возможности LLM за пределы текстового взаимодействия.
Мультиагентные системы:
Несколько агентов, специализирующихся на разных задачах, могут совместно решать более сложные комплексные проблемы.
Каждый агент имеет свою роль, экспертизу и отвечает за определенный аспект задачи.
Агенты взаимодействуют друг с другом, обмениваются информацией и результатами.
Могут работать как коллаборативно (выполняя разные подзадачи), так и соревновательно (решая одну задачу, дискутируя и предлагая альтернативные решения).
Координация человек-агент:
Агенты могут получать инструкции от человека и работать под его руководством.
Такая координация позволяет учитывать человеческие предпочтения и использовать экспертизу человека.
Человек может ставить задачи, давать обратную связь и сотрудничать с агентами для достижения общей цели.
В обзоре рассматриваются агенты, которые выполняют задачи, связанные с разработкой и жизненным циклом ПО (сбор требований, проектирование, генерация кода, обеспечение качества ПО, улучшение ПО)
В обзоре рассматриваются только те агенты, которые используют LLM как основу своего «мозга» и способны интерактивно взаимодействовать с окружающей средой, получая обратную связь и действуя в режиме реального времени.
Процесс сбора статей об агентах включал в себя два этапа: поиск по ключевым словам и метод «снежного кома».
Использовалась база данных DBLP, охватывающая более 7 миллионов публикаций.
Применялся итеративный подход «проб и ошибок» для определения ключевых слов.
На основе анализа релевантных статей был сформирован список ключевых слов, включающий термины, связанные с агентами, БЯМ и задачами разработки ПО.
Поиск по ключевым словам в DBLP дал 10 362 результата, из которых вручную было отобрано 67 релевантных статей.
Для повышения полноты обзора использовался метод «снежного кома»:
Обратный: анализ ссылок в отобранных статьях для поиска релевантных работ.
Прямой: поиск статей, цитирующих отобранные работы, с помощью Google Scholar.
На этом этапе было найдено 39 дополнительных статей.
Всего было собрано 106 статей.
Наблюдается постоянный рост числа публикаций в этой области.
Большинство статей опубликованы на arXiv и еще не прошли рецензирование, что ожидаемо для развивающейся области.
В этом разделе мы рассмотрим собранные статьи с точки зрения различных задач разработки ПО. Важно отметить, что агенты на основе LLM могут быть разработаны не только для решения отдельных задач, но и для поддержки комплексных процессов разработки и сопровождения ПО.
Большинство агентов ориентированы на решение отдельных задач, особенно генерацию кода и обеспечение качества кода (статический анализ и тестирование).
Некоторые агенты предназначены для комплексной разработки или сопровождения ПО, что указывает на потенциал LLM в решении сложных реальных задач.
Сбор и анализ требований – это критически важный этап разработки ПО, который включает в себя следующие фазы:
Выявление: сбор новых требований.
Моделирование: описание требований с помощью абстрактных моделей (UML, ERA).
Согласование: обеспечение согласованности требований между заинтересованными сторонами.
Спецификация: формализация и документирование требований.
Верификация: проверка полноты и однозначности требований.
Эволюция: адаптация требований к изменяющимся потребностям.
Агенты на основе LLM для сбора и анализа требований:
Автоматизация отдельных фаз: например, агент Elicitation [54] использует симуляцию взаимодействия с продуктом для выявления скрытых требований.
Автоматизация нескольких фаз: например, агент MARE [57] охватывает выявление, моделирование, верификацию и спецификацию требований.
LLM демонстрируют впечатляющие результаты в генерации кода на основе контекста или описания на естественном языке. Однако сгенерированный код может быть несовершенным из-за таких проблем, как галлюцинации. Агенты на основе LLM могут повысить качество генерации кода с помощью планирования и итеративного уточнения.
1. Генерация кода с планированием
Цепочка мыслей (CoT): разбиение задачи на подзадачи для повышения точности генерации [61, 70, 76, 84, 86, 91-93, 95].
Динамическое планирование: адаптация плана на основе наблюдений за текущими действиями [62, 85, 87, 88].
Различные представления для шагов планирования: псевдокод [95], промежуточный код [61], скелет кода [93, 97].
Многопутевое планирование: генерация нескольких планов и выбор наилучшего [76, 98].
2. Генерация кода с итеративным уточнением
Агенты могут динамически улучшать сгенерированный код на основе обратной связи:
Обратная связь от модели:
Взаимодействие между несколькими моделями (peer-reflection): обмен информацией, совместная работа, code review [62, 64, 68].
Самоулучшение одной модели (self-reflection): итеративная оптимизация кода на основе предыдущих результатов [71, 73, 90].
Обратная связь от инструментов:
Инструменты динамического выполнения: компиляторы, интерпретаторы, движки выполнения [79, 81-87, 92-98].
Инструменты статического анализа: [89, 82, 88].
Инструменты поиска: локальные репозитории знаний [86], поисковые системы [78, 82, 86, 96], веб-скрапинг [80].
Обратная связь от человека: уточнение требований, проверка кода на соответствие ожиданиям [91, 92].
Гибридная обратная связь: комбинация различных типов обратной связи [62-67, 71-77, 91, 97].
Проверка кода — это важный этап. Она позволяет выявлять проблемы качества кода (баги, уязвимости) до запуска тестов, что значительно экономит время и ресурсы. Исследования показывают, что LLM могут эффективно применяться для выявления потенциальных проблем в коде. Обучение на наборах данных с корректным и ошибочным кодом, а также prompt engineering позволяют LLM находить баги, уязвимости и code smells.
Mao et al. [111] предлагают имитировать процесс code review с помощью LLM, которые играют роли тестировщиков и разработчиков. Взаимодействие и обмен информацией между агентами повышает эффективность обнаружения.
GPTLENS [104] — это двухуровневая система для поиска уязвимостей в смарт-контрактах, использующая GPT-4. Агенты-аудиторы генерируют потенциальные уязвимости и обоснования, а агент-критик оценивает их правдоподобность.
Fan et al. [105] предлагают концепцию «Интеллектуального агента анализа кода» (ICAA). ICAA объединяет AI-модели (например, LLM), принципы проектирования процессов разработки и традиционные инструменты статического анализа.
LLIFT [115] — инструмент для обнаружения ошибок типа «Использование до инициализации» (UBI) в ядре Linux. LLIFT использует LLM для анализа кода, помеченного инструментом UBITect как потенциально проблемный.
E&V [107] — агент для статического анализа кода ядра Linux, использующий LLM для «виртуального» выполнения кода и традиционные инструменты для получения недостающей информации.
IRIS [113] — агент, использующий CodeQL для извлечения API и LLM для их классификации как потенциальных источников или приемников уязвимостей.
ART [102] — это универсальная платформа, которая расширяет возможности LLM за счет многоэтапного планирования и использования внешних инструментов.
LLM4Vuln [110] — агент, который извлекает информацию об уязвимостях из текстовых отчетов и баз данных, а также использует инструменты для анализа кода.
CodeAgent [119] — многоагентная система, имитирующая конвейер разработки с четырьмя этапами: синхронизация информации, проверка кода, согласование кода и документирование. Система включает шесть агентов с разными ролями: пользователь, CEO, CPO, CTO, кодер, рецензент. Каждый агент выполняет свою функцию на соответствующем этапе.
Система, предложенная Rasheed et al. [120] — в отличие от CodeAgent, каждый агент специализируется на одной задаче проверки кода, например, поиск ошибок, обнаружение code smells, оптимизация кода.
ICAA [105] — многоагентная система для выявления несоответствий между кодом и его назначением. Система использует агента для сбора информации из репозитория кода, агента для анализа информации и выявления несоответствий и агента для формирования отчета.
CORE [121] — система с двумя агентами и традиционными инструментами статического анализа для автоматического исправления проблем с качеством кода. Агент-предлагатель генерирует варианты исправлений, а агент-ранжировщик оценивает их и выбирает наиболее подходящие.
Создание высококачественных тестов на практике сопряжено с трудностями, поскольку сгенерированные тесты должны быть не только синтаксически и семантически корректными, но и достаточными для покрытия как можно большего числа состояний тестируемого ПО.
TestPilot [123] — генерирует тесты на основе подробных подсказок, анализирует результаты выполнения тестов и сообщения об ошибках, итеративно уточняет подсказки и генерирует исправленные тесты.
ChatTester [122] — использует LLM для понимания намерений тестируемых методов, генерирует соответствующие модульные тесты и выполняет более детальное уточнение тестов, чем TestPilot, анализируя сообщения об ошибках и используя инструменты статического анализа для локализации ошибок в коде.
ChatUniTest [124] — использует механизм генерации-проверки-исправления для уточнения тестов.
CoverUp [126] — система генерации тестов, ориентированная на достижение высокого уровня покрытия кода тестами. Система сегментирует исходный код, проводит анализ покрытия, уточняет подсказки для LLM, чтобы сфокусироваться на областях кода с недостаточным покрытием.
TELPA [125] — система, использующая анализ вызовов методов для лучшего понимания методов с непокрытыми ветвями, и применяющая выборку контрпримеров для направления LLM на генерацию новых тестов.
MuTAP [127] — система, использующая мутационное тестирование для генерации модульных тестов с улучшенными возможностями обнаружения ошибок. Система использует аугментацию подсказок с выжившими мутантами и шаги уточнения для исправления синтаксиса и предполагаемого поведения тестов.
KernelGPT [130] — агент для фаззинга ядра ОС. Анализирует драйверы и генерирует спецификации системных вызовов, используя обратную связь от инструмента Syzkaller [131] для валидации и коррекции сгенерированных данных.
WhiteFox [133] — система с двумя агентами: агент анализа и агент генерации. Анализирует низкоуровневый код оптимизации и генерирует требования к высокоуровневым тестовым программам, которые могут вызвать эти оптимизации. Агент генерации создает тестовые программы на основе требований и использует обратную связь от тестов, успешно запустивших оптимизации.
LLM4CBI [134] — агент для изоляции ошибок компилятора путем генерации тестовых случаев с улучшенными возможностями обнаружения ошибок. Использует инструменты статического анализа для сбора информации о программе, генерирует варианты программы, проверяет их с помощью статического анализа и использует обратную связь для улучшения генерации тестов.
GPTDroid [139] — агент для GUI-тестирования мобильных приложений. Анализирует информацию о GUI, генерирует тестовые сценарии, выполняет их и получает обратную связь от приложения.
DroidAgent [144] — многоагентная система для GUI-тестирования мобильных приложений. Состоит из агентов планировщика, актора, наблюдателя и рефлектора, каждый из которых выполняет свою роль и использует модули памяти для долгосрочного планирования и взаимодействия с внешними инструментами.
AXNav [145] — многоагентная система для воспроизведения тестов доступности на мобильных приложениях. Состоит из агентов планировщика, агента действий и агента оценки, которые переводят инструкции по тестированию в исполняемые шаги, проводят тесты на iOS-устройстве в облаке и суммируют результаты тестов.
AdbGPT [15] — агент для автоматизации воспроизведения ошибок Android. Анализирует отчеты об ошибках, переводит сущности «Шаг к воспроизведению» (S2R) в последовательность действий для воспроизведения ошибки, анализирует состояния GUI и сопоставляет сущности S2R с фактическими событиями GUI.
XUAT-Copilot [148] — система для автоматизации приемочного тестирования. Состоит из агентов планирования действий, проверки состояния и выбора параметров, а также модулей осведомленности о состоянии и перезаписи сценариев.
RESTSpecIT [149] — система для автоматического вывода спецификаций RESTful API и проведения тестирования «черного ящика». Генерирует и мутирует HTTP-запросы, анализирует ответы API, использует валидные запросы для уточнения мутаций.
Fuzz4All [150] — универсальный фаззер на основе LLM для общего и целевого фаззинга на различных языках программирования. Состоит из агента дистилляции пользовательского ввода и агента генерации фаззингового ввода.
PentestGPT [151] — модульная среда для проведения пентеста. Включает модули логического вывода, генерации и анализа. Использует стратегию планирования «Дерево задач пентеста» и методы CoT для решения проблем потери контекста и неточной генерации инструкций.
Отладка ПО обычно включает в себя две фазы: локализация ошибок и исправление программ. Техники локализации ошибок нацелены на выявление ошибочных элементов (например, некорректных операторов или методов) программы на основе симптомов ошибок (например, информации о сбое теста). Затем, основываясь на ошибочных элементах, выявленных на этапе локализации ошибок, техники исправления программ генерируют патчи для исправления ошибочного кода. Кроме того, недавние работы также предлагают унифицированную отладку, чтобы связать локализацию ошибок и исправление программ двунаправленным способом.
Локализация ошибок на основе машинного обучения широко изучалась еще до эпохи LLM. Обычно для этого обучались модели глубокого обучения, чтобы предсказать вероятность того, является ли каждый элемент кода ошибочным или нет. Однако точное определение ошибочного элемента в ПО является сложной задачей, учитывая большой масштаб программных систем, а также массивные и разнообразные сообщения об ошибках, которые часто выходят за рамки возможностей автономных моделей обучения, включая LLM.
Поэтому в последних работах создаются LLM-агенты, которые включают в себя мультиагентность и использование инструментов, чтобы помочь LLM справиться с этими проблемами.
AgentFL [160] — это мультиагентная система для локализации ошибок на уровне проекта. Основная идея AgentFL заключается в том, чтобы масштабировать локализацию ошибок на основе LLM до контекста кода уровня проекта за счет синергии нескольких агентов. Система состоит из четырех различных LLM-агентов: рецензента тестового кода, рецензента исходного кода, архитектора ПО и инженера по тестированию ПО.
RCAgent [162] — это мультиагентная система для анализа первопричин в промышленных облачных средах. RCAgent включает в себя два компонента: управляющий агент и экспертные агенты. Управляющий агент контролирует комплексный цикл «мысль-действие-наблюдение», в то время как экспертные агенты действуют для выполнения специализированных задач и могут использоваться управляющим агентом.
AUTOFL [163] — это одноагентная система, которая расширяет возможности автономных LLM за счет вызова инструментов (т.е. четырех специализированных вызовов функций) для лучшего изучения репозитория. Сначала он выполняет объяснение первопричины, вызывая инструменты для просмотра репозитория исходного кода на предмет соответствующей информации, требуя только один неудачный тест и его стек сбоев. На этом этапе он автономно решает, продолжать ли вызов функции или завершить работу с созданием объяснения первопричины. Затем используется этап постобработки, чтобы сопоставить выходные данные с точными элементами кода с целью локализации ошибки. Кроме того, AgentFL [160] и RCAgent [162] также включают вызов инструментов (например, статический анализ, динамическое инструментирование и навигацию по базе кода) в свою структуру.
ACFIX [174] — это мультиагентная система для исправления уязвимостей контроля доступа в смарт-контрактах. Специализируя LLM на различных ролях, ACFIX включает в себя идентификатор механизма контроля доступа на основе ролей (RBAC), идентификатор пары «роль-разрешение», генератор патчей и валидатор.
FlakyDoctor [175] — это агент для исправления ненадежных тестов. Он принимает во внимание результаты выполнения тестов и местоположение сбоев тестов. После этого система генерирует целевые исправления и тестирует их для проверки. Этот процесс является итеративным, с целью постоянного уточнения исправлений до тех пор, пока проблема ненадежности тестов не будет решена.
Этот раздел посвящен LLM-агентам, которые способны выполнять полный цикл разработки программного обеспечения, например, создание игры «Змейка» с нуля. Благодаря высокой автономности и гибкости, достигаемым за счет синергии нескольких агентов, такие системы выходят за рамки отдельных этапов разработки и охватывают весь жизненный цикл ПО: от анализа требований до обеспечения качества.
Как и реальные команды разработчиков, LLM-агенты используют классические модели процесса разработки, такие как каскадная модель (waterfall model), инкрементальная модель, унифицированный процесс и гибкая разработка.
1. Каскадная модель
Большинство существующих систем LLM-агентов (например, AISD [191], LCG [194], ChatDev [186], CTC [197] и Self-Collaboration [4]) используют классическую каскадную модель. Она представляет собой линейный и последовательный рабочий процесс, разбивающий проект на отдельные фазы: анализ требований, проектирование, реализация кода, тестирование, развертывание и сопровождение. Завершение одной фазы знаменует переход к следующей без возможности возврата.
Некоторые агенты [4], [187], [191], [194] расширяют традиционную каскадную модель, добавляя итерации в определенные фазы для повышения качества. Например, результаты тестирования могут быть переданы обратно агенту-разработчику для доработки кода. MetaGPT [187] идет еще дальше, интегрируя каскадную модель со стандартизированными операционными процедурами, подобными человеческим, которые распределяют обязанности между ролями и стандартизируют промежуточные результаты, способствуя сотрудничеству.
2. Гибкая разработка
Некоторые работы исследуют потенциал LLM-агентов в контексте гибкой разработки, включая разработку через тестирование и Scrum. TDD отдает приоритет написанию тестов перед написанием кода и поощряет цикл написания тестовых наборов, реализации кода для прохождения тестов и завершения рефлексивной фазой для улучшения. Scrum — это гибкая модель процесса разработки ПО, которая разбивает разработку на несколько спринтов, достигая создания сложных систем через итеративные обновления. Эксперименты на бенчмарках генерации кода на уровне функций показывают, что модель Scrum может достигать наилучших и наиболее стабильных результатов.
2. Специализация ролей в команде разработки
Подобно реальным командам, многоагентные системы для комплексной разработки ПО часто назначают разные роли для решения специализированных задач и взаимодействия на протяжении всего жизненного цикла. Роли в существующих агентах, как правило, проектируются путем моделирования реальных команд разработчиков или специализируются в соответствии с рабочим процессом.
Большинство сред комплексной разработки ПО моделируют реальные команды и назначают базовые роли, включая менеджеров (например, руководителей проектов или менеджеров по продукту), аналитиков требований, проектировщиков, разработчиков и специалистов по контролю качества (например, тестировщиков ПО или рецензентов кода), для охвата всего процесса разработки [4], [187], [191], [193], [194], [198].
В дополнение к этим общим ролям существуют специальные роли для решения узкоспециализированных задач. Например, роль Scrum-мастера также включается в задачи анализа требований и планирования для агентов с рабочим процессом Scrum [194], [198], роли генерального директора/технического директора также включаются в некоторых агентах для выполнения задачи проектирования [186], [197]. Кроме того, в некоторых агентах есть специальные роли супервизоров для обеспечения бесперебойного процесса совместной работы (например, координация или критика), такие как роли оракула в предыдущей работе [185] и наблюдатель действий в AutoAgents [189].
Вместо моделирования реальных команд разработчиков некоторые агенты делят роли в соответствии с рабочим процессом фреймворка агента. Например, CodeS [195] разделяет сложную задачу генерации кода на реализацию уровней репозитория, файлов и методов и устанавливает роли RepoSketcher, FileSketcher и SketchFiller. Co-Learning [190] и его последующая работа [196] абстрагируют процесс генерации кода в пары инструкция-ответ, устанавливая таким образом только роли инструктора и ассистента.
Основываясь на общей архитектуре LLM-агентов, этот раздел описывает парадигмы планирования, восприятия, памяти и действий в существующих агентах.
Планирование — важный компонент для агентов, поскольку сложные задачи, такие как разработка и поддержка, требуют скоординированных действий множества агентов в течение нескольких итераций.
A. Один планировщик или несколько?
Планирование может осуществляться одним специализированным агентом [4, 61, 91, 98, 105, 144, 145, 183, 187, 191, 193] или быть обязанностью каждого агента [76, 82, 85, 86, 148, 162, 192]. Некоторые работы используют интерфейс вызова функций в GPT-3.5 или GPT-4, передавая задачу планирования высокопроизводительным моделям [82]. Однако, учитывая важность планирования, некоторые работы используют совместное планирование несколькими агентами для повышения точности и практичности планов [91, 186, 189, 195, 197, 198, 205].
B. Одноэтапное или многоэтапное планирование?
Базовая стратегия — создать полный план в начале и затем выполнять его поэтапно [4, 61, 82, 86, 91, 98, 105, 183, 186, 187, 191–193, 195, 197, 198, 205]. Многие агенты используют архитектуру, подобную ReAct [219], с многоэтапным планированием, где действия на следующем этапе определяются после получения обратной связи от предыдущего. Это позволяет динамически корректировать план и адаптироваться к изменяющимся условиям, например, при исправлении ошибок [76, 210], итеративной генерации кода [82, 85], тестировании мобильных приложений [144, 145, 148] и других задачах [162].
C. Планирование с одним или несколькими путями?
Большинство агентов используют планирование с одним путем, т.е. линейное выполнение задач [4, 61, 86, 105, 151, 186, 187, 191–195, 198, 205, 220]. Однако, агенты наследуют случайность от базовых LLM, что приводит к вариациям в декомпозиции задач. Некоторые подходы улучшают однопутевое планирование, используя обратную связь для динамического планирования следующего шага. Хотя эти стратегии остаются однопутевыми, они обеспечивают гибкость благодаря адаптации к прогрессу и результатам выполнения. Другой подход — многопутевое планирование, когда агенты генерируют или симулируют несколько планов и выбирают [76], переключаются [98] или объединяют [197] оптимальные пути для выполнения.
D. Представление плана
План может быть представлен в различных формах:
Естественный язык: Список процедурных шагов [4, 86, 91, 98, 105, 183] или функций для реализации [187, 191, 194, 198].
Полуструктурированный формат: AXNav [145] представляет список действий в формате JSON. Системы генерации кода могут выдавать каркас кода [61, 97, 192, 195] или исполняемый код [205].
Граф: Некоторые агенты моделируют план в виде графа для облегчения расширения и отслеживания путей выполнения [76, 88, 151].
Память — ключевой механизм для хранения истории действий, наблюдений и рассуждений, позволяющий агентам поддерживать согласованность и решать сложные задачи. В разработке ПО сложные задачи разработки и поддержки требуют от агентов итеративных изменений, где промежуточная информация, такая как сгенерированный код и отчеты о тестировании, важна для целостности и непрерывности. Далее мы рассмотрим реализацию механизмов памяти с четырех точек зрения: продолжительность хранения, владение, формат и операции. На Рисунке ниже представлена таксономия компонентов памяти в существующих агентах.
A. Продолжительность хранения
Кратковременная память: Также известная как рабочая память [221], используется для поддержания траекторий текущей задачи и часто применяется при многоэтапном взаимодействии. Cуществуют следующие шаблоны кратковременной памяти:
Записи диалогов: Хранение истории диалогов между агентами в виде сводок [148, 189] или пар «инструкция-ответ» [186, 197, 198].
Записи «действие-наблюдение-критика»: Фокусируются на взаимодействии агента с окружающей средой, запоминая последовательности действий и наблюдений, а также критические замечания [144].
Промежуточные результаты: Хранение результатов предыдущих этапов для предотвращения переполнения памяти и избыточного влияния нерелевантной информации.
Долговременная память: Используется для запоминания ценного опыта прошлых задач, который может быть востребован при решении новых. Из-за большого объема данных используются методы дистилляции или хранение только ключевой информации:
Дистиллированная траектория: Сжатие полной траектории выполнения задачи с помощью методов, таких как суммирование [144, 187] и извлечение кратчайших путей [190, 196].
Избирательное хранение: Хранение только важных данных каждой задачи, например, конечных результатов [186, 189, 197, 198], выводов [62, 189] и пар «действие-наблюдение» [76, 144, 162].
B. Владение памятью
Индивидуальная память: Предназначена для ограниченной группы агентов и имеет четкие правила использования [62, 76, 88, 97, 98, 107, 139, 144, 148, 162, 186, 187, 189, 190, 196–198, 205].
Общая память: Доступна всем агентам и хранит записи их действий, служа динамическим центром обмена информацией [4, 57, 160, 187, 198].
C. Формат памяти
Естественные языки: Наиболее распространенный формат [4, 62, 139, 148, 186, 189, 194, 197, 198, 205], обеспечивающий гибкость и сохранность информации.
Языки программирования: Хранение сгенерированного кода для последующего использования [88, 97].
Структурированные сообщения: Организация памяти в виде списка сообщений с атрибутами, удобная для индексации, обработки и хранения метаданных [57, 107, 187].
Пары «ключ-значение»: Хранение информации во внешней памяти с ключами для запросов агентов [162, 190, 196].
Векторные представления: Встраивание памяти в вектор для поиска наиболее релевантного опыта [144].
Деревья: Использование деревьев или графов для запоминания, особенно в сценариях, требующих гибкого расширения или отслеживания путей [63, 76].
D. Операции с памятью
Запись в память: Включает предварительную обработку информации (например, дистилляцию [62, 107, 144, 148, 187, 190, 196, 205]) и обработку переполнения памяти.
Чтение из памяти: Получение необходимой информации из памяти с использованием различных критериев фильтрации ( давность [88, 139, 144, 148, 186, 187, 197, 198, 205], релевантность [88, 187, 198], схожесть [144, 190, 196]) и способов чтения ( рефлексия [189, 194], поиск [144, 190, 196], подписка [187, 198]).
Существующие LLM-агенты используют два основных типа восприятия: текстовое и визуальное.
A. Текстовое восприятие:
Входные данные на естественном языке: инструкции и дополнительная информация из среды.
Входные данные на языке программирования: контекст кода.
B. Визуальное восприятие:
Используется в задачах, связанных с изображениями, например, UML-диаграммами [187] или UI-страницами. В тестировании мобильных приложений визуальный ввод используется для определения кликабельных элементов на скриншотах [144, 145, 148]. Для обработки изображений агенты используют внешние модели компьютерного зрения, такие как SegLink++ [224] и ConvNeXts [225].
В этом обсуждаются инструменты, используемые агентами на LLM для решения задач разработки. Эти инструменты расширяют возможности LLM за пределами обычного интерактивного диалога.
A. Инструменты поиска
Агенты используют инструменты поиска для извлечения информации, такой как документация или фрагменты кода.
A.1: Поиск в Интернете. Агенты [78], [96], [105], [153], [187], [193] используют поисковые системы, такие как Google, Bing, WikiSearch, для поиска информации на сайтах сообществ программистов и учебных ресурсах. Например, агенты [78], [81], [82], [188] используют DuckDuckgo [228] для поиска API. Paranjape1 et al. [102] используют SerpAPI [229] для извлечения сниппетов ответов или комбинирования первых двух результатов поиска.
A.2: Поиск в базе знаний. Агенты также могут искать информацию в собственной базе знаний, такой как пул памяти или репозиторий кода. Для этого используются методы сравнения на основе схожести (например, BM25 [78], [82] и плотные вложения текста [64], [77], [105], [110], [144], [151], [162], [190]) и строкового сопоставления [107], [171].
B. Работа с файлами
Агенты [113], [153], [171], [172], [207], [210] используют файловые операции, такие как команды оболочки (например, Linux shell) или утилиты кода (например, пакет os Python) для просмотра, добавления, удаления и редактирования файлов.
C. Работа с графическим интерфейсом
Для работы с ПО, имеющим графический интерфейс, агенты [15], [139], [145], [148] используют такие операции, как клики, ввод текста, прокрутка, смахивание, возврат и завершение. Для идентификации элементов интерфейса используются модели распознавания изображений и текста (например, SegLink++ [231], Screen Recognition [232] и ConvNeXts [233]), дампы (например, Android UIAutomator [147]) или анализ иерархии представлений интерфейса [15], [139]. Для тестирования используются виртуальные устройства Android (например, Genymotion [146], VirtualBox [140] и pyvbox [141]) и инструменты, такие как Android Debug Bridge [143].
D. Статический анализ программ
Инструменты статического анализа программ широко используются агентами для получения информации о коде (например, потоки данных и управления) для LLM.
D.1: Сбор статической информации. Агенты используют статический анализ для сбора информации о программе, такой как абстрактные синтаксические деревья (AST) [15], [77], [82], [88], [89], [107], [125], [126], [198], [206], [210], [226], графы потока управления (CFG) [75], [134], графы вызовов (CG) [125], [226], графы потока данных (DFG) [113], [134], графы зависимостей кода (CDG) [88], [198] и токены автодополнения кода [77], [88], [89], [227].
D.2: Проверка качества кода. Инструменты статического анализа также используются для проверки синтаксиса [77], [84], [197], форматирования кода [82], [192], сложности кода [134], уязвимостей [134], [174] и спецификаций [226].
E. Динамический анализ
Агенты используют динамический анализ для сбора информации о времени выполнения, такой как трассировка вызовов методов, значения переменных во время выполнения и охват кода тестами.
Трассировка вызовов методов. AgentFL [160] использует пакет java.lang.instrument [240] для записи трассировки вызовов методов.
Значения переменных во время выполнения. Некоторые агенты [75], [172] имитируют отладку для установки точек останова и получения значений переменных.
Охват кода тестами. Информация об охвате кода тестами используется агентами [125], [126], [134] для оценки качества тестов.
F. Инструменты тестирования
F.1: Проверка тестов. Агенты [62]–[67], [71]–[74], [79], [81]–[85], [87], [91], [92], [94], [95], [97], [98], [102], [122], [123], [125], [128], [133], [153], [159], [171], [172], [175], [187], [188], [191], [194], [198], [206], [210], [230] используют фреймворки для запуска тестов, такие как PyTest, unittest и JUnit, для выявления ошибок и сбоев.
F.2: Инструменты генерации тестов. Традиционные инструменты генерации тестов, такие как Pynguin [241], используются агентами [125] для создания набора модульных тестов.
F.3: Мутационное тестирование. Инструменты мутационного тестирования, такие как MutPy [242], используются агентами [127] для оценки качества тестов.
G. Инструменты локализации дефектов
Агенты [171], [206] могут использовать традиционные методы локализации дефектов, такие как GZoltar [243], для определения подозрительных элементов кода.
H. Системы управления версиями
Агенты, работающие с целыми репозиториями, используют системы управления версиями, такие как Git. Например, RepoAgent [227] использует Git для отслеживания изменений в коде и синхронизации документации.
Более половины (52.8%) существующих агентов для разработки представляют собой многоагентные системы. Такие системы получают преимущество за счет разделения ролей и координации между агентами, что позволяет эффективно решать сложные задачи, особенно те, которые охватывают несколько этапов разработки.
В многоагентной системе каждому агенту, как правило, назначается специализированная роль, предназначенная для решения конкретных задач. Рассмотрим наиболее распространенные роли:
A. Управляющие роли (Manager Roles)
A.1 Декомпозиция задач: Разбивают проект на управляемые подзадачи и составляют план для разработчиков и тестировщиков [98, 144, 145, 162, 193, 196, 198, 205].
A.2 Принятие решений: Координируют взаимодействие в команде и предоставляют рекомендации по выполнению задач.
A.3 Организация команды: Формируют состав команды агентов, выбирая роли для оптимального решения задач проекта.
B. Анализ требований (Requirement Analyzing Roles)
Анализируют требования к программному обеспечению, преобразуя идеи пользователей в структурированный формат.
C. Проектирование (Designer Roles)
C.1 Архитектура ПО: Разрабатывают высокоуровневую структуру программного обеспечения.
C.2 Дизайн UI/UX: Создают визуальные и интерактивные аспекты пользовательского интерфейса.
D. Разработка (Developer Roles)
Создают и совершенствуют код на различных уровнях (от функций до файлов и проектов).
E. Обеспечение качества ПО (Software Quality Assurance Roles)
E.1 Ревью кода: Выявляют потенциальные проблемы качества кода путем статического анализа.
E.2 Тестирование: Пишут тесты и генерируют тестовые сценарии.
E.3 Отладка: Анализируют отчеты о тестировании, воспроизводят ошибки и исправляют код.
F. Вспомогательные роли (Assistant Roles)
Оказывают помощь другим агентам, например, предоставляют информацию об архитектуре проекта или преобразуют ответы на естественном языке в формализованные отчеты об ошибках.
2. Механизмы коллаборации
В мультиагентных системах для разработки ПО (SE) эффективность напрямую зависит от механизма взаимодействия агентов. Выделяют четыре основных типа структур: слоистая, кольцевая, древовидная и звездообразная (рисунок ниже).
A. Слоистая структура. Задача разбивается на подзадачи, каждая из которых поручается отдельному агенту или группе агентов. Взаимодействие происходит последовательно: агенты получают данные от предыдущего уровня и передают результаты на следующий. Примеры: [105], [133], [160], [183], [191], [206]. Возможны вариации: агенты могут ссылаться на данные не только от соседних уровней [98], [187], [195], подзадачи могут решаться группами агентов [57], [91] или диалогом между двумя агентами с разными ролями [119], [186], [197]. Некоторые системы, например, LCG [194] и AgileCoder [198], задействуют еще больше агентов на одном уровне. В GPTLENS [104] несколько агентов-аудиторов независимо ищут уязвимости, а затем их результаты объединяются. В [69] используется механизм голосования, а DyLAN [70] представляет собой многослойную нейросеть.
B. Кольцевая структура. Основана на многоэтапных диалогах или механизмах обратной связи для итеративного улучшения результатов. Может включать два или более агента.
B.1: Две роли. В некоторых системах [63], [66], [67], [95], [174] реализован цикл «генерация-валидация», где один агент генерирует код, а другой проверяет его и предлагает улучшения. Например, INTERVENOR [65] использует «ученика» для генерации кода и «учителя» для его корректировки. Другие системы [68], [111], [190] используют диалог двух агентов для достижения общей цели, например, тестировщик и разработчик в [111] или «инструктор» и «ассистент» в [68], [190].
B.2: Несколько ролей. При увеличении числа агентов цикл становится более гибким. Например, в [62], [145], [193] задачи разделяются между несколькими агентами. DroidAgent [144] встраивает внутренний цикл между «актером» и «наблюдателем» в общий цикл между «планировщиком» и «аналитиком».
C. Древовидная структура. В отличие от слоистой структуры, агенты одного уровня не взаимодействуют друг с другом, а фокусируются на своих задачах. Например, SoA [97] динамически создает новых агентов для генерации кода, формируя древовидную структуру. В MASAI [210] тесты и патчи генерируются параллельно, а затем лучший вариант выбирается ранжировщиком.
D. Звездообразная структура. Центральный агент координирует работу остальных. Например, в RCAgent [162] контроллер вызывает экспертов-агентов по мере необходимости. В AutoGen [64] «командир» взаимодействует с «писателем» (генерация кода) и «охранником» (безопасность). В XUATCopilot [148] операционный агент получает данные от агента проверки и вызывает агента выбора параметров для планирования действий.
3. Взаимодействие человека и агента
Несмотря на стремление к максимальной автоматизации, исследования [183], [191] показывают, что LLM-агенты сталкиваются с трудностями. Поэтому некоторые системы внедряют участие человека на разных этапах: планирование, требования, разработка и оценка (рисунок ниже).
A. Планирование. LLM-платформа позволяет выбирать предопределенные действия для изменения сгенерированных сценариев. AISD [191] и LLM4PLC [192] дают возможность проверить и скорректировать дизайн системы, но это требует определенных навыков.
B. Требования. Нечеткие формулировки требований могут привести к несоответствию результата ожиданиям. Поэтому часто используются механизмы уточнения требований, например, диалоговые системы ClarifyGPT [94] и CodeAct [85], обратная связь в Sapper IDE [184] и MARE [57], оценка и корректировка use-кейсов в AISD [191]. HARA [245] генерирует краткое описание требований для экспертной оценки.
C. Разработка. Человек может направлять агентов, предлагать решения и помогать в случае ошибок. Flows [91] использует решения, созданные человеком, для генерации более качественного кода. AutoGen [64] и LLM4PLC [192] позволяют пользователям вносить коррективы в процесс. CodeS [195] строит репозиторий из трех частей, позволяя редактировать каждую из них.
D. Оценка. Человек проверяет результаты работы агентов, например, проводит ручное тестирование в AISD [191] и Prompt Sapper [184], чтобы убедиться в соответствие требованиям. ART [102] позволяет пользователям улучшать работу агентов, корректируя библиотеки задач и инструментов.
Оценка агентов: Необходимо разработать более совершенные методы оценки агентов, выходящие за рамки простого измерения успешности выполнения задач. Важно анализировать промежуточные этапы работы агента, чтобы понимать причины его ошибок. Также нужно учитывать такие аспекты, как надежность, безопасность и этичность, а не только эффективность. Необходимо оценивать стоимость использования агентов, включая затраты на вызовы LLM, обработку данных и время работы.
Тестирование: Существующие бенчмарки для оценки агентов часто не отражают сложность реальных задач. Необходимо создавать более реалистичные бенчмарки, которые учитывают комплексный характер разработки ПО.
Взаимодействие человека и агента: Разработка ПО — это творческий процесс, поэтому важно обеспечить согласованность действий агентов с намерениями разработчиков. Необходимо исследовать способы более глубокой интеграции человека в жизненный цикл разработки ПО, управляемой агентами. Важно разработать удобные интерфейсы для взаимодействия человека и агента, которые позволят эффективно представлять информацию и получать обратную связь.
Многомодальность: Большинство агентов используют только текст или изображения. Необходимо исследовать потенциал других модальностей восприятия, таких как голос или жесты, для повышения гибкости и доступности агентов.
Новые задачи: LLM-агенты могут быть применены к большему числу задач разработки ПО, которые пока остаются малоизученными. Например, это задачи проектирования, верификации и поддержки функциональности.
Обучение LLM: Для решения сложных задач требуются LLM, обученные не только на коде, но и на других данных, отражающих весь жизненный цикл разработки ПО, таких как документация, обсуждения разработчиков, история изменений кода и информация о времени выполнения.
Экспертиза в области разработки ПО: Важно интегрировать в агентов знания и опыт, накопленные в области разработки ПО. Например, можно использовать существующие инструменты и методы разработки ПО в качестве компонентов агентов. Знание предметной области может помочь в управлении рабочими процессами агентов.
LLM-агенты обладают большим потенциалом для автоматизации и улучшения процессов разработки ПО. Однако для их успешного применения необходимо решить ряд задач, связанных с оценкой, тестированием, взаимодействием с человеком, использованием различных модальностей восприятия, обучением LLM и интеграцией экспертизы в области разработки ПО.
Ссылки на референсы в исследовании можно также найти здесь.