Два запроса агенту, один за другим. Первый: "собери страницу по ТЗ из файла TZ_LANDING.md". Через несколько минут в папке появляется index.html, и он выглядит так, как задумано. Второй, тем же вечером: "собери игру 2048". И тут агент либо задаёт пять вопросов подряд, либо молча собирает поле 5×5 с кнопкой отмены хода, которую никто не просил.

Разница не в агенте. Разница в том, что он получил на входе. В этой статье разберём, из чего состоит ТЗ для маленькой задачи, где взять смысл, который в него записать, что делать, когда известно только направление, и почему после "готово" вы проверяете результат по тем же строкам, что написали до начала.

1. Идея ещё не задача

"Хочу 2048". "Сделай красивую страницу". "Сделай новую игру, поинтереснее". Всё это идеи, и у них одна общая беда: в голове у вас целая картинка, а в тексте два слова. Агент видит только текст.

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

"Все знают, как играть в 2048" - это у вас в голове. Агент это "все знают" не читает. Какое поле? Откуда берутся новые плитки и когда? Какие сливаются и во что? Когда победа, когда конец? Для вас одно слово, для него - пустое, пока не разложено на правила. В чате это выглядит так:

Вы:    собери игру 2048
Агент: Уточню перед началом:
       1. Какое поле, 4×4?
       2. Что считать победой?
       3. Нужна ли отмена хода?

Это хороший исход. Бывает и другой, на тот же запрос:

Вы:    собери игру 2048
Агент: Готово. Игра в файле index.html:
       - поле 5×5
       - кнопка отмены последнего хода
       - таблица рекордов в localStorage

Это не ошибка агента. Это три ваших пустых места, закрытых без вас.

Агент умеет спрашивать, но рассчитывать на это нельзя

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

  • Идея
  • Вопросы
  • ТЗ в файле
  • Агент
  • Проверка по ТЗ

Так выглядит путь от идеи до результата, которому можно верить. Статья идёт по нему слева направо. А последний шаг возвращает к третьему: проверили, нашли дырку, дописали строку в ТЗ и отдали агенту снова.

2. Откуда берётся смысл

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

Люди - это тот, кто заказал, и тот, кто будет пользоваться. Вопросы им лучше задавать пачкой. Список из пяти-шести пунктов за раз, а не по одному вопросу в день. Пачка выглядит навязчиво, знаю. На деле она экономит всем неделю переписки.

Когда заказчик - вы сами (своя игра, своя страница), вопросы задаёте себе, и тут главный соблазн ответить "ну это же очевидно". Очевидное записывается так же, как неочевидное. "Поле 4×4" - это две секунды, а агенту они закрывают целую развилку.

Третий источник - агент, и тут есть ловушка, о которой стоит знать заранее: вы не можете спросить о том, чего не знаете. Считается ли ходом ход, который ничего не сдвинул? Нужен ли свайп на телефоне? Показывать ли счёт? Эти вопросы не приходят в голову, пока игра не окажется перед глазами. А агент видел тысячу таких игр и знает, где обычно спотыкаются. Поэтому вместо "собери" иногда полезнее начать с "давай обсудим":

Хочу собрать игру 2048 в браузере. Пока ничего не пиши.
Задай мне вопросы, без которых не сможешь начать. Все сразу, списком.
Я отвечу, и потом соберём ТЗ в файл TZ_2048.md.

Два правила для такого разговора, иначе он не заканчивается. Первое: обсуждение закончено, когда заполнены четыре опоры из следующей секции, и его итог - файл, а не чат. Второе: вопросы агента - это варианты, а не требования. Он охотно спросит "а таблицу рекордов делаем?", и "нет" - нормальный ответ. Такое "нет" тоже строка ТЗ, только в "не делаем".

И в любом случае - спросили вы или спросил агент - ответ пишется в файл ТЗ, а не остаётся репликой в чате. Иначе следующий запрос начнётся с той же дырки.

Ответы от людей, от вас самих и от агента сходятся в один файл ТЗ, а реплика в чате теряетсяответыЛюдизаказчик, пользователиВы самисвоя игра или страницаАгентзнает, где спотыкаютсяФайл ТЗЧатреплика теряется
Откуда бы ни пришёл ответ, записывается он в файл. Чат его не сохранит

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

