Spec-first: как организовать команду AI-агентов, чтобы ревью длилось минуты, а не часы

· 1 мин чтения
ai-agents spec-driven workflow review verification
Spec-first: как организовать команду AI-агентов, чтобы ревью длилось минуты, а не часы

Большинство команд не планировали становиться «командами AI-агентов». Один разработчик начал пользоваться coding agent, другой подключил агента в CI, и через квартал половина PR в репозитории пишется машинами. Код приходит быстрее, чем кто-либо успевает решить, что именно должно быть построено, и проверить, что было построено на самом деле. Spec-first-подход устраняет этот дисбаланс: он перемещает усилия человека туда, где агенты не могут его заменить — формулировка намерения и проверка результата.

Проблема: узкое место сместилось, а процесс — нет

До появления coding agents самое медленное звено — написание кода, поэтому процессы оптимизировали под пропускную способность разработчика. С агентами реализация почти бесплатна, и два других этапа становятся ограничением: решение, что именно строить, и подтверждение, что результат соответствует задумке.

При старом процессе это ощущается как специфическая боль: PR накапливаются быстрее, чем ревьюеры успевают их читать. Два агента решают пересекающиеся задачи несовместимыми способами. Промпт, который жил только в чате одного разработчика, породил продуктовое решение, которое никто не утверждал. Проблема не в агентах — проблема в том, что намерение команды не существует в форме, которую агент или ревьюер может проверить. Ответ spec-first: сделать намерение долговечным.

Пять этапов рабочего процесса

Подход работает с Claude Code, Cursor, Copilot и любыми другими агентами, потому что контракт живёт в файлах, а не в памяти инструмента.

Этап Владелец Артефакт Критерий прохода
1. Спецификация Владелец фичи spec.md Цель, не-цели и acceptance criteria утверждены человеком
2. Декомпозиция Техлид или planning agent tasks.md У каждой задачи есть write scope и проверяемый результат
3. Реализация Один агент на задачу Diff в изолированной ветке Diff не выходит за границы write scope
4. Сбор доказательств Тот же агент evidence.md Тесты, логи и проверки, названные в спецификации, существуют и проходят
5. Ревью Человек-ревьюер PR со связанными артефактами Проверка по чек-листу, а не по ощущениям

Этап 1: спецификация

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

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

Этап 2: декомпозиция на ограниченные задачи

Надёжная единица работы агента — задача, которую один агент может выполнить, а один человек — отревьюить за один присест. Каждая задача в tasks.md требует трёх полей помимо описания:

  • Write scope — список файлов, которые агенту разрешено менять.
  • Acceptance criteria — скопированные или выведенные из пакета.
  • Требование к доказательствам — название теста или проверки, подтверждающей завершение.

Задачи, которые используют одни и те же файлы, не могут выполняться параллельно. Если две задачи требуют правок в billing/index.ts, их нужно либо объединить, либо сериализовать явной зависимостью. Конфликты слияния между агентами — это не проблема инструментов, это проблема декомпозиции.

Этап 3: параллельный запуск агентов в рамках write scope

Каждый агент получает одну задачу, её пакет и изолированную ветку. Write scope — это линия принуждения: агент, отредактировавший файл за пределами scope, получает отклонение диффа до ревью, без обсуждений.

Критически важна оговорка «остановись и сообщи»: если задача требует трогать что-то вне scope, агент должен остановиться и доложить, а не редактировать молча. Самая дорогая ошибка агента — не неправильная реализация, а тихое решение: лишняя колонка, переименованная функция, новая зависимость, закопанная в правдоподобном диффе.

Этап 4: сбор доказательств до запроса ревью

Заявление агента о завершении работы ничего не стоит — ценность имеет цепочка артефактов. Перед открытием PR агент заполняет evidence.md: какие тесты добавлены и их вывод, какое acceptance criterion покрывает каждый тест, и любые логи, скриншоты или проверки контрактов, которые требовал пакет.

Именно здесь умирает галлюцинаторная полнота. Агент, который говорит «все тесты проходят», но не может вставить вывод запуска для export_retry_idempotent, не закончил. Команды, внедрившие evidence-гейты, сообщают, что гейт отлавливает больше плохих слияний, чем само код-ревью, потому что он механический: названный тест либо существует и проходит, либо нет.

Этап 5: человеческое ревью по чек-листу

Человеческое ревью — самый дефицитный ресурс, поэтому тратьте его только на то, что предыдущие гейты не могут проверить: соответствует ли дифф намерению и не проскользнуло ли что-то незаявленное. Ревьюер подтверждает, что дифф остаётся в scope, сопоставляет каждое изменение с задачей, выборочно проверяет evidence и специально ищет изменения, которых не требовала ни одна задача.

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

Рабочий пример: одна фича, три агента

Фича: «админы поддержки могут повторить упавший экспорт данных». Пакет фиксирует политику (только админы, один повтор за раз, без редизайна схемы) и планку доказательств (тест на идемпотентность, запись в аудит-лог, отсутствие изменений формата экспортного файла).

  • Задача 1 (агент A): колонка состояния retry + миграция, scope: db/migrations, models/export.ts
  • Задача 2 (агент B): эндпоинт retry + идемпотентность, scope: src/exports/retry.ts + тест
  • Задача 3 (агент C): кнопка retry в админской консоли, scope: console/exports/*.tsx + тест

После слияния задачи 1 задачи 2 и 3 запускаются параллельно. Общее время ревью — около 40 минут на всю фичу.

Показательный сбой: агент B добавил полезную колонку retry_count в модель, выйдя за write scope. Проверка scope отловила это до ревью. Команда решила, что счётчик действительно полезен, оформила его как follow-up задачу и отклонила out-of-scope правку. Процесс сработал: хорошая идея выжила, непроверенное решение — нет.

Что измерять в первые 30 дней

Внедряйте процесс на одном потоке фич, а не на всей команде, и отслеживайте три метрики:

  • Время ревью на агентский PR — должно падать от недели к неделе по мере стандартизации артефактов.
  • Out-of-scope правки, пойманные до ревью — сначала должно быть ненулевое значение (гейт работает), затем снижаться (промпты учатся).
  • Доля переделок — PR, которым потребовался второй проход реализации после ревью. Это число оправдывает процесс перед скептиками.

Типичные сбои

Симптом Причина Исправление
Агенты создают конфликтующие диффы Задачи используют одни файлы Перекроить write scope или сериализовать
Спецификация занимает больше времени, чем реализация Слишком большой scope пакета Один пакет на обозримый срез фичи, а не на эпик
Evidence-логи превращаются в формальность Критерии не тестируемы Переписать acceptance criteria как наблюдаемые исходы до декомпозиции
Ревьюеры штампуют зелёные чек-листы Чек-лист заменил суждение вместо фокусировки Ревьюер лично отвечает на вопрос «что никто не просил?» в каждом PR

Установившийся режим негламурный: спецификации короткие, задачи скучные, агенты взаимозаменяемы, ревью быстрое. Именно так выглядит процесс, когда люди тратят время на намерение и доказательства, а машины — на всё, что между ними.

Источник: https://spec-coding.dev/blog/ai-agent-team-spec-workflow