almdev Технический блог

Границы в описании: «НЕ для этого, это агент X»
Положительная часть описания подходит слишком многим задачам. Отрицательная — ровно одной.

Агент выбирается по описанию, и описание почти всегда написано как визитка. Разбираю три реальных описания с отрицательной частью, почему отрицание работает лучше уточнения и как проверить набор десятью задачами.

Подкатегория: Субагенты

Чтение
5 мин
Технологии / версии
Coding agent · Воркфлоу · Laravel · Subagents
Серия
Цикл «Субагенты» · часть 3 из 6
7 июл 2026 · 5 мин · 2 просмотра · AI
Карточка агента, где отдельной строкой выделено, чем он не занимается
Субагенты 07/2026

Два агента, оба подходят, выбирается случайный. Так выглядит проблема маршрутизации на практике, и лечится она не в теле агента, а в одной строке описания.

Причём лечится не тем, что описание становится точнее. Тем, что в нём появляется вторая половина: чего этот агент не делает.

Описание — условие выбора

Тело агента читается после того, как он выбран. До выбора видно только описание, и именно оно решает.

Из этого следует вещь, которую я долго не понимал. Описание пишется не для человека, который просматривает список, а для механизма, который сопоставляет задачу с набором. Визитка вида «специалист по бэкенду проекта» этому механизму бесполезна: под неё подходит любая задача, где есть слово «модель».

Положительная часть описания по природе своей широкая. Она перечисляет, что агент умеет, а умеет он много. Сужать её уточнениями можно бесконечно, и это не помогает: чем длиннее перечисление умений, тем большему числу задач оно соответствует.

Три описания с отрицанием

Вот что стоит у меня сейчас, дословно.

Агент бэкенда:

Бэкенд блога на Laravel + Filament. Используй для моделей Eloquent, миграций,
политик, сервисов, артизан-команд и админ-ресурсов Filament. Все php/artisan/
composer — внутри контейнера. НЕ для публичных Blade-шаблонов (это blade-ui)
и не для прогона тестов (это qa-runner).

Агент публичного интерфейса:

Публичный фронтенд блога — Blade-шаблоны, Tailwind CSS 4, Alpine.js, AOS.
Используй для вёрстки и стилей публичных страниц, светлой/тёмной темы,
адаптива и Blade-компонентов. НЕ для Filament-админки и моделей
(это backend-filament).

Агент ревью:

Ревью изменений блога на Laravel/Filament на регрессии — пропуск validation/
authorization, mass-assignment, N+1 и тяжёлые запросы, побочки jobs/events/
notifications, Blade-escaping, нарушения CSP, пробелы в тестах. Используй для
проверки диффа перед коммитом/PR. Фичи не пишет — только ревью.

Во всех трёх последнее предложение — отрицание. В первых двух оно ещё и называет адресата.

Почему отрицание сильнее уточнения

Уточнение положительной части добавляет признаки, по которым агент подходит. Отрицание добавляет признаки, по которым не подходит, и это принципиально другая операция.

Задача «поправь вёрстку карточки поста в списке рубрики» соответствует агенту бэкенда по словам «пост» и «рубрика». Сколько ни уточняй, что он про модели и миграции, слово «пост» никуда не денется. А строка «НЕ для публичных Blade-шаблонов» отсекает задачу целиком, потому что в ней есть слово «вёрстка».

Второй эффект — на границе двух агентов. Пара «пишет тесты» и «гоняет тесты» неразличима по положительной части: обе про тесты. У меня они разведены явно, у стратега тестов в описании стоит «прогон и починку красных делегируй qa-runner».

Третий эффект неожиданный: отрицание дисциплинирует меня самого. Чтобы написать «НЕ для этого», надо решить, для кого это. Половина моих пересечений между агентами всплыла именно в момент написания отрицательной части.

Адресат в отрицании

Отрицание без адресата работает наполовину.

«НЕ для публичных шаблонов» отсекает задачу и оставляет её без исполнителя. Дальше выбор делается из оставшихся одиннадцати описаний, и результат снова непредсказуем.

«НЕ для публичных Blade-шаблонов (это blade-ui)» отсекает и указывает. Задача уходит по адресу за один шаг.

Есть и побочная польза, про которую я узнал случайно. Ссылки между описаниями образуют карту набора: пройдя по всем «это агент X», видно, кто с кем граничит. У меня таких ссылок сейчас семь на двенадцать агентов, и все семь стоят на реальных стыках.

Проверка набора десятью задачами

Способ, которым я проверяю набор после каждой правки. Занимает минут пятнадцать.

Беру десять формулировок задач, какие реально пишу. Не выдуманных ровных, а настоящих, кривых:

1. Карточка поста в списке рубрики съезжает на узком экране
2. Добавить поле «серия» в модель поста и в форму админки
3. Проверить, не ломает ли последний дифф CSP
4. Тесты стали красными после правки сидера
5. Написать тест на превью по подписанной ссылке
6. Обновить общий модуль редактора в соседних проектах
7. Пост не появляется в RSS после публикации
8. Проверить доступность формы обратной связи с клавиатуры
9. Перед правкой понять, что вообще затрагивает смена slug рубрики
10. Перекрасить акцент рубрики «инфраструктура» в обеих темах

Дальше для каждой отвечаю: какой агент должен взяться. Если ответ приходит за пять секунд — строка проходит. Если я задумываюсь или называю двоих — это дефект описаний, а не задачи.

На последнем прогоне споткнулся на седьмой: пост не в ленте. Это может быть агент контента (публикация, лента, карта сайта) или агент разведки (сначала понять, где рвётся). Я оставил как есть, потому что честный ответ — «сначала разведка», и его же дала бы таблица маршрутизации.

Когда две зоны спорят

Спор за задачу — не всегда дефект. Иногда это правдивое отражение того, что задача на стыке.

Различаю так. Если два агента спорят из-за размытых описаний — правлю описания. Если спорят потому, что задача действительно затрагивает две зоны, — делю задачу, а описания не трогаю.

Пример первого случая у меня был с парой про изображения: два описания перекрывались на слове «обложка», и я свёл их в одно. Пример второго — задача про поле «серия»: она честно про модель и про админку, и режется на два шага.

Есть третий вариант, самый неприятный: спорят агент, чья зона задана каталогом, и агент, чья зона задана предметной областью. У меня это content-seo против blade-ui на задачах про вывод постов. Отрицанием тут не лечится, потому что оба правы. Развожу руками по ситуации: если задача про то, что показывается, — контент, если про то, как выглядит, — вёрстка.

Что осталось

Отрицательная часть описания — самая дешёвая правка во всём наборе. Одно предложение на агента, пишется за минуту, эффект виден сразу.

Что я так и не автоматизировал — проверку десятью задачами. Список у меня записан, прогоняю его руками, и делаю это раз в несколько месяцев, обычно после того, как задача уехала не туда. Правильнее было бы гонять его после каждой правки набора, но пока держится на памяти и раздражении.

Серия

Цикл «Субагенты»

#coding-agent #workflow #laravel #subagents #marshrutizaciya