Технологии

Петля Ральфа Виггама: почему системы сходят с ума «с нуля»

Поделиться:

Если вы пользовались ИИ-агентом для написания кода дольше пары часов, вы знакомы со «стеной»: агент делает видимый прогресс, затем застревает — и в итоге вы сами доделываете и латаете работу.

Как это часто бывает с инженерами по ИИ, для решения этой проблемы возник шаблон: просто зациклить агента на внешних проверках, пока работа действительно не будет сдана.

Подход стал настолько популярен, что получил имя — Ральф Виггам.

The Ralph Wiggum Loop, From First Principles
через dev.to

И мем прижился, потому что подход работает. К концу 2025 года Anthropic формализовала его в официальный плагин Claude Code.

Ральф представляет собой сдвиг в том, как разработчики используют существующие инструменты. Вместо того чтобы относиться к ИИ-системам как к интерактивным помощникам, их запускают как долгоживущие процессы, управляемые тестами, линтерами и явными условиями остановки.

Итак, это короткое практическое руководство. Мы посмотрим, что такое Ральф на самом деле, почему он работает, как он распространился и что изменилось, когда его превратили в продукт.

Что такое «Ральф» на самом деле?

По своей сути, Ральф — это следующее: запускайте агента в цикле, проверяйте его вывод с помощью чего-то, что не может лгать, например теста, линтера, проверки типов; и продолжайте цикл, пока проверка не пройдёт.

Вот и всё.

Исходный пример, которым поделился Джеффри Хантли в июле 2025, был намеренно простым:

while :; do cat PROMPT.md | npx --yes @sourcegraph/amp ; done

Варианты для Claude Code следуют той же схеме, просто с большим количеством защитных механизмов. Но принцип не меняется: подавайте зафиксированный промпт агенту снова и снова, пока внешняя реальность не скажет, что вы закончили.

The Ralph Wiggum Loop, From First Principles

Сам цикл почти не имеет значения, важнее контракт:

  • Состояние хранится в репозитории: Файлы, диффы, логи, история git; всё долговременное хранится здесь.
  • Завершение определяется вне модели: Тесты, линтеры, проверки типов; агент не решает, когда он закончил; это делает обвязка.
  • Агент заменяем: Это рабочий, который вызывается многократно, пока шлюз не пройден; если он сегодня медленный или глупый, замените его завтра на что-то быстрее.

Если смотреть так, Ральф становится принципом проектирования: перестаньте спрашивать модель, знает ли она, когда всё готово. Перестаньте ожидать, что она будет помнить ограничения между сбросами контекста.

Вместо этого стройте систему так, чтобы модель не могла ошибаться таким образом.

Получайте контент прямо в ваш почтовый ящик

Подпишитесь сейчас, чтобы получать все последние обновления напрямую на вашу почту.

Почему этот цикл жизнеспособен?

Несколько причин:

1. Окна контекста ведут себя как буферы

Хантли часто описывает окна контекста в терминах низкоуровневого программирования:

«Думайте как инженер на C или C++. Окна контекста — это массивы».

У них фиксированный размер; они скользят; перезаписывают; забывают.

Долгие сессии предполагают преемственность, которой не существует, поэтому обращение с буфером как с долговременной памятью ведёт к дрейфу, пропущенным ограничениям и нестабильному поведению.

Ральф принимает реальность системы. Вместо того чтобы делать вид, что окно контекста стабильно, он рассматривает его как одноразовое.

Рабочее пространство агента сбрасывается между итерациями, в то время как долговременное состояние сохраняется на диске. Репозиторий накапливает истину по всем запускам. Это делает перезапуск агента обычной процедурой, а не расточительством; каждый цикл начинается заново, но строится на том, что действительно сохранилось.

2. Внешние проверки превосходят внутренние рассуждения

Многие фреймворки для агентов реагируют на неудачу добавлением структуры внутри модели: планировщиков, резюме, внутреннего состояния, циклов рефлексии.

Ральф оставляет интеллект вне агента. Он полагается на:

  • Зафиксированную спецификацию, которая не дрейфует
  • Конкретные свидетельства последнего запуска
  • Детерминированный шлюз, оценивающий успех

Агент не решает, когда работа закончена — это делает обвязка.

The Ralph Wiggum Loop, From First Principles

Вот почему Ральф преуспевает в механической работе: рефакторинге, миграциях, очистке, задачах на соответствие… Везде, где успех можно измерить скриптом, а не суждением, итерации становятся надёжными.

