Artículo

Ingeniería de IA

Qué LLM usaría para desarrollo backend

Puse varios LLMs a resolver el mismo assessment backend en Go para ver cuál me resulta más útil en el día a día desarrollando software. El resultado tuvo menos que ver con escribir más código y más con sobrevivir la verificación.

Empecé esto por curiosidad, no como un paper formal. Quería responder una pregunta muy práctica: si estoy construyendo software backend todos los días, ¿qué LLM me ayuda más? No cuál suena más inteligente en una ventana de chat. No cuál escribe el README más largo. Cuál puede tomar una tarea backend, tomar decisiones razonables, generar código Go mantenible y sobrevivir el tipo de verificación que yo aplicaría antes de confiar en algo dentro de un codebase real.

Así que les di a varios modelos la misma tarea: implementar un servicio de orquestación de notificaciones en Go. El servicio debía exponer una API, validar notificaciones, procesar múltiples destinatarios, manejar proveedores poco confiables, usar concurrencia de forma segura, mantenerse extensible e incluir tests y documentación. Luego evalué los resultados con un benchmark de ingeniería backend puntuado sobre 280 puntos.

El benchmark completo estará publicado aquí:

Repositorioaikssen/llm-benchmark-for-devEl assessment backend, la rúbrica, las soluciones de los modelos y los reportes de evaluación detrás de este artículo.GoVer en GitHub

Lo más interesante no fue el ranking. Fue la forma de los fallos.

Los modelos evaluados son: Opus5, Fable5, Opus-4.8, Sonnet5, GPT-5.6-Sol, GPT-5.6-Terra, GPT-5.5, Kimi-K3, Grok-4.5, Gemini-3.6-flash, Gemini-3.5-Flash, GLM-5.2, MiniMax-M3, DeepSeek-V4-Pro, Qwen3.7-Max, MiMo-V2.5-Pro y Kimi-K2.7-Code

El problema: las demos perdonan demasiado

Por eso no quería usar un prompt de juguete. Un servicio de notificaciones es lo suficientemente pequeño para implementarse en una sesión, pero contiene puntos de presión reales de backend:

  • Límites de API y validación de requests.
  • Modelado de dominio y transiciones de estado.
  • Abstracciones de proveedores para email, SMS y push.
  • Procesamiento concurrente bajo ráfagas de tráfico.
  • Retries, timeouts, backpressure y graceful shutdown.
  • Tests que prueban comportamiento, no solo suben cobertura.

Es el tipo de tarea donde un modelo puede verse bien a primera vista y aun así entregar una data race.

El modelo mental: el LLM no es el ingeniero

El modelo no es el ingeniero. El loop es el ingeniero.

Para desarrollo diario me importa el ciclo completo:

  1. El modelo recibe la tarea.
  2. Un agente o harness convierte esa tarea en cambios de archivos.
  3. El proyecto generado se compila y se prueba.
  4. El resultado se revisa con criterio de ingeniería.
  5. El costo y la fricción deciden si realmente usaría esa configuración todos los días.

Ese último punto importa. Un modelo puede ser excelente y aun así ser poco práctico si es demasiado caro, no está disponible, es incómodo de ejecutar o está dentro de un harness que no encaja con mi flujo. En desarrollo real, utilidad no es solo puntuación. Es puntuación dividida por fricción.

DIAGRAMA

Del output del modelo a confianza backendEl modelo útil no es el que escribe más. Es el que sobrevive la verificación y tiene un costo suficientemente bajo para mantenerse en el flujo.Del output del modelo a confianza backendMisma tareabackendServicio GogeneradoBuild, testsrace detectorCriterio deingenieríaAsistente útildiarioOpus5 / Fable5 / Sonnet5Kimi-K3 / GLM-5.2Race / deadlock / incomplete

El modelo útil no es el que escribe más. Es el que sobrevive la verificación y tiene un costo suficientemente bajo para mantenerse en el flujo.

La comparación no es solo el output del modelo. La señal útil aparece después de pasar el código por build, tests, race detector y criterio humano de ingeniería.

El assessment

La tarea consistía en implementar un servicio backend responsable de orquestar la entrega de notificaciones por email, SMS y push notifications.

El enunciado dejaba espacio deliberado para el criterio de ingeniería. El diseño exacto de la API estaba abierto. Los proveedores externos podían simularse. El servicio debía correr localmente, tener tests, estar documentado y diseñarse como una primera versión productiva de un sistema que un equipo podría mantener con el tiempo.

El benchmark puntuó cada solución en doce categorías:

  • Correctitud.
  • Arquitectura y organización del proyecto.
  • Inyección y gestión de dependencias.
  • Go idiomático.
  • Concurrencia.
  • Manejo de errores.
  • Calidad y legibilidad del código.
  • Testing.
  • Patrones de diseño y extensibilidad.
  • Preparación para producción.
  • Documentación.
  • Criterio de ingeniería.

