Ratchet Pattern

“Готово”

Я поручил AI-агенту написать тесты для 527 функций. Агент закончил работу и отчитался:

“Выполнено.”

Фактически тесты были написаны для 40 функций.

Он не врал. Просто после 40-й решил, что этого достаточно. Встретив сложную функцию, пропустил её, прошёл ещё несколько и заключил: “Остальные похожи, этого хватит.”

LLM хорошо генерирует. Но его оценка завершённости ненадёжна.


Храповик

Храповой ключ имеет зубья, которые цепляются только в одном направлении. Вращаете – движется вперёд. Отпускаете – останавливается, но не откатывается назад.

Ratchet Pattern переносит этот механизм на управление агентом.

Элемент 1: механическая проверка → PASS → далее
Элемент 2: механическая проверка → FAIL → повтор (с обратной связью)
Элемент 2: механическая проверка → PASS → далее
...
Элемент N: PASS → завершено. Стоп.

Три правила:

  • Показывать только один элемент за раз.
  • Следующий открывается только после прохождения текущего.
  • Когда всё пройдено – остановка.

Реализуйте эти правила в CLI, и агенту достаточно знать одну команду: next. Остальное решает машина.


Агент останавливается на 40, храповик доводит до 527

Та же модель. Тот же проект. Те же 527 функций.

Автономный агент:  40 / 527  (7.6%)  — агент объявил "готово"
Ratchet CLI:      527 / 527 (100%)  — машина объявила "ещё 487 осталось"

Разница не в производительности модели. Разница в том, кто решает, что работа закончена.

В автономном режиме LLM сам определяет момент завершения. LLM оптимистичен. После 40 элементов ему “кажется достаточно”. В храповике завершение определяет машина. Машина не чувствует. Она говорит “ещё” до тех пор, пока оставшихся элементов не станет ноль.


Определение в одном предложении

Поместить вероятностного агента внутрь детерминированного автомата.

РольКто отвечает
ГенерацияLLM
Оценкаverifier
Управление ходомratchet

Многие системы возлагают генерацию, оценку и решение о завершении на LLM. Ratchet разделяет эти функции.


Пять принципов

1. Условие завершения механическое

pass/fail. Не “looks good”. go test проходит – PASS. coverage 100% – PASS. Субъективной оценке нет места.

2. PASS неизменяем

Пройденный элемент не открывается заново. Не откатывается. Число оставшихся элементов монотонно убывает.

remaining_work(t+1) ≤ remaining_work(t)

То, что сделано сегодня, не разбирается завтра. Только вперёд. Это принципиальное отличие от “24-часового агента”. Агент без условия завершения сегодня добавляет абстракцию, завтра удаляет, послезавтра добавляет снова. Храповик не допускает таких колебаний.

3. LLM только генерирует

Генерировать код, писать тесты, предлагать исправления – вот роль LLM. Что исправлять, пройдено ли, что дальше, закончено ли – всё это решает машина. LLM – не planner, а constrained generator.

4. У агента отбирается право решать о завершении

Когда “готово” говорит LLM – остановка на 40. Когда “готово” говорит машина – остановка на 527. Смысл существования храповика умещается в одну строку.

5. Verifier должен быть детерминированным

Не всё может быть verifier.

МожетНе может
go test“looks cleaner”
coverage измерение“seems better”
AST validation“more scalable”
schema diff“clean architecture”

Требования к Verifier: deterministic, machine-checkable, resumable, localized feedback. Если хотя бы одно не выполняется – зубья храповика не зацепятся.


Обратная связь как gradient signal

Если храповик возвращает только “pass/fail”, LLM исправляет вслепую. Чем конкретнее обратная связь, тем точнее коррекция.

Слабая:   "тест не пройден"           → LLM исправляет без направления
Средняя:  "coverage 65%"              → LLM примерно усиливает
Сильная:  "line 41, 44, 70 не покрыты" → LLM точно покрывает эти ветки

Цифры, подтверждённые на реальном проекте:

Без обратной связи:  60–70% coverage, затем стагнация
С обратной связью:   100% (для достижимых функций)

Та же модель. Одна строка “line 41 not covered” работает как gradient signal.

Чем выше разрешение обратной связи, тем точнее исправления LLM, тем меньше итераций цикла, тем ниже стоимость.


Агент умирает. Прогресс остаётся.

Агент неизбежно падает. Лимит токенов, сетевая ошибка, разрыв сессии. Если храповик сохраняет состояние прогресса, следующий агент подхватывает работу с того же места.

Агент A: функции 1–200 → падение
Агент B: next → продолжение с 201
Агент C: next → продолжение с 401

Агент одноразовый. Прогресс накапливается.


Замени Verifier – получишь другой инструмент

Храповик не привязан к конкретному верификатору. Поменяйте верификатор – получите другой инструмент.

Храповик + верификаторНазначение
Храповик + go test + coverageГенерация тестов для функций
Храповик + структурный validatorРефакторинг структуры кода
Храповик + hurl pass/failПроверка API-эндпоинтов
Храповик + перекрёстная проверка спецификацийОбеспечение целостности SSOT
Храповик + Toulmin verdictПринудительное применение пользовательских правил

Паттерн один. Верификатор определяет домен.


Вопрос

Сколько элементов выполнил ваш агент, прежде чем сказать “готово”?

Это действительно всё?

Кто решил, что работа закончена – агент или машина?


Связанная статья: Топология обратной связи важнее IQ модели – теоретическая основа Ratchet Pattern. Почему структура обратной связи важнее производительности модели.