Модель не может увильнуть от требований, потому что требования живут вне её рассуждений.

3. Сжатие размывает ограничения

Одна из повторяющихся критик Хантли направлена на суммаризацию и сжатие.

Когда система просит модель решить, что достаточно важно, чтобы оставить, информация теряется — ограничения смягчаются, крайние случаи исчезают, фиксаторы выпадают.

Ральф обходит это, сохраняя входные данные буквальными:

  • Спецификации остаются дословными вместо того, чтобы быть суммаризированными, 
  • Вывод ошибок остаётся сырым и нефильтрованным; и 
  • Курирование памяти никогда не перемещается в модель.

Обвязка сохраняет точность; агент работает внутри неё, ограниченный тем, что есть на самом деле, а не тем, что модель считает важным.

Итак, как распространилась эта идея?

Хронология довольно сжатая.

  • 19 июня 2025: На митапе в Сан-Франциско с участием около 15 инженеров, обсуждавших агентное программирование, Хантли демонстрирует Ralph, Cursed (язык программирования, который создаёт Ralph) и ведёт трансляцию автономного кодинга всю ночь, пока сам спит в Австралии. В комнате завязывается тревожный разговор о том, как легко скопировать 80–90% SaaS-продукта и как много видов работы вот-вот исчезнут полностью.
  • Июль 2025: Хантли публикует оригинальный пост в блоге с базовой структурой bash-цикла. В материале приводится простой пример промпта и содержится просьба: «вы, вероятно, могли бы найти репозиторий cursed lang на GitHub, если бы поискали, но, пожалуйста, пока не делитесь им».
  • Август 2025: Проходит хакатон YC agents — команды запускают Claude Code в непрерывных циклах. Результат — 6 репозиториев, созданных за ночь. Декстер Хорти запускает экспериментальный цикл Ralph для рефакторинга кодовой базы на React. За 6 часов он разрабатывает полный план рефакторинга и выполняет его.
  • Сентябрь 2025: Хантли официально представляет Cursed Lang — язык программирования, созданный Ralph. Он существует в трёх реализациях (C, Rust, Zig), имеет стандартную библиотеку и компилятор второй стадии, написанный на самом Cursed.
  • Октябрь 2025: Декстер представляет Ralph на встрече Claude Code Anonymous в Сан-Франциско. Вопрос из аудитории: «Так вы это рекомендуете?» Его ответ: «Глупые вещи могут работать удивительно хорошо. Чего тогда можно ожидать от умной версии?»
  • Декабрь 2025: Anthropic выпускает официальный плагин Ralph Wiggum. Плагин берёт bash-цикл Хантли и формализует его с помощью Stop Hooks и структурированных данных об ошибках.
  • Январь 2026: Хантли и Хорти проводят подробное обсуждение на YouTube, сравнивая оригинальную реализацию Ralph на bash-циклах с реализацией от Anthropic на стоп-хуках.

Bash-цикл Ralph против плагина Ralph

Оригинальный Ralph — это bash-цикл из 5 строк. Вы передаёте файл с промптом, отправляете его в Claude, проверяете, проходит ли вывод ваши тесты, и повторяете, пока не пройдёт. Всё живёт на диске, всё на виду. Если что-то ломается, вы видите точную причину.

Плагин от Anthropic инвертирует эту модель: вместо запуска цикла извне, он устанавливает Stop Hook внутри вашей сессии Claude. Когда Claude пытается выйти, хук перехватывает управление, проверяет ваши условия завершения и, если работа не закончена, снова подаёт тот же промпт. Файлы, изменённые Claude, остаются на месте.

История Git тоже остаётся, но механизм управления теперь непрозрачен — скрыт в файле состояния markdown, чувствителен к разрешениям, его легко сломать, если не знать, что делаешь.

Это классический компромисс абстракции.

Плагин снижает порог вхождения. Вам не нужно писать bash и не нужно думать о циклах. Но по мере того как механизм скрывается, исходная идея становится легче для упущения.

Версия на bash-циклах заставляет вас проектировать механизм управления. Версия с плагином позволяет пропустить этот шаг, что хорошо до тех пор, пока вы не столкнётесь с крайним случаем и не сможете увидеть, что на самом деле происходит.

Декстер Хорти протестировал её и обнаружил, что она вылетает загадочным образом, если не использовать «--dangerously-skip-permissions». Плагин устанавливает хуки в странных местах, использует непрозрачные файлы состояния, и если вы удалите markdown-файл до остановки, вы сломаете Claude в этом репозитории, пока полностью не отключите плагин.

