Pasé un mes intentando sustituir los modelos que escriben nuestro código

Publicado el  · Actualizado el  · Igor Tkachenko

Un búho analista de OwlMeans examina código y un gráfico

Pasé cerca de un mes intentando sustituir los modelos propietarios de nuestro pipeline de desarrollo por modelos de pesos abiertos.

Era un mes que podría haber dedicado al producto en sí. Hice la apuesta porque cada rol especializado de OwlMeans llama a un modelo de lenguaje, y un cambio ahí llega a todo el flujo de desarrollo.

Por entonces, nuestro preset combinaba modelos de Anthropic y de OpenAI. Probé GLM, Kimi, DeepSeek y Qwen a través de proveedores que los alojaban. Quería saber si otro preset podía hacer el mismo trabajo de forma fiable.

Este experimento de junio no es un benchmark. No demuestra ninguna ventaja de costes para OwlMeans.

Nuestro pipeline divide un producto en piezas pequeñas. Un rol trabaja sobre una historia de usuario, una decisión de diseño o un cambio de código acotado. Recibe el contexto de ese trabajo, no el encargo de inventarse la aplicación entera.

Pensé que esa estructura podía hacer que cambiar de modelo fuera sencillo. Si la tarea era lo bastante acotada, quizá el modelo tendría menos ocasiones de malinterpretarla.

Era una hipótesis de ingeniería que podía probar en mi propio sistema. También era un desvío tentador para un fundador en solitario. Mejorar la maquinaria parecía útil para todos los proyectos futuros, y eso hacía fácil justificar otro día más de ajustes.

Tenía que mirar la ejecución completa, además de la app que salía de ella.

Respuestas vacías

El primer problema fue el razonamiento.

Algunos modelos gastaban en razonamiento interno el presupuesto de salida disponible y no devolvían contenido utilizable. El rol de programador terminaba su petición, pero la siguiente etapa no tenía nada que aplicar.

Intenté desactivar el razonamiento con un parámetro que el proveedor no siempre respetaba. Después puse límites explícitos a los roles afectados y los fui ajustando modelo por modelo.

Aquello exigió más atención de la que hacía pensar el cambio de preset. Un rol de planificación y uno de programación no necesitaban el mismo trato. Un parámetro que funcionaba con un modelo no era una regla que pudiera copiar sin riesgo a los demás.

El siguiente problema fue el formato de las respuestas. Nuestras etapas se pasan resultados estructurados unas a otras. Una respuesta que a mí me parece sensata puede no cumplir el esquema que espera el paso siguiente.

Añadí una vía basada en llamadas a herramientas para los casos en que un modelo no devolvía de forma fiable la estructura esperada. También cambié cómo circulaba el código por el pipeline: el agente pasó a trabajar con los fragmentos y parches pertinentes, en lugar de manejar una y otra vez archivos completos.

Esos cambios pasaron a formar parte del sistema que tenía que mantener. El experimento ya iba más allá de elegir un modelo de una lista.

El proveedor de por medio

El nombre de un modelo no identificaba todo el entorno de ejecución.

El proveedor que alojaba el modelo influía en qué funciones había disponibles y en cómo se comportaban las peticiones. Probé varios proveedores y al final usé el enrutamiento y la conmutación por error de OpenRouter en el preset experimental.

La documentación de OpenRouter sobre el enrutamiento entre proveedores explica los controles que hay para elegir y filtrar dónde se aloja el modelo. Mi pipeline dependía de una forma de respuesta concreta, así que esos controles importaban. Aun así, tuve que probar la ruta completa que estaba usando.

Por fin podía cambiar de preset y pasar el mismo proyecto por cada uno. Para entonces, detrás de ese cambio había límites de razonamiento, tratamiento de respuestas, extracción de código y elección de proveedores.

La app del final

En esas ejecuciones, las aplicaciones resultantes se parecían bastante. Noté diferencias en el CSS y, de vez en cuando, añadidos en la interfaz que yo no había pedido.

También vi a modelos capaces adornar una tarea pequeña cuando yo quería una implementación literal. Era una observación sobre mi carga de trabajo y mi configuración. Sería una mala base para clasificar los modelos en general.

A mí, que era quien operaba el sistema, me tocó lidiar con diferencias menos visibles. Los resultados estructurados que fallaban necesitaban otro intento, y tenía que ocuparme de los parches que no se aplicaban. Hasta un paso corriente podía detenerse por una incompatibilidad con el proveedor.

Una captura de pantalla final esconde ese trabajo.

Sustituir modelos significaba asumir más trabajo dentro del pipeline.

Tenía una comparación informal sacada de mis propias mediciones. No me fiaba de ella lo suficiente como para convertirla en una afirmación general sobre el rendimiento.

Los modelos tenían ajustes distintos. El comportamiento del proveedor formaba parte del resultado. Con los reintentos y los pasos de reparación, el recorrido de una ejecución importaba tanto como el artefacto final.

Una comparación seria necesitaría una tarea definida, las mismas comprobaciones de aceptación, una medición coherente y los fallos documentados. Mis ejecuciones me habían dado notas de ingeniería.

Por eso esta revisión deja fuera el antiguo titular con cifras. La dirección pública no cambia, para que los enlaces existentes sigan funcionando.

Aún tenía que decidir en qué invertir el tiempo. Podía seguir ajustando el preset experimental o volver a ocuparme del resto del producto. Más mediciones solo servirían si respondían a una decisión que de verdad tuviera que tomar.

Un mes de ajustes

Me quedé con una vía que funciona para probar modelos distintos. También encontré varias suposiciones que estaban escondidas dentro del pipeline: cómo razona un rol, cómo devuelve un resultado, cuánto código fuente recibe y qué pasa cuando falla su proveedor.

Es un conocimiento útil para el motor que estoy construyendo. No demuestra que otro fundador deba repetir el mismo experimento.

Si lo volviera a hacer, definiría antes las condiciones para parar. Decidiría qué patrones de fallo necesitaba entender antes de pasarme otra semana cambiando parámetros.

Ese mes me sirvió para entender mejor mi propio sistema. También le quitó un mes al resto de OwlMeans. Las dos cosas van en el balance.

Revisado el 15 de octubre de 2026. Se conserva el experimento de junio. El comportamiento de modelos y proveedores ha seguido cambiando; las observaciones de más arriba describen aquellas ejecuciones.

OwlMeans