Esta es una continuación de las Partes 1 y 2 de "Por qué fracasan las fábricas de software"
mejoramos los benchmarks
¿Recuerdan cuando dije esto en la Parte 1?
NO HAY BUENOS BENCHMARKS para la capacidad de un modelo de mantener la calidad de una base de código
Eso no era del todo cierto, pero quería guardarme lo mejor para un poco más adelante. En este artículo, miraremos hacia el futuro.
Analizaremos SlopCodeBench, un benchmark de codificación de horizonte largo bastante nuevo (marzo de 2026) del laboratorio de @GOrlanski en UW Madison. Aborda el problema exacto que destacamos en la Parte 1: que incluso los benchmarks más "grandes" y complejos siguen revelando todo el problema desde el principio:

Sin embargo, cada desafío en SlopCodeBench tiene múltiples "puntos de control": el modelo no conoce todo el problema de antemano, tiene que evolucionar la base de código con el tiempo a medida que se revelan nuevos requisitos. Es un buen artículo. No es muy largo. Deberían leerlo.

Lo interesante de este benchmark es que está no saturado: en el momento de su ejecución, los mejores modelos disponibles, GPT-5.4 y Opus 4.6, obtuvieron tasas de aprobación estrictas del 11% y 17%, respectivamente.

evaluando opus 5 en slopcodebench
El viernes ejecuté tres modelos de Claude (Opus 4.8, Sonnet 5 y Opus 5) en un subconjunto de SlopCodeBench y lo vi en vivo durante seis horas. Opus 5 gana técnicamente, pero ninguno hizo un muy buen trabajo en mi opinión. Publicaré más resultados pronto con Fable y 5.6 Sol en la mezcla.

El gran titular es que Opus 5 obtuvo un 24% en el pequeño subconjunto del benchmark que ejecuté, no mucho más alto que el 17% de tasa de aprobación estricta de Opus 4.6 en el artículo original. Todos los modelos probados mostraron un aumento bastante significativo en verbosidad, complejidad y varias otras métricas de código con olor a lo largo de cada desafío, con Opus 5 escribiendo cinco veces la cantidad de funciones/elementos invocables que Opus 4.8 durante el mismo conjunto de desafíos.

Mi interpretación personal de esta tasa de aprobación del 23% es que SlopCodeBench da una señal que justifica mis corazonadas de la parte 1: que para el trabajo de ingeniería de software real, construyendo un problema a la vez, los modelos actuales no son confiables para funcionar sin supervisión.
el subconjunto del benchmark
Le pedí a Claude que seleccionara 3 problemas del repositorio, 17 puntos de control en total, una mezcla de problemas etiquetados como fáciles/medios/difíciles:
- circuit_eval — fácil (8 puntos de control)
- database_migration — medio (5 puntos de control)
- dynamic_config_service_api — difícil (4 puntos de control)
Hay un apéndice al final con los 17 puntos de control explicados en detalle, pero no pondré todo eso aquí.
Y luego los ejecuté en los tres modelos, en paralelo, con una ventana de contexto nueva por punto de control. Todos los modelos recibieron las mismas indicaciones y se ejecutaron en el arnés de Claude Code.
La métrica que decidí que me importa es la aprobación estricta: todo lo nuevo está en verde, incluyendo cada prueba de regresión que se heredó de puntos de control anteriores.
Un modelo falla un punto de control si la solución tiene un defecto; los defectos se detectan tomando la salida del modelo, una CLI para ejecutar o, en algunos casos, por ejemplo, un servidor API para probar, y ejecutando un conjunto de pruebas de caja negra reservadas contra el punto de entrada producido.
- El modelo escribe código para ck1
- El arnés de evaluación ejecuta pruebas de caja negra contra ck1
- El modelo escribe código para ck2
- La evaluación ejecuta pruebas de caja negra para ck1 y ck2
- etc.
De nuevo, el criterio de aprobación estricta significa que si un modelo estropea algo en el punto de control 4, no puede pasar los siguientes puntos de control porque esa parte fallida del código se arrastra (a menos que el modelo, sin querer, arregle un caso de evaluación en el punto de control 6 que estaba roto en el punto de control 4, pero no vimos que esto sucediera en la práctica).
Para las 9 ejecuciones de prueba, ninguno de los modelos llegó al final de ningún desafío con todo aprobado, ni siquiera en el problema marcado como "fácil".
mientras se ejecutaba
El primer punto de control de Sonnet fue más costoso, pero para el final del problema 1, Sonnet se convirtió en el más barato de los tres. (Parece que una vez que se construyeron los conceptos básicos y el trabajo se convirtió en mantenimiento, los ahorros de costos comenzaron a aparecer).
Para el primer desafío, los modelos de la generación anterior acumularon defectos de manera constante, Opus 5 un defecto cada uno en los puntos de control 4 y 5.

