Merge queue для ИИ-агентов — самый надёжный способ держать main зелёным, как только вы запускаете больше одного агента одновременно. С одним агентом драмы нет: он работает в ветке, вы смотрите результат, вы сливаете. Но когда три-четыре агента начинают заканчивать работу в своих ветках, всё меняется. Каждая ветка проходит проверки по отдельности, вы сливаете их одну за другой, и main красный.
В этой статье: почему ветки параллельных агентов ломают main, как это исправляет merge queue и как шаг за шагом работает merge queue в AgentVera.
Зелёные поодиночке, красные вместе
Начнём с примера. В main есть функция formatPrice(amount). Вы запускаете двух агентов одновременно:
- Агент A добавляет параметр валюты:
formatPrice(amount, currency)— и обновляет все места вызова. - Агент B делает новый экран счетов, который вызывает
formatPrice(amount).
Обе ветки начались от одного и того же main. Тесты A проходят, потому что в мире A экрана счетов нет. Тесты B проходят, потому что в мире B функция всё ещё принимает один аргумент. Git тоже не видит конфликта: ветки меняли разные файлы.
Вы сливаете A, затем B. Git молчит. Но теперь main вызывает функцию с двумя параметрами, передавая один аргумент, и проверка типов падает.
Это семантический конфликт: текстового конфликта нет, но изменения ломают друг друга. С параллельными агентами он встречается чаще, потому что:
- Агенты не видят друг друга. Каждый работает в своём worktree и не знает, что делают остальные.
- Ветки копятся быстро. К середине дня могут ждать пять-шесть веток.
- Каждая ветка тестировалась на старой базе. Чем дольше ветка ждёт, тем устаревшее её база.
- Сливать по порядку вручную утомительно. После каждого слияния нужно обновлять следующую ветку, снова запускать тесты и разбирать конфликты. Люди начинают это пропускать.
Что такое merge queue
Merge queue выстраивает в очередь ветки, ожидающие влития, сливает каждую с актуальной вершиной целевой ветки и тестирует получившийся результат. Идея проста: прежде чем ветка попадёт в main, проверь, как main будет выглядеть после этого на самом деле.
Сравнение со слиянием вручную:
| Слияние вручную | Merge queue | |
|---|---|---|
| На чём запускается тест | На собственной базе ветки | На актуальной вершине main + ветка |
| Семантические конфликты | Находятся после попадания в main | Ловятся до влития |
| Порядок | Кто первым нажал | Порядок очереди |
| Сломанная ветка | Ломает main | Отклоняется, main остаётся чистым |
У GitHub тоже есть merge queue на уровне репозитория: она ставит в очередь pull request’ы и тестирует их вместе с последней версией целевой ветки. Очередь AgentVera применяет ту же идею на вашем десктопе, для веток ваших агентов, и дополнительно подключает агентов, которые разрешают конфликты слияния и исправляют упавшие проверки.
Как работает merge queue в AgentVera
Очередь находится в десктопном приложении в разделе Details → Automation → Merge queue. У каждого проекта одна очередь; в проекте с несколькими репозиториями у каждого репозитория своя очередь и свои настройки. Ветки вливаются по одной.
1. Ветка попадает в очередь
Есть три способа:
- Вручную: введите имя ветки в поле Branch, при желании задайте Title и нажмите Add to queue.
- Из параллельной команды: когда параллельная команда закончила, нажмите Queue, чтобы отправить её интеграционную ветку.
- Из автоматизации: выберите Add to the merge queue как способ доставки в правиле автоматизации, и ветка завершившего работу агента сразу попадёт в очередь.
Карточки в Review inbox тоже предлагают Send to the merge queue. Для каждого элемента показано, откуда он пришёл: вручную, из параллельной команды или из автоматизации.
2. Слияние с актуальной вершиной целевой ветки
Когда подходит очередь ветки, она сливается с текущей вершиной целевой ветки в отдельном worktree самой очереди. Ваша рабочая папка и папки ваших агентов остаются нетронутыми. Если у репозитория есть удалённый репозиторий, целевая ветка сначала подтягивается, и слияние выполняется поверх последней версии origin.
Стратегию вы выбираете в настройках: Merge commit или Squash. Если ветка уже содержится в целевой, элемент отмечается как влитый.
3. Конфликт получает агента
Если при слиянии возникает конфликт, очередь не останавливается. Она открывает агента-резолвера, а элемент переходит в состояние «resolving conflicts». Агенту велено сохранить намерения обеих сторон, не оставлять маркеров конфликта и закоммитить результат.
Когда агент сдаёт работу, AgentVera не принимает его слова на веру. Она проверяет, нет ли неслитых файлов, ищет маркеры <<<<<<< и >>>>>>> и убеждается, что ветка действительно слита. Если что-то из этого не выполнено, элемент завершается ошибкой и не вливается.
При включённом Automatic model модель резолвера выбирается по сложности задачи.
4. Проверка на слитом результате
Когда слитый результат готов, очередь запускает команду проверки. Оставьте Check пустым, и она возьмёт тестовую команду проекта, либо впишите свою, например pnpm typecheck && pnpm test.
Если проверка падает, агент-резолвер получает конец вывода и пытается её исправить. Раундов исправления не больше двух. Если проверка всё ещё красная, элемент отклоняется, а очередь идёт дальше. Сломанная ветка в main не попадает.
Именно так и происходит в примере с formatPrice: ветка B сливается с main, где уже есть A, проверка типов падает, резолвер обновляет вызов на экране счетов под новую сигнатуру, и проверка зеленеет.
5. Подтверждение и влитие
Прошедшая ветка готова. По умолчанию Land passing branches automatically выключено, поэтому элемент ждёт в статусе «ready, awaiting approval», а вы получаете уведомление. Посмотрите и нажмите Land, когда всё устраивает.
Влитие происходит так:
- Если есть удалённый репозиторий, слитый результат отправляется в целевую ветку. Для репозиториев GitHub используется вход в GitHub на вашем компьютере.
- Если удалённого репозитория нет, локальная целевая ветка перематывается вперёд (fast-forward). Её никогда не сдвигают из-под незакоммиченной работы.
- Если целевая ветка за это время ушла вперёд, элемент пересобирается на новой вершине и проверяется снова. Это происходит не более трёх раз; если целевая ветка продолжает двигаться, элемент завершается ошибкой.
Если закрыть и снова открыть приложение, прерванная работа не пропадёт; она возвращается в очередь.
Настройки
Их немного, и все они в одной вкладке:
| Настройка | Что делает | По умолчанию |
|---|---|---|
| Target branch | Ветка, в которую вливается работа | Пусто: ветка по умолчанию |
| Merge | Merge commit или Squash | Merge commit |
| Check | Команда, запускаемая на слитом результате | Пусто: тестовая команда проекта |
| Land passing branches automatically | Вливает прошедшие ветки без подтверждения | Выключено |
Элементы в очереди можно переставлять кнопками Up и Down, останавливать через Cancel и перезапускать упавшие или отменённые через Retry. У каждого элемента свой лог и история, а у элементов с pull request есть кнопка, открывающая его на GitHub.
Очередь делит ресурсы с другими фоновыми задачами и имеет приоритет: слияния идут раньше автоматизаций и параллельных команд. Агентов, которых вы запускаете сами, в очередь не ставят никогда.
Параллельные команды и очередь вместе
Больше всего пользы merge queue приносит с параллельной командой. Параллельная команда делит большую работу максимум на восемь частей; по умолчанию одновременно работают три агента, каждый в своём worktree. Части сливаются в интеграционную ветку, а интеграционный агент занимается конфликтами и проверкой.
Когда команда закончила, у вас одна интеграционная ветка. Нажмите Queue, чтобы отправить её. Другая команда или автоматизация за это время могли отправить что-то в main; очередь берёт всё по порядку, тестируя каждое на самом свежем main.
Общую картину работы с несколькими агентами смотрите в статье о параллельных кодинг-агентах.
Типичные ошибки
- Пустой Check и нет тестовой команды. Очередь всё равно сливает, но без чего-либо для проверки не поймает семантические конфликты. Задайте тестовую команду проекта или впишите команду в Check.
- Только юнит-тесты. Многие поломки вроде описанной выше проявляются в проверке типов или сборке. Добавьте их в проверку.
- Автоматическое влитие с первого дня. Не включайте Land passing branches automatically, пока не понаблюдали за очередью какое-то время. Сначала несколько недель подтверждайте вручную.
- Огромные ветки. Очередь их примет, но вероятность конфликтов и сбоев растёт с размером. Давайте агентам небольшие, чётко очерченные задачи.
- Игнорирование отклонённых элементов. Отклонение обычно указывает на реальный конфликт в дизайне. Прочитайте лог и при необходимости верните работу агенту с пояснением.
Пример одного дня
Утро
Вы запускаете трёх агентов на три задачи: страница оформления заказа, API отчётов и обновление зависимости. Каждый работает в своём worktree. Есть ещё упавший с вечера CI; правило автоматизации уже поймало его и отправило исправление в очередь.
Ближе к полудню
Когда агенты заканчивают, вы открываете их карточки в Review inbox. Страница заказа и API отчётов выглядят хорошо, и вы нажимаете Send to the merge queue для обеих. В очереди теперь три элемента: исправление CI, страница заказа и API отчётов.
Полдень
Исправление CI проходит проверку и ждёт подтверждения. Вы нажимаете Land. Страница заказа сливается с новым main и проходит. API отчётов конфликтует с типом, изменённым страницей заказа; вмешивается агент-резолвер, обновляет места вызова, и проверка зеленеет. Всё, что сделали вы, — два раза подтвердили.
После обеда
Обновление зависимости после двух раундов исправлений всё ещё красное и отклоняется. Main остаётся чистым. Лог показывает смену мажорной версии в одной из библиотек, поэтому вы возвращаете работу агенту с более узкими указаниями.
Чек-лист
- Есть ли у проекта тестовая команда или команда в Check?
- Охватывает ли проверка тип-чек и сборку?
- Правильна ли Target branch? Пусто означает ветку по умолчанию.
- Соответствует ли стратегия слияния привычкам команды: Merge commit или Squash?
- Включено или выключено Land passing branches automatically осознанно?
- Для репозиториев GitHub: выполнен ли на этом компьютере вход в GitHub?
- Небольшие и чётко очерченные ли задачи у ваших агентов?
Итоги
Параллельные агенты работают быстро, но скорость, ломающая main, долго не живёт. Merge queue сливает и тестирует каждую ветку на самом свежем main, так что ветки, проходящие по одной, не сломают main вместе. В AgentVera очередь поручает конфликты и упавшие проверки агенту, сама проверяет результат, а решающее слово по умолчанию оставляет вам.
Читайте дальше:
Чтобы попробовать AgentVera, начните с главной страницы.