Итак, в чём урок? Оба работают, но по разным причинам. Bash-цикл работает, потому что он простой и прозрачный. Плагин работает, когда абстракция не скрывает что-то критически важное.

Что вы узнаёте, запуская его?

Ralph предполагает дистанцию между человеком и агентом. Вы не сидите в сессии и не направляете его. Вместо этого вы запускаете его, уходите, проверяете артефакты, когда он закончит, и корректируете ограничения для следующей итерации.

Взаимодействие происходит на уровне механизма управления — промпт, тесты, условия остановки — а не внутри диалога.

Со временем проявляется паттерн: большинство неудач — это не ошибки модели, а ошибки механизма управления.

Спецификация была расплывчатой, тест слишком широким, или условие завершения фактически не описывало, что значит «готово».

Как только вы увидите это несколько раз, ваша интуиция сместится. Вы перестанете спрашивать: «Как сделать Claude умнее?» и начнёте спрашивать: «Как сделать ограничения жёстче?»

Вот где спецификации становятся критически важными.

Спецификации как поверхности управления

Хантли переосмысливает спецификации не как документацию, а как фиксированные управляющие входные данные. Вы создаёте их через диалог с Claude, намеренно редактируете, пока они не станут точными, а затем фиксируете. После фиксации они не меняются в течение всего цикла.

Это важно, потому что спецификации делают три вещи одновременно:

  1. Ограничивают то, что может изобрести агент: Без чёткой спецификации Claude будет добавлять защитные слои, абстракции или функции, о которых вы не просили, расширяя объём работы с каждой итерацией. 
  2. Служат якорем для поиска и извлечения информации: Чтобы агент не галлюцинировал новые требования.
  3. Стабилизируют поведение между запусками: Каждая итерация решает одну и ту же проблему, а не слегка отличающуюся её интерпретацию.

Если ваша спецификация расплывчата в определении «готово», агент будет интерпретировать её по-разному в каждом цикле. Вы получите дрейф, раздувание функционала и итерации, которые противоречат друг другу.

Как ответственно запускать цикл?

Минимальная настройка Ralph часто выглядит так:

MAX_ITERS=30
for i in $(seq 1 $MAX_ITERS); do
  cat PROMPT.md | claude
  if ./ci.sh; then exit 0; fi
done
exit 1

Механика цикла гораздо менее важна, чем правила вокруг него:

  • Держите спецификацию неизменной; не корректируйте её в середине цикла на основе действий Claude. 
  • Выражайте условие завершения в виде исполняемых проверок.
  • Применяйте ограничения на количество итераций и время, чтобы цикл не мог работать вечно и сжигать ваш бюджет токенов. 
  • Сохраняйте логи и диффы, чтобы вы могли проанализировать, что пошло не так, если это произойдёт. 

Кроме того, эксплуатационная практика выявила несколько важных эвристик:

  • Предпочитайте небольшие, регулярные изменения большим рефакторингам, потому что крупные изменения умножают ошибки и их сложнее отлаживать. 
  • Перезапускайте на актуальной ветке main вместо перебазирования, потому что конфликты слияния тратят итерации впустую.
  • И избегайте использования Ralph для исследовательской работы, потому что если у вас нет чётких acceptance-тестов, вы просто получите хаотичный цикл, который изобретает то, о чём вы не просили.

Ограничение — это и есть фича.

Цикл и есть урок

По мере роста популярности Ralph появились его вариации. Некоторые команды строили структурированные внешние циклы вокруг агентов, вызывающих инструменты. Другие добавляли отдельные компоненты верификации: другая модель, которая проверяет вывод рабочего агента, прежде чем цикл решит завершиться. Эти расширения работают, да, но только если они уважают исходную идею.

Правило простое: верификация должна оставаться детерминированной, а сводки никогда не должны заменять первичные входные данные.

  • Если вы добавляете верификатор, он должен проверять конкретные вещи: тесты проходят, линтер завершается чисто, git diff соответствует ожиданиям. 
  • Если вы добавляете структурированные внешние циклы, они всё равно должны видеть сырой вывод и сырые логи, а не прибранную сводку о том, что пошло не так. 

Ключевой аргумент Хантли заключается в том, что разработка программного обеспечения как профессия фактически мертва, но software engineering — практика построения систем хорошо — живее всех живых.

Получайте контент прямо в свой почтовый ящик

Подпишитесь сейчас, чтобы быть в курсе всех последних обновлений, доставляемых прямо на вашу почту.