La parte importante es que la evaluación se basó en evidencia. Cada proyecto se compiló. Se ejecutaron los tests. Se ejecutó go test -race. En algunos casos añadí probes específicos cuando los tests entregados no ejercitaban el camino riesgoso.

Todos los modelos se usaron con su nivel de thinking por defecto. No subí, bajé ni ajusté el parámetro de reasoning-effort en ninguno. La idea era ver cómo se comporta cada modelo tal cual sale de fábrica, como lo usa la mayoría de la gente en el día a día, y no hasta dónde se le puede exigir con configuraciones de razonamiento afinadas a mano.

El harness importa tanto como el modelo

Hay otra variable que quiero dejar explícita, porque es fácil de olvidar y cambia el resultado: el harness. Un modelo nunca toca el codebase directamente. Lo maneja un agente o CLI que decide cómo se llaman las herramientas, cómo se editan los archivos, cómo se corren los tests y cuánto contexto ve realmente el modelo. El mismo modelo puede producir código muy distinto según esa capa.

Cada modelo fue manejado por su agente nativo, y en todos los casos usé la versión CLI del harness, no un IDE ni una interfaz web:

Harness (CLI)Modelos que manejó
Claude CodeOpus5, Fable5, Sonnet5, Opus-4.8
CodexGPT-5.6-Sol, GPT-5.6-Terra, GPT-5.5
AntigravityGemini-3.6-flash, Gemini-3.5-Flash
OpenCodeKimi-K3, Grok-4.5, GLM-5.2, MiniMax-M3, DeepSeek-V4-Pro, Qwen3.7-Max, MiMo-V2.5-Pro, Kimi-K2.7-Code

El harness queda registrado por modelo, pero las puntuaciones reflejan el código entregado, no la herramienta. Aun así, tenlo presente al leer el ranking: lo que comparas es un modelo más su agente, no un modelo en el vacío.

Vale la pena decirlo claro: nada de esto corrió con tokens de API medidos. Cada modelo se manejó a través de una subscripción plana — OpenCode (plan Go), Codex en ChatGPT Plus, y Claude Code en el plan Max (5x). Así es exactamente como la mayoría de la gente usa estas herramientas en el día a día, y eso cambia lo que significa “costo”: la restricción real no es un monto por llamada, sino cuánto del uso del plan consume un modelo antes de topar con sus límites.

El ranking

Benchmark

Puntuación de ingeniería backend

El mismo assessment de orquestación de notificaciones en Go, evaluado contra una rúbrica backend de 280 puntos.

  • Opus5Mejor268 /280
  • Fable5256 /280
  • Sonnet5254 /280
  • Opus-4.8252 /280
  • GPT-5.6-Sol247 /280
  • Kimi-K3242 /280
  • GLM-5.2225 /280
  • Gemini-3.6-flash216 /280
  • Gemini-3.5-Flash214 /280
  • MiniMax-M3211 /280
  • GPT-5.5209 /280
  • Grok-4.5206 /280
  • GPT-5.6-Terra203 /280
  • DeepSeek-V4-Pro164 /280
  • Qwen3.7-Max161 /280
  • MiMo-V2.5-Pro157 /280
  • Kimi-K2.7-Code153 /280
  • Strong Hire
  • Hire
  • Lean Hire
  • Lean No Hire

ComparaciónResultado por tier

Tier Modelos Qué los separó
Strong HireOpus5, Fable5, Sonnet5, Opus-4.8, GPT-5.6-SolArquitectura limpia, concurrencia acotada, ejecución sin races, tests útiles y documentación fuerte. Opus5 saca doce puntos al resto cerrando los gaps operativos y de manejo de errores que los demás dejaron abiertos.
HireKimi-K3, GLM-5.2, Gemini-3.6-flash, Gemini-3.5-Flash, MiniMax-M3Correctos, sin races y bien estructurados en capas, con ideas realmente buenas (admisión atómica de lote, middleware de proveedores, circuit breakers, provider failover), pero cada uno frenado por un gap de rigor o de shutdown.
Lean HireGPT-5.5, Grok-4.5, GPT-5.6-Terra, DeepSeek-V4-Pro, Qwen3.7-MaxLigeros en los ejes de producción/rigor, shutdowns que descartan trabajo ya aceptado, o arquitectura sólida en apariencia donde aparecieron data races reales al inspeccionar.
Lean No HireMiMo-V2.5-Pro, Kimi-K2.7-CodeConcurrencia peligrosa: data race, fan-out sin límites o deadlock determinístico.

