Рабочий процесс разработки, ориентированный на спецификации: от требований к коду

Пять этапов: от намерения к проверенному коду.

Содержимое страницы

Спецификация-ориентированная разработка (Spec-Driven Development, SDD) работает, когда спецификация представляет собой рабочий процесс, а не документ, который откладывают в архив после старта. Цель состоит не в том, чтобы создать большой документ с требованиями к продукту.

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

Если вы не знаете, что такое SDD концептуально, начните с Что такое спецификация-ориентированная разработка? для получения определений, сравнений с TDD и BDD, а также обоснования подхода, при котором спецификация считается источником истины. Эта статья в кластере документации Архитектура приложений является практическим руководством. В ней рассматриваются пять фаз, показано, что должен содержать каждый артефакт, объясняется, где в процессе участвуют ИИ-агенты, и приведены шаблоны, которые можно скопировать в ваш репозиторий уже сегодня.

Workflow спецификации-ориентированной разработки – требования, дизайн, задачи, реализация, валидация

SDD — это рабочий процесс, а не документ

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

Рабочий процесс SDD производит цепочку артефактов, каждый из которых проверяется перед началом следующей фазы. Требования снижают неопределенность продукта. Дизайн снижает техническую неопределенность. Задачи снижают неопределенность исполнения. Реализация производит код по известной цели. Валидация доказывает, что цепочка сохранилась. Когда на любой фазе выявляется ошибка, вы исправляете артефакт и запускаете процесс заново с этой точки — а не после того, как три тысячи строк дрифта (отклонений) попали в основную ветку.

flowchart LR A[Спецификация] --> B[Планирование] B --> C[Задачи] C --> D[Реализация] D --> E[Валидация] E -->|найден дрифт| A E -->|выпуск| F[Готово]

Этот рабочий процесс нейтрален к инструментам. Вы можете использовать его с файлами Markdown в Git, с GitHub Spec Kit, с планами Cursor или просто с текстовым редактором и дисциплинированным ревьюером. Важны последовательность и контрольные точки проверки, а не бренд инструмента.

Фаза 1 — Спецификация требований

Фаза спецификации отвечает на вопрос: какую проблему вы решаете и как выглядит «готово». Она намеренно избегает вопроса «как это построить». В тот момент, когда ваша спецификация требований говорит «использовать упорядоченные множества Redis», вы перестали специфицировать и начали проектировать в неправильном документе. Держите реализацию вне требований. Поместите ее в план.

Утверждение проблемы и пользователи

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

Пример для функции ограничения скорости API (rate-limiting):

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

Цели, не цели (non-goals) и критерии приемки

Цели описывают результаты, которые вы предоставите. Не цели описывают соблазнительную смежную работу, которую вы явно не будете выполнять. Вместе они ограничивают творчество агента, что особенно важно, когда инструменты ИИ иначе «помогательно» расширяют объем работ.

Раздел Хороший пример Слабый пример
Цель Отклонять запросы, превышающие лимит на ключ, с HTTP 429 Сделать API быстрее
Не цель Дашборды биллинга для каждого клиента Улучшить производительность всего API
Критерий приемки Неаутентифицированные запросы получают 401 до запуска проверки лимита Эндпоинт безопасен

Критерии приемки должны быть достаточно точными, чтобы каждый из них мог быть сопоставлен как минимум с одним тестом. «Эндпоинт безопасен» — это не критерий приемки. «Неаутентифицированные запросы получают HTTP 401» — это критерий. Если вы не можете написать конкретный критерий, требование все еще слишком расплывчато для реализации.

Открытые вопросы

Перечислите каждое решение, которое еще не принято. Непонятные вопросы — это не признак неудачи. Это фаза спецификации, выполняющая свою работу. Разрешите их перед написанием плана дизайна, иначе вы заплатите за неопределенность переделками при реализации.

Минимальный шаблон требований:

## Проблема
[Один абзац: кто страдает, почему и что вызывает боль.]

## Пользователи
- [Роль основного пользователя]
- [Роль вторичного пользователя]

## Цели
1. [Измеримый результат]
2. [Измеримый результат]

## Не цели
- [Явно вне области применения]
- [Явно вне области применения]

## Критерии приемки
- [ ] [Проверяемое поведение]
- [ ] [Проверяемое поведение]

## Открытые вопросы
- [ ] [Вопрос, блокирующий планирование]

Фаза 2 — Планирование дизайна

