learn-se · Урок 1 · ~15 минут

Спека поведения: говори ЧТО, а не КАК

Один навык: превращать пожелание в проверяемую спецификацию. Это фундамент всего курса — и самый быстрый способ сократить итерации с агентом.

Проблема

Сравни две постановки одной задачи из setlog:

Расплывчато «Сделай чтобы после подхода запускался таймер отдыха»

Агент вынужден угадывать: запускать после каждого подхода или кроме последнего? Что если пользователь уже сам запустил таймер? Что на заблокированном экране? Каждая неверная догадка — итерация: ты смотришь результат, объясняешь, ждёшь заново. Штраф платится не при написании, а после.

Два слова, которые всё меняют

Specification (спека) — описание того, что система должна делать: наблюдаемое поведение. Implementation — то, как это устроено в коде: файлы, функции, библиотеки.

Разделение труда в vibe coding проходит ровно по этой границе: спека — твоя территория, реализация — агента. Ты не читаешь код — значит, единственный язык, на котором ты можешь и ставить задачу, и принимать работу, — это наблюдаемое поведение (behavior): что видит пользователь, что сохранилось, что отправилось.

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

Формат: Given / When / Then

Индустрия сжала «как описывать поведение» в три слова (Fowler, GivenWhenThen):

СловоЗначениеПример
Givenсостояние доGiven идёт тренировка и остались подходы
Whenдействиеwhen пользователь сохраняет подход
Thenнаблюдаемый результатthen автоматически стартует таймер отдыха

Сила формата — в Given: он заставляет назвать условия, при которых поведение другое. Это и есть edge cases — краевые случаи, где живёт большинство багов:

Проверяемая спека

— Given остались подходы, when подход сохранён, then стартует таймер отдыха.
— Given это был последний подход, when он сохранён, then таймер не стартует, показывается завершение.
— Given таймер уже идёт, when сохранён ещё подход, then таймер перезапускается с нуля.
Не входит: экран настроек таймера не трогаем.

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

Суждение: когда применять, когда вредно

Применяй — когда фича трогает несколько сценариев или данные пользователей, когда прошлый промпт на эту тему ушёл в лишние итерации, когда результат нужно принять не глядя в код.
Вредно — для исследовательских прототипов («набросай и посмотрим») и микро-правок: спека длиннее диффа — это бюрократия. Там хватит одного предложения с наблюдаемым результатом.
Цена — 5–10 минут мышления до промпта. Ты платишь их всегда; вопрос лишь, заранее или в виде итераций после.

Проверь себя

1. Что из этого — спека (поведение), а не реализация?

useEffect и компонент — это «как устроено» (implementation). Наблюдаемое поведение — то, что заметит пользователь, не открывая код.

2. Что описывает блок Given?

Given — предусловия («идёт тренировка, остались подходы»). Действие — When, результат — Then.

3. Где полная спека из пяти блоков — вредный overkill?

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

Упражнение — твой первый выигрыш

Возьми расплывчатый промпт ниже и перепиши его по шаблону (поведение в Given/When/Then, минимум один edge case, «не входит», критерии приёмки). Пиши где угодно — хоть на бумаге. Потом раскрой образец и сравни: совпали ли твои edge cases?

Исходник «Сделай чтобы в чате было видно, что собеседник печатает»
Показать образец ответа (сначала напиши свой!)
Образец

Контекст: чат тренера и клиента; индикатор снижает ощущение «меня игнорируют».

Поведение:
— Given открыт диалог, when собеседник набирает текст, then под его именем видно «печатает…».
— Given собеседник перестал печатать и не отправил, when прошло ~5 секунд, then индикатор исчезает.
— Given собеседник офлайн или диалог не открыт, then индикатор не показывается никому.

Не входит: статусы «онлайн/был недавно», звуки, push.

Критерии приёмки:
— [ ] в двух окнах браузера: печать в одном ⇒ индикатор во втором в течение секунды;
— [ ] индикатор гаснет сам, без обновления страницы;
— [ ] в списке чатов (вне диалога) ничего не изменилось.

Твои формулировки не обязаны совпадать дословно. Главное: есть ли у тебя edge case про «перестал печатать» и наблюдаемые критерии, проверяемые без чтения кода?

Что читать

Главный источник к уроку: Simon Willison — «Here's how I use LLMs to help me write code». Смотри, как он «указывает направление» модели и требует план до реализации — это спека в действии. Дополнительно: официальные best practices Claude Code — раздел про то, что агент должен показывать evidence, а не утверждать «готово»: это и есть твои acceptance criteria.

Непонятно что-то из урока — спроси у меня в сессии Claude Code, я твой преподаватель: «объясни ещё раз Given/When/Then на примере setlog» — нормальный вопрос.
Источники: Fowler — GivenWhenThen · Willison — Using LLMs for code · Anthropic — Claude Code best practices