Durante las primeras dos horas, Opus 5 fue el único modelo con alguna aprobación estricta: tres seguidas al principio.

Las cosas evolucionaron a medida que avanzábamos. Claude actualizó diligentemente el HTML.

En comparación con los otros modelos, Opus 5 fue técnicamente mejor en el problema 1 (circuit_eval). Pero después de acertar los primeros tres puntos de control, cada solución subsiguiente tenía al menos un defecto (caso de prueba fallido).
resultado final
Si nuestra definición de éxito es "llegó al punto de control final sin defectos", entonces Opus 5 falló en los tres problemas, pero falló un poco menos mal que los otros modelos.

En cuanto al informe de costos vs defectos, realmente odio los claude-ismos, pero este decidí dejarlo:
cada dólar compró corrección. nadie compró suficiente.
(Obviamente, este pequeño subconjunto del banco no puede decirnos de manera definitiva que gastar más $$ conducirá a tasas de aprobación más altas)

En cuanto a las aprobaciones estrictas, Opus 5 obtuvo cuatro de ellas (tasa de aprobación del 24%) (los primeros tres puntos de control de circuit_eval, más database_migration ck1).
opus 4.8 y sonnet 5 obtuvieron una aprobación estricta cada uno (tasa de aprobación del 6%), el mismo database_migration ck1 que obtuvo opus 5.
Así que el ganador logró 4/17, y 3 de esos fueron los puntos de control iniciales de un problema. Parecería que tenemos un benchmark no saturado para la próxima frontera de modelos. buen trabajo @GOrlanski y equipo.
el medidor de slop
Todavía no estoy completamente convencido de "eliminar el slop con linting", porque no creo que sea posible analizar de manera determinista la "mantenibilidad" de un punto de control de base de código en particular. Pero son interesantes para seguir...
Las métricas de calidad de código son interesantes de seguir, y probablemente sean direccionalmente correctas, y
Con SlopCodeBench, obtienes los resultados después de cada punto de control en varias métricas de calidad. Hay 41 de ellas en el archivo de resultados. Agrupadas aproximadamente:
- tamaño — líneas de código fuente, archivos, funciones, métodos, clases, sentencias, y líneas añadidas y eliminadas en ese punto de control
- complejidad — media de complejidad ciclomática, máxima, y dispersión, cuántas funciones caen en las bandas "alta" y "extrema", qué tan concentrada está la complejidad, profundidad máxima de anidamiento, y longitud media de función
- duplicación — líneas clonadas, y líneas clonadas como proporción del código fuente
- descomposición — funciones de un solo uso, envoltorios triviales, variables no utilizadas, líneas por símbolo
- violaciones de reglas — errores de lint y cuántos son auto-corregibles, aciertos de ast-grep contra reglas de slop de prueba, y la proporción de líneas marcadas como verbosas
- grafo de dependencias — costo de propagación (qué tan lejos se extiende un cambio), masa de dependencia cíclica, entropía de dependencia (probablemente la más interesante para mí)
Cada una de estas se calcula de manera determinista utilizando el estado actual del código después de cada punto de control.
El gráfico a continuación muestra la dispersión entre modelos para la puntuación de ck1 vs. ck8 en el desafío circuit_eval. (Es decir, cuánto aumentó el indicador de slop durante la vida útil de los puntos de control del desafío). Lo más interesante es que la mayoría de las métricas no diferencian entre modelos.