Kimi-K3 y Kimi-K2.7-Code son modelos distintos, por eso aparecen como entradas separadas. Gemini aparece dos veces a propósito: Gemini-3.6-flash es un run sucesor de Gemini-3.5-Flash, y ambos se conservan en los resultados. Juntos representan la línea Flash actual de Google, que reemplazó al preview anterior de Gemini 3. (Ese preview, un run abortado de Gemini3-Pro, nunca produjo un servicio ejecutable y no se incluye.)

Opus5 es la excepción a la regla de “no sobrerreaccionar al orden”. Con 268 le saca doce puntos al líder anterior y dieciséis a su propia generación previa, y ese margen no es ruido: gana las dos categorías sobre las que gira este problema y es la única solución cuya superficie de producción quedó verificada corriendo, no solo leída.

Por debajo, el resto del tier superior estuvo tan cerca que no conviene sobrerreaccionar al orden exacto. Fable5 obtuvo 256, Sonnet5 254, Opus-4.8 252 y GPT-5.6-Sol 247. Es una diferencia de nueve puntos en una rúbrica de 280. En términos prácticos, los cuatro fueron fuertes.

La observación más útil está en lo que ocurrió por debajo de ese tier.

Qué separó a los modelos

La concurrencia fue el gran separador.

La mayoría de soluciones podía producir un backend con capas razonables. La mayoría podía escribir un README que sonaba maduro. Muchas podían implementar providers, validators, repositories y handlers con nombres correctos. Pero el assessment giraba alrededor de entrega concurrente segura bajo ráfagas, y ahí se rompía la ilusión.

Las soluciones más fuertes tenían una historia coherente de concurrencia:

  • Worker pools acotados.
  • Backpressure explícito.
  • Timeouts por intento.
  • Políticas de retry que distinguían errores transitorios y permanentes.
  • Copias defensivas alrededor del estado en memoria.
  • Tests que realmente ejercitaban caminos concurrentes.

Las soluciones más débiles fallaban de formas sutiles. El bug más común fue la trampa de punteros o slices compartidos: el store en memoria devolvía datos que los workers en background todavía podían mutar. El código se veía limpio. Los tests pasaban. Pero lecturas y escrituras concurrentes entraban en race porque el límite de copia estaba incompleto.

Ese es el tipo de bug que importa en backend. No aparece en una captura de pantalla. Aparece cuando tráfico real toca un camino que los tests del propio modelo nunca ejecutaron.

Los mejores resultados

Opus5 entregó la mejor solución de todo el benchmark con 268, y es la única que combina todas las propiedades del top tier en un solo codebase. La arquitectura es ports-and-adapters de manual alrededor de un dominio sin dependencias, con una capa de aplicación real e independiente del transporte — justo el gap que dejó a Kimi-K3 fuera del top tier. Su modelo de concurrencia es el más completo del grupo: un worker pool acotado alimentado por una cola acotada con admisión atómica de lote todo-o-nada (Queue.Reserve(n) toma las N ranuras o ninguna), un drenado limpio correcto y con testsStop cierra primero la cola y solo cancela el trabajo en vuelo si se vence el deadline —, una protección estructural contra el panic de enviar sobre un canal cerrado, y recuperación de panics por job. Todo sin races, y con tests que realmente ejercitan esos caminos en vez de simplemente convivir con ellos.

Donde se separa definitivamente es en el manejo de errores. Es una de solo dos soluciones que no ignora los errores de escritura terminales al store, y la única que escribe el resultado de la entrega a través de context.WithoutCancel, así que el resultado queda registrado incluso cuando el contexto que la rodea ya fue cancelado en el shutdown. Esa propiedad de durabilidad no la tiene nadie más en el grupo, y es el tipo de detalle que normalmente solo aparece después de que alguien perdió datos por no tenerlo.

Pero lo que de verdad me sorprendió pasó durante el run, no en la revisión. Opus5 es el único modelo que verificó su propio contenedor: abrió Docker Desktop en mi Mac, construyó su imagen, levantó el contenedor, comprobó que /healthz y /readyz respondieran en verde, envió una notificación y la vio llegar a delivered — y después destruyó el contenedor y limpió lo que había creado. Ningún otro modelo hizo nada parecido. Seis de las diecisiete soluciones no traen Dockerfile siquiera, y varias de las que sí lo traen fijan una versión de Go con la que su propio módulo no compila. Opus5 es la única solución cuyo Dockerfile no tuve que creerle: un binario estático de 8.99 MB sobre scratch, sin root, confirmado corriendo de punta a punta. Su único defecto es mecánico y pequeño — cinco símbolos exportados sin usar, confirmados con deadcode, por −2.

Fable5 obtuvo la segunda mejor puntuación. Su solución se leía como una primera versión productiva: arquitectura limpia con dependencias hacia adentro, cola acotada, worker pool fijo, validación fail-fast, retry/backoff, buenos tests y documentación excelente. También tomó una buena decisión de modelado: la unidad de trabajo no era solo una notificación, sino la entrega de una notificación a un destinatario.

