Agentic Control Loop

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

Чем он отличается от двух соседних циклов

В базе описаны два цикла, и оба про одну попытку решить задачу:

  • ReAct — цикл внутри задачи: наблюдение, рассуждение, действие, и так до ответа;
  • Reflexion — цикл между попытками: разбор неудачи переносится вперёд, следующая попытка начинается с ним.

Здесь третий класс: цикл над системой, у которого нет «ответа» и нет конца. Он запускается по расписанию, каждый раз берёт небольшой кусок работы и возвращается. Определяющая разница — возмущение: пока цикл работает, коллеги вливают свои изменения, обновляются зависимости, перегенерируется код. Свойство, которое цикл улучшает, одновременно ухудшается снаружи, и конструкция должна это выдерживать.

Пять компонентов

Компонент Что это Типовая ошибка
уставка желаемое значение свойства: инвариант («ни один модуль не импортирует через эту границу»), порог («покрытие ≥ 80% в ядре») или направление («каждый прогон — меньше вхождений») сформулирована так, что её нечем измерить
датчик чем меряется текущее состояние и разрыв до уставки: линтер, структурный поиск, проверка типов, набор тестов, запрос к телеметрии, скрипт — или агент, читающий код измерение нестабильно, и регулятор не может на нём работать
регулятор как из измерения выбирается следующее изменение: что делать сейчас, что отложить, сколько взять за раз сразу делается умным; его настраивают по выходу цикла, поэтому начинают с простого
исполнитель что применяет изменение: кодовый агент с умением проекта, открывающий пул-реквест ему не заданы образцы того, как выглядит правильное изменение
возмущение что меняет систему снаружи цикла: чужие коммиты, обновления зависимостей, генерируемый код, нестабильные тесты не названо, и тогда цикл считается сломанным при первом откате прогресса

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

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

Четвёртый критерий выбора датчика

Датчик обычно выбирают по трём свойствам: устойчивость измерения, стоимость прогона, повторяемость. Есть четвёртое, которое нельзя измерить — только заметить при проектировании: можно ли этот датчик тихо отключить.

Вопрос существенный именно здесь, потому что исполнитель цикла — агент, и у него есть все права, чтобы отключение выполнить. Правило то же, что в цикле починки (AI Native SDLC, Generator Evaluator): тому, кто исправляет систему, нельзя позволять ослаблять измерение, по которому его исправление оценивают. Датчик, выключаемый строкой в конфиге, которую агент имеет право править, измеряет не систему, а собственную включённость.

Цикл и демпфер — два механизма на одно свойство

Цикл уменьшает уже имеющиеся нарушения. Он не мешает появляться новым — и на этом проигрывает возмущению: пока он чинит по одному за прогон, снаружи добавляют по два.

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

  • цикл отвечает за то, чтобы величина убывала;
  • демпфер отвечает за то, чтобы она не росла.

Это ратчет, собранный из двух разных механизмов, и ни один из них в одиночку свойство не держит. Обратная сторона того же — обратный ход ратчета в Agent First Repository: там записано, при каких условиях ограничение снимается.

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

Ограничение потока: цикл не должен обгонять приёмку

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

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

Это вторая половина того, что записано про потолок размера изменения (Agent Code Review). Потолок делает единичное изменение пригодным к чтению, но не увеличивает объём внимания; ограничение потока управляет тем, сколько таких изменений одновременно ждёт этого внимания. Оба ограничения выведены из одной и той же ёмкости приёмки, и без второго первое просто откладывает затор.

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

Память цикла — не журнал прогонов

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

Различение содержания здесь жёсткое:

Туда идёт Туда не идёт
постоянные исключения из области действия разовые указания на этот прогон
известные ложные срабатывания датчика журнал того, что делалось в прошлые разы
обратная связь ревьюера, меняющая будущий отбор пересказ уже применённых изменений

Критерий один: запись обязана менять будущее поведение. Всё, что описывает прошлое, относится к журналу и в этот файл не попадает — иначе он растёт монотонно и вытесняет собой то, ради чего заведён (Memory Write Policy).

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

Каждый компонент запускается руками до того, как попадёт в расписание

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

Требование выглядит процедурным, но у него техническая причина: сломавшийся плановый цикл отлаживать нечем. Его прогон идёт в чужой среде, по расписанию, без человека рядом, и различить «датчик ничего не нашёл» и «датчик не запустился» по пустому результату невозможно (Unknown Not A Value).

Границы

  • Это не способ сделать разовый рефакторинг. Контур окупается там, где свойство надо удерживать против возмущения; для однократной задачи он дороже прямого изменения.
  • Уставка обязана быть измеримой. Свойство, для которого не нашлось датчика, контуром не управляется — получается агент, запускаемый по расписанию, и это другой, гораздо более слабый механизм.
  • Регулятор — то, что настраивают, а не то, что проектируют один раз. Его качество видно только по выходу цикла, поэтому первая версия делается простой намеренно.

Связано с

  • ReAct — цикл внутри одной задачи; здесь цикл над системой
  • Reflexion — цикл между попытками одной задачи и его потолок
  • Agent Code Review — потолок размера изменения, вторая половина того же ограничения по ёмкости приёмки
  • Agent First Repository — устройство репозитория, в котором такой цикл работает
  • AI Native SDLC — цепочка артефактов одного изменения; контур гоняет её по расписанию
  • Generator Evaluator — почему исправляющему нельзя ослаблять измерение
  • Memory Write Policy — критерий «меняет будущее поведение» как условие записи
  • Unknown Not A Value — пустой результат датчика не отличается от незапустившегося датчика
  • Online Quality Signal — соседний контур обратной связи, замкнутый внутри одного запроса, а не по расписанию
  • Harness Optimization — когда наблюдение вообще достойно превращения в правку