Фаза плана переводит намерения в технические решения. Здесь должны быть упорядоченные множества Redis, а также границы модулей, изменения схемы, контракты API, шаги миграции, ограничения безопасности и стратегия тестирования. План выводится из спецификации требований плюс существующие ограничения вашего проекта — выбор стека, записи решений и соглашений, хранящихся в файлах, таких как AGENTS.md или конституция проекта.

Архитектура и затронутые модули

Назовите модули, сервисы или пакеты, которые изменятся, и обобщите паттерн интеграции. Если функция пересекает границу сервиса, документируйте контракт с обеих сторон. Агенты галлюцинируют API, когда контракты подразумеваются. Явное их указание в плане предотвращает создание выдуманных эндпоинтов и неправильных форматов ответов.

Модель данных, контракты API и миграции

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

Безопасность, наблюдаемость и стратегия тестирования

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

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

flowchart TB subgraph plan [Содержимое плана дизайна] R[Спецификация требований] C[Конституция проекта / ADR] R --> D[Архитектурные решения] C --> D D --> M[Модель данных и миграции] D --> A[Контракты API] D --> S[Ограничения безопасности] D --> T[Стратегия тестирования] end

Фаза 3 — Декомпозиция задач реализации

Фаза задач декомпозирует план на части, достаточно мелкие для независимой реализации, ревью и валидации. Это то, что делает разработку с помощью агентов проверяемой. Вместо одного огромного диффа вы получаете последовательность фокусированных изменений, каждое из которых отсылает к названному требованию.

Размер задач и зависимости

Хорошая задача затрагивает ограниченный набор файлов, выполняется за одну сессию агента и заканчивается этапом проверки. Задачи должны явно объявлять зависимости. Задачи миграции запускаются до кода, читающего новую схему. Изменения общих библиотек запускаются до потребителей. Изменения middleware аутентификации запускаются до эндпоинтов, зависящих от нового поведения.

flowchart TD T1[Задача 1 -- миграция схемы] --> T2[Задача 2 -- слой репозитория] T2 --> T3[Задача 3 -- HTTP обработчик] T2 --> T4[Задача 4 -- инструментация метрик] T3 --> T5[Задача 5 -- интеграционные тесты] T4 --> T5

Файлы, валидация и контрольные точки ревью

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

Минимальная запись задачи:

### Задача 3 -- Добавить middleware ограничения скорости

**Зависит от:** Задача 1 (схема), Задача 2 (репозиторий)
**Файлы:** middleware/ratelimit.go, middleware/ratelimit_test.go, server.go
**Удовлетворяет:** AC-2 (429 при превышении лимита), AC-3 (заголовки лимита в ответе)
**Валидация:** `go test ./middleware/...` проходит; curl при превышении лимита возвращает 429 с Retry-After
**Контрольная точка ревью:** Подтвердить, что middleware запускается после аутентификации, но до обработчика

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

Фаза 4 — Реализация по одной задаче за раз

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

Применяйте ограничения из стека спецификаций

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

Обновляйте план, когда реальность отличается

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

sequenceDiagram participant H as Ревьюер-человек participant A as ИИ-агент participant S as Артефакты спецификации H->>S: Утвердить задачу N A->>S: Прочитать задачу + план + ограничения A->>A: Реализовать задачу N A->>A: Запустить валидацию задачи A->>H: Отправить дифф на ревью H->>H: Ревью диффа по задаче alt дрифт или сюрприз H->>S: Обновить спецификацию/план H->>A: Запустить повторно с исправленным контекстом else утверждено H->>S: Отметить задачу N как выполненную H->>A: Перейти к задаче N+1 end

Фаза 5 — Валидация против спецификации

Валидация — это то, где SDD оправдывает свое существование. Без нее спецификация — это упражнение в планировании. С ней спецификация — это контракт, который можно проверить против выпущенного кода.

Автоматизированные проверки

Запустите полный набор тестов, линтинг и проверки типов в CI. Подключите их к вашему конвейеру, используя паттерны из шпаргалки по GitHub Actions, если вам нужна практическая отправная точка. Автоматизированные проверки ловят регрессии. Они не ловят неправильно созданные функции, построенные правильно, поэтому ревью критериев приемки по-прежнему важно.

Критерии приемки и ручное ревью

Пройдитесь по каждому критерию приемки из спецификации требований. Отметьте каждый как выполненный, проваленный или отложенный с обоснованием. Ручное ревью ловит проблемы UX, пробелы в безопасности и неправильное поведение, которое тесты пропустили, потому что тесты были написаны по flawed (неправильной) спецификации.

Дифф спецификации к коду

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