Me gusta que estas medidas sean repetibles y no utilicen un modelo para juzgar. Pero el vínculo entre cualquiera de ellas y "¿es fácil cambiar y evolucionar esta base de código?" aún no está establecido.
más corrección llegó a costa de mucho más código

Pero gran parte de eso fueron "más pruebas": el volumen de producción real es más cercano a 1.8x para opus 5 vs opus 4.8.

Mi suposición sería... verbosidad costosa aquí que no se tradujo directamente en resultados mucho mejores.
Tendré que profundizar más para saber si esto es una señal de tic del modelo o simplemente "este es un problema realmente difícil y justifica esta cantidad de código".
casi todo el código escrito disparó el medidor de slop
Para todos los modelos, una gran mayoría de las líneas de código activaron al menos una de las reglas de slop del benchmark. Los promedios en los tres problemas:
- opus 4.8 — 98%
- opus 5 — 93%
- sonnet 5 — 89%
Y específicamente, las líneas marcadas como demasiado verbosas aumentan a lo largo de la trayectoria para todos los modelos, aproximadamente del 65% en ck1 al 80% en ck8, incluso para Opus 5.
En realidad, probablemente diría que esto es una señal de que algunas de las medidas de calidad del código son un poco demasiado agresivas. Investigué aplicar el conjunto de reglas a nuestro monorepo de TypeScript, pero los detectores actuales de slop-code-bench son solo para Python.
Así que le pedí a 5.6-Sol que preparara un subconjunto de reglas para TypeScript, pero solo generó 76 detectores de slop (en comparación con la biblioteca de Python de SCB de más de 200), pero encontró algunos hallazgos direccionales: las soluciones generadas sin supervisión de Opus 5 tienen más de 11 veces más disparadores de slop por kLOC que nuestro monorepo de TypeScript generado en un 99% por IA pero también revisado cuidadosamente (sí, eso es un aumento del 1000%).

Obviamente, hay una montaña de asteriscos en este hallazgo (menos reglas, no he revisado la paridad, etc.), pero es interesante, por decir lo menos.
estos modelos escriben muchas funciones
Otro punto de datos interesante: opus 5 escribió 5 veces más funciones que los otros dos modelos. Pero Opus 4.8 escribió un mayor porcentaje de funciones de un solo uso (casi el 50% de sus funciones se llamaron exactamente una vez). Y la proporción de funciones de un solo uso de Sonnet 5 es la más alta, con un 71.5%.

Dicho esto, no creo que muchas funciones pequeñas sean malas. Hoy en día lo tomo con pinzas, pero solía ser un fanático acérrimo de Clean Code. Los nombres de funciones pequeños y descriptivos son mucho mejores que muchos comentarios, etc., etc.
La complejidad crece con el tiempo para todos los modelos
He estado diciendo que los modelos degradan la calidad de la base de código con el tiempo durante aproximadamente un año, principalmente basado en corazonadas. Pero ahora tenemos algunos datos.

Ni un solo modelo superó todos los desafíos sin aumentar la complejidad a lo largo de los puntos de control. Si bien Opus 5 tiene la complejidad media más baja, también escribió 2000 funciones. Hay un equilibrio aquí: muchas funciones pequeñas o menos funciones grandes. No creo que ninguna de estas métricas de complejidad pueda mantenerse por sí sola, pero nos dan algún tipo de señal compuesta.

