Learn (Almost) Anything
КаталогСкачать курс

От промптов к спекам с AI-агентами

Из чего состоит спека, по которой агент реально может писать код: цель и не-цели, требования, граничные случаи, ограничения по стеку, критерии готовности. Разделяем «что» (requirements) и «как» (design), чтобы не смешивать продуктовую и техническую части. Пишем первую спеку для своей фичи и фиксируем «конституцию» проекта — неизменные принципы и договорённости по стеку.

ruМини-курс6 уроков1 модуль8
Spec Driven DevelopmentAI-агентамиSpec Driven Development на выходныхот спеки до приёмкиspecdrivendevelopmentпромптовспекамагентами

Анатомия рабочей спеки

Из чего состоит спека, по которой агент реально может писать код: цель и не-цели, требования, граничные случаи, ограничения по стеку, критерии готовности. Разделяем «что» (requirements) и «как» (design), чтобы не смешивать продуктовую и техническую части. Пишем первую спеку для своей фичи и фиксируем «конституцию» проекта — неизменные принципы и договорённости по стеку.

Анатомия рабочей спеки

В прошлом подмодуле мы разобрались, почему промпт не масштабируется на проект, и завели CLAUDE.md как постоянный контекст для агента. Теперь следующий слой: как написать спеку конкретной фичи, по которой агент сможет работать, а не заполнять пробелы угадками.

Почему «короткое описание» не работает

Большинство первых спек страдают одним из двух дефектов.

Слишком коротко. «Добавь авторизацию через JWT» — это одна строчка, не спека. Всё, что не написано явно, агент придумает сам. На третьем запросе вы обнаружите, что у вас появился cookie-session, о котором вы не просили.

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

Рабочая спека — не длинный документ. Это структурированный.

Шесть блоков рабочей спеки

flowchart TD S["specs/feature.md"] S --> A["Цель: что и для кого"] S --> B["Не-цели: исключения скоупа"] S --> C["Требования — ЧТО"] S --> D["Дизайн — КАК"] S --> E["Граничные случаи"] S --> F["Критерии готовности"] style C fill:#dbeafe,stroke:#3b82f6,color:#1e3a8a style D fill:#fef3c7,stroke:#d97706,color:#78350f
flowchart TD
    S["specs/feature.md"]
    S --> A["Цель: что и для кого"]
    S --> B["Не-цели: исключения скоупа"]
    S --> C["Требования — ЧТО"]
    S --> D["Дизайн — КАК"]
    S --> E["Граничные случаи"]
    S --> F["Критерии готовности"]
    style C fill:#dbeafe,stroke:#3b82f6,color:#1e3a8a
    style D fill:#fef3c7,stroke:#d97706,color:#78350f
Шесть блоков рабочей спеки. Голубым — продуктовая часть (что), жёлтым — техническая (как).

Цель — одна-две строки: что делаем и для кого. Агент читает это первым и получает контекст для всей задачи.

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

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

*Пример:* не входит — OAuth, сброс пароля, 2FA, «запомнить меня».

Требования — список «что»: поведение системы с точки зрения пользователя, без деталей реализации.

  • При успешном входе возвращается токен сроком 7 дней.
  • При неверном пароле — 401 и сообщение «Invalid credentials».
  • После 5 ошибок подряд — блокировка на 15 минут.

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

  • POST /auth/login принимает {email, password}, возвращает {token, expiresAt}.
  • Токен — JWT HS256, payload: {userId, email, exp}.
  • Счётчик ошибок: колонки failed_attempts и lock_until в таблице users.

Граничные случаи — самый часто пропускаемый блок. Агент не спросит про edge case, если вы его не написали.

  • User@Example.com и user@example.com — один пользователь или разные?
  • Верный пароль введён во время блокировки — что происходит?
  • Просроченный токен возвращает 401 или 403?