Sonnet5 quedó casi empatado. Tenía arquitectura madura, tests fuertes, circuit breakers y documentación de diseño excelente. Los peros principales fueron operativos: sin Dockerfile ni Makefile, un detalle de shutdown/drain y mapas en memoria sin límite. No son detalles irrelevantes, pero no están al nivel de una race en el camino central. También vale la pena mencionar que Sonnet5 funciona mejor cuando se le pasa un requerimiento bien estructurado, funciona mejor cuando le dices claramente que hacer.

Opus-4.8 también fue excelente, aunque conviene decirlo de entrada: ya no es seleccionable en Claude Code — más sobre eso abajo. Usó pocas dependencias, defaults con mentalidad productiva, worker pool acotado, backpressure, retry con jitter, circuit breakers, logging estructurado y buena cobertura. Sus gaps principales estuvieron alrededor de Docker y observabilidad.

GPT-5.6-Sol, manejado por Codex, fue la sorpresa de la ronda con 247, entrando al tier Strong Hire justo en la puerta del bloque de Anthropic. Se leía como un servicio genuinamente orientado a producción: paquetes limpios con dependencias hacia adentro, concurrencia sin races con admisión atómica de lote completo y un shutdown que drena la cola, y un stack de fiabilidad real — clasificación de errores retryable-vs-permanente, backoff acotado con jitter determinístico, idempotency keys que devuelven 409 en conflicto, config por entorno validada, Docker, endpoints de health y readiness, e incluso un contrato OpenAPI. Lo único que lo dejó fuera del top tres fueron los errores de store terminales descartados (−5) y una cobertura de tests moderada. Es la más fuerte de todas las soluciones de GPT y Gemini.

Kimi-K3, manejado por OpenCode, fue la solución más fuerte fuera del top tier con 242 (Hire). Trajo las dos propiedades que definieron al tier Strong Hire — admisión atómica de lote todo-o-nada y un drenado limpio comprobado por un test — más un stack de resiliencia a la medida del enunciado: timeouts por intento compuestos con decoradores, retry con backoff y jitter, un circuit breaker y clasificación de errores temporales vs permanentes. Corrió 44 tests que fijan propiedades con relojes inyectados, no cargó dependencias de terceros y entregó la mejor documentación del grupo. Fue además una de solo dos soluciones que nunca ignoran un error de escritura al store — la otra es Opus5 —, y una de las pocas cuyo rate limiter desaloja buckets ociosos. Lo dejó fuera del top tier un único gap de arquitectura — no tiene capa de aplicación, con el caso de uso de submit viviendo dentro del handler HTTP y alcanzable solo por HTTP — más dos métodos exportados muertos (−2), sin Dockerfile y un binario compilado commiteado al árbol.

GLM-5.2, manejado por OpenCode, alcanzó 225 (Hire) con trabajo de alta factura: un stack de middleware de proveedores (circuit breaker ∘ retry ∘ timeout ∘ attempts) que fue la respuesta más limpia al enunciado de proveedores poco confiables, errgroup usado exactamente donde el benchmark lo premia y usado correctamente, y resultados por destinatario con códigos de error estructurados y un estado agregado partial — el reporte de entrega más expresivo del grupo. Sumó backpressure 503 real, recuperación de panics, 44 tests y un README muy completo. Quedó por debajo de Kimi-K3 por un shutdown que abandona la mayoría de sus notificaciones encoladasStop() cancela antes de drenar, con un test que fija el mismísimo mecanismo que causa la pérdida — más una escritura terminal descartada en el camino de backpressure (−5), dos símbolos exportados muertos y un campo Jitter sin cablear (−2), un http.Server al que le faltan tres de sus cuatro timeouts, y sin Dockerfile.

Gemini-3.6-flash, también manejado por Antigravity, quedó apenas por encima de su predecesor con 216 (Hire) — un run sucesor de 3.5 que amplía bastante la superficie de producción. Suma un circuit breaker, backpressure real no bloqueante (Submit devuelve ErrQueueFull), config por entorno externalizada, un endpoint de health, un Dockerfile con docker-compose, un spec OpenAPI y clasificación de status HTTP por errores centinela vía errors.Is — arreglando justo el string-matching que frenaba a 3.5. Lo que lo mantiene a media tabla son tres problemas de rigor, dos de ellos regresiones frente a 3.5. Su graceful drain es cosmético: Pool.Stop() cancela el contexto del pool antes de drenar, así que el backlog del shutdown se desencola pero se fuerza a fallar bajo un contexto cancelado (verificado 0/20 entregados, terminal failed, donde 3.5 al menos sí entregaba su drain). Su pipeline de validación despliega una goroutine por validador por ítem sobre cuatro chequeos puramente en memoria sin I/O (−3, donde 3.5 se salvó solo porque sus validadores simulaban latencia). Y repite los errores de repo.Update sistemáticamente ignorados de 3.5 (−5). Añade tres archivos de fuente sin formatear, un binario de 9.1 MB commiteado, un go.mod desprolijo y un Dockerfile que fija golang:1.22 contra un módulo go 1.26.3, y tienes un modelo que mejora la superficie operativa de su predecesor mientras arrastra sin cambios sus gaps de rigor centrales.

