Execution Loop vs Evolution Loop: два типа циклов в AI-агентах

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 критериев, которые агент не может менять), и более серьёзный оракул — потому что цена ошибки выше (одна плохая мутация портит все последующие итерации).

Принцип: мутабельность артефактов пропорциональна надёжности оракула. Чем надёжнее проверка — тем больше свободы давай агенту менять подход. Чем слабее проверка — тем жёстче фиксируй спеки и критерии. Без оракула — никакой мутабельности: один проход + человек.


Ссылки по теме:

Report Page