TL;DR
Constraint Decay (затухание ограничений) — это явление: когда ты добавляешь в промпт всё больше требований, модель начинает их терять. Не случайно и не равномерно — чем конкретнее и «структурнее» требование, тем выше шанс, что именно оно выпадет.
Главная находка: добавление каждого нового ограничения бьёт по качеству сильнее, чем предыдущее. Модели потеряли в среднем 30 процентных пунктов качества при переходе от «пиши свободно» к «пиши с соблюдением архитектуры + базы данных + конкретного ORM». Самый сильный удар дают самые конкретные, технические требования — в коде это база данных, в обычных задачах это любые жёсткие структурные ограничения. Расплывчатые требования вроде «пиши в деловом стиле» страдают меньше. Очень специфичные — «используй SQLAlchemy», «соблюдай Clean Architecture», «только PostgreSQL» — падают первыми.
Решение, которое вытекает из исследования: не складывай все ограничения в один промпт и не полагайся что модель сама проверит все из них. Явные и подробные инструкции работают лучше отсылок к «принятым стандартам». Проверяй соблюдение каждого ограничения отдельно, а не надейся на итоговый результат.
Схема явления
СИТУАЦИЯ 1 (без стека)
Промпт: {задача} → Качество: высокое
Ограничений нет → модель свободно генерирует → результат хороший
СИТУАЦИЯ 2 (умеренный стек)
Промпт: {задача} + Требование A + Требование B → Качество: среднее
Каждое ограничение → небольшой штраф
СИТУАЦИЯ 3 (тяжёлый стек — constraint decay)
Промпт: {задача} + A + B + C + D → Качество: низкое
Самые жёсткие/конкретные требования выпадают первыми
Всё это происходит в одном промпте без отдельных запросов. Проблема не в диалоге — в стеке требований внутри одного задания.
Пример применения
Задача: Ты хочешь написать скрипт для холодного звонка в B2B. Задача нетривиальная — нужно попасть в несколько требований сразу: тон, структура, конкретные фразы-табу, длина, отсылка к кейсам, призыв к действию, конкурентный контекст.
Промпт (наивный — ловушка стека):
Напиши скрипт холодного звонка для продажи CRM-системы малому бизнесу.
Требования:
— Тон: дружелюбный, без давления
— Длина: не больше 90 секунд (≈150 слов)
— Нельзя использовать слова "уникальный", "инновационный", "лучший"
— Упомяни кейс из ритейла
— Структура: крючок → боль → решение → вопрос
— В конце — конкретный призыв к встрече на 15 минут
— Без корпоративного канцелярита
— Сделай так, чтобы звучало как живая речь, не презентация
Что произойдёт: Модель выдаст текст, который будет удовлетворять части требований. Скорее всего «потеряет» самые конкретные и жёсткие — например, точный лимит слов или строгий запрет на конкретные слова. Структура может поехать. Кейс из ритейла может оказаться абстрактным.
Промпт (с учётом constraint decay):
Напиши скрипт холодного звонка для продажи CRM малому бизнесу.
Структура строго: крючок (1 предложение) → боль (2 предложения) → решение (2 предложения) → вопрос (1 предложение).
Внутри этой структуры соблюди:
— Тон как у друга, не продавца
— Упомяни магазин одежды как пример клиента
После того как напишешь, проверь каждый пункт списком:
✓ Слова "уникальный/инновационный/лучший" отсутствуют?
✓ Общая длина ≤ 150 слов?
✓ Есть предложение о встрече на 15 минут в конце?
Если что-то нарушено — исправь.
Результат: Модель сначала напишет текст по чёткой структуре (структура здесь — якорь, не ограничение). Потом выдаст явный чек-лист самопроверки с галочками и исправит нарушения. Самые конкретные требования (запрещённые слова, точная длина) теперь проверяются явно, а не надеясь что модель «помнит» их из стека.
Почему это работает
Слабость LLM: модель не держит в голове «счётчик требований». Когда требований много, она генерирует текст ориентируясь на общее направление задачи — и чем дальше требование от сути, тем выше шанс что оно потеряется. Это не забывчивость — модель буквально генерирует следующий токен на основе контекста, и конкретное техническое ограничение из середины промпта к моменту генерации может иметь слабый «вес».
Ключевой паттерн из исследования: сильнее всего страдают самые конкретные структурные требования — то что нельзя «угадать», нужно точно выполнить. В коде это база данных и ORM. В тексте — точный лимит слов, запрещённые фразы, обязательные элементы структуры.
Что помогает: - Явно > неявно. «Не используй слово X» работает лучше «пиши в разговорном стиле» — потому что первое конкретно, второе модель интерпретирует сама - Структура как якорь. Жёсткая схема (крючок → боль → решение) снижает количество «свободных переменных» — модели меньше что угадывать - Самопроверка в конце промпта. Попроси модель после генерации пройтись по чек-листу — это переводит ограничения из «фоновых» в явные задачи
Рычаги управления: - Количество требований в одном промпте → больше 4-5 жёстких = жди потерь, разбивай на шаги - Чек-лист самопроверки → добавляй для самых критичных ограничений - Порядок требований → самые важные — ближе к концу промпта (перед задачей), не в середине списка
Шаблон промпта
{Задача основная}
Структура ответа строго:
— {Блок 1}: {что должно быть}
— {Блок 2}: {что должно быть}
— {Блок 3}: {что должно быть}
Дополнительные требования:
— {Требование конкретное 1}
— {Требование конкретное 2}
После завершения проверь каждый пункт:
✓ {Критерий 1 — да/нет вопрос}?
✓ {Критерий 2 — да/нет вопрос}?
✓ {Критерий 3 — да/нет вопрос}?
Если нарушено — исправь.
Что подставлять:
- {Задача} — основное задание в одном предложении
- {Блок 1-3} — структурный скелет (крючок, тело, финал / введение, аргументы, вывод)
- {Требование} — конкретные жёсткие ограничения (запрещённые слова, точная длина, обязательные элементы)
- {Критерий} — то же в форме да/нет вопроса: «Слово X отсутствует? Длина ≤ N слов?»
🚀 Быстрый старт — вставь в чат:
Вот шаблон против constraint decay — когда много требований и важно что ни одно не потерялось. Адаптируй под мою задачу: {твоя задача}.
Задавай вопросы, чтобы заполнить поля.
[вставить шаблон выше]
LLM спросит про структуру задачи и ключевые ограничения — потому что без этого не сможет построить чек-лист самопроверки, который является главным механизмом «зафиксировать» конкретные требования.
Почему это работает
LLM не может параллельно отслеживать 8 ограничений пока генерирует текст. Это как читать книгу и держать в голове список из 10 вещей которые нельзя говорить.
Самые конкретные и «нестандартные» ограничения исчезают первыми — потому что у модели нет «якоря» для них в паттернах обучения. «Деловой тон» — есть миллион примеров. «Не использовать слово "синергия"» — нет. Модель просто генерирует то, что статистически следует за предыдущим текстом.
Явный чек-лист в конце промпта меняет игру: он переводит ограничения из фонового контекста в отдельную задачу верификации. Модель не «помнит» ограничения — она их проверяет по списку. Это два разных режима работы.
Ограничения
⚠️ Работает с конкретными/верифицируемыми требованиями: Чек-лист самопроверки — только для того что можно объективно проверить («слово отсутствует», «длина ≤ N»). Субъективные требования («тон дружелюбный») модель оценит сама без надёжной верификации.
⚠️ Не решает проблему, только смягчает: Если требований очень много — даже с чек-листом часть потеряется. Радикальное решение — разбивать задачу на несколько промптов, добавляя требования итерационно.
⚠️ Исследование на коде, принципы экстраполированы: Статья изучала именно генерацию бэкенд-кода с архитектурными ограничениями. Применимость к обычным текстовым задачам — логически обоснованная экстраполяция, не прямое измерение.
⚠️ Явные инструкции не всегда выигрывают у конвенций: Иногда ссылка на стиль или формат («как в НЛО») даёт лучший результат чем длинный список правил — модель хорошо знает некоторые конвенции. Исследование показало проблему с малоизвестными конвенциями.
Как исследовали
Исследователи взяли один и тот же API и одну и ту же задачу — сгенерировать работающий бэкенд-сервис — и начали систематически добавлять структурные требования: сначала просто «напиши на Flask», потом добавили «соблюдай Clean Architecture», потом «используй PostgreSQL», потом «и SQLAlchemy для запросов». 80 задач, 8 веб-фреймворков, 4 уровня ограничений — итого почти 5 миллиардов токенов обращений к моделям. Сравнивали современные модели: GPT-5-mini, GPT-5.2, Kimi-K2.5, MiniMax-M2.5, несколько версий Qwen3.
Элегантность дизайна в том, что функциональная задача не менялась — только структурные требования. Это позволило изолировать именно эффект ограничений, а не сложности самой задачи. Результаты оказались неожиданно безжалостными: даже самые мощные модели теряли в среднем 30 процентных пунктов качества. Что удивило — ORM-ограничение иногда помогало: оно снимало неоднозначность (модель не гадала «как работать с данными»), а значит конкретность может работать в плюс когда убирает вариативность, а не добавляет новое требование поверх.
Кстати, исследование параллельно проверило реальные репозитории — взяли готовые проекты где уже была архитектура, и попросили модели добавить функциональность. Результат похожий: структурные требования не исчезают как проблема даже когда они «встроены» в существующий код.
Адаптации и экстраполяции
🔧 Техника: «Самый важный критерий — последним в промпте»
В исследовании показано, что модели лучше соблюдают ограничения которые более явны и структурно понятны. Если ты пишешь список требований — самое важное ставь последним перед задачей, а не в середине. Последние строки перед задачей имеют больший вес в контексте генерации.
Было: «Тон дружелюбный, длина 100 слов, нет канцелярита, упомяни конкурента, и главное — сделай так чтобы человек перезвонил»
Стало: «Тон дружелюбный, нет канцелярита, длина 100 слов, упомяни конкурента.
Главное: каждое предложение должно вести к тому, чтобы человек захотел перезвонить.»
🔧 Техника: «Декомпозиция через явные требования к Framework»
Исследование показало: лёгкие, явные фреймворки (Flask) работают лучше конвенционально-тяжёлых (Django, FastAPI). Аналог в промптинге: не говори «напиши как принято в деловой переписке» — это Django. Скажи «пиши коротко, без "уважаемый", без "в рамках", без пассивных конструкций» — это Flask. Явные запреты и явные правила = меньше угадывания = меньше потерь.
Ресурсы
Constraint Decay: The Fragility of LLM Agents in Backend Code Generation
Preprint, under review.
Авторы: Francesco Dente, Dario Satriani, Paolo Papotti
EURECOM (Франция) и University of Basilicata (Италия)
Код и датасет: https://anonymous.4open.science/r/constraint-decay
