Что такое разработка через спецификации
Почему ИИ-агенту для кода нужен продуманный план, что такое SDD и спецификация, три уровня подхода по Биргитте Бёккелер (spec-first, spec-anchored, spec-as-source), что в SDD нового по сравнению с требованиями, BDD и model-driven development, когда он окупается — и как устроена программа.
Зачем это нужно
Заголовок раздела «Зачем это нужно»Автор курса описывает идею этой программы так: «суть идеи в том, чтобы хорошенько пошевелить мозгами на этапе планирования, родить тонну md-файлов, а затем скормить их агенту и спокойно идти пить кофе, пока Claude перемалывает ваши спеки в рабочий код».
В этой фразе сразу и сила подхода, и его ловушки. Сила — в первой половине: продумать задачу до того, как агент написал первую строку, дешевле, чем переписывать его код. Ловушки — во второй. «Тонна» markdown-файлов, которую никто не перечитывает, — это не план, а макулатура. А кофе можно пить спокойно только тогда, когда вы заранее знаете, как проверите результат: агент не обязан делать то, что написано в спецификации, — он делает то, что счёл правдоподобным.
Разработка через спецификацииразработка через спецификации (SDD)EN Spec-Driven DevelopmentПодход к работе с ИИ-агентами для кода: сначала продумать задачу и записать её в спецификации (что и зачем, затем план и задачи), а код получать из них и проверять по ним. (Spec-Driven Development, SDD) — способ работать с ИИ-агентом для кодаИИ-агент для кодаEN AI coding agentПрограмма, в которой языковая модель в цикле читает и правит файлы проекта, запускает команды и тесты и сама решает, что делать дальше: Claude Code, GitHub Copilot, Cursor, Codex и др. как инженер: сначала договориться с собой, командой и агентом, что и зачем строим, потом — как, и только потом писать код, который проверяется по этим договорённостям. За программу вы научитесь писать спецификации, которые агент понимает однозначно, пользоваться инструментами Spec Kit и OpenSpec и проверять, что код действительно соответствует замыслу. Этот урок — вход: что такое SDD, откуда он взялся, какие у него уровни, когда он окупается и как устроена программа.
Вайб-кодинг и что ломается без плана
Заголовок раздела «Вайб-кодинг и что ломается без плана»В начале 2025 года Андрей Карпатый назвал вайб-кодингомвайб-кодингEN vibe codingВыражение Андрея Карпатого (2025): писать программу в разговоре с ИИ — попросил, получил, поправил, — почти не вчитываясь в код и не фиксируя требований. Годится для прототипов, опасен для систем с правилами. (vibe coding) стиль, в котором программу пишут в разговоре с ИИ: попросил — получил — поправил — снова попросил, почти не вчитываясь в код. Для прототипа на выходные это прекрасно. Для системы, у которой есть бизнес-правила и которая будет жить годами, — нет.
Возьмём сквозной пример программ DDD и SDD — онлайн-школу (подробно она описана в уроке DDD.1.1). Попросим агента одной фразой: «Сделай на Python запись студентов на курсы с отменой и возвратом денег». Типичный результат выглядит примерно так — у вашего агента детали будут другими, но характер тот же:
from datetime import datetime
class Order: # «заказ», хотя в школе говорят «запись на поток» def __init__(self, user_id, course_id, price): self.user_id = user_id self.course_id = course_id # запись на курс, а не на поток с датой старта self.price = price # рубли числом с плавающей точкой self.status = "active" self.created_at = datetime.now() # время внутри модели — не протестировать
class CourseManager: def __init__(self): self.orders = []
def enroll(self, user_id, course_id, price): order = Order(user_id, course_id, price) # ни вместимости, ни проверки повторной записи self.orders.append(order) return order
def cancel(self, order, course_start): self.orders.remove(order) # запись удалена — история пропала days_left = (course_start - datetime.now()).days return order.price if days_left > 7 else order.price * 0.5 # откуда 50%?Код запускается, выглядит аккуратно и даже правдоподобно. Но посчитайте, сколько решений о продукте агент принял молча:
| Что решил агент | Как на самом деле в школе | Почему так вышло |
|---|---|---|
| записываются на курс | записываются на конкретный поток с датой старта и вместимостью | в промпте не было слова «поток» |
| мест сколько угодно | не больше вместимости потока | правило не названо |
| записаться дважды можно | нельзя | правило не названо |
| возврат, если осталось больше 7 целых суток | полный возврат при отмене за 7 суток и более (7 × 24 часа), позже — без возврата | «неделю» каждый понимает по-своему |
| при поздней отмене — 50% | возврата нет | агент заполнил пробел «разумным» значением |
| отмена удаляет запись | запись получает статус «отменена» | так короче |
деньги — float в рублях | целое число копеек и валюта | так чаще пишут в интернете |
время — datetime.now() внутри | время передаётся параметром, чтобы тесты были детерминированы | так чаще пишут в интернете |
Агент не «ошибся» — ему не хватило информации, и он заполнил пробелы самым вероятным, на его взгляд, вариантом. Из урока 8.1.2 вы помните: модель — умный новичок без контекста. Чего нет в промпте и в файлах, которые она прочитала, того для неё не существует.
Дальше начинается цикл «поправь». Вы пишете «записывают на поток, а не на курс», потом «нет, возврата 50% не бывает», потом «не удаляй запись». Каждое исправление живёт в истории чата. В новой сессии, у коллеги или у другого агента этой истории нет, и решения приходится принимать заново — иногда иначе. Создатели OpenSpec формулируют это прямо: агенты мощные, но непредсказуемые, когда требования живут только в истории чата.
Что ломается без плана, если собрать в один список:
- агент додумывает — и делает это уверенно, без вопросов;
- решения теряются между сессиями и людьми, потому что записаны в чате, а не в репозитории;
- нет определения «готово»: непонятно, по чему проверять результат, кроме ощущения «вроде работает»;
- ревьюить нечего, кроме кода: намерение нигде не записано, и спорить приходится о строчках, а не о правилах;
- большие задачи разваливаются: агент держит в голове всё сразу, и к концу длинной сессии забывает начало (почему — разберём в следующем уроке).
Что такое SDD
Заголовок раздела «Что такое SDD»Спецификация — главный артефакт
Заголовок раздела «Спецификация — главный артефакт»СпецификацияспецификацияEN specification (spec)Документ на естественном языке о том, что должна делать система и зачем: цель, требования, сценарии, границы. Описывает поведение, а не реализацию. В SDD — главный артефакт, из которого выводятся план, задачи и код. — это документ на естественном языке о том, что должна делать система и зачем: цель, пользователи, требования, сценарии, границы, открытые вопросы. Она описывает поведение, наблюдаемое снаружи, а не реализацию: в ней нет имён библиотек и схем таблиц. Для онлайн-школы это, например, «при отмене записи за 7 суток и более до старта потока студенту возвращается полная стоимость» — и сценарий с конкретными датами, по которому это проверяется.
В SDD спецификация становится главным артефактом, а код — производным от неё. Манифест Spec Kit называет это «инверсией власти»: десятилетиями документы служили коду — их писали и выбрасывали, когда начиналась «настоящая работа»; в SDD код служит спецификации. Звучит как лозунг, но практический смысл простой: если код и спецификация расходятся, по умолчанию неправ код (или спецификацию надо осознанно поменять — сначала её, потом код).
Три вида документов
Заголовок раздела «Три вида документов»Почти все инструменты SDD разделяют три слоя, хотя называют их по-разному:
| Слой | Вопрос | Что в нём | Пример для школы |
|---|---|---|---|
| Спецификация | что и зачем? | цель, истории, требования, сценарии, «вне рамок», открытые вопросы | «запись закрывается в момент старта потока»; сценарий с Глебом, который опоздал |
| План | как? | архитектура, стек и обоснование, модель данных, контракты, решения | агрегат «Поток» (Cohort), статусы EnrollmentStatus, исключение EnrollmentClosed |
| Задачи | в каком порядке? | маленькие проверяемые шаги со ссылками на требования | «T-003: запрет записи после старта; требования: REQ-004» |
Разделение нужно не ради бюрократии. Спецификацию читает и подтверждает эксперт предметной области — методист школы, которому неинтересны классы. План читает и подтверждает разработчик. Задачи нужны агенту, чтобы двигаться маленькими шагами и не терять нить. Когда эти уровни смешаны, эксперт не может проверить правила, а агент принимает решения о продукте внутри технических деталей.
Цикл SDD
Заголовок раздела «Цикл SDD»flowchart LR I["Идея<br/>одна фраза"] --> S["Спецификация<br/>что и зачем"] S --> Q["Уточнения<br/>вопросы агента<br/>и эксперта"] Q --> S S --> P["План<br/>как"] P --> T["Задачи<br/>маленькие шаги"] T --> C["Реализация<br/>агентом"] C --> V["Проверка<br/>тесты из сценариев,<br/>ревью диффа"] V -->|"расхождение"| S V -->|"готово"| D["Принято"]
Обратите внимание на две обратные стрелки. Уточнения возвращают нас к спецификации до кода — это самое дешёвое место для исправлений. Проверка возвращает к спецификации после кода: если тест по сценарию упал, разбираемся, кто неправ — код или спецификация. Spec Kit, например, предлагает цикл команд constitution → specify → plan → tasks → implement → converge, где последний шаг сверяет реализацию со спецификацией, планом и задачами и дописывает задачи на то, что упущено. OpenSpec — предложение изменения, реализацию и архивирование. Детали инструментов — в модуле SDD.3.
Три уровня SDD по Бёккелер
Заголовок раздела «Три уровня SDD по Бёккелер»Слово «спецификация» сейчас используют очень по-разному, и споры об SDD часто идут потому, что люди имеют в виду разное. Самая ясная классификация — в статье Биргитты Бёккелер (Thoughtworks) «Understanding Spec-Driven-Development: Kiro, spec-kit, and Tessl», опубликованной в 2025 году в серии «Exploring Generative AI» на сайте Мартина Фаулера. Бёккелер предлагает различать уровни по тому, как долго живёт спецификация и кто правит код.
1. сначала спецификациясначала спецификация (spec-first)EN spec-firstПервый уровень SDD по Биргитте Бёккелер: продуманную спецификацию пишут до кода и используют для текущей задачи. Что с ней будет после реализации, не оговаривается.. Продуманную спецификацию пишут до кода и используют для текущей задачи. После
реализации её могут выбросить или просто перестать обновлять. Пример: вы написали specs/003-enrollment/spec.md,
агент реализовал запись на поток, код принят. Через полгода нужен перенос записи на другой поток — вы пишете новую
спецификацию, а старая лежит в папке как исторический документ и постепенно расходится с кодом. Это уже огромный шаг
вперёд по сравнению с вайб-кодингом: агент работал по продуманному плану.
2. спецификация как якорьспецификация как якорь (spec-anchored)EN spec-anchoredВторой уровень SDD по Бёккелер: спецификацию сохраняют после реализации и развивают вместе с функцией — изменения сначала вносятся в спецификацию, потом в код.. Спецификацию сохраняют после реализации и используют для дальнейших изменений
той же функции. Изменение начинается с правки спецификации, а код и тесты следуют за ней. Пример: в репозитории живёт
specs/enrollment/spec.md — актуальное описание правил записи. Чтобы добавить перенос записи, сначала описывают
изменение требований (что добавлено, что изменено), согласуют его, затем реализуют и обновляют основную спецификацию.
Требования и сценарии имеют идентификаторы, тесты ссылаются на сценарии, и по спецификации всегда можно понять, как
система работает сейчас.
3. спецификация как исходникспецификация как исходник (spec-as-source)EN spec-as-sourceТретий уровень SDD по Бёккелер: человек правит только спецификацию, а код целиком генерируется из неё и вручную не редактируется.. Человек правит только спецификацию — она единственный исходник, а код целиком
генерируется из неё и вручную не редактируется. Пример: файл enrollment.spec.md превращается в enrollment.py
с пометкой «сгенерировано из спецификации, не редактировать»; чтобы исправить ошибку, правят спецификацию и
генерируют код заново. Пример инструмента, который движется в эту сторону, по описанию Бёккелер, — Tessl.
| spec-first | spec-anchored | spec-as-source | |
|---|---|---|---|
| Когда пишут спецификацию | до кода | до кода и при каждом изменении | всегда; код руками не пишут |
| Что живёт дольше | код | код и спецификация вместе | спецификация |
| Кто правит код | агент и люди | агент и люди, после спецификации | только генератор |
| Цена дисциплины | низкая | средняя: спецификацию надо поддерживать | высокая: вся логика должна быть в тексте |
| Главный риск | спецификация устаревает | спецификация и код незаметно расходятся | недетерминированная генерация, негибкость |
Уровни — не оценки «плохо, лучше, отлично». Это разные договорённости, и у каждого своя цена. Интересно, что сам Spec Kit в документации (страница о моделях жизни спецификации) ссылается на эту классификацию и сознательно оставляет выбор команде: держать ли папку каждой функции как исторический документ или обновлять спецификацию как живой контракт. Мы в программе будем учиться работать в основном на уровнях spec-first и spec-anchored — они применимы уже сегодня с любым агентом.
Что здесь нового: требования, BDD, model-driven development
Заголовок раздела «Что здесь нового: требования, BDD, model-driven development»Идея «сначала описать, потом построить» старше большинства из нас. Полезно понимать, что SDD берёт у предшественников и чем от них отличается.
Документы требований. Ещё в 1990-х существовали стандарты оформления требований к программам (например, IEEE 830 о спецификации требований, 1998). Слабое место классики — документ пишут один раз в начале, потом он устаревает, а код живёт своей жизнью. SDD наследует отсюда структуру: требования с идентификаторами, критерии приёмки, нефункциональные требования, границы.
BDD и спецификация на примерах. разработка через поведениеразработка через поведение (BDD)EN Behavior-Driven DevelopmentПрактика, которую предложил Дэн Норт в середине 2000-х: описывать поведение системы примерами «Дано / Когда / Тогда» на языке бизнеса и превращать их в автоматические тесты (инструмент Cucumber, язык Gherkin). (Behavior-Driven Development) Дэна Норта и спецификация на примерахспецификация на примерахEN specification by exampleСпособ описывать правила конкретными примерами с числами и ожидаемым результатом вместо общих фраз (книга Гойко Аджича, 2011). Примеры вскрывают неясности и затем становятся тестами. Гойко Аджича предложили описывать поведение конкретными сценариями «Дано / Когда / Тогда», которые сразу становятся автоматическими тестами. Это прямой предок критериев приёмки в SDD; сценарии мы разберём в уроке SDD.2.1. Родственная практика — разработка через тестированиеразработка через тестирование (TDD)EN Test-Driven DevelopmentПрактика Кента Бека: сначала падающий тест, потом минимальный код, чтобы он прошёл, потом рефакторинг («красный — зелёный — рефакторинг»). Тесты становятся исполняемой спецификацией.: сначала тест, потом код.
Model-driven development. разработка на основе моделейразработка на основе моделей (MDD)EN Model-Driven DevelopmentПодход, популярный в 1990–2000-х: систему описывают моделями (обычно UML), а код генерируют из них; известный вариант — Model Driven Architecture (MDA) консорциума OMG. Широко не прижился: модели оказались не проще кода, а генераторы — негибкими. обещала то же, что spec-as-source: описываем систему моделями (обычно UML), код генерируется. Широко подход не прижился: модели оказались не проще кода, генераторы — негибкими, а правки в сгенерированном коде терялись при следующей генерации. Бёккелер прямо проводит эту параллель и задаётся вопросом, не получим ли мы в spec-as-source недостатки обоих миров: негибкость MDD и недетерминизм языковых моделей.
Что действительно нового:
| Было | В SDD |
|---|---|
| «компилятор» понимал только строгий формальный язык (UML, DSL) | агент понимает естественный язык, примеры и даже нечёткие формулировки |
| генерация детерминирована: одна модель — один код | генерация недетерминирована: одна спецификация — разный код при каждом запуске |
| писать код было дорого, документы — «лишняя работа» | код стал дешёвым; дорогими стали решение, что строить, и проверка |
| документ читает человек | спецификацию читает и человек, и агент: это одновременно документ и промпт |
Из последней строки следует важное: хорошая спецификация в SDD — это хороший контекст для модели. Поэтому всё, что программа DDD говорит о едином языке, глоссарии и правилах с числами, здесь работает напрямую.
Сила и честные ограничения
Заголовок раздела «Сила и честные ограничения»Вернёмся к «кофе». Чтобы спокойно уйти от компьютера, пока агент работает, нужны три вещи: продуманная спецификация, план, который вы прочитали, и автоматическая проверка, которая скажет, что получилось. Посмотрим трезво, что SDD даёт, а чего не даёт.
Что даёт.
- Дешёвые ошибки. Неясность, найденная в спецификации, стоит пять минут разговора. Та же неясность в коде, который уже ушёл пользователям, — инцидент и переделка.
- Контекст для агента. Решения записаны в файлах репозитория, и их читает любой агент в любой сессии.
- Предмет для ревью до кода. Эксперт подтверждает правила, разработчик — план; спорят о смысле, а не о строчках.
- Определение «готово». Сценарии из спецификации становятся приёмочными тестами.
- Параллельная работа. Хорошо нарезанные задачи можно отдать нескольким агентам или людям.
Чего не даёт — и об этом важно знать с первого дня.
- Ложное чувство контроля. Подробная спецификация создаёт ощущение, что всё учтено. Но агент может пропустить пункт, переосмыслить его или сделать «больше, чем просили». Бёккелер пишет об этом прямо: шаблоны и чек-листы не гарантировали, что агент в её опытах будет следовать всем инструкциям.
- Многословие. Шаблоны поощряют длинные документы. Длинную спецификацию не читает человек — и хуже использует агент: важное тонет в контексте. Ревьюить десять markdown-файлов бывает тяжелее, чем сам код.
- Недетерминизм. Дважды запущенная генерация по одной спецификации даст разный код. Значит, проверка нужна каждый раз, а не один раз «на процесс».
- Один процесс на всё. Полный цикл для исправления опечатки — стрельба из пушки по воробьям.
- Ошибка в спецификации размножается быстрее. Агент добросовестно реализует неверное правило во всех местах сразу.
- Дрейф. Код правят в обход спецификации, и через месяц непонятно, какому документу верить.
Отсюда рабочая версия девиза программы: пошевелить мозгами на этапе планирования — обязательно; markdown-файлов — ровно столько, сколько вы и агент действительно прочитаете; кофе — да, но с возвращением к тестам и диффу.
flowchart LR H1["Человек:<br/>спецификация<br/>и ответы на вопросы"] --> A1["Агент:<br/>план"] A1 --> H2["Человек:<br/>ревью плана"] H2 --> A2["Агент:<br/>реализация по задачам<br/>и тесты"] A2 -.->|"здесь можно пить кофе"| A2 A2 --> H3["Человек:<br/>отчёт тестов,<br/>ревью диффа"] H3 -->|"расхождение"| H1
Когда SDD окупается, а когда это бюрократия
Заголовок раздела «Когда SDD окупается, а когда это бюрократия»Создатели OpenSpec называют свой принцип «постепенной строгостью» (progressive rigor): по умолчанию — лёгкая спецификация из коротких требований, границ и нескольких проверок; полная — только для рискованных изменений: между командами, в контрактах, миграциях, безопасности. Это хороший ориентир для любого инструмента.
| Задача | Что делать |
|---|---|
| опечатка, переименование, мелкий баг с понятной причиной | хороший промпт и тест на исправление |
| прототип «проверить идею за выходные» | вайб-кодинг честно разрешён; спецификацию пишут, если идея выживет |
| новая функция с бизнес-правилами (запись на поток, возвраты) | спецификация с требованиями и сценариями, план, задачи |
| изменение в существующей системе | короткое описание изменения: что добавлено, что изменено, что удалено |
| работа нескольких людей и агентов, контракты между частями системы | полный процесс: конституция проекта, ревью спецификаций, трассируемость |
Простая проверка: если задачу можно объяснить одной фразой и проверить глазами за минуту, спецификация не нужна. Если в задаче есть правила с числами, статусы, сроки или она займёт больше одной сессии агента — нужна.
Инструменты: короткий обзор
Заголовок раздела «Инструменты: короткий обзор»Подробно инструменты разобраны в модуле SDD.3; здесь — только чтобы узнавать названия. Имена команд и папок — по README и документации репозиториев, проверено в октябре 2026 года; инструменты меняются быстро, сверяйтесь с источником.
| Инструмент | Что это | Как устроен процесс |
|---|---|---|
| Spec Kit (github/spec-kit, MIT) | набор шаблонов и команд для разных агентов; CLI specify | конституция проекта один раз (/speckit.constitution), затем для каждой функции /speckit.specify → /speckit.plan → /speckit.tasks → /speckit.implement → /speckit.converge; артефакты spec.md, plan.md, tasks.md. В режиме навыков команды пишутся через дефис: /speckit-specify |
| OpenSpec (Fission-AI/OpenSpec, MIT) | лёгкий слой спецификаций, рассчитанный и на существующие проекты; CLI openspec | актуальные спецификации в openspec/specs/, каждое изменение — папка в openspec/changes/ (proposal.md, specs/, design.md, tasks.md); команды /opsx:propose, /opsx:apply, /opsx:archive |
| Kiro (AWS) | агентная среда разработки со спецификациями: IDE, CLI, веб- и мобильный клиент | требования, проектные решения и задачи; steering-файлы с соглашениями проекта |
| Свой процесс | папка specs/, шаблоны, файл памяти проекта | то же самое вручную — это урок SDD.3.3 |
Обратите внимание: все инструменты сходятся на одном и том же скелете — спецификация, план, задачи, проверка. Выучив скелет, вы сможете работать с любым из них и даже без них.
Карта программы
Заголовок раздела «Карта программы»Программа рассчитана примерно на 34 часа: четыре модуля, две домашние работы с автотестами и уровнями Simple, Medium, Strong и Boss — как в основном курсе (как устроены домашние работы, вы знаете по уроку 0.1.3).
flowchart LR M1["SDD.1<br/>Идея SDD"] --> M2["SDD.2<br/>Как писать<br/>спецификации"] M2 --> M3["SDD.3<br/>Инструменты:<br/>Spec Kit, OpenSpec"] M3 --> M4["SDD.4<br/>Практика<br/>и качество"] M2 --> H1["ДЗ sdd-hw01-spec<br/>пакет спецификаций"] M4 --> H2["ДЗ sdd-hw02-implement<br/>реализация с агентом"] D["Программа DDD:<br/>модули DDD.1–DDD.2"] -.->|"язык и правила<br/>для спецификаций"| M2
| Модуль | Часов | Что в нём | Что появится в онлайн-школе |
|---|---|---|---|
| SDD.1 Идея SDD | 6 | что такое SDD; как работает агент и его контекст | файл памяти проекта с глоссарием и правилами |
| SDD.2 Как писать спецификации | 10 | требования и критерии приёмки; план, модель данных и контракты; задачи и конституция проекта | спецификация записи на поток; ДЗ sdd-hw01-spec — пакет спецификаций фичи «Перенос записи на другой поток» |
| SDD.3 Инструменты SDD | 8 | Spec Kit; OpenSpec; обзор остальных и свой процесс | та же функция, проведённая через Spec Kit и через OpenSpec |
| SDD.4 Практика и качество | 10 | полный цикл с агентом; проверка, тесты и ревью; подводные камни и критика; выпускной проект | ДЗ sdd-hw02-implement — реализация «Выдачи сертификатов» с агентом по готовым спецификациям |
Связь с программой DDD
Заголовок раздела «Связь с программой DDD»Вторая программа курса — DDD, предметно-ориентированное проектирование. Программы дополняют друг друга. SDD отвечает на вопрос, как передать замысел агенту и проверить результат. DDD — на вопрос, что записать: какие в системе понятия, как они называются, какие правила нельзя нарушать и где проходят границы. Глоссарий школы из урока DDD.1.2 — готовый словарь для требований, правила Набора — готовые критерии приёмки, а границы контекстов — готовый скелет плана. Поэтому до модуля SDD.2 желательно пройти модули DDD.1–DDD.2; дальше программы можно идти параллельно.
Что нужно заранее
Заголовок раздела «Что нужно заранее»- Python, классы, модули, исключения и pytest — ступень 0 основного курса;
урок 0.2.3 о классах и
@dataclassпригодится в практиках. - Git и терминал — урок 0.1.1: агент работает в репозитории, а коммит после каждой задачи — главная страховка.
- Доступ к любому ИИ-агенту для кода: Claude Code, GitHub Copilot, Cursor, Codex или аналог. Примеры в программе чаще даны для Claude Code, но идеи переносятся на любой агент.
- Желательно — урок 8.3.1 об агентном цикле: он объясняет, как агент устроен изнутри.
Практика
Заголовок раздела «Практика»Проведите эксперимент «промпт против спецификации» с вашим агентом. Он займёт около часа и покажет разницу лучше любых слов.
Шаг 1. Вайб-кодинг. Создайте пустую папку, выполните git init и дайте агенту одну фразу: «Сделай на Python
запись студентов на курсы с отменой и возвратом денег». Закоммитьте результат и ответьте на вопросы: как названы
классы? Есть ли поток с датой старта и вместимостью? Можно ли записаться дважды? Сколько вернут при отмене ровно за
7 суток до старта и через минуту после этого момента? Деньги — float или целые копейки? Откуда берётся текущее
время? Что происходит с записью при отмене? Есть ли тесты? Посчитайте, сколько решений о продукте агент принял сам.
Шаг 2. Спецификация. Откатитесь к пустому репозиторию (новая ветка от первого коммита) и положите файл
specs/enrollment/spec.md. Это сокращённая спецификация; полный формат разберём в
уроке SDD.2.1.
# Спецификация: запись на поток
## КонтекстОнлайн-школа продаёт курсы потоками. У потока есть дата старта, вместимость и цена.Студент записывается на поток; запись ожидает оплаты, после оплаты подтверждается.Числа (7 суток) — условия учебного примера.
## Требования- **REQ-001**: Когда студент записывается на поток со свободными местами, система должна создать запись со статусом «ожидает оплаты».- **REQ-002**: Если свободных мест на потоке нет, то система должна отказать в записи (NoFreeSeats).- **REQ-003**: Если у студента уже есть действующая запись на этот поток («ожидает оплаты» или «подтверждена»), то система должна отказать в повторной записи (AlreadyEnrolled).- **REQ-004**: Если студент записывается в момент старта потока или позже, то система должна отказать в записи (EnrollmentClosed).- **REQ-005**: Когда студент отменяет запись за 7 суток (7 × 24 часа) или более до старта потока, система должна вернуть полную стоимость.- **REQ-006**: Когда студент отменяет запись позже, система должна отменить запись без возврата.
## СценарииПо одному на требование, с датами: старт потока 2 ноября 2026 года в 10:00, вместимость 2, цена 30 000 руб.Например, SC-005: Анна отменяет запись 26 октября в 10:00 (ровно за 7 суток) — возврат 30 000 руб.;SC-006: Анна отменяет запись 26 октября в 10:01 — возврат 0.
## Вне рамокОплата, лист ожидания, уведомления.
## Открытые вопросы- [УТОЧНИТЬ] Поток перенесли на другую дату — что с записями и правилом 7 суток? До ответа эксперта агент это не реализует.
## Интерфейс (для тестов; вообще это часть плана — урок SDD.2.2)Модуль enrollment.py: Cohort(capacity, starts_at, price) — цена в копейках;cohort.enroll(student_id, now) -> Enrollment с полями id и status (EnrollmentStatus.PENDING_PAYMENT, CONFIRMED, CANCELLED);cohort.cancel(enrollment_id, now) -> сумма возврата в копейках; cohort.free_seats() -> int;исключения NoFreeSeats, AlreadyEnrolled, EnrollmentClosed. Время передаётся параметром now, datetime.now() не используем.Отменённая запись место не занимает.Затем дайте агенту промпт в два захода. Первый — без кода:
Прочитай specs/enrollment/spec.md. Код пока не пиши. Перечисли, что в спецификации тебе неясноили допускает два толкования, и задай мне не больше пяти вопросов. Ничего не додумывай сам.Ответьте на вопросы (и, если ответ меняет правила, допишите его в спецификацию). Второй заход:
Реализуй specs/enrollment/spec.md в enrollment.py строго по разделу «Интерфейс».Не добавляй ничего из раздела «Вне рамок». Когда закончишь, запусти python -m pytest -v tests/и покажи результат. Если тест падает, исправляй код, а не тест.Шаг 3. Приёмочные тесты. Положите в tests/test_acceptance.py тесты по сценариям — до того, как агент начнёт
писать код. Имя каждого теста начинается с ID сценария: так видно, какое правило проверяется.
"""Приёмочные тесты из specs/enrollment/spec.md: один тест — один сценарий SC-…"""from datetime import datetime, timedelta
import pytest
from enrollment import AlreadyEnrolled, Cohort, EnrollmentClosed, EnrollmentStatus, NoFreeSeats
STARTS_AT = datetime(2026, 11, 2, 10, 0) # старт потока «Python для аналитиков»PRICE = 3_000_000 # 30 000 руб. в копейках
def new_cohort(capacity=2): return Cohort(capacity=capacity, starts_at=STARTS_AT, price=PRICE)
def test_sc_001_enroll_with_free_seat(): cohort = new_cohort() enrollment = cohort.enroll("anna", now=datetime(2026, 10, 1, 10, 0)) assert enrollment.status == EnrollmentStatus.PENDING_PAYMENT assert cohort.free_seats() == 1
def test_sc_002_no_free_seats(): cohort = new_cohort() cohort.enroll("anna", now=datetime(2026, 10, 1, 10, 0)) cohort.enroll("boris", now=datetime(2026, 10, 1, 11, 0)) with pytest.raises(NoFreeSeats): cohort.enroll("vera", now=datetime(2026, 10, 1, 12, 0))
def test_sc_003_enroll_twice(): cohort = new_cohort() cohort.enroll("anna", now=datetime(2026, 10, 1, 10, 0)) with pytest.raises(AlreadyEnrolled): cohort.enroll("anna", now=datetime(2026, 10, 2, 10, 0))
def test_sc_004_enrollment_closed_at_start(): with pytest.raises(EnrollmentClosed): new_cohort().enroll("gleb", now=STARTS_AT)
def test_sc_005_full_refund_exactly_7_days_before(): cohort = new_cohort() enrollment = cohort.enroll("anna", now=datetime(2026, 10, 1, 10, 0)) refund = cohort.cancel(enrollment.id, now=STARTS_AT - timedelta(days=7)) assert refund == PRICE assert cohort.free_seats() == 2
def test_sc_006_no_refund_later(): cohort = new_cohort() enrollment = cohort.enroll("anna", now=datetime(2026, 10, 1, 10, 0)) refund = cohort.cancel(enrollment.id, now=STARTS_AT - timedelta(days=7) + timedelta(minutes=1)) assert refund == 0Если реализация соответствует спецификации, вывод python -m pytest -v tests/ будет таким:
tests/test_acceptance.py::test_sc_001_enroll_with_free_seat PASSED [ 16%]tests/test_acceptance.py::test_sc_002_no_free_seats PASSED [ 33%]tests/test_acceptance.py::test_sc_003_enroll_twice PASSED [ 50%]tests/test_acceptance.py::test_sc_004_enrollment_closed_at_start PASSED [ 66%]tests/test_acceptance.py::test_sc_005_full_refund_exactly_7_days_before PASSED [ 83%]tests/test_acceptance.py::test_sc_006_no_refund_later PASSED [100%]
============================== 6 passed in 0.01s ===============================А если агент всё-таки решил, что «7 суток» — это «больше семи целых дней» ((starts_at - now).days > 7), сценарий
на границе это поймает. Вот сокращённый вывод короткого режима python -m pytest -q tests/ (без трассировки ошибки):
....F. [100%]FAILED tests/test_acceptance.py::test_sc_005_full_refund_exactly_7_days_before1 failed, 5 passed in 0.01sШаг 4. Сравнение. Заполните таблицу для обеих веток: сколько решений о продукте агент принял сам; сколько сценариев проходит (тесты из шага 3 можно запустить и против кода из шага 1 — скорее всего, они даже не импортируются); сколько сообщений «поправь» вы написали; сколько минут ушло. Сохраните таблицу: в уроке SDD.4.1 вы повторите эксперимент на полном цикле и сравните.
Проверь себя
Заголовок раздела «Проверь себя»- Без плана агент заполняет пробелы самыми вероятными вариантами и молча принимает решения о продукте, а исправления живут в истории чата и теряются между сессиями.
- SDD делает спецификацию главным артефактом: сначала что и зачем, потом как (план), потом задачи, а код проверяется по сценариям спецификации.
- Бёккелер различает три уровня: spec-first, spec-anchored и spec-as-source — по тому, сколько живёт спецификация и кто правит код. Прочитайте её статью целиком.
- SDD продолжает требования, BDD и TDD; от model-driven development его отличает «генератор», который понимает естественный язык, но недетерминирован.
- Сила подхода — дешёвые ошибки, контекст для агента и определение «готово». Ограничения — многословие, ложное чувство контроля, недетерминизм и дрейф. Пейте кофе, но возвращайтесь к тестам и диффу.
Дальше: урок SDD.1.2 — как устроен ИИ-агент для кода, что такое его контекст и почему он «забывает», как файлы памяти проекта, режим планирования и субагенты помогают держать его на рельсах и как не открыть агенту дорогу к секретам.