por Vinay Gaba, Ankit Mathur, Rishabh Singh, Patrick Wendell y Matei Zaharia
En Databricks, la forma en que creamos software está cambiando rápidamente a medida que adoptamos de manera decidida la AI para la ingeniería. El panorama de modelos y harnesses para la creación de código se ha expandido rápidamente en el último año, ofreciendo a los desarrolladores más opciones que nunca. Con más opciones, se ha vuelto cada vez más importante entender qué agentes de codificación ofrecen el mejor rendimiento en tareas de codificación del mundo real, así como comprender cómo varía el rendimiento de las tareas según el precio.
Este artículo comparte los resultados y la metodología del benchmark de codificación interno que creamos en Databricks, el cual evalúa las herramientas en tareas de codificación reales que nuestros ingenieros realizaron en la base de código de Databricks. Las tareas incluyeron modificaciones en una base de código de millones de líneas que abarca muchos lenguajes populares (Python, Go, Typescript, Scala, etc.), y tanto las tareas como las soluciones se revisaron minuciosamente para garantizar su precisión. Esto no pretende ser exhaustivo, pero el ejercicio reveló información valiosa que ya ha hecho que nuestro equipo de ingeniería sea significativamente más eficiente al usar agentes de codificación. A continuación, puede ver cómo puntuaron los modelos y harnesses en el benchmark general:

Figura 1: Costo vs. rendimiento en nuestro benchmark
Las principales conclusiones de nuestro análisis fueron:
Analicemos cada uno de ellos con un poco más de detalle.
El hecho de que los resultados específicos varíen por un par de puntos a menudo se compensa en las tareas del mundo real. Nos enfocamos más en los patrones temáticos que nos ayudan a razonar sobre qué modelos usar para diversas tareas. De hecho, los resultados mostraron una clara agrupación de los modelos y harnesses en 3 niveles de capacidad.

Figura 2: Surgieron tres niveles de capacidad distintos en nuestros resultados generales, con matices sobre qué modelos fueron efectivos en cada grupo
En el extremo superior del rendimiento, vemos que los modelos más inteligentes son muy eficaces para resolver todo tipo de problemas, pero son muy costosos. Los modelos de inteligencia media y baja siguen siendo muy eficaces en las tareas comunes y, en muchos casos, también son significativamente más baratos.
En el día a día, los ingenieros realizan muchas tareas diferentes que varían significativamente en complejidad: las tareas operativas comunes, como cambiar un flag o actualizar configuraciones, no requieren modelos extremadamente inteligentes, pero las exploraciones de diseño más profundas sí. Sin embargo, en el pasado, nuestros modelos predeterminados siempre eran los más costosos. Con base en este análisis, determinamos que deberíamos delegar más trabajo a la clase de modelos Haiku y GPT 5.4 Mini.
Ha habido mucho entusiasmo en torno a GLM 5.2, y nuestros resultados demostraron que GLM puede ser un modelo de uso diario para muchos de nuestros desarrolladores. Se posicionó en el nivel de capacidad superior, empatando estadísticamente en calidad con Opus 4.8, pero con un costo de $1.28 por tarea frente a los $1.94 de Opus.
Las puntuaciones de calidad de GLM son consistentes con los comentarios cualitativos que hemos recibido de los desarrolladores internos que han estado probando GLM para el desarrollo diario. Debido a su excelente rendimiento en las tareas de codificación cotidianas, nos hemos enfocado en ofrecer GLM con el mejor rendimiento, y la evidencia demuestra que es hora de comenzar a implementarlos como modelos de uso diario para la codificación.
Los desarrolladores a menudo estiman a simple vista los costos de los tokens para determinar qué tan costoso será un modelo al completar tareas de codificación. Sin embargo, descubrimos que los costos de los tokens suelen ser un mal indicador de los costos generales de las tareas, debido a la variación en la eficiencia de razonamiento entre los modelos. Esto subraya la necesidad de realizar benchmarks a nivel de tarea, ya que la forma y la complejidad de la tarea pueden ser diferentes en distintos contextos.
Como ejemplo, Sonnet 5 es aproximadamente 1.7 veces más barato por token que Opus 4.8, pero, en nuestras tareas, descubrimos que Sonnet costó $2.09 por tarea frente a los $1.94 de Opus, mientras que obtuvo una puntuación seis puntos menor en la finalización de tareas (81% frente a 87%). Esto se debió principalmente a que Sonnet 5 trabajó durante más tiempo y leyó más para lograrlo, consumiendo 1.9 veces más tokens.
Cuando ejecutamos el mismo modelo con el mismo esfuerzo de pensamiento a través de dos harnesses diferentes (Claude Code/Codex frente a Pi), observamos que el costo por tarea difería significativamente (más del doble en algunos casos), mientras que la calidad se mantenía igual. La diferencia principal radicó en la cantidad de contexto que cada harness proporcionaba al modelo en cada turno.

Pi envió aproximadamente 3 veces menos contexto por turno. Administró mejor el contexto, manteniendo un conjunto de trabajo más acotado y finalizando las tareas en menos ejecuciones.

