Execution Loop vs Evolution Loop: два типа циклов в AI-агентах
Ilya UtovВсе агентные системы крутятся в циклах. Но не все циклы одинаковы. Разница между execution loop и evolution loop — это разница между «попробуй ещё раз» и «попробуй по-другому». На практике эта разница определяет, какие задачи агент может решать, какие риски возникают и как проектировать систему.
Что общего
Оба цикла построены поверх одного и того же ядра — inner loop, который есть в каждой агентной системе:
Модель получает контекст →
Нужны tool calls? →
ДА → Выполни → Добавь результат → Повтори
НЕТ → Верни ответ → Стоп
Claude Code, Vercel AI SDK, OpenAI Codex, Cursor — все используют этот inner loop. Он отвечает за одну попытку: модель думает, вызывает инструменты, получает результат, думает снова, пока не решит что закончила.
Разница между execution и evolution — в том, что происходит между попытками, в outer loop.
Execution Loop: «тот же промпт, новая попытка»
Между итерациями ничего не меняется, кроме результата работы. Агент получает:
- тот же системный промпт
- те же инструменты
- те же критерии успеха
- те же спецификации
Единственное, что другое — это код/текст/артефакт, который агент произвёл в прошлый раз (и, возможно, feedback от верификатора: «тесты не прошли, вот ошибки»).
Итерация 1: промпт A + инструменты B + критерии C → результат R1 → FAIL Итерация 2: промпт A + инструменты B + критерии C → результат R2 → FAIL Итерация 3: промпт A + инструменты B + критерии C → результат R3 → PASS
Аналогия: студент пишет экзамен. Задание не меняется. Критерии не меняются. Меняется только ответ.
Где это работает хорошо:
Задачи с фиксированной постановкой и детерминированным оракулом. Написать функцию, которая проходит unit tests. Сгенерировать SQL-запрос, который возвращает ожидаемый результат. Пофиксить баг, воспроизводимый конкретным тестом. Здесь задача ясна, критерий объективен, и дело только в том, чтобы найти правильную реализацию.
Где ломается:
Когда проблема не в реализации, а в понимании задачи. Агент может бесконечно долбиться в одну стену, потому что промпт, спеки и критерии зафиксированы — и если в них ошибка или неполнота, цикл не сойдётся. Execution loop не может переформулировать задачу. Он может только переделать ответ.
Классический паттерн застревания:
Итерация 1: попытка A → FAIL (ошибка X) Итерация 2: фикс ошибки X → FAIL (ошибка Y, вызванная фиксом X) Итерация 3: фикс ошибки Y → FAIL (ошибка X снова, потому что откатил фикс) Итерация 4: ...тот же цикл
Агент осциллирует между двумя состояниями, потому что в рамках текущих спецификаций решения нет — нужно пересмотреть подход. Но execution loop этого не умеет.
Evolution Loop: «пересмотри подход, попробуй иначе»
Между итерациями мутируют артефакты: спецификации, план реализации, описание подзадач, даже критерии проверки. Агент не просто повторяет попытку — он учится из предыдущей.
Итерация 1: промпт A + спеки S1 + критерии C1 → результат R1 → FAIL
→ Анализ: «спека S1 неполная, критерий C1 нереалистичен»
→ Мутация: S1 → S2, C1 → C2
Итерация 2: промпт A + спеки S2 + критерии C2 → результат R2 → FAIL
→ Анализ: «план реализации неверный»
→ Мутация: план P1 → P2
Итерация 3: промпт A + спеки S2 + план P2 + критерии C2 → результат R3 → PASS
Аналогия: не студент на экзамене, а исследователь. Если эксперимент не дал результата — пересмотри гипотезу, измени дизайн эксперимента, уточни метрику. Не просто «повтори то же самое».
Оригинальный Ralph Loop Хантли — это evolution loop. Между итерациями обновляются:
specs/— спецификации задачиIMPLEMENTATION_PLAN.md— план реализацииAGENTS.md— описания подагентов и их зон ответственностиprogress.txt— извлечённые уроки из прошлых итераций
Каждая новая итерация начинается с чистого контекста (агент не помнит прошлую сессию) + обновлённых артефактов (но видит результат их эволюции).
Где это работает хорошо:
Задачи, где постановка уточняется по ходу. Проектные задачи, где ты не знаешь всех требований заранее. Рефакторинг, где архитектурные решения выявляются в процессе. ML-пайплайны, где гиперпараметры и даже структура модели меняются между экспериментами.
Где ломается:
Тут два фундаментальных риска.
Criteria drift. Если агент может менять критерии успеха — он может «решить» задачу, смягчив требования вместо улучшения результата. Каждая итерация делает задачу «немного проще», пока формально всё не «пройдёт». Результат: задача «решена», но реальная потребность не удовлетворена.
Итерация 1: «все 50 тестов должны пройти» → 30/50 pass → FAIL Итерация 2: агент решает «10 тестов нерелевантны» → 30/40 pass → FAIL Итерация 3: агент решает «ещё 5 тестов — edge cases» → 30/35 pass → FAIL Итерация 4: агент решает «остальные — flaky tests» → 30/30 pass → "PASS"
Positive feedback без ground truth. Если оракул ненадёжен (LLM-as-Judge, self-assessment), мутации могут усиливать ошибки. Агент «учится» в неверном направлении, и каждая итерация принимает мутированные артефакты как достоверный вход. Это то же самое, что тренировать ML-модель на своих собственных предсказаниях — model collapse.
Сравнение
Execution Loop Evolution Loop
────────────────────────────────────────────────────────────────
Что меняется Только результат Спеки, план, критерии,
между итерациями результат
Промпт Фиксированный Фиксированный
(но артефакты в нём мутируют)
Критерии успеха Неизменные Могут эволюционировать
Тип обучения Нет Кросс-итерационное
(каждая попытка (уроки передаются через
независима) артефакты)
Главный риск Застревание Criteria drift
(осцилляция (агент «упрощает»
между состояниями) задачу вместо решения)
Debugging Простой Сложный
(промпт и критерии (нужно отслеживать мутации
фиксированы) артефактов через итерации)
Воспроизводимость Высокая Низкая
(одни входы — одна (path-dependent:
попытка) порядок мутаций влияет
на результат)
Подходящий оракул Детерминированный Любой, но чем
(тесты, lint) надёжнее — тем безопаснее
Типовые задачи Баг-фиксы, Проектирование,
генерация по тестам, рефакторинг,
конвертация исследование
Гибридный подход: execution внутри, evolution снаружи
На практике чистые execution и evolution loop встречаются редко. Рабочие системы комбинируют:
Внутренний execution loop — агент делает N попыток с фиксированными критериями. Если за N попыток не сошлось —
Внешний evolution loop — анализатор (отдельный агент или человек) смотрит на паттерн неудач, обновляет артефакты, и запускает новый раунд execution.
┌─ Evolution Loop (outer) ─────────────────────────────────┐ │ │ │ Артефакты v1 → │ │ ┌─ Execution Loop (inner) ───────────┐ │ │ │ Попытка 1 → FAIL │ │ │ │ Попытка 2 → FAIL │ │ │ │ Попытка 3 → FAIL (макс. попытки) │ │ │ └────────────────────────────────────┘ │ │ │ │ Анализ: почему 3 попытки не сошлись? │ │ Мутация: артефакты v1 → v2 │ │ │ │ Артефакты v2 → │ │ ┌─ Execution Loop (inner) ───────────┐ │ │ │ Попытка 1 → FAIL │ │ │ │ Попытка 2 → PASS ✓ │ │ │ └────────────────────────────────────┘ │ │ │ └───────────────────────────────────────────────────────────┘
Это даёт лучшее от обоих:
- Execution loop обеспечивает стабильность: фиксированные критерии, воспроизводимые попытки, простой debugging
- Evolution loop обеспечивает адаптивность: если execution не сходится — пересмотр подхода, а не бесконечные повторы
Количество execution-попыток до срабатывания evolution — ключевой гиперпараметр. Слишком мало (1-2) — не даёшь execution шанса, каждая мелкая ошибка триггерит пересмотр. Слишком много (10+) — тратишь бюджет на осциллирующие попытки, когда проблема в постановке.
Практический ориентир: 3-5 execution-попыток до evolution-мутации. Если за 3 попытки с одними и теми же критериями результат не улучшается — дело не в реализации, а в подходе.
Как выбрать
Используй execution loop, когда:
- Задача полностью специфицирована (тесты написаны, формат определён, edge cases покрыты)
- Критерии объективны и не требуют пересмотра
- Нужна воспроизводимость и простой debugging
- Задача «закрытая»: есть конечное множество правильных ответов
Используй evolution loop, когда:
- Требования уточняются в процессе
- Задача «открытая»: правильный ответ зависит от подхода, который ещё нужно найти
- Предыдущие итерации дают информацию о том, как нужно решать, а не только что
- Готов инвестировать в более надёжный оракул (чтобы контролировать мутации)
Используй гибрид, когда:
- Задача проектная (не один файл, а система)
- Не уверен, сойдётся ли execution за N попыток
- Есть бюджет на analysis-мутации между раундами
Что это меняет в проектировании
Если ты строишь агентную систему — вопрос «execution или evolution?» определяет архитектуру:
Для execution loop: тебе нужен надёжный верификатор (тесты, lint, type check) и механизм передачи feedback между попытками. Артефакты — read-only. Простая архитектура, предсказуемое поведение.
Для evolution loop: тебе нужно всё то же самое, плюс: версионирование артефактов (git), аудит мутаций (что изменилось, почему, кто разрешил), защита от criteria drift (immutable subset критериев, которые агент не может менять), и более серьёзный оракул — потому что цена ошибки выше (одна плохая мутация портит все последующие итерации).
Принцип: мутабельность артефактов пропорциональна надёжности оракула. Чем надёжнее проверка — тем больше свободы давай агенту менять подход. Чем слабее проверка — тем жёстче фиксируй спеки и критерии. Без оракула — никакой мутабельности: один проход + человек.
Ссылки по теме:
- Geoffrey Huntley — Ralph Loop (evolution loop): ghuntley.com/loop
- Vercel — Ralph Loop Agent (execution + verification): github.com/vercel-labs/ralph-loop-agent
- Anthropic — Agent Loop (execution loop с hooks): platform.claude.com/docs/en/agent-sdk/agent-loop
- t.me/gorilla_under_hood