ПроблемаБольшие MR4000 строк в одном MR. Три часа на ревью, 12 замечаний, исправления - ещё 800 строк. На четвёртом заходе я закрыл вкладку и понял: проблема неПроблемаБольшие MR4000 строк в одном MR. Три часа на ревью, 12 замечаний, исправления - ещё 800 строк. На четвёртом заходе я закрыл вкладку и понял: проблема не

Spec-Driven Development: контроль AI-кодогенерации

Проблема

Большие MR

4000 строк в одном MR. Три часа на ревью, 12 замечаний, исправления - ещё 800 строк. На четвёртом заходе я закрыл вкладку и понял: проблема не в коде, а в том, что никто не знал, что именно нужно было написать.

Если ты работаешь с большими кодовыми базами, ситуация знакомая. Большие MR - симптом. Когда непонятно, что именно нужно сделать, разработчик пишет больше кода, чем требуется. Добавляет на всякий случай. Покрывает сценарии, которые никто не просил. MR растёт не потому что задача большая, а потому что границы размыты.

Другая причина - иллюзия, что проще сделать всё в одной задаче, чем декомпозировать. Кажется, что разбиение создаёт лишнюю работу. На практике монолитный MR на 4000 строк никто не может нормально проверить, и баги просачиваются в продакшн.

AI-кодогенерация

С AI эта проблема становится критичнее. Агент пишет код быстро, но если требования размыты - генерирует то же самое: много кода на всякий случай.

Я пользуюсь AI ежедневно. Claude Code - основной инструмент, в который можно подключить разные модели: Anthropic, DeepSeek, GPT-семейство, локальные через Ollama. И в какой-то момент заметил закономерность: чем точнее формулирую задачу, тем лучше результат. Промпты становились всё более структурированными - простые инструкции, потом шаблоны, потом что-то похожее на техническое задание.

Где проблема? Сначала я думал, что ленюсь давать AI детальные инструкции. Потом решил, что AI Agent собирает недостаточный контекст - нужен RAG или что-то подобное. В итоге понял, что проблема в обоих местах: создавать полные инструкции кажется оверкилом, а как помочь агенту собрать нужный контекст - непонятно.

Но главное - нечего проверять. Нет артефакта, на который можно указать и сказать: здесь написано одно, а сделано другое.

Идея

Идея не новая - в индустрии давно говорят о spec-driven development подходе. Я долго хотел попробовать и наконец решил проверить.

Если формализовать требования в виде спецификации до начала кодирования, то:

  1. AI Agent будет генерировать более предсказуемый код

  2. Результат можно будет валидировать против спецификации

  3. Архитектура останется контролируемой

Когда AI Agent генерирует сотни строк кода за минуту, единственный способ контролировать результат - иметь формальное описание того, что должно получиться, и инструмент, который проверит соответствие реализации спецификации. О втором - в отдельной статье.

Метод

Я решил проверить гипотезу на реальном проекте - инструменте для построения архитектурных графов из Go кода. Правило простое: ни одной строчки кода без спецификации.

Первая спецификация - создать пустой проект на Go со стандартным layout. Вторая - модель графа. Третья - анализатор Go кода. За несколько дней накопилось 10 завершённых спецификаций.

Структура хранения

Kanban-подобная организация через файловую систему:

specs/ ├── todo/ # очередь задач │ ├── 0010-feature-x.md │ └── 0020-feature-y.md ├── inprogress/ # в работе (максимум одна - WIP limit) │ └── 0005-current.md └── done/ # выполнено ├── 0001-init-project.md ├── 0003-data-model.md └── 0004-go-analyzer.md

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

d58c5c77625e105d798a5668a92d945e.png

Размеры спецификаций

Классификация по времени на написание спецификации (T-shirt sizing):

  • S (Small) - до 10 минут

  • M (Medium) - 10-20 минут

  • L (Large) - больше 20 минут

Размер определяет глубину проработки. S-задача: Problem Statement и 5 Acceptance Criteria. L-задача: полные UML/C4 диаграммы, детальные Requirements, 15+ критериев приёмки. Корреляция между размером спецификации и предсказуемостью результата - прямая.