Критерии готовности — чеклист, по которому однозначно видно «сделано». Эти же пункты используются при приёмке (об этом — в пятом подмодуле).

  • [ ] POST /auth/login возвращает токен при верных данных.
  • [ ] Неверный пароль → 401, правильное сообщение.
  • [ ] Блокировка после 5 ошибок — покрыта тестом.
  • [ ] Email регистронезависим — есть тест.

«Что» и «Как»: зачем разделять

Блоки «Требования» и «Дизайн» легко перепутать, но их разделение даёт конкретную практическую выгоду.

Если вы работаете с продактом, он видит раздел «Требования» и проверяет поведение без необходимости понимать JWT или структуру базы. Разработчик работает с «Дизайном» и предлагает технические решения, не трогая продуктовые условия. Когда они смешаны, правка в одной части ломает понимание другой.

Продакт читает «Требования», разработчик — «Дизайн»: одна спека, два независимых фокуса.

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

<!-- ❌ смешано: реализация вписана в требование -->
## Требования
- Хранить сессии в Redis с TTL 7 дней.

<!-- ✅ разделено -->
## Требования
- Сессия остаётся активной 7 дней после входа.

## Дизайн
- Хранить сессии в Redis, ключ `session:{userId}`, TTL 604 800 с.

Простой тест: «Если реализация изменится, этот пункт всё равно останется верным?» Да — требование. Нет — дизайн.

ИнтерактивТребование или дизайн?
Для каждого утверждения выберите: это требование (что делает система) или дизайн (как это реализовано). 6 вопросов с мгновенной обратной связью.

Шаблон для копирования

Сохраните в specs/_template.md и используйте для каждой новой фичи:

# [Название фичи]

## Цель
[Что и для кого — одна-две строки]

## Не-цели
- [Явные исключения скоупа]

## Требования
- [ ] [Поведение с точки зрения пользователя / системы]

## Дизайн
[Эндпоинты, структуры данных, алгоритмы]

## Граничные случаи
- [Edge case]

## Критерии готовности
- [ ] [Проверяемый пункт]

Каждая фича — отдельный файл: specs/auth-login.md, specs/user-profile.md. Имена в kebab-case, совпадают с названием задачи.

Папка specs/ в файловом дереве проекта — каждая фича в отдельном .md файле с именем в kebab-case.

Конституция и спека фичи: два разных инструмента

CLAUDE.md — про весь проект: стек, соглашения, неизменные принципы. Меняется редко, агент читает его при каждом запуске автоматически.

Спека фичи — про один конкретный скоуп. Вы кладёте её в контекст явно, когда начинаете работу над фичей. Оба файла работают в паре: конституция задаёт правила, спека — цель.

CLAUDE.md — постоянная конституция проекта, спека фичи — прицельный контекст для одной задачи.