Агента можно попросить и больше: не только спросить, но и самому набросать черновик ТЗ по вашим ответам, заполнив то, чего вы не сказали. Что потом делать с тем, что он додумал, - в секции 4. Сначала о том, из чего ТЗ состоит.

3. Четыре опоры ТЗ

Для маленькой задачи ТЗ - это шесть-восемь строк. Держатся они на четырёх опорах: цель, что должно происходить, чего в первой версии не будет, как проверим. Вот целиком, для игры:

# ТЗ: 2048

ЦЕЛЬ:      браузерная игра 2048, открывается из файла, без установки.
           HTML, CSS и JavaScript, без сборки

ПРАВИЛА:   поле 4×4
           при старте и после каждого хода появляется новая плитка: 2 или 4
           стрелки двигают все плитки в одну сторону, до упора
           две одинаковые плитки при столкновении сливаются в одну с суммой
           победа: на поле появилась плитка 2048
           поражение: ходов нет, поле забито, слить нечего

НЕ ДЕЛАЕМ: таблицу рекордов, анимации, отмену хода

ПРОВЕРКА:  открыть index.html в браузере, увидеть поле и стартовые плитки
           сделать три хода стрелками, после каждого появляется новая плитка
           свести две двойки, получить четвёрку
           доиграть до конца, увидеть экран поражения

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

Цель

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

Проверка цели: если, читая её, вы видите код, а не то, что увидит человек, - это уже не цель. "Сделать функцию слияния плиток" - не цель, это кусок работы.

Сюда же одной строкой "чем собираем": HTML, CSS и JavaScript, без сборки. Без этой строки агент выберет сам, и не факт, что выберет то, что вы умеете запустить.

А "сделай красиво" целью быть не может. Непонятно, кому красиво и где это увидеть.

Что должно происходить

Самая длинная опора, и для игры она уже написана выше. Правило одно: строка хорошая, если после запуска на неё можно посмотреть и сказать "да" или "нет". "Поле 4×4" - да или нет. "Две одинаковые плитки сливаются в одну с суммой" - да или нет. "Поинтереснее" - ни да, ни нет, и такой строке в ТЗ не место.

Одна мысль на строку. "Плитки появляются и сливаются" - это две проверки, значит, две строки.

Для страницы то же самое, только вместо правил - что на ней есть: "шапка с названием и датой", "три блока: что будет, для кого, где", "кнопка Записаться ведёт на адрес формы". Каждую можно открыть и увидеть.

Такой список выглядит скучно рядом с идеей. Скучно - это и есть хорошо. скучное проверяется.

Чего в первой версии не будет

Единственная опора, о которой обычно забывают, и потому самая ценная. Пустое место агент закрывает сам, и охотнее всего - добавлением. Таблица рекордов, анимация плиток, кнопка отмены хода, тёмная тема. Всё это полезно, и всё это вы не просили.

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

Зачем это вам, а не агенту. Чем меньше собрано, тем меньше проверять. И тем понятнее, откуда взялось то, что сломалось: в шести строках искать проще, чем в шести экранах. Маркер, что границы нет: в вашей просьбе или в ответе агента зачастило слово "заодно".

В "не делаем" не попадает то, без чего нет цели

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

Как проверим

Каждая строка из "что должно происходить" - это одна проверка после того, как агент сказал "готово". Открыли игру - поле 4×4, да. Нажали стрелку - плитки поехали, появилась новая, да. Свели две двойки - четвёрка, да. Список проверок вы не пишете отдельно, он уже написан.

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

"Готово" от агента - реплика, а не проверка. Проверка - ваша, по вашим строкам.

Экран победы за минуту, а не за полчаса

До плитки 2048 играть долго, и экран победы честно не проверить. Попросите агента на время проверки считать победой плитку 64: "для проверки сделай победу при 64". Посмотрели экран, попросили вернуть 2048. Это тоже строка в ТЗ, временная, и потом её убирают.

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

# ТЗ: страница-приглашение

ЦЕЛЬ:        страница-приглашение на встречу клуба настольных игр:
             человек понимает, что за встреча, когда и где, и записывается по кнопке.
             один файл HTML, стили внутри