Tanto Sonnet como Opus 4.8 respondieron a la creciente complejidad de los puntos de control del desafío haciendo que las funciones individuales fueran más grandes en lugar de reestructurar las cosas. Opus 4.8 es el extremo, con un aumento del 70% en ocho puntos de control, y su peor función terminó con una complejidad ciclomática de 93.
La duplicación es donde se dividen. Opus 4.8 pasa del 4.6% al 16.8%, con un punto de inflexión en ck3, aproximadamente donde los nuevos requisitos comienzan a chocar con el diseño inicial.
Aparte: esto es lo que piden los primeros tres puntos de control de circuit_eval (lista completa para todos los desafíos en el apéndice al final):
- ck1 — una CLI con --help, --version, un modo de salida JSON y un comando check que analiza y valida un archivo de circuito .circ. Cada señal es un solo bit.
- ck2 — un comando eval: pasarle al circuito algunas entradas, obtener las salidas. Todavía un bit por señal, operadores booleanos estándar.
- ck3 — las señales se convierten en vectores. data[7:0] en lugar de data, más división, indexación, concatenación, nuevos operadores (MUX, reducciones, EQ), una verificación de ancho en cada operando y formato de salida --radix.
Para el final, una de cada seis líneas es una copia de otra línea. Los otros dos modelos bajaron en el mismo tramo.
Sin embargo, opus 5 está prácticamente plano, de 2.41 a 2.64. En la Parte 1 tenía un gráfico que suponía que "mejorar la calidad de la base de código con el tiempo" no había cambiado mucho entre generaciones de modelos. Así que si confías en la duplicación como una métrica dorada, podrías argumentar que mejoramos incrementalmente en los últimos ~3 meses. Gran "si", y creo que la mayoría de los expertos en arquitectura de software estarían de acuerdo en que no es blanco o negro.
la forma de un mejor oráculo para la calidad del software
Si bien las métricas de calidad del código son interesantes, no creo que cuenten toda la historia, y es fácil para un modelo recompensar cualquier hackeo de ellas. Así como los problemas con forma de SWE-bench eran el mejor verificador para "resolver un problema de software una vez", porque se mapean al trabajo del mundo real a ese "nivel de zoom", creo que "pasar todos los verificadores para una especificación revelada incrementalmente" es una evaluación muy realista para "¿puede un modelo mantener una base de código a lo largo del tiempo?".
Es decir, una base de código que se vuelve difícil de mantener llevaría a fallar puntos de control en etapas posteriores, por lo que una tasa de aprobación estricta más alta es una señal de que el modelo es bueno construyendo una base de código que sea mantenible.
Con modelos de frontera como Fable / Sol demostrando ser expertos depuradores e ingenieros inversos, incorporar métricas de costo/tiempo/tokens podría volverse más importante con el tiempo; los modelos de frontera como Fable y Sol probablemente puedan lograrlo en las bases de código MÁS DIFÍCILES, pero me aventuraría a decir que una base de código bien estructurada tenderá a conducir a soluciones más cortas y más eficientes en tokens para problemas futuros.
Y si bien "construir una característica completa a través de 8 puntos de control" es mucho más lento que "resolver un problema multilingüe de SWE-bench de 15 minutos", se puede ejecutar sin supervisión y está sujeto a verificadores de comportamiento deterministas al final. Así que en mi opinión, es un oráculo mucho mejor que, por ejemplo, "¿otro modelo piensa que este código es limpio?".
Creo que cualquier señal aún mejor que podemos esperar obtener de un modelo que es realmente bueno manteniendo una base de código, es que podríamos intentar que un modelo de frontera como Opus 5, Fable 5 o GPT-5.6-Sol escriba los primeros N puntos de control, y ver si un modelo más tonto como Sonnet 5 o GPT-5.6-Terra puede implementar el punto de control N+1.