Если в процессе написания спеки вы понимаете, что правило относится ко всему проекту — например, «все эндпоинты требуют авторизации, кроме /auth/*» — это место в CLAUDE.md, не в спеке фичи.

Задание

Возьмите одну фичу из своего pet-проекта — небольшую: один эндпоинт, одна форма. Заполните шаблон выше. Правило: не тратьте на это больше 30 минут. Пропуски — нормально; в следующем подмодуле вы прогоните спеку через агента, и он сам найдёт дыры.

Самопроверка

  1. Статья определяет две основные проблемы коротких спек: «слишком коротко» и «всё перемешано». В чём ключевое различие между ними с точки зрения работы агента?
  2. Как правильно применить тест из статьи для разделения требования и дизайна: «Если реализация изменится, этот пункт всё равно останется верным?»
  3. Почему статья называет раздел «Не-цели» одним из самых ценных блоков спеки?
  4. В статье говорится, что разделение требований и дизайна даёт практическую выгоду. Какой из примеров наиболее точно иллюстрирует эту выгоду?
  5. Статья говорит, что граничные случаи — самый часто пропускаемый блок спеки. Почему?
  6. Во время написания спеки для новой фичи вы формулируете правило: «Все эндпоинты требуют авторизации, кроме /auth/*». Где должно быть это правило?
  7. Что произойдёт, если в спеке написать дизайн вместо требования, например: «Хранить сессии в Redis»?
  8. Когда вы описываете требование про блокировку: «После 5 ошибок подряд — блокировка на 15 минут», какой из этих вопросов ТОЧНО должен быть описан как граничный случай?

Домашние задания

Разобрать спеку на компонентыtext

Перед вами такое описание: «Нужна авторизация через JWT. Хранить токены в Redis, срок 7 дней. После 5 ошибок юзер блокируется на 15 минут. POST /auth/login принимает {email, password}, возвращает {token, expiresAt}. Не входит: OAuth, восстановление пароля, 2FA. Токены проверяются на каждом запросе.» Это хаос — требования смешаны с дизайном, не-цели потеряны в тексте. Ваша задача: выпишите каждое предложение или фразу и распределите по 6 блокам спеки (цель, не-цели, требования, дизайн, граничные случаи, критерии готовности). Если какого-то блока нет — напишите, какая информация там должна быть.

• Все 6 блоков идентифицированы, предложения корректно распределены • Требования (поведение системы) явно отделены от дизайна (техдетали) • Указано минимум 2 отсутствующих блока или информации, которую надо добавить • Объяснено, почему определённое предложение попало именно туда, а не в другой блок

Написать спеку для фичиdocument

Возьмите небольшую фичу из своего проекта — достаточно небольшую, чтобы уложиться в 30 минут. Один эндпоинт, одна форма, функция с чётким скоупом. Сохраните файл `[название-фичи].md` и заполните шаблон: # [Название] ## Цель [Что и для кого — одна-две строки] ## Не-цели [Явные исключения из скоупа] ## Требования [Поведение с точки зрения юзера, без деталей реализации] ## Дизайн [Эндпоинты, структуры, алгоритмы] ## Граничные случаи [Edge cases — не просто список, а 'когда X, система делает Y'] ## Критерии готовности [Чеклист проверяемых пунктов] Ключевой момент: если вы завтра переделаете реализацию, требование должно остаться актуальным. Если нет — это не требование, это дизайн.

• Все 6 блоков присутствуют и содержат информацию (не шаблонный текст) • Требования описывают 'что', без слов вроде 'хранить в Redis' или 'POST /api' • Дизайн содержит технические решения, не в требованиях • Не-цели исключают минимум 2 реальных расширения (не абстрактные) • Граничные случаи конкретны: 'email не регистронезависим', а не 'обработать ошибки' • Критерии готовности можно проверить тестом или вручную — они измеримые

Проверить спеку через глаза кодировщикаtext

Вернитесь к спеке, которую только что написали. Прочитайте её как будто вы — агент, который будет её кодить. Ответьте честно на каждый вопрос: 1. **Требования и дизайн:** есть ли в требованиях слова 'эндпоинт', 'таблица', 'Redis', 'JWT'? Если да — переместите в дизайн или переформулируйте. 2. **Граничные случаи:** для каждого перечисленного edge case ясно, что система должна делать? Или это просто список ситуаций? Переформулируйте в чеклист: 'Когда... → система...' 3. **Двусмысленность:** может ли другой разработчик прочитать эту спеку и понять её иначе? Найдите минимум одно слово или фразу, которая неоднозначна. 4. **Что забыли:** выпишите 3-4 граничных случая, которые вы первый раз не заметили. Добавьте их в спеку. Напишите короткий отчёт: что нужно доработать и почему это важно.

• Ответы на все 4 пункта, не просто 'да'/'нет', а с примерами • Минимум 3 новых граничных случая добавлены в спеку, описаны поведением • Указаны конкретные фразы из спеки, где видна двусмысленность • Отчёт показывает, что вы честно смотрели критически, нашли реальные дыры • Правки внесены в файл спеки (или описаны, как их внести)

Сдача и проверка заданий — в приложении Learn (Almost) Anything.

Источники

  1. How to write a good spec for AI agents — Addy Osmani
  2. Spec-Driven Development (FredAntB/Spec-Driven-Development) — GitHub