НА СТРАНИЦЕ: шапка с названием клуба и датой встречи
             три блока: что будет, для кого, где
             кнопка "Записаться" ведёт на адрес формы

НЕ ДЕЛАЕМ:   саму форму записи, оплату, галерею фотографий

ПРОВЕРКА:    открыть в браузере, увидеть шапку и три блока
             нажать кнопку, попасть на адрес формы

Заметьте, что слово "красивую" в ТЗ не попало вовсе. Оно не проверяется. Если красота правда важна, она раскладывается на строки так же, как всё остальное: "одна картинка в шапке", "не больше двух цветов", "всё помещается на экран телефона". Это уже можно открыть и посмотреть.

Названия блоков в двух примерах разные: для игры "правила", для страницы "на странице". Это не важно, назовите как удобно. Важно, что в каждом есть четыре опоры:

ОпораНа какой вопрос отвечаетДля 2048Для страницы
ЦельЧто делаем и для когобраузерная игра 2048, открывается из файластраница-приглашение: понять, что за встреча, и записаться
Что должно происходитьЧто я увижу после запускаполе 4×4, новые плитки, слияние, победа, поражениешапка, три блока, кнопка на форму
Чего не будетЧто агент добавил бы сам, а мы не просимрекорды, анимации, отмена ходаформа, оплата, галерея
Как проверимЧто сделать руками после "готово"три хода, свести двойки, доиграть до концаоткрыть, посмотреть, нажать кнопку

4. Чьё это решение

В ТЗ появляются решения, которые никто не согласовывал, и случается это двумя способами. Первый: вы разрешили агенту закрыть дырки "чем-то разумным", чтобы получить черновик сейчас, а не ждать ответов до вторника. Второй: вы сами решили за заказчика, потому что спросить некого или некогда.

Оба случая нормальные. Ненормально - забыть, что это допущение. Через неделю никто не вспомнит, кто придумал, что кнопка ведёт на почту, а не на форму, и спорить будут именно об этом.

Для первого случая запрос агенту выглядит так:

Собери черновик ТЗ для страницы-приглашения по этим ответам.
Где ответов нет - придумай разумное и отдельным списком
перечисли, что придумал сам. Запиши в файл TZ_INVITE.md.

Список додуманного читаете первым, до самого ТЗ. Это решения, принятые за вас: каждое либо уходит на согласование тому, кто в теме, либо остаётся в ТЗ с пометкой.

Для второго случая - пометка в самом файле. Строка "допущение:" перед решением или просто знак вопроса в конце строки: "кнопка ведёт на почту клуба (?)". Когда ответ придёт, сразу видно, что менять. и не нужно вспоминать, откуда это взялось.

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

5. Песочница вместо вопросов

Бывает, что четыре опоры не пишутся, сколько ни сиди. "Хочу что-то вроде 2048, но не знаю, нужен ли счёт, нужны ли свайпы, и 4×4 ли это вообще". Это не ТЗ и даже не идея в привычном смысле. Это ориентир: направление понятно, результат - нет. Вопросы тут не помогают: ответов пока нет ни у вас, ни у заказчика, а варианты от агента вам не с чем сравнить.

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

Песочница - это тоже ТЗ на четыре опоры, только цель у него другая:

# ТЗ: песочница 2048

ЦЕЛЬ:      посмотреть, как играется 2048 в браузере, и понять, чего хочу.
           HTML, CSS и JavaScript, без сборки

ПРАВИЛА:   поле 4×4
           стрелки двигают плитки, одинаковые сливаются
           после хода появляется новая плитка

НЕ ДЕЛАЕМ: всё остальное: победу, поражение, счёт, свайпы, оформление

ПРОВЕРКА:  поиграть пять минут и записать, чего не хватает и что лишнее

Посмотрите, что изменилось. Цель - не игра, а понимание. "Не делаем" - самая длинная строка, в ней всё, в чём вы не уверены. А проверка - не "работает ли", а "что я теперь знаю". Поиграли пять минут - и вопросы, которые нельзя было задать в начале, появляются сами: свайпы не нужны, за компьютером играют стрелками; счёт нужен, без него скучно; 4×4 мало, хочется попробовать 5×5; поражение надо показывать, а то непонятно, что игра кончилась.