Esto amplifica la señal de si los modelos inteligentes hicieron un buen trabajo manteniendo un código de alta calidad que sea fácil de cambiar. Si un modelo pequeño como Sonnet, Terra o incluso Haiku puede implementar el punto de control 8, impacta la puntuación de los modelos inteligentes en los puntos de control 1-7.
por qué fracasan las fábricas de software: algo que puedes medir
Mi interpretación personal de todo esto es que SlopCodeBench da una señal que justifica algunas de las corazonadas de la parte 1: que para el trabajo de ingeniería de software real, construyendo un problema a la vez, los modelos actuales no son confiables para funcionar sin supervisión.
SCB es una medida del futuro que estaré vigilando de cerca; dije en la Parte 1 que no apostaría mi base de código por Frontier Code, SWE-Marathon o DeepSWE, pero si/cuando los modelos puedan obtener un 80% o más en un benchmark (bien reservado) como SlopCodeBench que mide la iteración a lo largo del tiempo, me sentiré MUCHO mejor al dejarlos sueltos sin supervisión.
No voy a postular cuándo sucederá eso, porque "cuándo" importa menos que tener una buena señal para saber que está sucediendo.
(Asumiendo que nadie "accidentalmente" entrene con datos de prueba mientras tanto).
qué sigue / cosas que haría diferente
Leeré algunos de los problemas de slopcodebench más a fondo para inspirarme y seleccionar algunos que creo que se corresponden bien con la construcción diaria que hacemos aquí en @humanlayer_dev.
Claude decidió paralelizar por modelo, ejecutando cada uno a través de tres desafíos en secuencia. Podríamos haber hecho fácilmente 3 modelos x 3 desafíos en 9 sesiones paralelas y haber terminado en 1-2 horas en lugar de 6.
Como dije, investigué aplicar el conjunto de reglas a nuestro monorepo de TypeScript, pero los detectores actuales de slop-code-bench son solo para Python. Sería interesante portarlos a TypeScript y algunos otros lenguajes. Odio ser ese tipo, pero apostaría a que Python es un lenguaje más propenso al slop que la mayoría.
Creo que en lugar de centrarme en la aprobación estricta y los defectos totales, será interesante explorar más dimensiones del benchmark. En la puntuación actual, estamos tomando cualquier fallo en el camino como un defecto acumulado, a menos que el modelo resuelva ese defecto pasado en una sesión futura, todos los puntos de control restantes no pueden pasar.
Muchas fábricas de software incluyen indicaciones para un mejor estilo, incluyen retroalimentación determinista durante el bucle de código para la complejidad y muchas de estas otras métricas de calidad de software. Los resultados de hoy no evalúan la calidad del código del modelo ni las tasas de éxito con ese tipo de barreras de seguridad implementadas. Usamos la versión "solo-resuelve" de la indicación de SlopCodeBench, pero hay otras variaciones como incluir instrucciones sobre calidad/duplicación en la indicación. Y sería muy interesante volver a ejecutar toda la evaluación con una o ambas: 1) un bucle de "revisión adversaria" con un modelo juzgando la calidad y 2) contrapresión de calidad de código para cosas como la complejidad ciclomática.
No estoy hecho de dinero ni de tiempo, pero sería divertido hacer un conjunto de datos más grande aquí.
Y, por supuesto, lo más interesante es esta idea de "¿podemos amplificar la señal de slop entregando la base de código de Fable a un modelo más pequeño como Sonnet?".
verificación de corazonada: la frontera sigue siendo muy tonta
mientras todo este experimento sucedía, en otra sesión, Opus 5 decidió volverse rebelde y reescribir un borrador de correo electrónico con nuevo formato, y luego enviarlo a 100 personas sin consultarme. Terrible.
El usuario está molesto porque cometí un error crítico: sobrescribí su borrador editado parcheándolo con la versión final y luego lo envié.
Lo siento si recibiste una de esas actualizaciones de producto de humanlayer con el banner de encabezado feo (creo que el nuevo claude-ismo para esto es "kicker"?)
Realmente sintiendo la AGI aquí, amigos
🫡 -dex
PD: Todavía estamos obsesionados con esto
Estamos construyendo humanlayer.com, un IDE agéntico y plataforma de colaboración para ayudarte a moverte a la velocidad de la IA mientras mantienes un nivel humano (o bastante cercano a humano) de calidad de código.
Estamos construyendo hacia dos ideas: "bloques de construcción para tu fábrica de software" y "mejores verificadores para la mantenibilidad del software" (quizás incluso mejores modelos).
HumanLayer es gratuito para equipos pequeños de hasta 3 personas, y si quieres ayuda para comenzar, puedes venir a nuestro discord o enviarnos un mensaje a founders@humanlayer.dev
Enlaces de esta publicación
- Por qué fracasan las fábricas de software, Parte 1: el arnés no es suficiente
- Por qué fracasan las fábricas de software, Parte 2: volviendo a encender las luces
- SlopCodeBench (artículo)
- Ejecutor de SlopCodeBench (SprocketLab/slop-code-bench)
- Problemas de SlopCodeBench (gabeorlanski/scb-problems)
- Gabe Orlanski en X
- SWE-bench Multilingual (conjunto de datos)
- SWE-Marathon (Abundant AI)
- DeepSWE (Datacurve)
- Frontier Code (Cognition)
- Pruebas de mutación (Wikipedia)
- HumanLayer
- Discord de HumanLayer
Apéndice: los puntos de control del desafío
Los 17, en orden, directamente de las indicaciones que se les dieron a los modelos. Cada uno llega frío: el modelo no tiene idea de que existe ninguno de los siguientes.
circuit_eval — fácil, simulación, 8 puntos de control
- ck1 — una CLI con --help, --version, un modo de salida JSON y un comando check que analiza y valida un archivo de circuito .circ. Cada señal es un solo bit.
- ck2 — un comando eval: pasarle al circuito algunas entradas, obtener las salidas. Todavía un bit por señal, operadores booleanos estándar.
- ck3 — las señales se convierten en vectores. data[7:0] en lugar de data, más división, indexación, concatenación, nuevos operadores (MUX, reducciones, EQ), una verificación de ancho en cada operando y formato de salida --radix.
- ck4 — lógica de tres valores. Las entradas ahora pueden ser X (desconocido), y cada operador tiene que decir qué hace con una.
- ck5 — dos formatos de entrada más. check y eval ahora leen archivos .json y .bench además de .circ, detrás de una bandera --format.
- ck6 — tres comandos de análisis: stats para métricas, lint para advertencias, dot para exportación a Graphviz. Todos funcionan con los tres formatos.
- ck7 — cone (extraer un subcircuito), truth-table (enumerar cada salida), equiv (verificar que dos circuitos coinciden), más una bandera --seed para aleatoriedad reproducible.
- ck8 — opt: un optimizador de circuitos con pasos configurables, salida determinista, verificación de equivalencia opcional y exportación BENCH.
database_migration — medio, bases de datos, 5 puntos de control
- ck1 — una CLI que lee especificaciones de migración de archivos JSON y las aplica a una base de datos SQLite: crear tablas, añadir columnas, cambiar la estructura de la tabla.
- ck2 — migraciones de datos. Transformar las filas que ya están allí usando expresiones SQL, no solo el esquema que las rodea.
- ck3 — claves foráneas, índices personalizados y restricciones avanzadas. Integridad relacional y rendimiento de consultas.
- ck4 — reversión. Deshacer migraciones una por una o en lotes, con manejo de dependencias.
- ck5 — gestión de dependencias. Las migraciones declaran depends_on, y la herramienta tiene que resolver el orden y detectar dependencias circulares.
dynamic_config_service_api — difícil, diseño de sistemas, 4 puntos de control
- ck1 — un servicio REST que almacena objetos de configuración JSON con versiones inmutables, ámbito, reversión a cualquier versión anterior e importaciones/herencia entre configuraciones.
- ck2 — un registro de esquemas con su propio versionado, esquemas vinculados a configuraciones, validación al crear y al resolver, e ingesta de YAML/TOML/JSON sin procesar analizados en JSON canónico internamente.
- ck3 — un flujo de trabajo de gestión de cambios. Cada nueva versión comienza como un borrador, las propuestas recogen revisiones humanas, la activación requiere un quórum, y cada propuesta lleva un diff determinista.
- ck4 — una capa de barreras de seguridad a nivel de organización que ejecuta paquetes de políticas contra configuraciones resueltas y el gráfico que las rodea, bloqueando propuestas inseguras con detalles de violación distintos de los errores de esquema.