Слой валидации Ловит
Модульные и интеграционные тесты Регрессии и неверная логика в рамках области
Линтинг и проверки типов Проблемы со стилем и ошибки типов
Проход по критериям приемки Неправильное поведение, построенное по спецификации
Дифф спецификации к коду Архитектурный дрифт и расширение области

Где ИИ-агенты вписываются в рабочий процесс

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

flowchart LR subgraph human [Человек владеет] H1[Намерения и приоритеты] H2[Утверждение архитектуры] H3[Ревью диффа на контрольных точках] H4[Финальная приемка] end subgraph agent [Агент ускоряет] A1[Черновик требований] A2[Черновик плана дизайна] A3[Генерация списка задач] A4[Реализация срезов задач] A5[Черновик тестов] end H1 --> A1 --> H1 A1 --> A2 --> H2 H2 --> A3 --> A4 --> H3 H3 --> A4 A4 --> A5 --> H4

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

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

Распространенные ошибки, убивающие спецификация-ориентированную разработку

Огромные спецификации до какой-либо валидации. Тридцатистраничный документ требований, написанный до прототипа или спайка — это бюрократия водопада, а не SDD. Пишите минимальную спецификацию, которая устраняет неопределенность для следующей фазы, затем валидируйте предположения рано. Не каждой функции нужен полный пятифазный цикл — Спецификация-ориентированная разработка против Vibe Coding объясняет, когда более легкой структуры достаточно.

Расплывчатые критерии приемки. Прилагательные вроде «быстро», «чисто» и «удобно для пользователя» — это не критерии приемки. Замените их измеримым поведением. Если вы не можете это протестировать, вы не можете реализовать это надежно — особенно с ИИ-агентом.

Отсутствие не целей. Без не целей агенты расширяют область по умолчанию. Они добавляют слои кэширования, рефакторят соседние модули и вводят зависимости, которые вы не запрашивали. Не цели — это то, как вы говорите «нет» заранее.

Нет плана тестов в фазе дизайна. Тесты, написанные только после реализации, склонны подтверждать то, что было построено, а не то, что было задумано. План должен называть, какие критерии приемки отображаются на какие типы тестов, до того как изменится первый производственный файл.

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

Позволять сгенерированным задачам взрываться. Относитесь к списку из пятидесяти задач, сгенерированному ИИ, как к первому черновику, а не к расписанию. Объедините избыточные элементы, разделите перегруженные и удалите задачи, которые не отображаются на требование.

SDD работает, когда каждая фаза снижает неопределенность. Она проваливается, когда создает бюрократию.

Повторно используемые шаблоны

Скопируйте их в ваш репозиторий и адаптируйте. Храните спецификации рядом с веткой функции, ревьюьте их в pull requests и держите их в системе контроля версий, чтобы агенты и люди читали один и тот же источник.

Шаблон требований

# Функция -- [название]

## Проблема
## Пользователи
## Цели
## Не цели
## Критерии приемки
## Открытые вопросы

Шаблон дизайна

# Дизайн -- [название функции]

## Сводка
## Затронутые модули
## Изменения модели данных
## Контракты API
## Миграции
## Безопасность
## Наблюдаемость
## Стратегия тестирования
## Риски и смягчения

Шаблон списка задач

# Задачи -- [название функции]

## Задача 1 -- [заголовок]
Зависит от:
Файлы:
Удовлетворяет:
Валидация:
Контрольная точка ревью:

## Задача 2 -- [заголовок]
...

Чек-лист валидации

# Валидация -- [название функции]

## Автоматизированная
- [ ] Все тесты прошли
- [ ] Линтинг чист
- [ ] Проверка типов чиста

## Критерии приемки
- [ ] AC-1 --
- [ ] AC-2 --

## Спецификация к коду
- [ ] Измененные файлы соответствуют плану
- [ ] Нет недокументированных архитектурных изменений
- [ ] Спецификация обновлена, если реализация отличалась

Заключение

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

Начните с малого. Запустите полный рабочий процесс на одной функции среднего размера. Держите артефакты в Markdown в репозитории. Обновляйте спецификацию, когда реальность расходится. Валидируйте перед мержем. Когда цепочка работает, вы получаете меньше дрифта, меньшие проверяемые диффы и долговременную запись намерений, которая выживает при сбросах сессий и передаче между командами.

Когда цепочка становится бюрократией, сокращайте объем — а не ревью. Двухстраничная спецификация, которая была валидирована, лучше тридцатистраничной спецификации, которую никто не читал.

Полезные ссылки

Подписаться

Получайте новые материалы про системы, инфраструктуру и AI engineering.