TL;DR
Specification Frame — это фиксированный блок текста на 267 слов, который вставляется перед задачей на генерацию кода. Он не учит модель как писать (стиль, структура файлов), а прямо говорит что должно быть верно в результате: как считать деньги, как хранить пароли, как обрабатывать повторные запросы. Работает как готовая «прошивка», одна и та же для любой задачи — вставил один раз, применяешь всегда.
Главная боль: нейросети пишут код, который выглядит правильным, но содержит одни и те же классические баги — деньги через float (округление плывёт), даты без часового зоны (получатель в другом городе получит письмо не в 9 утра, а в 2 ночи), повторный запрос к оплате может списать деньги дважды, пароли хранятся не тем способом. Причём попытки решить это через файлы-инструкции («AGENTS.md», «правила для Cursor») не работают — крупное исследование показало, что они не улучшают, а иногда даже ухудшают результат и увеличивают расход токенов на 20%.
Разница в том, что инструкция объясняет «как работать», а спецификация объясняет «что должно получиться». Автор протестировал короткий блок с конкретными ограничениями (деньги — только через Decimal, время — только с часовым поясом, платежи — только с проверкой на повтор) на 5 разных нейросетях от 5 разных компаний, и блок снизил количество ошибок во всех пяти без исключения, никогда не сделав код хуже.
Схема метода
ШАГ 1: Вставь Specification Frame (роль + контекст + правила) → фиксированный блок, без изменений под задачу
ШАГ 2: Сразу после него — опиши свою задачу как обычно → одно сообщение, один запрос
Оба шага — в одном промпте, без диалога и уточнений.
Пример применения
Задача: Предприниматель делает Telegram-бота для приёма оплаты через ЮKassa и просит Claude написать обработчик вебхука — код, который получает уведомление «оплата прошла» и записывает это в базу.
Промпт:
Роль: ты — старший backend-инженер, работающий в кодовой базе финансового сервиса,
где код проверяют на соответствие требованиям безопасности перед каждым релизом.
Контекст: Python 3.12, стандартная библиотека. Действуют правила:
- Денежные суммы только через Decimal или целые копейки, никогда через float.
- Все даты и время — с явной временной зоной UTC, "голых" datetime быть не должно.
- SQL-запросы только через параметризованные плейсхолдеры.
- Ключи и токены только из переменных окружения, никогда текстом в коде.
- Секреты и персональные данные никогда не попадают в логи.
Задача: реализуй именно то, что описано ниже, и не больше.
Ограничения:
1. Денежная арифметика — только Decimal или целые копейки. Округление — на последнем
шаге. Никогда не сравнивай деньги через float-равенство.
2. Обработчик, который могут вызвать повторно (вебхук платежа), должен требовать
и проверять ключ идемпотентности перед применением эффекта — то есть повторное
уведомление не должно повторно засчитать оплату.
3. Входные данные валидируй на границе, при ошибке — отказывай, не пропускай "на всякий случай".
4. Если формулировка неоднозначна — выбирай самую строгую трактовку.
Задача: напиши обработчик вебхука ЮKassa, который получает JSON с полями
payment_id, amount, currency, status, записывает успешную оплату в таблицу orders
и возвращает 200 OK.
Результат: Модель выдаст один готовый код на Python. По сравнению с "голым" запросом без блока, здесь сумма будет обработана через Decimal, а не float, обработчик потребует ключ идемпотентности (чтобы повторный вебхук от ЮKassa не засчитал оплату второй раз), и не будет прямых SQL-строк со вставленными переменными.
Почему это работает
Нейросеть по умолчанию пишет код так, как чаще всего видела в обучающих данных — а там много учебных примеров с float для денег и наивным datetime, потому что это самый короткий путь для демо-кода. Модель не «глупая», она просто не знает, что в этой конкретной задаче нужна строгость продовой системы, а не туториала.
Сильная сторона модели — она отлично следует явно сформулированным ограничениям, если они конкретны и не абстрактны. «Пиши безопасный код» — это стиль, размытая просьба. «Никогда не сравнивай деньги через float-равенство» — это спецификация, конкретное правило, которое легко проверить построчно.
Метод работает, потому что переносит фокус с инструкции о стиле на описание результата. Эффект был сильнее там, где модель по умолчанию была слабее — то есть блок работает как страховочная сетка именно там, где она нужнее всего.
Рычаги управления: - Можно сократить блок правил, если задача не касается денег/дат (оставить только релевантные пункты) — экономия токенов. - Можно добавить свои домен-специфичные правила в раздел «Ограничения» (например, правила для конкретного законодательства) — блок не заменяет специфику задачи, он даёт базовый пол. - Роль можно заменить под свой контекст ("senior backend-инженер" → "инженер embedded-систем") — острее выполнение под нужный домен.
Шаблон промпта
Роль: ты — старший backend-инженер, работающий в кодовой базе финансового
и медицинского сервиса, где код проверяют на соответствие требованиям безопасности
(PCI DSS, HIPAA) перед каждым слиянием.
Контекст: стек — {укажи язык и версию}. Действуют правила:
- Денежные суммы только через Decimal или целые копейки/центы, никогда через float.
- Все даты и время — с явной временной зоной (UTC), "голых" datetime без зоны быть не должно.
- SQL-запросы только через параметризованные плейсхолдеры, никогда через склейку строк.
- Пароли и ключи доступа только из переменных окружения, никогда текстом в коде или в логах.
- Секреты, персональные данные и номера карт никогда не попадают в логи.
Задача: реализуй именно то, что описано ниже, и не больше.
Ограничения:
1. Денежная арифметика — только Decimal или целые копейки. Округление — только на
последнем шаге, "вверх при равенстве". Никогда не сравнивай деньги через float-равенство.
2. Любой обработчик, который могут вызвать повторно (вебхуки, платежи), должен быть
идемпотентным: требует и проверяет ключ идемпотентности перед применением эффекта.
3. Пароли храни только через медленные соленые хеши (scrypt, pbkdf2 с большим числом
итераций). Никогда — открытым текстом или быстрым несоленым хешем.
4. Целевые адреса редиректов проверяй по allow-списку.
5. Пути к файлам из пользовательского ввода проверяй — они должны оставаться внутри
разрешённой базовой директории.
6. Валидируй входные данные на границе, при ошибке — отказывай, не пропускай "на всякий случай".
7. Если формулировка неоднозначна — выбирай самую строгую трактовку, не придумывай лишнего.
Задача: {текст твоей задачи}
Подставь язык программирования, платформу и саму задачу в фигурные скобки. Остальной текст — не менять, это протестированная формулировка.
🚀 Быстрый старт — вставь в чат:
Вот шаблон Specification Frame для генерации кода. Адаптируй под мою задачу: {твоя задача}.
Задавай вопросы, чтобы заполнить поля.
[вставить шаблон выше]
LLM спросит про язык программирования и специфику задачи — потому что от этого зависит, какие ограничения из блока релевантны, а какие можно убрать. Она возьмёт структуру ролей и ограничений и адаптирует под твою задачу.
Ограничения
⚠️ Не заменяет описание задачи: блок задаёт базовый пол безопасности, но не знает бизнес-логику твоей конкретной задачи. Специфичные требования (налоговые правила, форматы API) всё равно нужно описывать отдельно.
⚠️ Работает для определённого класса кода: эффект измерен для денег, времени, повторных запросов и доступа. Для творческого кода, фронтенда, UI-логики применимость не проверена.
⚠️ Требует, чтобы задача была явной: если в задаче нет упоминания денег или дат вообще, блок не добавит того, чего в задаче нет — он не изобретает требования сам.
Как исследовали
Исследователь заранее — до единого запуска — зафиксировал гипотезы, критерии провала и правило «одна попытка»: если модель выдала результат, его нельзя перегенерировать, даже если он неудачный. Это устраняет главный соблазн — подгонять данные под желаемый результат.
Дальше взяли 50 реалистичных задач из практики финтеха, здравоохранения и страхования (расчёт частичного возврата, вебхук платежа, проверка логина, планирование встречи через часовые пояса) и прогнали каждую задачу через 5 топовых нейросетей от 5 разных компаний, дважды — один раз без блока, один раз с ним. Итого 500 сгенерированных кусков кода.
Оценивали код двумя независимыми способами: девять автоматических проверок по дереву кода (считают конкретные баги — float для денег, наивные даты) и отдельный сканер безопасности Bandit, который вообще не знает о существовании этого блока — это защита от подгонки под тест. Оба метода показали одно и то же: с блоком багов в разы меньше, причём эффект был сильнее именно у тех моделей, которые без блока делали больше ошибок — блок выравнивает слабые модели до уровня сильных.
