Спека вместо промпта: как ставить задачу агенту
Коротко
Спека (от specification) — короткий документ, в котором вы с агентом договариваетесь о результате до того, как он начал писать код. Не «сделай форму подписки», а: что считается готовым, какие входы и выходы, что делать при ошибке, что трогать нельзя. В айтишном жаргоне слово «спека» значит две вещи: техническую спецификацию стандарта («спека HTTP») и ТЗ на конкретную фичу. В работе с ИИ-агентами прижилось второе — контракт на одну задачу.
Рабочий размер — одна страница и 15–30 минут на написание. Внутри пять блоков: цель, границы, критерии приёмки, ограничения, что не делаем. Спека отвечает на «что» и «почему»; план и код — на «как». Живёт файлом в репозитории (specs/имя.md), а не в чате: чат агент потеряет при следующем запуске, файл прочитает.
Не нужна на «поправь опечатку» и «переименуй переменную». Нужна везде, где переделка стоит дороже получаса вашего времени.
Зачем это нужно
Промпт — команда: агент читает её один раз, выполняет и забывает. Спека — то, на что можно сослаться на пятой итерации, когда агент дважды переписал модуль и вы не помните, о чём договаривались вначале.
Разница вылезает в момент приёмки. Без критериев готовности «готово» определяется задним числом: вы смотрите на диф в 800 строк и пытаетесь понять, это оно или не оно. С критериями приёмка занимает две минуты — прошёл список, принято.
Второй эффект менее очевидный. Написание спеки заставляет вас самих ответить на вопросы, которые вы обычно откладываете: что при пустом ответе от API, что при дубле, кто владеет данными. Агент их не задаст — он додумает. И додумает не так, как вы.
Подробнее про сам механизм постановки задачи — в разборе как поставить задачу, чтобы агент понял. Спека — это его тяжёлая версия для задач, которые не влезают в один заход.
| Размер задачи | Чем ставить | Где хранить |
|---|---|---|
| Правка в одну строку, опечатка | Обычный промпт в чате | Нигде |
| Одна функция, понятный вход и выход | Промпт + критерий приёмки в конце | Нигде |
| Фича на 2–10 файлов | Спека на страницу | specs/имя.md в репозитории |
| Модуль, миграция, интеграция | Спека + отдельный файл плана | specs/ + ветка |
| Правила, которые действуют всегда | Не спека | CLAUDE.md / AGENTS.md |
Готовый пример целиком
# Спека: экспорт заявок в CSV
## Цель
Менеджер выгружает заявки за период одной кнопкой и открывает файл
в Excel без плясок с кодировкой.
## Область
Меняем: страницу /admin/leads, добавляем эндпоинт GET /api/leads/export.
Не меняем: схему БД, права доступа, вёрстку списка заявок.
## Поведение
1. Кнопка «Выгрузить CSV» на /admin/leads, справа от фильтров.
2. Экспорт учитывает текущие фильтры страницы (даты, статус, источник).
3. Колонки: id, дата (ISO 8601), имя, телефон, email, источник, статус.
4. Кодировка UTF-8 с BOM, разделитель — точка с запятой.
5. Имя файла: leads-YYYY-MM-DD.csv.
## Границы и ошибки
- Пустая выборка: отдаём файл только с заголовками, не 404.
- Больше 50 000 строк: отдаём 413 и текст «Сузьте период».
- Нет прав: 403, тело не раскрывает наличие данных.
- Телефон пустой: пустая ячейка, не "null" и не "None".
## Критерии приёмки
- [ ] Файл открывается в Excel и в LibreOffice, кириллица не битая.
- [ ] Фильтр по статусу «новая» даёт ровно те же строки, что на экране.
- [ ] Тест на пустую выборку и тест на лимит строк — зелёные.
- [ ] На эндпоинт есть проверка прав, есть тест на 403.
## Чего не делаем
Excel-формат (.xlsx), выгрузку по расписанию, отправку на почту.
Это отдельные задачи.
Это всё. Одна страница, никаких диаграмм. Каким кодом это сделать, агент решает сам.
Разбор по частям
Цель. Одно предложение о том, кому и зачем. Не «реализовать эндпоинт», а «менеджер выгружает и открывает без плясок». Формулировка от пользователя не даёт агенту скатиться в решение задачи, которой нет.
Область. Самый недооценённый блок. «Не меняем: схему БД» — это то, что удерживает агента от «заодно я тут отрефакторил». Пишите явно, что за пределами.
Поведение. Нумерованный список наблюдаемых фактов: каждый пункт видно глазами или тестом. «Работает быстро» — не пункт. «Ответ меньше 2 секунд на 10 000 строк» — пункт.
Границы и ошибки. Здесь живёт вся ценность спеки. «Обрабатываются ошибки корректно» бесполезно; «телефон пустой — пустая ячейка, не строка None» экономит полчаса на второй итерации.
Критерии приёмки. Чекбоксы, каждый проверяется без вашего мнения. Непроверяемый пункт — не критерий, а пожелание.
Чего не делаем. Предохранитель от разрастания. Заодно вы сами перестаёте вспоминать посреди приёмки «а ещё бы неплохо».
| Блок | Что пишете | Что сломается без него |
|---|---|---|
| Цель | Кому и зачем, одно предложение | Агент решит соседнюю задачу |
| Область | Что меняем, что не трогаем | Правки расползутся по репозиторию |
| Поведение | Наблюдаемые факты списком | «Готово» станет вопросом вкуса |
| Границы и ошибки | Пусто, дубль, лимит, нет прав | Разбор крайних случаев после релиза |
| Критерии приёмки | Чекбоксы с проверкой | Приёмка по дифу на 800 строк |
| Чего не делаем | Явный список отрезанного | Задача разрастётся вдвое |
Три разбора «до/после»
Форма обратной связи. Было: «сделай форму обратной связи с валидацией». Агент придумал эндпоинт /api/contact, хотя в проекте уже был /api/leads, и повесил валидацию только на фронт. Стало: строка «эндпоинт POST /api/leads, поля см. модель Lead; валидация на сервере обязательна». Одна итерация вместо трёх.
Импорт CSV от партнёра. Было: «напиши импорт заявок из CSV». Файл приехал с дублями по email и с датами в двух форматах, агент об этом не знал и молча записал всё как есть. Стало: блок «Границы» с тремя строками — дубль по email обновляет запись, а не создаёт новую; дата в неизвестном формате — строка уходит в отчёт об ошибках, импорт продолжается; файл больше 5 МБ отклоняем. Разбор проблем переехал из продакшена в спеку.
Рефакторинг платежей. Было: «отрефактори модуль оплаты, он разросся». Агент переименовал публичные методы, и отвалилась интеграция, про которую он не знал. Стало: «Не меняем: сигнатуры экспортируемых функций, названия событий в шине, формат вебхука». Остальное можно — рефакторинг прошёл за один заход.
Во всех трёх случаях спасли не подробные требования, а две строки про границы.
Чего в него класть не надо
Стек и архитектуру — если только они не заданы жёстко снаружи. «Используй React Query» в спеке превращает её в план. Разделение «спека = что, план = как» взято у GitHub Spec Kit, где это разные команды: /speckit.specify описывает результат, /speckit.plan — технические решения.
Код. Псевдокод в спеке агент воспримет как обязательный и начнёт натягивать реализацию на вашу заготовку, даже когда в проекте есть готовая утилита.
Постоянные правила проекта. Стиль коммитов, запрет на any, порядок запуска тестов — это не спека, это память проекта. Их место — CLAUDE.md или общий AGENTS.md, который агент подхватывает автоматически (документация Claude Code про память). Дублировать их в каждой спеке — гарантированный рассинхрон.
Сроки и оценки. Агенту всё равно, а вам они помешают резать область.
Всё сразу. Спека на 15 страниц не читается ни человеком, ни моделью: в длинном контексте середина теряется первой. Не влезает на страницу — это две задачи.
Как поддерживать в актуальном виде
Главная ошибка после первой удачной спеки — начать собирать их в базу знаний. Через месяц у вас двадцать документов, половина расходится с кодом, и агент уверенно врёт про несуществующее поведение. Устаревшая спека хуже отсутствующей.
Что работает:
- Спека одноразовая. Живёт от постановки до мержа. После мержа — в
specs/done/или удалить. Источник истины после релиза — код и тесты, не документ. - Правится в том же PR. Договорились в процессе, что лимит не 50 000 строк, а 20 000 — правите спеку тем же коммитом. Не «потом».
- Долгоживущее переезжает. Решения, которые действуют дальше задачи (формат дат, правило про UTF-8 с BOM), уносятся в
CLAUDE.mdили в ADR. В спеке они были один раз и умерли вместе с ней. - Тест вместо абзаца. Всё, что можно закрепить тестом, закрепляйте тестом: тест не протухает молча, он падает.
Честные ограничения. Спека не спасает от галлюцинаций: агент напишет вызов несуществующего метода, идеально соблюдая критерии приёмки. Ревью она не отменяет. На незнакомом легаси помогает слабее — нельзя описать границы того, чего сам не знаешь, сначала разведка. А на исследовательских задачах («попробуй три подхода, покажи, какой быстрее») спека мешает: там нужен простор.
Один воспроизводимый ориентир: автор разбора SDD на Хабре воспроизвёл проект по спекам с точностью 85,5% относительно оригинала. Это про повторяемость, а не про экономию времени — метрик по времени в публичных разборах пока нет ни у кого, и когда вам называют «в три раза быстрее», спросите методику.
Дальше по теме: системный промпт задаёт постоянные правила, спека — разовые; промпт для spec-driven сборки генерирует спеку по описанию; маршрут от цели к сборке показывает её место в общем порядке шагов.
Частые вопросы
Спека и ТЗ — это одно и то же?
По смыслу близко, по объёму нет. Классическое ТЗ пишется для человека-исполнителя и подписывается сторонами; спека — одноразовый документ на страницу, который никто не согласовывает и который умирает после мержа. Есть большое ТЗ — спека нарезается из него: одна задача, один файл.
Нужен ли Spec Kit или Kiro, или хватит markdown-файла?
Хватит файла. Инструменты дают структуру и команды: Spec Kit разводит /speckit.specify и /speckit.plan, Kiro генерирует три файла — requirements.md, design.md, tasks.md. Это полезно на командной работе, где нужен одинаковый формат у всех. В одиночку вы получите 80% пользы от одного specs/имя.md и потеряете день на освоение тулинга.
Кто пишет спеку — я или агент?
Быстрее всего гибрид: вы диктуете задачу свободно, агент разворачивает её в структуру, вы вычитываете границы и критерии. Эти два блока агент заполняет хуже всего — он не знает, что у вас в проде дубли по email.
Работает ли это с любой моделью?
Механика не зависит от модели: любой агент, читающий файлы из репозитория, подхватит спеку. Разница в дисциплине следования — слабые модели чаще игнорируют блок «чего не делаем». Проверка одна: попросите агента перед началом пересказать спеку своими словами. Расхождение в пересказе значит, что документ неоднозначен, а не что модель плохая.
Что делать, если агент по ходу дела предлагает лучшее решение?
Останавливаетесь и правите спеку, а не соглашаетесь в чате. Согласие в чате живёт до конца сессии; правка в файле — до конца задачи. Это тридцать секунд, и они окупаются на следующем запуске, когда агент открывает файл и видит актуальную договорённость, а не первую версию.