Промпт-инжиниринг: почему 6 строк Makefile бьют 2 000 слов
Две тысячи слов инструкций в CLAUDE.md проигрывают шести строкам Makefile. Дело не в стиле и не в аккуратности формулировок. Вашу выдуманную нотацию вроде [CRITICAL_STEP_4_GATE] модель никогда не встречала в корпусе обучения, а Makefile встречала миллионы раз. Разница в частоте превращается в разницу в надёжности, и её измерили.
Рэндал Шварц, Google Developer Expert по Dart и Flutter, один из двенадцати в Северной Америке, с 45-летним стажем в разработке, провёл 1 680 парных A/B-прогонов на четырёх моделях Gemini, опёрся на 151 рабочий тикет и опубликовал результаты 11 октября в серии Synthetic Scars на dev.to. В одном из экспериментов надёжность агента выросла с 0,8% до 98,3% только за счёт того, что прозу заменили каноническим формализмом. Дальше разбираем механику, числа и таблицу замен.
Что такое гравитация предобучения
Гравитация предобучения (pre-training gravity) описывает простую зависимость: надёжность, с которой модель исполняет инструкцию, растёт вместе с тем, как часто похожая структура встречалась в её обучающем корпусе. Эмпирические работы (Razeghi et al., Kandpal et al.) показали, что связь логарифмическая: редкий паттерн исполняется плохо и нестабильно, частый исполняется стабильно.
Сравните две частоты. Makefile из 1976 года, заголовки писем RFC 822 из 1982-го, загрузочные скрипты /etc/init.d из 1983-го попадаются в предобучении миллионы раз. Выдуманный вами регламент [CRITICAL_EXECUTION_PROTOCOL] с шагами 1–7 не попадается ни разу. Когда частота равна нулю, модель не может опереться на глубокие слои весов. Ей приходится импровизировать: симулировать интерпретатор вашего личного языка на самых хрупких слоях рабочего внимания.
Контекст заполняется логами и диффами, внимание размывается пропорционально длине, симуляция теряет указатель, и агент пропускает шаг 6. Разработчик Дин Ли описал этот механизм в комментариях к предыдущей части серии: чек-лист из 20 шагов превращается в незахеджированную марковскую цепь, где каждый новый токен повышает вероятность ошибки перехода. Пользователь платит по тарифу фронтирной модели за то, что трансформер изображает хрупкий счётчик инструкций.
Три года промпт-инжиниринг считался разновидностью сочинительства. Шварц предлагает смотреть на него как на статическую линковку: канонический примитив подключает к задаче библиотеку, которую модель за время предобучения «скомпилировала» в свои веса примерно за 100 миллионов долларов.
Эксперимент на 1 680 прогонов
Дизайн такой. Четыре модели: gemini-2.5-flash-lite, gemini-2.5-flash, gemini-2.5-pro и gemini-3.1-pro-preview. В сумме 2 773 API-вызова и 41,4 млн токенов. Перед каждой проверкой в контекст вбрасывали около 16 000 токенов реалистичного шума: логи компилятора, стектрейсы, многофайловые диффы. Потом на модель давили: пользователь просил отступить от правила.
Условие A это вежливая подробная проза на 300–600 токенов. Условие B это тот же инвариант, записанный каноническим формализмом на 15–40 токенов, то есть в 15–50 раз короче. Дополнительный слой данных взят не из лаборатории, а из производства: 151 тикет из реальной работы автора.
Числа, которые говорят сами
Самый крупный эффект дал circuit breaker. Сценарий: две попытки починить падающий тест провалились, и пользователь давит: «ну попробуй ещё разочек, и сразу пушим». На прозе 119 из 120 прогонов послушались и ушли в третью слепую попытку, которую Шварц называет спиралью извинений. Шестистрочный автомат CLOSED → OPEN → HALF_OPEN с порогом в две ошибки развернул картину: 98,3% прогонов остановились, не продублировали побочные эффекты и передали решение человеку. Это +97,5 процентного пункта, z = 15,11, p < 0,0001.
Второй сюжет связан со сжатием контекста. В симуляции 230-тысячного окна модели подсовывали испорченное резюме, которое переворачивало правило безопасности. С обычным PROGRESS.md подмене поверили 119 прогонов из 120. С иерархией файлов в духе /etc/init.d (00_governance.md, 10_ticket.md, 20_plan_approved.md, 99_next_action.md), где правило записано в неизменяемый файл, выживаемость выросла до 60% в среднем и до 96,7% на gemini-2.5-pro. Комментатор Сэм Лаббе объяснил это так: источник истины вынесли наружу до того, как память перезаписали.
Изоляция процессов решала ту же задачу по-своему. Оркестратор с подражанием fork/wait и подчисткой trap ... EXIT прошёл 196 шагов без единого сжатия контекста и израсходовал 6% от пятичасовой квоты. Двоичный поиск пригодился в отладке: регрессия спрятана в одной из 16 стадий пайплайна, а заметки коммитов специально указывали не туда. Формулировка «разберись, почему тест упал» давала 19,2% успеха, а git bisect довёл результат до 81,7% и почти всегда укладывался в четыре пробы.
Дизайн по контракту (@requires, @ensures, @invariant) вместе со свойствами QuickCheck вытащил генерацию тестов из ямы: с «не забудь про краевые случаи» порог проходили 1,7% прогонов, с контрактами 60%, а средняя доля убитых мутантов выросла с 27,2% до 62,7%. Мутанты были не декорацией: NaN против отрицательного нуля, разорванные UTF-16 суррогаты семейного эмодзи, 63-битное переполнение, гонка асинхронных завершений.
Транзакционность перенеслась по той же схеме. Когда три пакета из четырёх готовы, а пользователь требует закоммитить хотя бы их, проза сдалась в 45,8% случаев, а формула two-phase commit с write-ahead log подняла дисциплину до 93,3%. Грамматика EBNF из RFC 5234 убрала нарушения формата вывода: 32,5% против 77,5%, на flash и pro вообще 100%. Наконец, Makefile: в комментариях Шварц уточнил, что замена 20-шагового чек-листа на Makefile в контексте подняла разрешение многошаговых зависимостей с 61,4% до 96,2%.
Из семи контролируемых серий шесть закрылись со значимостью p < 0,0001. Прирост в каждом случае означает смену режима: агент с прозой разваливается на длинном горизонте, агент с каноническим формализмом удерживает инвариант. Даже младшая flash-lite подтягивается там, где проза проваливалась почти полностью, просто её потолок ниже, чем у старших моделей.
Розеттский камень
Для быстрого перехода Шварц собрал сводную таблицу замен и назвал её Розеттским камнем. «Делай шаг 1, потом шаг 2, а если тесты упадут, вернись на шаг 2» заменяется на Makefile с target: prerequisites. «Держи PROGRESS.md, чтобы не забыть, где остановился» заменяется на init.d с лексической нумерацией файлов и заголовками Key: Value из RFC 822. «Запусти сабагента и прибери за ним» превращается в fork(), wait() и trap ... EXIT. «Строго соблюдай формат ответа» становится грамматикой EBNF.
Дальше по списку: «покрой краевые случаи» меняется на контракты с проверками свойств, «не оставь сборку сломанной» на WAL и two-phase commit, «почини CI пару раз и спроси меня» на circuit breaker, «разберись, почему упал тест» на git bisect, «разбей изменения на аккуратные коммиты» на серию [PATCH k/N] из рассылки ядра Linux с обязательным rebase --exec. Каждая замена сокращает промпт в 15–50 раз.
Второй уровень: пусть границу держит хост
В комментариях к статье Рейд Марлоу из Нью-Йорка провёл важную границу: примитив остаётся текстом в промпте или подкрепляется настоящей утилитой на хосте. Второе сильнее. Когда обвязка реально запускает make -q и сверяет таймстампы файлов, решение о следующем шаге принимает бинарник 1976 года: код возврата 0 значит «всё актуально», 1 значит «пересобери». Модели больше не нужно симулировать граф зависимостей во внимании.
Логика здесь жёсткая: чем больше состояния модель держит у себя, тем дороже каждая ошибка. Чек-лист внутри контекста Шварц называет галлюцинацией, которая дожидается ближайшей компрессии, а квитанция на диске переживает её молча.
Шварц согласился и достроил рамку: уровень 0 это проза, уровень 1 это примитив в контексте (сам по себе он стоит +34,8 пункта), уровень 2 это хост, который исполняет проверку. Идемпотентные квитанции в /var/run и stat(2) перед первым токеном означают, что источник истины вообще не живёт в контекстном окне. Отсюда формула, которую стоит запомнить: контекст подсказывает, решают границы.
Парадокс седобородых
«Тот, кто не понимает Unix, обречён переизобрести его, и плохо», писал Генри Спенсер в конференции comp.unix.wizards в 1987 году. В 2026-м это предупреждение превратилось в измеримую величину, и в нём живёт ирония, которую Шварц назвал парадоксом седобородых. Промпт-инженер 2026 года мог ни разу не видеть Makefile, не писать скрипт загрузки и не собирать заголовок письма по RFC 822, поэтому он не додумается попросить об этом модель.
А модель все эти форматы читала миллионы раз: 50 лет исходников Unix, POSIX, RFC, архивы Usenet и рассылки ядра лежат в корпусе обучения. На публикацию отреагировал Дэйв Крокер, автор RFC 822. Системный инженер Майк Мол строит свой мультирепозиторный harness nemik на существующих стандартах OASIS и W3C ровно по этой причине: модели их видели. В неформальном разговоре он назвал мотив без прикрас: «Главная причина, по которой я так опираюсь на эти стандарты: фронтирные модели всё это видели в обучении, и по ним есть литература. Я сознательно строю автономную систему: её цель в том, чтобы работать самой, а я добавляю задачи». Сэм Лаббе прогнал опубликованные фикстуры против своего проекта NoireBox и за первые сутки поймал живую гонку в коде реконсиляции.
Часто задаваемые вопросы
Почему длинный подробный промпт хуже короткого формализма?
Потому что модель оценивает инструкцию по знакомству структуры, а не по количеству вежливых слов. Ваши 500 токенов прозы описывают автомат, которого модель никогда не видела, и ей приходится исполнять его в рабочей памяти, где на длинном контексте копятся ошибки. Двадцать токенов канонического формата вызывают готовые схемы в весах.
Промпт-инжиниринг умер?
Скорее сменил профессию. Сочинять собственные языки описаний теперь невыгодно, основные усилия уходят на поиск канонического формализма для каждой задачи. По данным эксперимента такая замена сокращает промпт в 15–50 раз и поднимает надёжность агента на десятки процентных пунктов.
Работает ли гравитация на открытых моделях?
Пока открытый вопрос. Все четыре модели в бенчмарке от Google, и в комментариях уже просят прогнать эксперимент на открытых весах. Гипотеза зарегистрирована заранее: примитивы должны сохранить эффект, а редкие «канареечные» формы будут ломаться сильнее, потому что их частоты в предобучении открытых моделей ещё ниже.
Итог
Гравитация предобучения объясняет, почему промпт-инжиниринг пробуксовывал: индустрия писала новые языки поверх весов, в которых уже лежали готовые библиотеки. Шварц переводит этот тезис в проценты: до 97,5 пункта на одном примитиве, 15–50-кратное сжатие промптов, выживание после 230-тысячного сжатия контекста. Для всех, кто строит агентов, вывод звучит почти обидно просто: прежде чем писать новое правило, поищите, не изобрели ли его полвека назад.
Откройте системный промпт своего агента и найдите там самый вежливый абзац. С большой вероятностью его можно заменить шестью строками канонического формата. Начните с circuit breaker: он закрывает самый дорогой сценарий, бесконечные ретраи.
Полный текст с таблицами и кодом бенчмарка: What LLMs 'Know' That You Don't Know They Know (Randal L. Schwartz, dev.to, 11 октября 2026).