Gemini-3.5-Flash, manejado por Antigravity, fue el más fuerte del bloque medio con 214 (Hire). Trajo ideas realmente buenas: provider failover con un primario y un fallback por canal, y un motor de validación concurrente cuyo paralelismo sí está justificado porque los validadores cargan latencia de I/O simulada. La cobertura en los paquetes de lógica fue alta. Lo frenó un cúmulo de problemas de rigor e higiene evitables: cada error de repo.Update descartado en el worker (−5), códigos de status HTTP clasificados por string-matching del mensaje de error, sin endpoint de health, sin configuración externa, un List que silenciosamente perdió sus filtros y paginación, cuatro archivos de test sin formatear y un binario compilado commiteado al repo.

Grok-4.5, manejado por OpenCode, quedó en 206 (Lean Hire) y fue el mejor equipado del bloque bajo en lo operativo: errores centinela mapeados a status HTTP vía errors.Is en vez de string-matching, backpressure 503 real, nueve perillas por entorno, endpoint de health y timeouts completos. Pero sus gaps de rigor caen todos sobre el camino de entrega asíncrono en el que gira el assessment: el worker pool nunca cierra su canal de jobs y los workers salen al cancelarse, así que un probe encontró 18 de 20 trabajos encolados silenciosamente abandonados en el shutdown; las 12 llamadas de update al store en el worker descartan su error (−5); un fallo de enqueue a mitad de fan-out devuelve 503 sin IDs mientras destinatarios anteriores ya están en vuelo; y la suite no ejercita ni concurrencia, ni backpressure, ni shutdown.

GPT-5.6-Terra, también manejado por Codex, quedó en 203 (Lean Hire). Su core es correcto y sin races, con capas de paquetes limpias, config por entorno validada, un shutdown que sí drena con un deadline y protege al productor para que un submit posterior al shutdown nunca haga panic, y la mejor idempotencia del grupo (202/200/409). Lo que lo frena es que no modela la premisa de apertura del enunciado: su único proveedor siempre devuelve éxito, así que los caminos de retry, timeout por intento y error permanente nunca se ejecutan en runtime; preferencias y rate limiting llegan como no-ops; la escritura terminal delivered descarta su error (−5); una rama de retry inalcanzable suma −2; y sus seis tests son los menos del grupo. Su README es el contrapunto honesto — nombra cada uno de estos gaps en vez de disimularlos. Mismo harness y ajustes por defecto que Sol, y un resultado distinto: un buen recordatorio de que ni siquiera una familia de modelo sobre un agente es una cantidad fija.

Si esto fuera solo una cuestión de puntuación, la respuesta ahora es inequívoca: ganó Opus5, y no por poco.

Pero para desarrollo diario, la respuesta tiene más matices.

Tiempo y costo

Hay dos dimensiones más que sí capturé, al menos en parte: cuánto tardó cada run y cuánto costó.

El tiempo de reloj fue de unos tres minutos y medio hasta casi cuarenta — y lo llamativo es lo poco que eso predijo la calidad.

ModeloTardóPuntaje
Grok-4.53m 35s206
Gemini-3.5-Flash~4m 10s214
DeepSeek-V4-Pro5m 41s164
Gemini-3.6-flash~6m 00s216
MiniMax-M36m 43s211
Kimi-K2.7-Code7m 01s153
GPT-5.57m 20s209
GPT-5.6-Terra8m 40s203
Qwen3.7-Max9m 39s161
GPT-5.6-Sol10m 23s247
MiMo-V2.5-Pro10m 31s157
GLM-5.211m 12s225
Sonnet5~15m254
Fable5~18m256
Opus-4.819m 48s252
Kimi-K325m 41s242
Opus539m 11s268

El run más rápido del grupo (Grok-4.5, 3m 35s) y uno de los más lentos (Kimi-K3, 25m 41s) quedan a un tier de distancia en la dirección equivocada — el lento puntuó más alto. Opus-4.8 tardó casi veinte minutos para 252; Gemini-3.5-Flash tardó cuatro para 214. La velocidad es un factor ergonómico real en el día a día, pero no es un proxy de la calidad de ingeniería.

Opus5 es la ilustración más clara de eso, en las dos direcciones. Es por amplio margen el run más lento del grupo con 39m 11s — más de once veces Grok-4.5 — y también produjo el mejor código. Parte de ese tiempo no es generación en absoluto: es el modelo construyendo su propia imagen, levantando el contenedor y probando los endpoints antes de darse por terminado. Es tiempo gastado en verificación en vez de output, que es exactamente el trade que hace un ingeniero cuidadoso y exactamente el que un benchmark que solo cuenta tokens por minuto anotaría como pérdida.

