Первый набор агентов у меня был собран по должностям и не работал. Второй собран по каталогам кода и работает. Разница в двух вещах: у зоны есть граница, а у должности её нет.
Цифры для затравки. Восемь агентов первого поколения — 3814 строк. Двенадцать агентов второго — 345 строк на всех. В одиннадцать раз меньше текста при полуторакратном росте числа исполнителей.
От профессий к каталогам
Переразметка началась с простого вопроса: где проходит граница между бэкенд-разработчиком и фронтенд-разработчиком в блоге?
Ответ оказался неприятным. Нигде. Один человек пишет модель, ресурс админки и публичный шаблон в одной задаче. Профессиональное деление отражает штат команды, которой у меня нет.
Зато в проекте есть границы другого рода, и они видны в дереве каталогов:
app/Models, app/Filament, database/migrations → backend-filament
resources/views/blog, resources/css → blade-ui
public/vendor/almcreate, CKEditor-компоненты → ckeditor-sync
посты, рубрики, теги, серии, SEO-разметка → content-seoЭти границы устойчивые. Правка в шаблоне рубрики не требует лезть в модель, правка в ресурсе админки не требует трогать CSS. Там, где требует, — задача действительно на стыке, и это видно сразу.
Кто за что отвечает
Полный набор блога сейчас такой.
Пишут код: backend-filament (модели, миграции, политики, ресурсы админки), blade-ui (публичные шаблоны, Tailwind, темы, адаптив), ckeditor-sync (общий модуль редактора и его раскладка по соседним проектам), content-seo (посты, рубрики, серии, разметка для поиска и соцсетей), test-strategist (проектирует и пишет тесты).
Не пишут код: code-reviewer, security-reviewer, a11y-reviewer, visual-qa (проверяют), flow-orchestrator и ecosystem-orchestrator (строят карту до правок), qa-runner (гоняет тесты и разбирает падения).
Семь из двенадцати не имеют права записи. Это отдельная тема, ей посвящена своя статья цикла; здесь важно, что деление на пишущих и проверяющих проходит поперёк деления на зоны.
Обратите внимание на content-seo. Это единственный агент, чья зона задана не каталогом, а предметной областью: посты, рубрики, теги, серии и их представление в выдаче. Файлы у него разбросаны от моделей до шаблонов. Такое исключение допустимо, когда предметная область сама по себе связная — но именно с ним у меня чаще всего возникают споры о границах.
Тело агента: команды, а не принципы
Файл агента второго поколения начинается не с принципов проектирования, а со среды.
Ты бэкенд-инженер проекта блога (Laravel 13 + Filament 5, PostgreSQL + Redis, Docker).
## Среда
Все php/artisan/composer/pint выполняй внутри контейнера:
docker compose --env-file .local/.env -f .local/docker-compose.yml \
exec -T webserver php artisan migrateДальше — что делает, правила, финальный формат ответа. Сорок одна строка целиком.
Сравните с семьюстами пятьюдесятью строками про SOLID в первом поколении. Дело не в объёме как таковом: короткий файл не лучше длинного просто потому, что короткий. Дело в том, что каждая строка нового файла верна только здесь. Форма вызова консоли, раскладка ресурсов админки, требование не хардкодить контент, потому что источник — сидеры.
Есть и приятный побочный эффект: такой файл невозможно скопировать в другой проект не думая. Он сразу перестанет работать, и это видно.
Правило соседних файлов
Одна строка есть почти в каждом моём агенте и приносит больше всех остальных вместе взятых:
Сначала смотри соседние шаблоны/компоненты и app.css: повторяй конвенции,
не вводи новый визуальный язык без причины.У агента бэкенда та же строка про модели и ресурсы, у агента редактора — про существующие плагины.
Она заменяет собой всё то, что в первом поколении занимало сотни строк описания стандартов. Стандарты уже записаны в коде, их не надо пересказывать — надо заставить посмотреть.
Работает это лучше всего в зрелом проекте, где соседних файлов много и они однородные. В свежем репозитории с тремя файлами повторять нечего, и там правила приходится выписывать явно.
Задача на стыке двух зон
Главное возражение против деления по каталогам: половина задач попадает в две зоны сразу. Добавить поле в модель, показать его в админке и вывести в публичном шаблоне — это три зоны.
Что делаю я.
Разбиваю задачу по зонам и иду по порядку данных: сначала модель и миграция, потом админка, потом публичный вывод. Каждый шаг заканчивается рабочим состоянием, и следующий получает готовую основу, а не обещание.
Границу передачи описываю явно. Для агента шаблонов это обычно «поле уже есть в модели и приходит в шаблон в такой-то переменной». Без этого он полезет проверять модель и по дороге её поправит.
Не разбиваю, когда изменение мелкое. Добавить в существующую страницу вывод уже существующего поля — одна задача, один исполнитель, любой из двух подходящих. Разбиение ради чистоты границ на десяти строках кода — это ритуал.
Сколько агентов нужно
У меня двенадцать. Не потому что это правильное число, а потому что столько получилось зон, и я могу описать каждую одной фразой.
Почему не три. Три агента — это «бэкенд, фронтенд, проверка», то есть возврат к должностям. Граница снова размывается, описания снова подходят всему, и выбор снова случайный.
Почему не тридцать. Каждый агент — это описание, конкурирующее за срабатывание. На двенадцати я ещё помню весь набор наизусть и вижу пересечения. На тридцати выбор придётся делать по таблице маршрутизации, а таблица на тридцать строк устаревает быстрее, чем правится.
Признак, что агентов слишком много: два описания, между которыми я сам не могу выбрать за пять секунд. У меня такое было с парой про изображения — свёл в один.
Признак, что мало: регулярно даю задачу и дописываю к ней три строки контекста, потому что исполнитель не знает специфики. Эти три строки и есть заготовка нового агента.
Что осталось
Переразметка заняла вечер и окупилась на второй неделе. Самое ценное в ней — не сами агенты, а то, что при их описании пришлось честно назвать границы в проекте. Половину пересечений я до этого не осознавал.
Чего не решил: content-seo с его зоной по предметной области всё ещё спорит за задачи с двумя соседями. Правильным решением было бы разрезать его по каталогам, но тогда потеряется связность — а связность там ровно та, ради которой он и заведён. Живу с этим и разруливаю руками.