TL;DR
LLM не исполняют длинные пошаговые инструкции — они имитируют исполнение. Если вы даёте модели процедуру из 20+ шагов с промежуточными переменными, она не "мысленно выполняет" каждый шаг по очереди. Она генерирует правдоподобный текст, который часто пропускает шаги, останавливается раньше времени или продолжает после финала.
Точность падает с 61% до 20% — и это при задачах с элементарной арифметикой. Проблема не в сложности операций: сложить два числа модель умеет. Проблема в том, что чем больше шагов нужно удержать в "голове" одновременно, тем чаще модель сбивается. Особенно плохо, когда шаг N ссылается на результат шага N-5: такие "прыжки назад" по промежуточным результатам дополнительно снижают точность ещё на ~18%.
Практический вывод: короткая цепочка (5–10 шагов) работает надёжно. Длинная (20+) — непредсказуемо. Решение: разбивать длинные процедуры на цепочки с явным выводом промежуточных значений и передачей результатов между блоками.
Схема метода
Это не именованная техника из статьи, а практическая операция, которую следует вынести из диагностики. Работает в одном или нескольких последовательных запросах.
ШАГ 1: Оцени длину процедуры
└─ До 10 шагов → выполняй в одном промпте
└─ 10+ шагов → переходи к чанкингу
ШАГ 2: Разбей на блоки по 5–7 шагов
└─ Каждый блок = отдельный запрос
└─ Каждый шаг должен ссылаться только на предыдущий (не на N-3, N-5)
ШАГ 3: Потребуй явный вывод промежуточных значений
└─ "На каждом шаге выводи: [номер шага] → [результат]"
└─ Это делает сбой видимым
ШАГ 4: Верификация между блоками
└─ Проверь результат блока, передай как входные данные следующему
ШАГ 5: Передача состояния
└─ Начало следующего блока: "Входные данные для шагов 8–14:
S7 = [результат предыдущего блока]"
Шаги 1–3 — в одном промпте. Шаги 4–5 — между отдельными запросами.
Пример применения
Задача: Вы — продавец на Wildberries. Нужно рассчитать чистую прибыль с учётом всех удержаний: закупка, логистика, комиссия, налог, хранение, реклама. Семь последовательных вычислений — классическая миграция промежуточных результатов.
❌ Опасный способ (одним куском):
"Рассчитай прибыль: закупка 450р → логистика 15% → комиссия WB 17% → налог 6% → хранение 8р/день × 30 дней → рекламный бюджет 10% от выручки → итог"
Слишком много "прыжков" между переменными. Модель может перепутать базы для процентов или пропустить шаг.
✅ Правильный способ (явный трекинг):
Выполни расчёт пошагово. На каждом шаге выводи: [Шаг N] → [результат]
Цена продажи: 1 200 рублей
Шаг 1: Вычти закупочную цену (450р) из цены продажи → выручка
Шаг 2: Вычти логистику WB: 15% от цены продажи → остаток
Шаг 3: Вычти комиссию WB: 17% от цены продажи → остаток
Шаг 4: Вычти налог УСН: 6% от цены продажи → остаток
Шаг 5: Вычти хранение: 8р × 30 дней = 240р → остаток
Шаг 6: Вычти рекламу: 10% от цены продажи → остаток
Шаг 7: Итог = чистая прибыль
После каждого шага отобрази: текущий остаток в рублях.
Результат: Модель покажет цепочку из 7 явных шагов с промежуточными суммами после каждого. Вы видите где именно результат расходится с ожиданием — и можете поймать ошибку, не пересчитывая всё заново.
Почему это работает
LLM не "держит переменные в памяти" — она предсказывает следующий токен на основе предыдущего текста. Когда процедура короткая, все промежуточные результаты находятся рядом в тексте — модель "видит" их и корректно на них ссылается. Когда процедура длинная, ранние результаты уходят далеко назад в контекст, и модель начинает их "забывать" или подменять правдоподобными, но неверными числами.
Явный вывод промежуточных значений решает проблему конкретно: модель не держит S3 = 780 "в уме" — она записывает его в текст. Следующий шаг видит это число прямо перед собой в контексте и берёт его, а не вычисляет заново из воздуха.
Чанкинг работает по той же логике: короткий блок = всё нужное рядом. Передача результата следующему блоку = явное обновление контекста. Модель работает надёжно не потому что стала умнее — а потому что у неё больше нет шанса "потерять нить".
Рычаги управления:
- Длина блока → уменьши до 3–4 шагов для задач с умножением/делением (эти операции дают нестабильные промежуточные значения)
- Формат вывода → [Шаг N] → [результат] делает каждый шаг явным и проверяемым
- Ссылки на переменные → перепиши "шаг 5 зависит от шага 2" как "используй результат предыдущего шага" — убери прыжки назад
- Верификация в конце блока → добавь "Проверь: [итог блока] должен быть меньше стартового значения" — это ловит ошибки внутри блока
Шаблон промпта
Выполни процедуру пошагово. На каждом шаге выводи: [Шаг N] → [результат].
Входные данные: {входные_данные}
{шаг_1}
{шаг_2}
...
{шаг_N} (не более 7 шагов в одном блоке)
После каждого шага: укажи текущий результат явно.
Финальный ответ: {что_вернуть}
Что подставлять:
- {входные_данные} — ваши стартовые значения или условия
- {шаг_1...N} — последовательные действия, каждое зависит только от предыдущего
- {что_вернуть} — итоговый результат (число, вывод, решение)
Для длинных процедур (10+ шагов): разбейте на несколько запросов. Завершите первый блок, скопируйте явный результат (S7 = 840р), начните следующий блок с этих данных.
🚀 Быстрый старт — вставь в чат:
Вот шаблон для надёжного пошагового выполнения. Адаптируй под мою задачу: {твоя задача}.
Задавай вопросы, чтобы заполнить поля.
[вставить шаблон выше]
LLM спросит: какие входные данные, сколько шагов, нужен ли явный вывод промежуточных значений — потому что для разных задач структура блока разная, а точность зависит от явности каждого шага.
Ограничения
⚠️ Это диагностическое исследование, не готовая техника: Статья показывает ЧТО идёт не так, но не тестирует конкретные способы исправления. Техника чанкинга выведена из результатов, а не проверена в этом же исследовании.
⚠️ Умножение и деление работают хуже: Задачи только с этими операциями деградируют сильнее, чем сложение и вычитание. Разрыв между верными и неверными ответами там больше. Для таких расчётов уменьшайте блок до 3–4 шагов.
⚠️ Крупные модели тоже сбоят: Деградация точности наблюдается почти во всех моделях — от 1.5B до 685B параметров. Большая модель делает это медленнее, но всё равно делает.
⚠️ Прыжки назад — отдельная проблема: Если ваша процедура требует "на шаге 15 возьми результат шага 8" — это самостоятельный источник ошибок, не связанный с длиной. Реструктурируйте процедуру так, чтобы каждый шаг ссылался только на предыдущий.
Как исследовали
Исследователи из IIT Gandhinagar поставили простой жёсткий эксперимент: дали 14 моделям арифметические алгоритмы с нарастающим числом шагов — от 5 до 95 — и попросили вернуть финальный результат. Каждая операция элементарная: сложить, вычесть, умножить, разделить. Но шагов — много, и каждый зависит от предыдущего.
Логика дизайна была остроумной: если модель сбоит не на арифметике (что проверить легко — ответ детерминирован), значит, сбоит на самом исполнении процедуры. Они намеренно разделили "умеешь ли ты считать" и "умеешь ли ты следовать длинному набору шагов". Оказалось — это разные вещи.
Второй уровень сложности: "look-back" зависимости — когда шаг N обращается не к результату шага N-1, а к шагу N-5 или N-7. Это резкое нарастание требований к "рабочей памяти" модели. При переходе от look-back1 к look-back7 точность падает дополнительно на ~18 процентных пунктов.
Самое интересное — анализ режимов сбоя. Исследователи смотрели не только на финальный ответ, а на весь текст генерации: где появился ответ, сколько шагов выполнено, было ли исправление по ходу. Выяснилось: доля точного выполнения шагов падает с 71% до 47%, а доля "недовыполнения" (модель остановилась раньше финала) растёт с 24% до 51%. То есть модели не столько ошибаются в арифметике, сколько тихо сдаются на полпути — и при этом всё равно выдают какой-то ответ.
Было 55,000 примеров, 55 датасетов, сравнение со строго детерминированным эталоном — никакой субъективности в оценке.
Адаптации и экстраполяции
1. Явный "трекер состояния" в промпте
🔧 Техника: добавить таблицу переменных → модель ведёт явный реестр
Вместо того чтобы просить "выполни пошагово", добавьте явную структуру отслеживания:
После каждого шага обновляй таблицу:
| Шаг | Действие | Результат |
|-----|----------|-----------|
| 1 | | |
| 2 | | |
...
Заполняй каждую строку перед переходом к следующему.
Таблица не просто форматирует — она вынуждает модель зафиксировать промежуточный результат явно. Пропустить шаг становится сложнее: пустая строка в таблице видна сразу.
2. Разбивка длинного workflow с передачей "эстафеты"
🔧 Техника: явная передача состояния между чатами → длинные процедуры без потерь
Когда процедура реально длинная (бизнес-анализ, сложный расчёт):
[КОНЕЦ БЛОКА 1]
Итоговые значения для передачи в блок 2:
- S_выручка = {результат}
- S_себестоимость = {результат}
- S_маржа = {результат}
---
[НАЧАЛО БЛОКА 2]
Входные данные (получены из блока 1):
- Выручка = {значение}
- Себестоимость = {значение}
- Маржа = {значение}
Продолжай с шага 8...
Вы сами выступаете передатчиком состояния между запросами — это надёжнее, чем надеяться что модель "запомнит" 15 промежуточных чисел из предыдущего сообщения.
3. Использование findings из исследования для аудита своих промптов
Исследование даёт конкретный чеклист для оценки любого длинного промпта:
- Сколько шагов? → больше 10 — риск зоны
- Есть ли прыжки назад? → "как в шаге 3" — красный флаг
- Операции однородны? → только умножение или только деление → уменьши блок
- Есть ли явный вывод промежуточных значений? → если нет — добавь
Ресурсы
When LLMs Stop Following Steps: A Diagnostic Study of Procedural Execution in Language Models
Авторы: Sailesh Panda, Pritam Kadasi, Abhishek Upperwal, Mayank Singh
Аффилиации: Indian Institute of Technology Gandhinagar (IIT Gandhinagar), Soket AI
Контакт: sailesh.panda@iitgn.ac.in
Связанные работы упомянутые в статье: "Illusion of Thinking" (Shojaee et al., 2025) — аналогичная диагностика на задачах типа Башни Ханоя