El costo es la dimensión que una subscripción plana esconde a propósito, y es la que más cambia la recomendación. Como nada de esto corrió con tokens de API medidos, no puedo poner una cifra en dólares limpia y transversal por modelo — pero la economía de fondo no es un secreto, y sí importa:

  • Los modelos de Anthropic son los más caros de correr — pero Opus5 cambió la forma de ese problema. Fable5 es el caso extremo; Opus5 queda alrededor de la mitad por run, que es justo la diferencia entre un modelo que usas de vez en cuando y uno con el que realmente puedes trabajar. Sigue siendo un sobrecosto frente a todo lo demás aquí, y sigue siendo el run más largo del grupo, pero ya no está fuera de precio para un flujo normal como lo estaba el top tier anterior.
  • La línea GPT-5.6 de OpenAI es la respuesta competitiva. Sol y Terra alcanzan una calidad de ingeniería comparable a un costo bastante menor, que es justo lo que los hace atractivos como herramientas de todos los días y no ocasionales.
  • Los modelos open source son aún más baratos, por un margen amplio. Para los modelos que corrí medidos a través de OpenCode, la tarea completa quedó entre unos $0.14 y $1.50 — DeepSeek-V4-Pro alrededor de $0.14, MiniMax-M3 $0.20, MiMo-V2.5-Pro $0.23, Grok-4.5 $0.29, Kimi-K2.7-Code $0.33, Qwen3.7-Max $0.83, Kimi-K3 $1.35, GLM-5.2 $1.50.

La cima del ranking es Anthropic. El mejor puntaje-por-dólar no lo es — y esa brecha es toda la razón por la que la respuesta práctica difiere del ranking bruto.

La recomendación práctica

Antes de la recomendación, un dato de contexto que el ranking no puede mostrar: Claude Code reemplaza sus modelos en vez de acumularlos. No es como ChatGPT, donde la generación anterior queda seleccionable un tiempo después de que llega la nueva. En el plan hoy están Fable5, Opus5, Sonnet5 y Haiku 4.5 — y esa es la lista completa. Opus-4.8 puntuó 252 aquí y simplemente ya no es una opción. Cualquier recomendación construida sobre él caducó el día que salió su sucesor, lo cual es una pequeña lección aparte sobre lo rápido que envejece este tipo de comparación.

Eso reordena la respuesta práctica más que el nuevo puntaje. Opus5 es el ganador del benchmark y, inesperadamente, también la opción razonable. Su costo por run queda alrededor de la mitad del de Fable5, lo que lo saca de la categoría de “usar con cuentagotas” en la que vivía el top tier anterior de Anthropic. Sigue siendo un sobrecosto frente a los modelos abiertos, que continúan siendo dramáticamente más baratos, y sigue siendo el run más lento del grupo con casi cuarenta minutos. Pero “mejor resultado del benchmark” y “suficientemente accesible para usarlo de verdad” no se habían solapado en esta comparación hasta ahora.

Fable5, el ganador anterior, sigue en el plan y sigue siendo el extremo caro. Su disponibilidad se ha extendido más de una vez sin una decisión anunciada sobre si se queda de forma permanente, y con un costo por run de alrededor del doble que Opus5 para doce puntos menos, ahora es difícil defenderlo por algo que no sea preferencia personal.

Sonnet5 también es muy fuerte, pero tiene varios peros prácticos dependiendo de su uso como agente o sub-agente, la suscripción, los límites de uso y el flujo de trabajo donde lo uses. Funciona mucho mejor si le das instrucciones claras y precisas sobre que hacer.

Eso deja una recomendación práctica distinta del ranking bruto:

ComparaciónCómo elegiría en la práctica

