TL;DR
Идея простая: перед запуском нескольких кодинг-агентов в одном репозитории заранее раздели работу на непересекающиеся зоны файлов и расставь порядок слияния по цепочке «кто меняет контракт → кто его использует». Каждому агенту в старте выдай явную инструкцию: какие файлы можно, какие нельзя, что именно изменилось в контракте и в каком порядке сливать ветки. Реакция по факту («коллега, возможно, правит файл X») не нужна. Предупреждение приходит уже после лишней правки.
Главная находка: каждый агент по отдельности проходит свои тесты, а общий результат сломан. Один агент переименовал поле amount в amountCents. Другой работал в своей ветке со старым контрактом. Ветки слились без конфликта, но код потребителя неверный. Расплывчатое предупреждение «что-то может измениться» не помогло: потребитель знал, что есть риск, и всё равно писал под старое поле. Причина в том, что нужного факта нет у него в рабочей копии. Модель покрупнее тут не спасает, она не может угадать то, чего не видела.
Метод в четыре хода. Опиши для каждой задачи, какие файлы она пишет и какие контракты потребляет. Найди пересечения и разведи их по очередям. Построй порядок слияния «производитель → потребитель». Выдай каждому агенту его зону, точную миграцию и место в очереди. Отдельный результат: решение, записанное в одной сессии, полностью убирает повтор ошибки в следующей. Доля повторов упала с 1.00 до 0.00.
Схема метода
ШАГ 1: Для каждой задачи записать: какие файлы пишет + какие контракты потребляет → таблица задач
ШАГ 2: Найти задачи с пересекающимися файлами → развести по разным очередям (батчам)
ШАГ 3: Найти «производитель → потребитель» (кто меняет контракт, кто на него опирается)
→ порядок слияния: производитель раньше потребителя
ШАГ 4: Выдать каждому агенту в начале: разрешено / запрещено + точная миграция контракта + его слот слияния
ШАГ 5: Проверка: реальное слияние веток + сборка + тесты, а не слова агентов
Шаги 1–4 можно выполнить в одном запросе к LLM-планировщику. Шаг 5 делается отдельно, в вашем репозитории.
Пример применения
Задача: Интернет-магазин на Python/TypeScript. Платёжный сервис хранит сумму в рублях (amount) и переходит на копейки (amountKopecks, целое число) из-за округлений в ЮKassa. Запускаете трёх агентов Claude Code в отдельных git worktree (отдельных рабочих копиях). Агент A меняет платёжный сервис. Агент B считает итог корзины, он потребитель. Агент C формирует чек для Telegram-бота, тоже потребитель. Ещё есть задача D: поправить тексты в письмах, она независима.
Промпт:
Ты — планировщик параллельной работы кодинг-агентов. Работаешь строго по алгоритму, не пропуская шагов.
<Задачи>
A: Платёжный сервис. Меняю поле amount (рубли, float) на amountKopecks (копейки, int).
Пишу: payments/models.py, payments/api.py, payments/schema.json
Потребляю: —
B: Итог корзины. Считаю сумму заказа по данным платежа.
Пишу: cart/total.py, cart/tests/test_total.py
Потребляю: контракт payments/schema.json (поле суммы)
C: Чек в Telegram-боте. Форматирую сумму для пользователя.
Пишу: bot/receipt.py
Потребляю: контракт payments/schema.json (поле суммы)
D: Тексты писем.
Пишу: emails/templates/*.html
Потребляю: —
Задачи>
<Алгоритм>
1. Выпиши, у каких пар задач пересекаются файлы записи. Для каждой пары укажи общий файл.
2. Построй зависимости «производитель → потребитель»: задача Х производит контракт, если её файлы записи пересекаются с тем, что потребляет задача Y. Выпиши все рёбра.
3. Построй порядок слияния: производитель всегда раньше потребителя. Если есть цикл — разорви его, убрав ребро от производителя с наименьшим числом потребителей, и скажи об этом явно.
4. Раздели задачи на батчи, которые можно запускать параллельно: внутри батча файлы записи не пересекаются.
5. Выдели «переназначенные» задачи: те, что делят файл с другой задачей, и те, что потребляют изменённый контракт. Для каждой напиши причину.
Алгоритм>
<Выход>
Таблица: задача | батч | слот слияния | переназначена? | причина.
Затем для каждой переназначенной задачи — готовая инструкция агенту:
- РАЗРЕШЕНО править: [файлы]
- ЗАПРЕЩЕНО править: [файлы]
- Что изменилось в контракте: [точная миграция: старое → новое поле, единицы, пример]
- Что делать: кодируй под НОВЫЙ контракт, а не под тот, что видишь в своей ветке. Не сливай, пока задача A не слита.
Выход>
Результат: Модель выдаст таблицу: A в первом слоте слияния, B и C после A, D независима и может идти параллельно. Для B и C будут готовые инструкции с запретными файлами и точным описанием миграции: «рубли → копейки, целое число, умножить на 100». Если пересечений по файлам нет, модель так и скажет. Дальше вы раздаёте инструкции агентам. После слияния обязательно запускаете сборку и тесты. В статье именно этот шаг показал, что ветки B и C слились чисто, но были сломаны.
Почему это работает
Слабость: агент видит только свою рабочую копию. Если коллега поменял контракт в другой ветке, у потребителя нужного факта просто нет. Поэтому он уверенно пишет под старую форму. Расплывчатое предупреждение («кто-то может править X») ничего не меняет: агент знает, что что-то может поменяться, но не знает что. Реакция по факту ещё и опаздывает. Агент работает секундами, и к моменту предупреждения конфликтный код уже написан.
Сильная сторона: если в стартовой инструкции прямо написано «эти файлы не трогай, вот новая форма поля, сливайся после A», модель такое соблюдает. В проверке на общий файл ни один из пяти агентов не вышел за свою зону. Несколько даже писали, что делают так «как договорились». Модель хорошо следует явным ограничениям и конкретным данным в начале.
Как метод это использует: проблему предотвращают, а не чинят. Конфликты и устаревшие контракты закрываются распределением до старта. Раздел «кто что трогает» и «в каком порядке сливаем» не требует рассуждений модели. Он требует информации в нужный момент. Поэтому эффект не уменьшался на более сильных моделях.
Рычаги управления: - Детализация миграции (точное «старое → новое» с примером против общих слов): в статье именно конкретика и порядок отличали рабочий вариант от бесполезного предупреждения. Полностью этот рычаг они не разделили, это честно отмечено в ограничениях. - Явный список запрещённых файлов: убирает «заодно поправлю». Для слабой модели добавь короткий чек-лист в конце задачи. - Число агентов: выигрыш растёт с их количеством. Для двух агентов и разных файлов планирование избыточно. - Правило разрыва циклов: замени на своё, например «приоритет у задачи с большим числом потребителей».
Шаблон промпта
Блок 1 — планировщик (вставляется в чат один раз перед запуском агентов):
Ты — планировщик параллельной работы кодинг-агентов. Работаешь строго по алгоритму.
<Задачи>
{ID}: {краткое описание}
Пишу: {файлы или папки, которые задача изменит}
Потребляю: {контракты, API, схемы, от которых зависит задача, или «—»}
[...повторить для каждой задачи]
Задачи>
<Алгоритм>
1. Найди пары задач с пересекающимися файлами записи. Укажи общий файл.
2. Построй рёбра «производитель → потребитель»: задача Х производит контракт, если её файлы записи входят в то, что потребляет Y.
3. Построй порядок слияния: производитель раньше потребителя. Цикл разорви, убрав ребро от производителя с наименьшим числом потребителей, и скажи об этом.
4. Раздели задачи на параллельные батчи: внутри батча файлы записи не пересекаются.
5. Отметь «переназначенные» задачи: делят файл с другой или потребляют изменённый контракт. Напиши причину.
Алгоритм>
<Выход>
Таблица: задача | батч | слот слияния | переназначена? | причина.
Для каждой переназначенной задачи — инструкция агенту:
- РАЗРЕШЕНО править: [...]
- ЗАПРЕЩЕНО править: [...]
- Что изменилось в контракте: [точно: было → стало, единицы, пример]
- Кодируй под НОВЫЙ контракт. Сливай только после: {задача-производитель}.
Выход>
Блок 2 — проверка после слияния (отдельным запросом агенту-ревьюеру или вручную):
Слей ветки в порядке: {порядок_слияния}. После слияния запусти {команда_сборки_и_тестов}.
Отчитайся структурированно:
- merge_conflicts: число
- build_ok: true/false
- tests_ok: true/false
- потребители_используют_новый_контракт: для каждого файла — да/нет + строка кода, где используется новое поле
Не пересказывай словами «всё хорошо» — приводи строки кода.
Что подставлять: {ID} и описание берёте из своего бэклога. Пишу и Потребляю — самый важный ввод: чем честнее вы укажете файлы и контракты, тем лучше план. {порядок_слияния} берёте из ответа планировщика.
🚀 Быстрый старт — вставь в чат:
Вот шаблон планировщика параллельных агентов. Адаптируй под мою задачу: [твоя задача — какие фичи или правки параллелятся в репозитории].
Задавай вопросы, чтобы заполнить поля.
[вставить шаблон выше]
LLM спросит, какие задачи идут параллельно, какие файлы каждая меняет и от каких контрактов зависит. Это нужно, потому что весь метод держится на заявленных зонах и зависимостях. Она возьмёт структуру из шаблона и соберёт готовый промпт под ваш репозиторий. Если не знаешь, какие файлы заденет задача, попроси LLM сначала разведать кодовую базу и предложить зоны, а потом проверь их глазами.
Ограничения
⚠️ Зоны объявляются вручную: статья не решает, как определять зоны автоматически. Если вы ошиблись с файлами или забыли зависимость, план гарантирует безопасность только на бумаге. Авторы сами называют это открытой проблемой.
⚠️ Слабая модель выполняет хуже: на маленькой модели план сработал не всегда. Часть правок вышла за зону или миграция осталась неполной. Для слабых агентов добавляйте проверку после работы.
⚠️ Не разделено, что именно помогло: в живом сравнении вместе менялись время выдачи, точность данных, зоны и порядок слияния. Какая часть даёт больше, неизвестно. Эксперимент «поздно, но детально» авторы оставили на будущее.
⚠️ Малые выборки: ключевые живые результаты сняты на 3–15 прогонах, на маленькой модели и у второго вендора — на пяти. Сценарии построены авторами, и в базовом варианте нужной информации у потребителя заведомо нет. Направление понятно, величину эффекта в реальных репозиториях пока не знаем.
⚠️ Простые случаи не требуют метода: если агенты работают в разных частях проекта и общих контрактов нет, планирование ничего не меняет. На контрольном сценарии без пересечений все варианты сработали одинаково.
⚠️ Маршрутизация фактов не повышает точность: гипотезу «если подсунуть агенту только нужный факт, он ответит точнее на длинном контексте» подтвердить не удалось. Выигрыш только в стоимости и в том, что контекст вообще помещается в окно.
Как исследовали
Идея была в том, чтобы превратить вопрос «помогает ли координация» из утверждения в измерение. Авторы сравнили три режима. Первый: агенты работают вслепую. Второй: реактивные предупреждения, намеренно расплывчатые, как в реальной жизни. Третий: заранее составленный план. Результат читали с настоящего git merge, а не с отчёта агента.
Сначала была детерминированная симуляция на девяти сценариях. Доля чистых интеграций: 1 из 9 при отсутствии координации, 4 из 9 при реактивных предупреждениях, 9 из 9 с планом. Конфликты слияния упали с 13 до 0. Когда N агентов переписывают один файл, конфликты растут как N−1 и при предупреждениях, и без них. Предупреждение всегда опаздывает. План держит ноль и при 32 агентах.
Затем живые агенты в изолированных git worktree. Основной сценарий — миграция контракта: поле денег переименовано из долларов в центы, потребитель считает итог. Ветки сливались чисто, но потребитель был сломан. На самой сильной модели (15 прогонов) 0 из 15 без плана и с предупреждением, 15 из 15 с планом. На небольшой модели 0.6 с планом, у второго вендора 1.0 на пяти прогонах. Предупреждение не помогало ни одной модели. В сценарии с общим файлом ни один из пяти агентов не нарушил выданную зону.
Отдельно проверили память. Два одинаковых модуля авторизации, а какой из них «правильный», нигде в коде не написано. Решение записали в первой сессии, во второй спросили, какой импортировать. Повторов ошибки: 1.00 без памяти, 0.00 с памятью, и у сильной, и у слабой модели. Без памяти агенты называли варианты «ничьёй» и угадывали.
Любопытнее всего две честные вставки. Первая: гипотеза о том, что роутинг фактов спасёт точность на длинном контексте, не подтвердилась. Модели находили нужное поле среди отвлекающих до 280 тысяч токенов. Выигрыш только в стоимости: около 155 токенов против 10–280 тысяч. Вторая: красивый результат «70% против 100%» оказался багом оценки, регулярка ложно помечала верные ответы. Авторы его отозвали и перешли на проверку по структурированным полям и сырым ответам. Вывод для практики: не доверяйте тому, что агент пересказал словами. Проверяйте реальный артефакт — строку импорта, слитое поле.
Адаптации и экстраполяции
🔧 Техника: перенести память в файл инструкций → решение переживает сессию
В статье память работала через инструмент системы. Без своей системы то же можно сделать файлом. Это моя адаптация, в статье измерялся именно инструмент памяти.
# В CLAUDE.md / AGENTS.md Перед выбором между равноценными вариантами (модуль, библиотека, подход) прочитай DECISIONS.md. Если решение уже записано — следуй ему и назови запись. Если принимаешь новое решение, которого нет в коде, допиши в DECISIONS.md: что выбрали, почему, дата.Эффект в статье был именно на решениях, которые нельзя вывести из кода. Для общего «как принято писать код» файл не нужен.
🔧 Техника: требовать от агента структурированный отчёт → вместо «всё готово» получаешь проверяемые поля
Добавь в конец задачи: «В финале выведи JSON:
files_changed,contract_field_used,tests_passed. Не добавляй пояснений». Это дешёвый аналог «оценивай по разобранным артефактам, а не по прозе».
Экстраполяция: распределение до старта + проверка после. Перед запуском попроси планировщик разложить работу по зонам. Затем после слияния отдай ветки отдельному агенту-ревьюеру с задачей «найди потребителей изменённого контракта и покажи строки, где используется старая форма». Так вы закрываете и профилактику, и ловлю то, что планировщик не предусмотрел. Это моя комбинация, статья проверяла только план и реальный merge.
Ресурсы
- Работа: Verifying Coordination in Parallel Coding Agents: NP-Bench and a Scheduling Planner
- Автор: Sumanyu Muku, Amira Learning
- Система и набор тестов NP-Bench: Nerveplane v0.17.0, открытый код, работает с Claude Code, Codex, OpenCode через MCP
- Отсылки из работы: SWE-bench, SWE-agent, MemGPT, Model Context Protocol, Agent2Agent, закон Конвея, закон Брукса, «lost in the middle»
