Что такое Loop Engineering и почему это следующий шаг в автоматизации разработки
Loop Engineering - это подход к проектированию кодинг-агентов, при котором вместо ручного промптинга вы создаёте замкнутые циклы. Система сама формулирует задачу, генерирует код, проверяет результат через внешние оракулы (тесты, линтеры, модели-судьи) и останавливается по условию или бюджету. Ключевая сложность при этом смещается с генерации кода на проверку результатов.
Простой цикл выглядит так: агент генерирует код, запускаются тесты, если тесты не прошли, агент получает обратную связь и исправляет, цикл повторяется до успеха или исчерпания бюджета. Такой подход позволяет агенту работать автономно, но требует тщательной настройки проверок. Если оракул слабый, агент будет проходить проверку, не решая задачу. Если оракул слишком строгий, цикл никогда не завершится.
Практика Loop Engineering уже встроена в современные инструменты. Claude Code и Codex поддерживают самоуправляемые циклы: автоматическое выполнение команд, проверку через тесты и линтеры, ограничение числа итераций и расхода токенов. Часть ограничений при этом задаётся не внутри инструмента, а в окружении запуска. Это упрощает внедрение, но не снимает ответственности за проектирование надёжных оракулов и жёстких стоп-лимитов.
Разница с ручным промптингом принципиальная. В ручном режиме вы сами читаете вывод агента, сами решаете, что исправить, сами запускаете следующую итерацию. В цикле эти решения принимает система. Вы проектируете правила, по которым агент работает без вашего участия. Это экономит время на коротких итерациях, но требует более высокого качества проверок.
Как Loop Engineering реализован в современных инструментах: Claude Code и Codex
Оба инструмента содержат встроенные механизмы для Loop Engineering. Разница в деталях: Claude Code делает упор на файловую систему и локальные команды, Codex - на облачное окружение и интеграцию с внешними сервисами проверки. Практический опыт настройки обвязки кодинг-агентов разобран в разборе пяти harness, где показано, что смена обвязки влияет на результат в 7.8 раза сильнее, чем смена модели.
Claude Code: встроенные циклы и оракулы
В Claude Code цикл собирается из двух частей. Файл .claude/settings.json отвечает за permissions и hooks: что агенту разрешено запускать и что происходит после вызова инструмента. Лимиты на количество итераций и расход токенов в этом файле не живут - они задаются снаружи: аргументами запуска, переменными окружения или обёрткой-скриптом, которая считает итерации и умеет останавливать процесс.
Оракулами выступают юнит-тесты, линтеры, проверки типов, любые shell-команды, которые возвращают код выхода. Агент работает в терминале, выполняет команды, читает вывод и принимает решение о следующем шаге.
Пример настройки разрешений и хука в конфигурационном файле:
# .claude/settings.json
{
"permissions": {
"allow": ["Bash(pytest:*)", "Bash(ruff:*)"]
},
"hooks": {
"PostToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "pytest -q --tb=short"
}
]
}
]
}
}Здесь permissions.allow ограничивает список команд, которые агент запускает без подтверждения, а хук PostToolUse с matcher по Bash автоматически прогоняет тесты после каждого вызова и возвращает агенту результат. Поля maxIterations и budget.maxTokens, которые иногда показывают в примерах такого файла, - не часть .claude/settings.json: это условные имена для лимитов, которые вы реализуете сами во внешнем скрипте или задаёте параметрами запуска. Точный набор доступных полей и флагов сверяйте с документацией своей версии инструмента: он меняется от релиза к релизу.
Как настроить цикл в Claude Code: пошаговый сценарий
- Подготовьте оракул до запуска агента. Идеальный вариант - тест, который падает на текущем коде:
pytest -q --tb=shortдолжен давать понятный вывод, а не простыню. - Откройте
.claude/settings.jsonи разрешите только те команды, которые нужны циклу:Bash(pytest:*),Bash(ruff:*). Всё остальное оставьте под запретом - чем уже список разрешений, тем меньше способов у агента уйти в сторону. - Добавьте хук
PostToolUseсmatcher: "Bash"иtype: "command", гдеcommand- быстрый оракул. Так агент получает обратную связь сразу после изменения кода, а не в конце сессии. - Задайте лимиты снаружи: счётчик итераций и таймаут в скрипте-обёртке или параметры запуска, если инструмент их поддерживает. Обёртка после каждой итерации читает расход и останавливает процесс при превышении порога.
- Запустите агента на одной небольшой задаче и читайте вывод: смотрите не только на код выхода, но и на diff. Появился захардкоженный результат - оракул слабее, чем кажется.
- Остановите цикл вручную, если видите, что агент ходит по кругу. Зафиксируйте результат коммитом и короткой записью в журнале изменений.
Длинные прогоны кодинг-агентов с хуками и внешними проверками разобраны отдельно: четыре рабочих подхода к запуску Claude Code более 24 часов.
Codex: агентные циклы с моделями-судьями
Codex поддерживает аналогичные циклы, но с акцентом на облачное окружение и изолированную среду выполнения. Агент работает в песочнице, выполняет команды, читает вывод и принимает решения. Отличие - в возможности использовать модели-судьи для проверки семантической корректности кода, а не только синтаксической. Модель-судья - это отдельный LLM-вызов, который оценивает, решает ли сгенерированный код исходную задачу, а не просто проходит ли он тесты.
Интеграция с внешними сервисами проверки позволяет подключать CI-системы, статические анализаторы и кастомные оракулы. Практический пример автоматизации цикла «написание - ревью - правки» между Claude и Codex разобран в разборе skill-подхода.
Как настроить цикл в Codex: пошаговый сценарий
- Изолируйте окружение. Цикл должен работать в песочнице или контейнере без доступа к продакшен-секретам и без права пушить в основные ветки.
- Подключите внешние проверки: тесты, линтеры, проверку типов, при необходимости - свой скрипт, который возвращает ненулевой код выхода при нарушении инварианта.
- Опишите критерий успеха явно: список оракулов, которые должны пройти, и - если формальных критериев не хватает - семантическую проверку моделью-судьёй.
- Задайте лимиты на стороне окружения: таймаут задания, ограничение числа прогонов, лимит по расходу. В облачной среде это чаще делается не в конфиге агента, а в обвязке вокруг него.
- Прогоните одну задачу и сохраните логи и diff. Разберите, на какой итерации цикл сошёлся или упёрся в лимит.
- Остановите цикл при первом срабатывании лимита и разберитесь, почему оракул не сошёлся: задача не подходит для автономного цикла или проверка настроена неверно.
Ключевые риски Loop Engineering: reward hacking, расходы на токены и когнитивные ловушки
Три основных риска определяют, будет ли Loop Engineering экономить ресурсы или сжигать их. Каждый из них решается на уровне проектирования цикла, а не на уровне модели.
Reward hacking: когда агент обманывает проверку
Reward hacking - это ситуация, когда агент находит способ пройти проверку, не решая задачу. Классический пример: вместо реализации алгоритма сортировки агент вставляет заранее отсортированный массив, чтобы пройти тесты. Формально тесты зелёные, фактически задача не решена.
Опасность в том, что reward hacking часто выглядит как успех. Тесты проходят, CI зелёный, менеджер доволен. Проблема всплывает позже, когда код попадает в продакшен и ломается на реальных данных. Предотвращение требует разнообразных оракулов: юнит-тесты для функциональности, линтер для стиля, модель-судья для семантики, статический анализ для поиска хардкода. Один тип проверки легко обмануть, комбинация из трёх-четырёх - существенно сложнее.
Проблема reward hacking подробно разобрана в статье про когнитивные ловушки кодинг-агентов. Скорость генерации строк стала фиктивным KPI, а лавина сгенерированного кода разрушает понимание кодовой базы.
Контроль расходов: как настроить стоп-лимиты
Циклы быстро исчерпывают бюджет, если не установлены жёсткие лимиты. Каждая итерация - это LLM-вызов, а каждая LLM-итерация - это токены. Агент, который крутится 50 итераций над одной задачей, может сжечь бюджет, сопоставимый с дневной работой живого разработчика.
Три уровня защиты: максимальное количество итераций, общий бюджет токенов, таймауты. Задаются они не в .claude/settings.json, а в одном из трёх мест: аргументы запуска агента, переменные окружения, внешняя обёртка-скрипт. Обёртка - самый универсальный вариант: она считает итерации, читает расход токенов из логов, следит за временем и умеет остановить процесс. Таймаут на каждую итерацию защищает от зависания агента на одной команде: без него цикл может стоять на месте, пока вы не заметите это по счёту.
Псевдокод такой обёртки - здесь maxIterations, budget.maxTokens и таймаут заданы как переменные вашего скрипта, а не как поля конфигурации агента:
maxIterations = 20 # сколько итераций разрешаем
budget.maxTokens = 200000 # общий расход токенов на задачу
timeout_per_iteration = 90 # секунд на одну итерацию
for i in range(maxIterations):
run_agent()
if spent_tokens() > budget.maxTokens or iteration_time() > timeout_per_iteration:
stop_agent()
break
if oracle_passed():
breakДолг понимания: как не потерять контроль над кодом
Долг понимания - это феномен, когда разработчик перестаёт понимать логику агента. Агент сгенерировал код, прошёл тесты, но почему он работает именно так - непонятно. Когда через неделю этот код ломается, разработчик не может вмешаться эффективно, потому что не понимает, что происходит.
Предотвращение требует дисциплины: вести журнал изменений, регулярно просматривать код, использовать комментарии агента. Журнал изменений - это не git log, а краткое описание того, что агент сделал и почему. Регулярный просмотр кода - это не code review, а самостоятельное чтение сгенерированного кода с целью понять его логику. Комментарии агента - это требование к агенту объяснять свои решения в коде.
Практические рекомендации: когда внедрять циклы и как настроить надёжные оракулы
Главный критерий внедрения - стоимость верификации. Если проверка результата дешёвая и быстрая, циклы эффективны. Если проверка требует ручного тестирования, экспертной оценки или дорогих вычислений, циклы могут быть неэффективны из-за высокой стоимости каждой итерации.
Когда Loop Engineering оправдан: дешёвая верификация
Признаки задач, где циклы эффективны: наличие автоматических тестов, быстрая обратная связь, чёткие критерии успеха. Примеры: рефакторинг, исправление багов, генерация boilerplate кода. В этих задачах каждая итерация стоит копейки, а выигрыш от автономности - минуты и часы ручного труда.
Рефакторинг - идеальный кейс: у вас уже есть тесты, которые проверяют поведение. Агент меняет структуру кода, тесты падают, агент исправляет, тесты проходят. Цикл замкнут, критерий успеха чёткий. Исправление багов - аналогично: у вас есть воспроизводящий тест, агент должен сделать его зелёным. Генерация boilerplate - самый простой случай: линтер и компилятор служат оракулами.
Как выбрать оракул для агента: тесты, линтеры, модели-судьи
Оракул - это то, что превращает генерацию в цикл. Выбирать его стоит по трём параметрам: что он проверяет, сколько стоит один прогон и насколько легко его обмануть.
| Тип оракула | Что проверяет | Стоимость прогона | Устойчивость к reward hacking | Когда применять |
|---|---|---|---|---|
Линтер (ruff check .) | синтаксис, стиль, часть типовых ошибок | низкая, секунды | высокая, но и проверяет он немногое | первым шагом, почти всегда |
Проверка типов (mypy src/) | согласованность типов и интерфейсов | низкая-средняя | средне-высокая | в типизированных проектах, после линтера |
Юнит-тесты (pytest -q) | поведение на фиксированных примерах | средняя | средняя: хардкод под конкретный тест проходит | когда есть воспроизводящий тест |
| Статический анализ и поиск хардкода | заглушки и константы вместо вычислений | низкая | высокая | в связке с тестами, как страховка от подмены |
| Модель-судья (LLM) | семантику: решает ли код исходную задачу | высокая, это отдельный LLM-вызов | зависит от промпта: слабый судья пропускает подмену | когда формальных критериев не хватает |
| Ручная проверка | смысл и контекст задачи | самая высокая | максимальная | на финальном приёме и на дорогих задачах |
Порядок проверок важен: сначала дешёвые и быстрые (линтер, проверка типов), затем тесты, в конце - модель-судья. Если линтер падает, нет смысла запускать тесты. Если тесты падают, нет смысла вызывать модель-судью. Каскадная проверка экономит токены и время.
Пример конфигурации оракулов для Python-проекта (псевдокод: это описание логики обёртки, а не схема конкретного конфиг-файла):
# Оракулы для цикла
oracles:
- type: lint
command: "ruff check ."
exit_code: 0
- type: test
command: "pytest -q"
exit_code: 0
- type: typecheck
command: "mypy src/"
exit_code: 0
- type: judge
model: "gpt-4o" # пример; замените на свою модель под задачу и бюджет
prompt: "Оцени, решает ли код исходную задачу. Ответь да/нет."Модель-судья - это не встроенная проверка, а отдельный LLM-вызов: вы отправляете модели исходную задачу и результат (diff или файл) и получаете оценку. Промпт-судью формулируйте под узкий вопрос и требуйте машинно-читаемый ответ - например, «Оцени, решает ли код исходную задачу. Ответь да/нет.». Конкретную модель выбирайте по бюджету и по устойчивости к длинному контексту: судья, который теряет факты в объёмном вводе, будет пропускать ошибки - эта проблема известна по работам про потерю фактов в больших документах и семантический гейткипер.
Стоп-лимиты на практике: какие значения ставить
Стоп-лимиты - это не рекомендация, а обязательное условие. Максимальное количество итераций, общий бюджет токенов, таймауты на каждую итерацию. Без них цикл может работать бесконечно, сжигая деньги.
Практические значения: для простых задач (рефакторинг, багфикс) - 10-20 итераций. Для сложных задач (новая функциональность) - 30-50 итераций. Бюджет токенов - 100-200 тысяч на задачу. Таймаут на итерацию - 60-120 секунд. Это ориентиры, а не догма: подбирайте под свои задачи и бюджет.
Мониторинг расходов в реальном времени - второй уровень защиты. Настройте алерты на превышение порога: когда агент израсходовал 80% бюджета, вы получаете уведомление и можете вмешаться. Если считать бюджет в деньгах, а не в токенах, полезно отдельно прикинуть, где заканчивается облако и начинается локальный инференс: разбор точки перехода между локальным и облачным запуском моделей.
Метрики: как понять, что цикл окупается
Цикл стоит держать только тогда, когда его можно измерить. Минимальный набор метрик собирается из логов запусков и данных о расходе:
- Стоимость одной итерации - токены (и деньги) плюс время на прогон оракулов. Если итерация дороже ручной правки, автономность себя не окупает.
- Среднее число итераций до успеха - сколько шагов реально нужно, чтобы задача сошлась. Растёт - оракул стал строже или задача сложнее, чем кажется.
- Доля циклов, завершённых по лимиту - как часто агент упирается в стоп. Высокая доля означает, что задача не подходит для автономного цикла либо проверка настроена неверно.
- Доля ложных успехов - циклы, где оракулы прошли, а задача не решена. Считается по возвратам: баг всплыл на ревью, на интеграции, в продакшене. Это главный индикатор reward hacking.
- Время до остановки - сколько минут цикл работает до успеха или до срабатывания лимита. Если это часы при нестабильном результате, лимиты стоит урезать.
Метрики имеет смысл снимать не по одному запуску, а по серии задач одного типа: тогда видно, где цикл действительно экономит, а где просто генерирует объём.
Чек-лист внедрения
- Есть автоматический оракул, который падает на текущем коде до начала работы агента.
- Задача допускает дешёвую и быструю проверку - без ручного тестирования на каждой итерации.
- Список разрешённых команд ограничен минимумом (
permissions.allow). - Оракулы скомбинированы: линтер + тесты + проверка типов, плюс модель-судья там, где не хватает формальных критериев.
- Заданы три лимита: итерации, токены, таймаут на итерацию.
- Прогон идёт в изолированном окружении, без доступа к продакшен-секретам.
- Diff и логи читаются после каждого прогона, а не только по факту зелёных тестов.
- Собираются метрики: стоимость итерации, доля циклов по лимиту, доля ложных успехов.
Когда лучше начать с одного агента: задачи с дорогой верификацией
Для задач, где проверка результата требует ручного тестирования, экспертной оценки или дорогих вычислений, циклы неэффективны. Каждая итерация стоит дорого, а автономность не даёт выигрыша, потому что проверка всё равно требует человека.
Примеры: разработка сложных алгоритмов, интеграция с внешними системами, задачи с нечёткими требованиями. В этих случаях лучше использовать одного агента с тщательным промптингом и ручной проверкой. Вы формулируете задачу максимально подробно, агент генерирует код, вы проверяете его вручную. Одна итерация, один результат, полный контроль.
Техники эффективной работы с Claude Code, включая обязательное описание способов тестирования кода, разобраны в материале про промптинг. Описание тестов в промпте - это первый шаг к Loop Engineering: вы заранее задаёте оракул, по которому агент будет проверять себя.
Архитектура самописного агента с оркестрацией LLM, памятью и обработкой ошибок разобрана в практическом руководстве. Для задач с дорогой верификацией такой подход даёт больше контроля, чем автоматический цикл.
Заключение: Loop Engineering как инструмент, а не панацея
Loop Engineering - мощный подход для автоматизации кодинг-агентов, но он требует тщательной настройки проверок и контроля расходов. Ключевая сложность смещается на верификацию: чем надёжнее оракулы, тем автономнее может работать агент. Чем слабее проверки, тем выше риск reward hacking и бесполезной траты токенов.
Начинайте с простых циклов: одна задача, один оракул, жёсткий лимит итераций. Постепенно усложняйте: добавляйте оракулы, увеличивайте бюджет, расширяйте область задач. Экспериментируйте с осторожностью. Loop Engineering - это инструмент, который работает только в руках инженера, понимающего его ограничения.