Elección práctica Por qué lo consideraría Caveat
Opus5El mejor resultado de ingeniería del benchmark por amplio margen, el único modelo que verificó su propio contenedor en vez de pedirme que le creyera al Dockerfile, y — a alrededor de la mitad del costo por run de Fable5 — el primer resultado top-tier de Anthropic que no duele usar con regularidad.El run más lento del grupo (39m 11s), y aún un sobrecosto claro frente a los modelos abiertos. En un plan tipo Max la restricción son los límites de uso del plan, no un precio por token.
GPT-5.6-SolUn resultado genuinamente top-tier manejado por Codex, con un stack de fiabilidad completo (clasificación de errores, jitter, idempotencia, Docker, health/ready) y amplia disponibilidad.Aún descarta errores de escritura terminales en el worker, y la cobertura de tests es solo moderada.
Kimi-K3Ingeniería casi top — admisión atómica de lote, drenado limpio con test, stack de resiliencia completo, cero dependencias, y una de solo dos soluciones que nunca ignoran un error de escritura al store.Sin capa de aplicación (la lógica de submit vive en el handler HTTP), sin Dockerfile y un binario commiteado al árbol.
GLM-5.2El diseño de fiabilidad de proveedores más limpio del grupo (middleware más errgroup) con resultados por destinatario muy expresivos, en un perfil abierto y de bajo costo.Un shutdown que descarta la mayoría de las notificaciones encoladas, una escritura terminal descartada, y un http.Server al que le faltan casi todos sus timeouts.
Gemini-3.6-flashUn run sucesor de 3.5 con una superficie de producción mucho más amplia — circuit breaker, backpressure real, endpoint de health, Docker, OpenAPI y clasificación HTTP con errors.Is — en el mismo perfil Flash rápido y barato.Un drain cosmético que no entrega nada en el shutdown, los errores de update ignorados heredados de 3.5, goroutines por validador innecesarias, y descuidos de higiene (archivos sin formatear, binario commiteado).
Gemini-3.5-FlashResultado bien estructurado en capas y sin races, con ideas lindas como provider failover, en un perfil Flash rápido y barato.Errores de update ignorados, status HTTP por string-matching, sin endpoint de health ni config externa, y descuidos de higiene.
MiniMax-M3Arquitectura suficientemente buena y ejecución sin races, con un shutdown que sí drena y un sweeper TTL que acota la memoria.Errores de repo-update ignorados, un pipeline de validación que nunca llama, una cola que puede responder 202 por trabajo que nunca aceptó, y sin Dockerfile.
GPT-5.5Output compacto, legible y pragmático, con buena arquitectura y sin data races.Tests más delgados, un shutdown que descarta trabajo aceptado, sin Docker y errores de update ignorados.

Una nota sobre los dos modelos frontera de GPT: GPT-5.5 sigue en la lista y continúa siendo perfectamente usable para trabajo real. Pero GPT-5.6-Terra alcanza más o menos el mismo resultado siendo más liviano para el plan, así que en la práctica Terra va tomando el lugar de 5.5 — hasta que eventualmente retiren 5.5 de la subscripción por completo.

Para trabajo backend diario, prefiero usar un modelo un poco menos brillante pero rápido, barato y confiable dentro del loop de editar-probar-revisar, antes que uno que solo usaría ocasionalmente porque cada iteración es cara o carga mucho al plan. Esa fue justo la trampa en la que cayó todo el top tier de Anthropic: ganaban el benchmark, pero su costo los empujaba al uso ocasional. Opus5 es el primero que escapa en parte. A la mitad del costo de Fable5 es defendible como herramienta habitual y no solo de emergencia — aunque la versión honesta es que sus runs largos lo siguen haciendo más adecuado para la pieza que tiene que salir bien a la primera que para el ida y vuelta rápido, y los modelos abiertos siguen siendo un orden de magnitud más baratos para todo lo que no necesita este nivel de rigor.

Los agentes y harnesses también son parte de la decisión. El mismo modelo puede sentirse distinto dentro de Claude Code, OpenCode, Cursor, un CLI propio o un evaluador vía API. El harness decide cómo se llaman herramientas, cómo se editan archivos, cómo se ejecutan tests, cuánto contexto hay disponible y cuánto cuesta cada ciclo. Eso significa que la comparación real no es solo modelo contra modelo. Es modelo más workflow.

Qué me sorprendió

La primera sorpresa fue que la documentación no discriminó demasiado. Casi todas las soluciones serias tenían un buen README. Algunas tenían notas de arquitectura excelentes. Pero un README bien escrito puede describir el sistema que el modelo quiso construir, no necesariamente el sistema que realmente construyó.

La segunda sorpresa fue cuántas veces los tests dieron falsa confianza. Pasar go test -race solo importa si los tests ejercitan el camino concurrente. Qwen3.7-Max es un buen ejemplo: su suite pasaba con -race, pero un probe específico reprodujo una race en el camino central.

La tercera sorpresa fue el valor de la verificación aburrida. go build, go vet, gofmt, go test, go test -race, builds de Docker y pequeños tests dirigidos revelaron más que leer el README. Probablemente esa es la lección más importante para el desarrollo diario.

La cuarta sorpresa llegó con Opus5, y es la que no anticipé en absoluto: un modelo que corrió ese loop de verificación sobre sí mismo. Dieciséis modelos me entregaron un Dockerfile — o no — y siguieron adelante. Opus5 abrió Docker Desktop, construyó la imagen, levantó el contenedor, revisó los endpoints de health, llevó una notificación hasta delivered y después destruyó el contenedor. Es algo pequeño y grande al mismo tiempo. Pequeño, porque construir tu propia imagen no es una idea difícil. Grande, porque el modo de fallo más común de todo este benchmark es un modelo afirmando una propiedad que nunca comprobó — y este es el único run donde el modelo cerró ese hueco por su cuenta en vez de dejármelo a mí.

