IA para Rails: agente que escribe tests y corre en CI | Keryc
En muchos monolitos Rails el desarrollo prioriza nuevas funciones y los tests quedan para después. ¿El resultado? Código sin pruebas que causa bugs difíciles de reproducir y horas perdidas en debugging.
Mistral presentó un agente autónomo que cierra esa brecha: lee archivos de un proyecto Rails, genera o mejora specs de RSpec, valida estilo y cobertura, y corre todo dentro del pipeline CI/CD sin intervención humana. ¿Suena a magia? Es ingeniería aplicada: automatiza pasos repetitivos y fuerza que las pruebas realmente se ejecuten.
Qué problema resuelve
¿Te imaginas una base de código donde la mitad de los archivos nunca tuvo tests? Eso fue el punto de partida. Equipos que escriben features pero no tests crean deuda técnica creciente. El agente actúa sobre archivos concretos (modelos, controladores, serializers, mailers, helpers) y se encarga de generar o mejorar las pruebas asociadas.
Ruby es dinámico: no hay compilación que detecte errores. Eso complica al agente: la única forma confiable de verificar la sintaxis y la validez de un spec es ejecutarlo. Por eso Mistral puso a correr las pruebas como parte del flujo del agente.
Cómo trabaja el agente (resumen práctico)
Lee el archivo fuente y la doc disponible.
Busca si ya existe un spec asociado; la convención entre app/... y spec/... facilita esto.
Elige una skill especializada según el tipo de archivo (por ejemplo, controladores tienen reglas distintas a modelos).
Reusa o crea factories cuando sean necesarias, con cuidado para no romper tests cruzados.
Ejecuta linters y coverage tools: RuboCop para estilo y SimpleCov junto con RSpec para asegurar que las pruebas corran y cubran líneas importantes.
Se auto-revisa: cuenta métodos públicos y pregunta "¿probé todos los métodos públicos?" antes de finalizar.
¿Y si una prueba falla al ejecutarse? El agente vuelve a escribir y corregir hasta que la prueba pase o se alcance el criterio de calidad.
Vibe: la plataforma donde corre el agente
Construyeron este flujo sobre Vibe, el asistente de codificación open source de Mistral. En lugar de un prompt genérico, usaron tres palancas:
contexto a nivel de repositorio (un AGENTS.md con plan de ejecución),
skills especializadas por tipo de archivo,
y herramientas personalizadas que permiten ejecutar comandos y leer resultados.
El AGENTS.md incluyó una lista paso a paso con criterios de éxito concretos y reglas de estilo RSpec (por ejemplo, evitar matchers vagos como be_truthy y preferir eq(exact_value)). Solo ese archivo subió la puntuación de calidad del agente de 0.68 a 0.74.
Skills y reglas para cada tipo de archivo
Una skill es una receta de cómo escribir tests para un tipo de archivo. Por ejemplo, la skill para controladores establece:
dónde crear el spec (spec/requests/..._spec.rb),
reglas: asertar el contenido del JSON, verificar cambios en el estado con change { Model.count }.by(1), y probar rutas autorizadas y no autorizadas,
cubrir acciones: index, show, create, update, destroy y acciones personalizadas.
Separar instrucciones por tipo evita que un mismo prompt mediocre intente adivinar cómo testear todo.
Herramientas clave: RuboCop y SimpleCov (y por qué ejecutarlas)
Dos decisiones prácticas marcaron la diferencia:
usar RuboCop para detectar y corregir violaciones de estilo, y
usar SimpleCov integrado con RSpec para forzar la ejecución de cada test y medir cobertura por archivo.
Sin ejecutar las pruebas, un spec puede verse perfecto en texto pero no correr por errores sintácticos, dependencias faltantes o factories inexistentes. Al correr todo, el agente pudo auto-corrigirse: solo 1/3 de los tests pasaban al primer intento; tras iteraciones automáticas alcanzaron 100% de tests pasando en el experimento.
Ejecutar las pruebas no es un lujo: es lo que separa las pruebas bonitas en papel de las pruebas que realmente protegen el código.
LLM-as-a-judge: evaluar calidad más allá de métricas
Además de métricas clásicas (porcentaje de tests que pasan, violaciones RuboCop, cobertura SimpleCov), usaron un enfoque que llamó LLM-as-a-judge: pedirle a un modelo que puntúe la calidad de un spec entre 0 y 1 según reglas claras (¿cubre errores? ¿usa aserciones precisas? ¿prueba casos límite?).
Esto ayuda a capturar calidad cualitativa, pero tiene limitaciones: la evaluación no es determinista al 100% y puede fallar si una prueba tiene buena intención pero no corre por un error sintáctico.
El problema de la parenthesis faltante (un ejemplo útil)
Un ejemplo sencillo muestra la trampa:
RSpec.describe User, "#full_name" do
it "combina nombre y apellido" do
user = User.new(first_name: "Ada", last_name: "Lovelace"
expect(user.full_name).to eq("Ada Lovelace")
end
end
Este spec está bien escrito a nivel de intención y aserción, pero nunca correrá por falta de un paréntesis. Un LLM puede puntuarlo alto si solo evalúa intención, por eso la ejecución real con SimpleCov fue clave para detectar y corregir estos fallos.
Resultados del experimento
Métricas del experimento en un repositorio con 275 archivos:
Archivos procesados: 275
Tests pasando: 100%
Cobertura promedio por archivo (SimpleCov): 100%
Violaciones RuboCop tras correcciones: 0
Puntuación LLM-as-a-judge (promedio): 0.74
Desglose por tipo de archivo (LLM-as-a-judge):
Modelos: 0.81
Controladores: 0.67
Serializers: 0.80
Los modelos resultaron más fáciles porque su lógica es autocontenida; los controladores requieren manejar HTTP, autenticación y más dependencias.
Limitaciones y advertencias prácticas
No es una solución mágica: hay que mantener las factories y las dependencias de testing.
Cambios en factories pueden romper tests amplios: el agente modifica factories con cuidado.
Evaluaciones LLM tienen ruido; la agregación a escala mitiga la variabilidad.
Versiones incompatibles de gems o sintaxis pueden causar errores que requieren intervención humana en casos complejos.
¿Por qué esto importa para ti?
Si trabajas en una base de código Rails grande, esto significa menos trabajo manual repetitivo y menos deuda técnica acumulada. ¿Quieres que los tests existan y sirvan para algo real? Haz que se ejecuten, mídelos y automatiza la retroalimentación. Ese es el principio simple que convirtió a un experimento en una herramienta práctica.