Вот это и есть результат песочницы. Не код, а ответы. Из них пишется настоящее ТЗ, и собирается оно с нуля, в чистой папке, одной фразой: "собери игру по ТЗ из файла". Песочница своё отработала.

Ориентир ведёт в песочницу, пять минут игры дают ответы, ответы уходят в файл ТЗ, и агент собирает настоящую версию с нуля в чистой папкеответы, не кодОриентирПесочницаsandbox/Поигралипять минутТЗ в файлеАгентчистая папкаПроверка по ТЗ
Из песочницы в ТЗ уходят ответы. Стрелки от неё к агенту нет: настоящую версию он собирает с нуля

Это та же цепочка из первой секции, только шаг "Вопросы" здесь заменила петля: когда спросить не о чем, сначала смотрим, потом записываем. Вниз, в ТЗ, уходит одно - ответы. У песочницы нет стрелки к агенту, и это не забывчивость: настоящую версию он собирает в чистой папке, с нуля. дальше всё по цепочке.

Песочница остаётся песочницей

Соблазн понятный: раз уже что-то работает, давайте доделаем. "Добавь счёт", "добавь поражение", "заодно свайпы". Так песочница превращается в продукт по кусочкам, без ТЗ, и через час никто не скажет, что в ней заказано, а что прилипло. Держите её в отдельной папке, например sandbox/, а настоящую версию начинайте в чистой. Десять минут агента дешевле, чем разбирать потом, откуда что взялось.

6. ТЗ живёт в файле

Почему файл, а не переписка. Переписка теряется: через десять сообщений правило про слияние плиток уже не найти. Файл лежит в папке проекта рядом с кодом, агент читает его сам, когда вы на него укажете, а поправить и отдать снова можно той же фразой. Имя любое: TZ_2048.md, TZ_LANDING.md, хоть zadanie.txt. Это обычный текстовый файл, никакого специального формата у него нет.

Отдаётся он одной фразой. Сравните:

Было: "собери игру 2048, ну ты понял какую, поинтереснее".

Стало: "собери игру по ТЗ из файла TZ_2048.md".

Второй запрос короче первого, а информации в нём в десять раз больше - она в файле. Копировать текст ТЗ в чат не нужно, агент откроет файл сам.

Что менять в файле, а что говорить словами. Ориентир такой: изменилось правило или граница - правим файл и отдаём снова ("победа при 2048, а не при 1024" - это в файл). Изменилась мелочь вида, которая на правила не влияет, - можно словами ("сделай кнопку синей"). Сомневаетесь - в файл: лишняя строка дешевле забытого правила.

О размере. Для маленькой задачи это шесть-восемь строк, как блок для 2048 выше. Если ТЗ на игру на один вечер растянулось на две страницы, скорее всего, в него попало то, что должно было попасть в "не делаем".

И последнее перед тем, как отдать файл агенту: прочитайте его один раз как чужой. Строка, которую нельзя проверить, найдётся почти всегда. у меня находится.

7. Что агент делает с ТЗ, а что остаётся вам

Соберём всё в одну картину: что в этой схеме делает Claude Code, а что остаётся на вашей стороне. По парам.

АгентВы
Читает файл ТЗ, когда вы на него указали, и собирает ровно по немуПишете ТЗ до запроса, а не в ответ на результат
Задаёт вопросы, в том числе те, что вам в голову не пришли бы, - если его об этом попросить. Без просьбы может закрыть дырку самОтвечаете в файл и закрываете пустые места заранее
За десять минут собирает песочницуРешаете, что из неё берёте в ТЗ, и не доделываете её до продукта
По просьбе набросает черновик ТЗ и перечислит, что додумалЧитаете этот список первым
Говорит "готово"Проходите по строкам ТЗ и по "проверке"
Охотно добавляет "заодно"Держите "не делаем" по именам
У каркаса есть взрослая версия

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

Смысл ТЗ не в том, чтобы агент понял. Он и по двум словам что-то соберёт. Смысл в том, чтобы вы сами знали, что заказали, и могли это проверить.