Qué haría distinto la próxima vez

Desde el inicio haría explícita la metadata del harness: modelo, proveedor, agente, versión, costo, duración, tier de suscripción, número de reintentos y si el modelo tuvo acceso a ejecución de herramientas. Capturé parte de esto informalmente, pero no lo suficiente para construir una tabla limpia de costo-rendimiento.

También añadiría un paquete estándar de pruebas adversariales. Los tests entregados son útiles, pero no suficientes. Un benchmark así debería incluir probes para:

  • Lecturas concurrentes mientras workers en background mutan estado.
  • Saturación de cola y comportamiento de enqueue parcial.
  • Graceful shutdown con trabajos en curso y trabajos pendientes.
  • Builds Docker contra la versión de Go declarada.
  • Casos borde de validación multi-destinatario.
  • Errores de persistencia al escribir estados terminales.

Ahí es donde se ve la calidad backend.

Ideas clave

  • La mejor puntuación del benchmark fue para Opus5 con 268 — doce puntos por encima de Fable5 (256) y dieciséis sobre su propia generación anterior —, seguido por Sonnet5, Opus-4.8 y GPT-5.6-Sol, que cerró el tier Strong Hire con 247.
  • Opus5 fue además el único modelo que verificó su propio trabajo de punta a punta: abrió Docker, construyó y levantó su contenedor, revisó los endpoints y luego lo destruyó. En un grupo donde el defecto más común es una afirmación sin comprobar, ese comportamiento pesó más que cualquier categoría individual.
  • Kimi-K3 (242) y GLM-5.2 (225) lideraron el tier Hire, por delante de Gemini-3.6-flash (216), Gemini-3.5-Flash (214) y MiniMax-M3 (211); GPT-5.6-Terra quedó en 203 pese a compartir la familia de modelo, el harness y los ajustes por defecto de Sol — un recordatorio de que la variante del modelo y el harness importan, no solo el nombre del modelo.
  • Todos los modelos se manejaron con su harness CLI nativo y thinking por defecto, así que lo que el ranking realmente compara es un modelo más su agente, no un modelo aislado.
  • Por primera vez el ganador del benchmark también es una respuesta práctica: Opus5 cuesta alrededor de la mitad que Fable5 por run, lo que lo hace defendible como herramienta habitual y no ocasional — con GPT-5.6-Sol, Kimi-K3, GLM-5.2, Gemini-3.6-flash, Gemini-3.5-Flash, MiniMax-M3 o GPT-5.5 como las opciones más baratas del día a día, según costo, disponibilidad y harness preferido.
  • La disponibilidad es parte de la recomendación: Claude Code reemplaza sus modelos en vez de acumularlos, así que Opus-4.8 — cuarto en este ranking — ya no está en el plan. Hoy están Fable5, Opus5, Sonnet5 y Haiku 4.5.
  • La correctitud de concurrencia separó a los modelos fuertes de los pulidos pero riesgosos.
  • La calidad de documentación fue alta en general, así que no bastó para juzgar utilidad.
  • Los tests solo importan cuando ejercitan los caminos donde fallan los sistemas backend.
  • El tiempo de ejecución (de ~3.5 a ~39 minutos) no predijo el puntaje en ninguna dirección: hubo runs rápidos a media tabla y lentos también — aunque el más lento de todos, Opus5 con 39m 11s, produjo el mejor código, con buena parte de ese tiempo gastado en verificar y no en escribir.
  • El costo es donde el ranking y la recomendación más divergían, y esa brecha se acortó: Anthropic sigue encabezando el puntaje y sigue siendo lo más caro, pero Opus5 corre a alrededor de la mitad que Fable5; la línea GPT-5.6 de OpenAI iguala buena parte de esa calidad por menos; y los modelos open source terminaron toda la tarea por unos $0.14$1.50.
  • La pregunta diaria no es “¿qué modelo es más inteligente?”, sino “¿qué modelo más agente más loop de verificación me ayuda a entregar código más seguro a un costo práctico?”.

Continuar explorando

Si quieres reproducir o cuestionar las conclusiones, empieza por el repositorio del benchmark. Lee el assessment, luego la rúbrica y después los reportes por modelo. El ejercicio más útil no es mirar quién ganó. Es mirar por qué código backend que parecía bueno falló.

Ideas relacionadas para explorar después:

  • Evaluación de LLMs en tareas de ingeniería de software.
  • Diseño de agentes/harnesses y confiabilidad en el uso de herramientas.
  • Race detection y testing de concurrencia en Go.
  • Assessments backend como benchmarks para modelos.
  • Workflows de IA conscientes del costo para desarrollo diario.

// seguir explorando

Seguir explorando