Ratchet Pattern

“Ya termine”

Le pedi a un agente de IA que escribiera tests para 527 funciones. El agente termino su trabajo e informo:

“Listo.”

Funciones que realmente obtuvieron tests: 40.

No mintio. Despues de 40, decidio que “era suficiente”. Cuando encontraba una funcion dificil, la saltaba. Tras unas cuantas mas, concluyo que “el resto sigue un patron similar, asi que estamos bien”.

Los LLM son excelentes generando. Pero no se puede confiar en ellos para juzgar si terminaron.


El trinquete

Una llave de trinquete tiene dientes que engranan en una sola direccion. Al girarla avanza. Al soltarla se detiene, pero nunca retrocede.

El Ratchet Pattern aplica este mecanismo al control de agentes.

Item 1: verificacion mecanica → PASS → siguiente
Item 2: verificacion mecanica → FAIL → reintentar (con feedback)
Item 2: verificacion mecanica → PASS → siguiente
...
Item N: PASS → completo. Detener.

Tres reglas:

  • Mostrar solo un item a la vez.
  • Un item debe pasar antes de que se abra el siguiente.
  • Cuando todos los items pasan, detenerse.

Implementa estas reglas como CLI y el agente solo necesita conocer un comando: next. La maquina decide el resto.


El agente que se detuvo en 40 vs. el trinquete que completo 527

Mismo modelo. Mismo proyecto. Las mismas 527 funciones.

Agente autonomo:  40 / 527  (7.6%)  — el agente declaro "listo"
Trinquete CLI:   527 / 527 (100%)  — la maquina declaro "quedan 487"

La diferencia no es el rendimiento del modelo. Es quien decide cuando se termina.

Con un agente autonomo, el LLM decide cuando parar. Los LLM son optimistas. Despues de 40, sienten que es suficiente. Con un trinquete, la maquina decide cuando parar. La maquina no siente. Declara “todavia no” hasta que el conteo restante llega a cero.


Definicion en una frase

Colocar un agente probabilistico dentro de una maquina de estados determinista.

RolResponsable
GeneracionLLM
Juicioverifier
Control de progresoratchet

Muchos sistemas delegan la generacion, el juicio y la decision de terminacion al LLM. El Ratchet los separa.


Cinco principios

1. La condicion de terminacion es mecanica

pass/fail. No “looks good”. Si go test pasa, es PASS. Si el coverage llega a 100%, es PASS. No hay espacio para el juicio subjetivo.

2. Un PASS es inmutable

Un item aprobado no se reabre. No se revierte. El numero de items restantes decrece monotonicamente.

remaining_work(t+1) ≤ remaining_work(t)

Lo que construyes hoy no se deshace manana. Solo hacia adelante. Esta es la diferencia fundamental con un “agente de 24 horas”. Un agente sin condicion de terminacion agrega una abstraccion hoy, la elimina manana y la vuelve a agregar pasado manana. El trinquete no permite esa oscilacion.

3. El LLM solo genera

Generar codigo, escribir tests, proponer correcciones: ese es el rol del LLM. Que corregir, si paso o no, cual es el siguiente, si termino o no: todo eso lo decide la maquina. El LLM no es un planner, es un constrained generator.

4. Despojar al agente de su derecho a declarar que termino

Si el LLM dice “listo”, se detiene en 40. Si la maquina dice “listo”, se detiene en 527. La razon de existir del trinquete se resume en esta unica linea.

5. El verifier debe ser determinista

No cualquier cosa puede ser un verifier.

Puede ser verifierNo puede ser verifier
go test“looks cleaner”
medicion de coverage“seems better”
AST validation“more scalable”
schema diff“clean architecture”

Condiciones del verifier: deterministic, machine-checkable, resumable, localized feedback. Si no se cumplen estas cuatro, los dientes del trinquete no enganchan.


El feedback como gradient signal

Si el trinquete solo devuelve “paso/fallo”, el LLM corrige sin direccion. Cuanto mas especifico el feedback, mas precisas las correcciones del LLM.

Feedback debil:   "test fallo"                → LLM corrige sin direccion
Feedback medio:   "coverage 65%"              → LLM refuerza aproximadamente
Feedback fuerte:  "line 41, 44, 70 sin cubrir" → LLM cubre exactamente esas ramas

Numeros verificados en un proyecto real:

Sin feedback:   coverage estancado en 60~70%
Con feedback:   100% alcanzado (para funciones alcanzables)

Mismo modelo. Una sola linea – “line 41 not covered” – actua como gradient signal.

A mayor resolucion del feedback, mayor precision de correccion del LLM, menos iteraciones del loop y menor costo.


Los agentes mueren. El progreso sobrevive.

Los agentes inevitablemente se caen. Limite de tokens, errores de red, desconexion de sesion. Si el trinquete persiste el progreso en almacenamiento, cuando un agente muere, el siguiente continua donde el anterior lo dejo.

Agente A: procesa funciones 1-200 → muere
Agente B: next → continua desde 201
Agente C: next → continua desde 401

Los agentes son desechables. El progreso se acumula.


Cambia el verifier, obtienes otra herramienta

El trinquete no esta atado a ningun verificador especifico. Cambia el verificador y obtienes una herramienta diferente.

Trinquete + VerificadorUso
Trinquete + go test + coverageGeneracion de tests por funcion
Trinquete + validator de reglas estructuralesLimpieza de estructura de codigo
Trinquete + hurl pass/failVerificacion de endpoints API
Trinquete + validacion cruzada de specsConsistencia SSOT
Trinquete + Toulmin verdictAplicacion de reglas definidas por el usuario

Un solo patron. El verificador determina el dominio.


Preguntas

¿Cuantos items completo tu agente antes de decir “ya termine”?

¿Realmente termino?

¿Quien decidio “fin” – el agente o la maquina?


Articulo relacionado: Mas que el IQ del modelo, importa la topologia del feedback – El trasfondo teorico del Ratchet Pattern. Por que la estructura del feedback importa mas que el rendimiento del modelo.