Если начинаешь с нуля - попробуй с S-спецификации. Это минимальные затраты на эксперимент.

Пример S-спецификации: инициализация проекта

# Spec 0001: Initialize Standard Golang Project Layout **Metadata:** - Priority: 0001 - Status: Done - Effort: S ## Overview ### Problem Statement Необходимо создать базовую структуру Go проекта для инструмента archlint согласно стандартным практикам разработки. ### Solution Summary Инициализировать Go module и создать минимальную структуру проекта. ## Requirements ### R1: Go Module Initialization - Инициализировать Go module с именем github.com/mshogin/archlint ### R2: Minimal Directory Structure - Создать cmd/archlint/ для точки входа - Создать internal/ для приватного кода - Создать pkg/ для публичных библиотек ## Acceptance Criteria - [x] AC1: go.mod создан с module path github.com/mshogin/archlint - [x] AC2: cmd/archlint/main.go существует и компилируется - [x] AC3: Директории internal/ и pkg/ существуют

Полная спецификация

Минимум деталей, максимум конкретики. AI получает чёткие границы задачи.

Пример M-спецификации: команда collect

Средние задачи требуют диаграмм. Я экспериментировал с Sequence-диаграммами - отправлял их агенту вместе с требованиями. Заметил, что по ним AI Agent выдаёт в целом то, что ожидается.

# Spec 0006: Implement Collect Command ## Overview ### Problem Statement Необходимо реализовать команду collect для сбора архитектуры из исходного кода и сохранения графа в YAML файл. ..... @startuml title Sequence: Collect Command actor User participant "collectCmd" as CC participant "GoAnalyzer" as GA participant "saveGraph" as SG User -> CC: archlint collect . -o arch.yaml CC -> GA: Analyze(dir) GA --> CC: *Graph CC -> SG: saveGraph(graph) SG --> CC: nil CC --> User: "Graph saved to arch.yaml" @enduml .....

Полная спецификация

Sequence-диаграмма определяет порядок вызовов. AI следует ей буквально.

Пример L-спецификации: анализатор Go кода

Большие задачи требуют нескольких диаграмм - Data Model и Sequence:

# Spec 0004: Implement Go Code Analyzer ## Overview ### Problem Statement Необходимо реализовать анализатор Go кода, который парсит исходный код с помощью AST и строит граф зависимостей между компонентами. ..... ### Data Model @startuml class GoAnalyzer { -packages: map[string]*PackageInfo -types: map[string]*TypeInfo -functions: map[string]*FunctionInfo -nodes: []model.Node -edges: []model.Edge ..... ### Sequence Diagram @startuml title Sequence: Code Analysis actor User participant "GoAnalyzer" as GA participant "go/parser" as GP participant "buildGraph" as BG .....

Полная спецификация

Для L-задач несколько диаграмм - необходимость. Data Model, Sequence, Component - вместе они задают архитектуру приложения и управляют зависимостями между компонентами.

Что делает AI

AI ускоряет работу, но архитектуру я не делегирую: решения фиксируются в спецификации, проходят ревью и проверяются валидаторами. Однако решения редко рождаются из воздуха: я приношу первичные варианты и ограничения, агент предлагает альтернативы и подсвечивает слепые зоны. Это влияет на ход мысли, и я это осознаю. Финальное "да/нет" и ответственность лежит на мне.

У агента две зоны ответственности.

  1. Specification Editor
    Я диктую голосом сырой поток мыслей (диктую быстрее, чем печатаю). Агент приводит его к моему шаблону спецификации: раскладывает по секциям, уточняет недосказанное, формулирует требования и критерии приемки так, чтобы их можно было проверить. После этого я ревьюю и фиксирую спецификацию как исходный контракт.

  2. Implementation Executor
    Когда спецификация согласована, я отдаю её агенту на реализацию. Агент пишет код по спецификации, а я проверяю результат: ревью, валидация, итерации до тех пор, пока архитектура не станет чистой и предсказуемой.

442e8f82ff4090a0a5a911f4ed9d2e48.png

Эксперимент