La lección aquí no es que un harness sea siempre más barato o que los harnesses nativos sean peores. En cambio, la elección del modelo es solo una pieza del rompecabezas. Establecer esta flexibilidad es la razón por la que invertimos en Omnigent para que los intercambios de modelo y harness sean fluidos.
Los benchmarks públicos como SWE-Bench y TerminalBench son útiles, pero no pueden responder a las preguntas que teníamos. Hay algunas razones para esto:
Al crear un benchmark en nuestras propias PR, podemos tomar estas decisiones con mayor confianza de que no obstaculizaremos a nuestros desarrolladores al implementar optimizaciones.
Utilizamos Unity AI Gateway para capturar registros de todas nuestras interacciones de codificación, lo que nos permitió analizar la complejidad de las tareas que los ingenieros abordan utilizando agentes de codificación. Hubo una diversidad significativa en la complejidad de las tareas, y aproximadamente una cuarta parte se etiquetó como trabajo de baja complejidad y alrededor del 60% como de complejidad media.

Sin embargo, los modelos costosos son los modelos predeterminados que usan los ingenieros, por lo que claramente había una gran oportunidad para mejorar la eficiencia.
Nuestros ingenieros fusionan miles de cambios de código al día, por lo que ya tenemos un excelente conjunto de datos sobre el cual construir. Un buen pull request es un artefacto valioso, con commits que muestran la iteración del desarrollador, la revisión por parte de humanos y pruebas que ayudan a verificar que un cambio de código sea fiel a su intención. Sin embargo, necesitamos varios controles de calidad y filtros para construir un benchmark de alta calidad a partir de ellos:

Una vez que tuvimos las PR candidatas, nos enfocamos en construir tareas bien especificadas mediante:
El resultado de este ejercicio fue una sola tarea en el benchmark. Aquí hay un ejemplo simplificado:
Aunque utilizamos scripts e AI para generar tareas candidatas, evaluamos cada muestra a mano. En algunos casos, descubrimos que las pruebas de la PR original debían reescribirse para permitir una implementación alternativa o para ser más rigurosas, lo cual hicimos manualmente (sin AI). Del mismo modo, también encontramos casos que requerían mejorar la descripción de la tarea para que estuvieran bien especificadas.

Figura 3: Un antes y un después de nuestra suite de pruebas: la prueba anterior se basaba en verificar la coincidencia exacta de cadenas, lo que provocó algunos fallos cuando el modelo intentó resolver la tarea. Esta no era una buena manera de probar resultados no deterministas, por lo que se reescribió para evaluar el comportamiento en su lugar.
Instanciamos los arneses (harnesses) y modelos de agentes de codificación utilizando sus configuraciones estándar listas para usar, con todas las herramientas comunes que los ingenieros de Databricks tendrían a su disposición.

Cuando el agente decía explícitamente que había completado la tarea, guardábamos un punto de control (checkpoint) de ese código, aplicábamos los parches a las pruebas que se habían reservado y evaluábamos las pruebas para determinar si esa tarea era un "aprobado" para esa combinación de modelo + arnés. No utilizamos un juez LLM para evaluar la corrección, ya que hemos descubierto que esto premia el parecer correcto por encima de ser correcto.

En nuestros primeros experimentos, algunas puntuaciones de los modelos parecían demasiado buenas para ser verdad, por lo que inspeccionamos manualmente las trazas para entender qué había sucedido en estas trayectorias de los agentes. Lo que vimos fue que, debido a nuestra configuración original, la implementación "correcta" aún se podía recuperar en el historial de Git del árbol de trabajo (worktree). Cada tarea se había originado a partir de un commit fusionado, por lo que nada impedía que un agente con una terminal (shell) avanzara por el historial de Git para encontrarlo. Para solucionar este problema, sellamos el historial de Git: durante la duración de cada ejecución, desconectamos por completo la copia de trabajo del repositorio.
Comenzamos con una pregunta simple: ¿podemos usar agentes de codificación de manera más eficiente? La respuesta es un sí rotundo y, dado que podemos basarnos en datos, podemos comenzar a crear capacidades para seleccionar los modelos correctos automáticamente y realizar un seguimiento de la eficiencia.
Cualquier empresa puede hacer lo mismo. Cualquier equipo con un backlog de PR fusionadas ya cuenta con un benchmark en el que ningún modelo se ha entrenado, evaluado por las pruebas que escribió su equipo. Estamos agregando activamente más tareas (especialmente las más difíciles) y planeamos pasar cada nuevo agente/arnés por ellas para sentirnos más seguros de nuestras elecciones.
En Databricks, siempre hemos sido cautelosos con la dependencia de proveedores (lock-in), no solo de los proveedores en sí, sino de las suposiciones que hacen que los equipos sean menos flexibles con el tiempo. Ese mismo instinto dio forma a nuestras primeras apuestas por formatos y estándares abiertos, y define cómo estamos abordando la AI ahora: medir lo que realmente funciona en el código que enviamos, dar espacio a los ingenieros para moverse entre modelos y arneses (harnesses) con medidas de seguridad consistentes, y realizar optimizaciones para usar la AI de manera efectiva.
En un próximo blog, hablaremos más sobre cómo estamos utilizando las funciones de enrutamiento inteligente en Unity AI Gateway y en Omnigent para ayudar a nuestros desarrolladores a usar los agentes más inteligentes de manera eficiente.
(Esta entrada del blog ha sido traducida utilizando herramientas basadas en inteligencia artificial) Publicación original
Suscríbete a nuestro blog y recibe las últimas publicaciones directamente en tu bandeja de entrada.