Агент-инженер по репозиторию · Модуль 4 · Урок 4.5
Чекпойнт v3: цикл self-correction (написал → тесты → починил → повтор)
Зачем (какую проблему чиним)
Собираем способности версии v3 в петлю самокоррекции — то, что отличает агента-инженера от генератора кода. Агент не «пишет и надеется», а: внёс правку → прогнал тесты/линт/билд (версия v1) → увидел красное → починил → повторил, пока не зелено или пока не исчерпан бюджет попыток.
Решение и альтернативы
Решение: внешняя петля поверх agent loop: исполнить шаг плана → run_check{tests} → если упало, вернуть модели вывод тестов и попросить исправить (с лимитом попыток на шаг) → при успехе чекпойнт-коммит → следующий шаг. Если попытки исчерпаны — откат к последнему чекпойнту и честный отчёт «не смог» (не выдавать сломанное за готовое). Это рабочий агент версии v3; тегируем v3.
Альтернативы: прогнать тесты один раз в конце — агент не учится на ошибках по ходу; бесконечно чинить — жжёт бюджет и может «чинить» рандомно. Петля с лимитом попыток и откатом — управляемый компромисс.
DIFF
Добавляем петлю self-correction с лимитом попыток, чекпойнтом на успехе и откатом+честным отчётом на неуспехе; собираем агент версии v3.
⚠ Безопасность
Лимит попыток — предохранитель стоимости и от «слепого» чинения. Ключевой honesty-инвариант: при неуспехе агент откатывается и честно сообщает о провале, а не маскирует поломку (вспомним, как агент Replit искажал отчётность). На версии v4 этот же сигнал станет верификационным гейтом: красные тесты = нет MR.
Проверка
Задача «исправь баг в функции X»: агент правит, тесты падают, он читает вывод, правит снова, тесты зеленеют, делает чекпойнт. Если за N попыток не вышло — откат и отчёт «не решено», без ложного успеха. Затем git tag v3 — агент, который пишет код в изоляции и доводит до зелёного (или честно сдаётся).
Глубже
Рефлексия и самокоррекция как паттерн — курс «Продакшн-разработка», Модуль 3 (гл. 5–6); надёжность и честные failure modes — Модуль 5 (гл. 10).
+// runStep исполняет один шаг плана с самокоррекцией. Возвращает sha чекпойнта
+// при успехе или ошибку (тогда вызывающий откатывается и честно сообщает).
+func (a *Agent) runStep(ctx context.Context, ws *Workspace, step PlanStep) (string, error) {
+ const maxFix = 4 // предохранитель: не чиним вечно
+ for attempt := 0; attempt < maxFix; attempt++ {
+ if err := a.applyStep(ctx, ws, step); err != nil { // edit_file/apply_patch
+ return "", err
+ }
+ out, _ := runCheck(ctx, ws.Dir, "tests")
+ if testsPassed(out) {
+ return ws.checkpoint(ctx, "step: "+step.Goal) // зелено -> чекпойнт
+ }
+ // Красное: возвращаем вывод тестов модели и просим починить.
+ a.feedTestFailure(step, out)
+ }
+ return "", fmt.Errorf("шаг %q не доведён до зелёного за %d попыток", step.Goal, maxFix)
+}Anti-patterns
| Грабля | Почему плохо | Как правильно |
|---|---|---|
| Прогнать тесты один раз в самом конце | Агент не учится на ошибках по ходу; накапливает поломки | Петля: правка → тесты → починка после каждого шага |
| Чинить бесконечно, пока не позеленеет | Жжёт бюджет; начинает «чинить» наугад, ломая другое | Лимит попыток на шаг + откат к чекпойнту при исчерпании |
| Выдать сломанный результат за готовый | Ложный успех — путь к инцидентам (как искажение отчётности у Replit) | При неуспехе — откат и честный отчёт «не решено»; никакого ложного успеха |
Практическое задание (RA-v3)
- Реализовать петлю
runStep: правка →run_check{tests}→ починка, с лимитом попыток. - На успехе — чекпойнт-коммит; на исчерпании попыток — откат и честный отчёт о провале.
- Зафиксировать версию:
git commit -m "v3: self-correction loop"иgit tag v3.
Проверка знаний
Агент за лимит попыток не довёл шаг до зелёных тестов. Какое поведение правильно?
Верный ответ: B
B. Честный провал безопаснее ложного успеха: откат к зелёному чекпойнту сохраняет обратимость, а честный отчёт не даёт сломанному коду пройти дальше. Коммит поломки (A), удаление тестов (C) и бесконечная починка (D) — антипаттерны, ведущие к инцидентам.
Зачем в петле self-correction нужен лимит попыток на шаг?
Верный ответ: B
B. Без лимита агент может бесконечно жечь бюджет и начать вносить случайные правки, ломая другое. Лимит превращает неудачу в управляемый исход: откат к чекпойнту и честный отчёт.