За несколько дней - 10 завершённых спецификаций и работающий проект. Код соответствует архитектуре из диаграмм.

Чтобы проверить, насколько спецификации самодостаточны, я провёл эксперимент: дал Claude Code пустую директорию и 10 спецификаций из archlint - без доступа к исходному коду. Задача: воссоздать проект с нуля.

Результат за 20 минут:

  • 85.5% успешность воспроизведения

  • 100% структурная идентичность (директории, файлы, типы)

  • 23 мутации в деталях реализации

Структура проекта воспроизведена полностью. Все acceptance criteria из спецификаций выполнены. Проект компилируется и проходит тесты.

Мутации возникли там, где спецификации описывали что делать, но не как. Критический пример: алгоритм построения sequence-диаграммы был реализован иначе - функционально эквивалентно, но с другой логикой обхода стека вызовов. Ещё одна категория мутаций - стилистические: язык комментариев, порядок функций в файлах, именование переменных.

Вывод для улучшения спецификаций: для критических алгоритмов нужен псевдокод или конкретные примеры входов/выходов. Спецификация что + как даёт более точное воспроизведение, чем только что.

Полный отчёт с каталогом мутаций: github.com/mshogin/archlint-reproduction

Идемпотентность спецификаций

Чтобы спецификации оставались воспроизводимыми, все изменения должны проходить через них. Никаких доработок в режиме copilot, никаких чатов с "поправь вот это". Каждое изменение - обновление спецификации, затем реализация.

Это основной вызов. Хочется быстро поправить баг в диалоге, а не возвращаться к спеке. Но каждая такая правка - потеря воспроизводимости.

Trade-off очевиден:

  • Нужен результат здесь и сейчас - режим copilot быстрее

  • Нужна воспроизводимость - только через спецификации

Выбор зависит от контекста. Прототип или эксперимент - copilot. Продуктовый код с долгим жизненным циклом - спецификации.

Ограничения

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

Цена: время на написание спецификаций, их ревью и итерации после валидации. Если относиться к спекам формально, всё скатывается обратно в хаос. Честно спроси себя: готов ли ты тратить 10-30 минут на спецификацию, чтобы агент реализовал её за 5-20 минут?

Детали реализации варьируются. Эксперимент с воспроизводимостью показал 23 мутации - алгоритмы интерпретируются по-разному, стилистика кода отличается. Для критических участков нужен псевдокод, а не только описание.

Я думаю, что подход работает хорошо там, где есть поставленный, сформированный и рабочий процесс. В процессах с фокусом на дисциплину, на понятные зоны ответственности, ревью, критерии готовности. Можно смотреть на этот процесс как на конвейер, доставляющий ПО 24/7.

Итоги

Гипотеза подтвердилась:

  1. AI генерирует более предсказуемый код - да, при наличии диаграмм

  2. Результат можно валидировать - да, 85.5% воспроизводимость

  3. Архитектура остаётся контролируемой - да, 100% структурная идентичность

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

Эксперимент продолжается.


Шаблоны и примеры: github.com/mshogin/archlint

Если пробуешь spec-driven подход или уже используешь - расскажи в комментариях, что работает, а что нет.
Пишу о практике AI-кодогенерации и архитектуре в Telegram: @MikeShogin

Источник

Возможности рынка
Логотип Spectral
Spectral Курс (SPEC)
$0.1021
$0.1021$0.1021
-0.48%
USD
График цены Spectral (SPEC) в реальном времени
Отказ от ответственности: Статьи, размещенные на этом веб-сайте, взяты из общедоступных источников и предоставляются исключительно в информационных целях. Они не обязательно отражают точку зрения MEXC. Все права принадлежат первоисточникам. Если вы считаете, что какой-либо контент нарушает права третьих лиц, пожалуйста, обратитесь по адресу service@support.mexc.com для его удаления. MEXC не дает никаких гарантий в отношении точности, полноты или своевременности контента и не несет ответственности за любые действия, предпринятые на основе предоставленной информации. Контент не является финансовой, юридической или иной профессиональной консультацией и не должен рассматриваться как рекомендация или одобрение со стороны MEXC.