Estandarizar el Desarrollo en una Era de Código Generado por IA
Impacto
Starters como producto interno, adoptados por todo el equipo
Cuando pasamos de plataformas low-code a que cada desarrollador tuviera control total del código con asistentes de IA, perdimos los límites invisibles que mantenían consistencia entre proyectos. Construí starters y herramientas internas con guardrails verificables automáticamente, y convertí su evolución en un proceso colaborativo con el equipo.
Durante mi última etapa trabajando en un equipo de desarrollo de aplicaciones web y móviles, viví un cambio que estaba pasando a una velocidad considerable. Durante años, buena parte del equipo había construido productos sobre plataformas low-code: la plataforma imponía determinadas reglas sobre cómo se construían las aplicaciones, y los desarrolladores podían avanzar rápido sin tener que preocuparse por todos los detalles internos de una codebase. La aparición de herramientas capaces de generar código con IA empezó a cambiar ese modelo. De un momento a otro, un desarrollador podía pasar de trabajar dentro de las restricciones de una plataforma low-code a tener control prácticamente absoluto sobre el código fuente. Eso abría muchas posibilidades, pero también eliminaba algunos de los límites que, aunque invisibles, ayudaban a mantener consistencia entre proyectos.
El problema de la libertad
Cuando cinco o seis desarrolladores usan herramientas de IA para construir aplicaciones, incluso con la misma herramienta, es muy probable que terminen resolviendo los mismos problemas de maneras completamente distintas. No porque una solución sea mejor que otra: simplemente porque ahora tienen la libertad de elegir. El problema aparece cuando esa libertad empieza a afectar la calidad y el mantenimiento de las codebases: archivos que ya no se usan, funciones declaradas pero nunca llamadas, dependencias innecesarias, código duplicado, configuraciones inconsistentes, reglas distintas entre proyectos, commits difíciles de rastrear, scripts que funcionan en la máquina de un desarrollador y fallan en la de otro. Es fácil ignorar cada uno de estos problemas mientras se construye una funcionalidad puntual, pero acumulados terminan aumentando el tamaño de las aplicaciones, dificultando el mantenimiento y generando fricción para el resto del equipo. La IA había reducido considerablemente el costo de producir código. Ahora necesitábamos asegurarnos de que también redujera, y no aumentara, el costo de mantenerlo.
Crear guardrails, no restricciones
En vez de intentar imponer una única forma de programar, empecé a trabajar en una serie de starters y herramientas internas que establecieran un mínimo común para los proyectos. El desarrollador seguía teniendo libertad para decidir cómo resolver un problema, pero la codebase debía tener mecanismos automáticos que evitaran los errores más comunes. Los starters incorporaban type checking, ESLint y reglas de calidad, validaciones automáticas, Conventional Commits, scripts de desarrollo y build, configuraciones consistentes para proyectos web y backend, y reglas y skills específicas para trabajar con agentes de desarrollo. La diferencia estaba en dónde poníamos la responsabilidad: no queríamos decirle al desarrollador exactamente cómo escribir cada función, queríamos que determinadas propiedades mínimas de la codebase fueran verificables automáticamente. Si algo podía validarlo una herramienta, no tenía sentido convertirlo en una discusión humana durante un code review.
Diseñar para humanos y agentes
La aparición de herramientas de desarrollo basadas en IA trajo otro desafío. Un desarrollador puede entender las convenciones de un equipo después de meses trabajando dentro de una organización; un agente de IA no tiene necesariamente ese contexto. Por eso empezamos a incorporar reglas y skills que transmitieran parte de esas convenciones directamente a las herramientas que usaban los desarrolladores, para que el contexto del proyecto no dependiera exclusivamente de que cada persona recordara cómo hacer determinada tarea. La codebase empezó a describir parte de sus propias reglas. El objetivo no era controlar al agente: era darle suficiente contexto para que pudiera producir código compatible con el proyecto desde el principio.
El starter como producto interno
Con el tiempo, los starters dejaron de ser un conjunto de archivos de configuración y se convirtieron en una especie de producto interno. Los desarrolladores los usaban para iniciar proyectos nuevos y, a medida que los usaban, aparecían nuevos casos de uso: un script que funcionaba perfecto en Linux pero necesitaba ajustes para Windows, una validación que no contemplaba un escenario real del equipo, una regla que parecía útil en teoría pero generaba demasiada fricción en la práctica. En vez de mantener los starters como una solución definida unilateralmente, abrimos el proceso de evolución al equipo.
Convertir la estandarización en un proceso colaborativo
Organizamos una retro para discutir cómo estaban funcionando los starters en proyectos reales. Lo interesante fue que personas que normalmente no participaban demasiado en este tipo de conversaciones empezaron a compartir sus experiencias: cada desarrollador estaba usando las herramientas de una manera ligeramente distinta, y eso nos permitió descubrir problemas que no habíamos previsto. La conversación pasó de “estas son las reglas que deberíamos usar” a “¿qué necesitamos como equipo para trabajar mejor?”. Esa diferencia importó: la estandarización dejó de ser algo impuesto desde arriba y se convirtió en una responsabilidad compartida, con los propios desarrolladores proponiendo mejoras y discutiendo qué cosas realmente valía la pena estandarizar.
El problema que no aparece en tu máquina
Uno de los aprendizajes más concretos vino de los detalles menos interesantes: los scripts tenían que funcionar en distintos sistemas operativos. Yo trabajaba principalmente en Linux, mientras que parte del equipo usaba Windows, y algo trivial en un entorno Unix podía comportarse completamente distinto en Windows. Eso nos obligó a revisar cómo diseñábamos los scripts, cómo manejábamos paths, comandos y dependencias del sistema y, sobre todo, a dejar de asumir que mi entorno local representaba el del resto del equipo. La estandarización no podía basarse en cómo funcionaba el proyecto en mi máquina. Tenía que funcionar para el equipo real.
Resultado
La adopción de los starters permitió que los desarrolladores arrancaran proyectos nuevos con una base técnica consistente, sin reconstruir desde cero todas las decisiones de calidad, tooling y configuración, y redujo la curva de aprendizaje para quienes pasaban de un entorno predominantemente low-code a un modelo de desarrollo basado directamente en código e IA. Pero el resultado más importante fue cultural: la conversación dejó de centrarse en qué herramienta de IA usaba cada desarrollador y empezó a centrarse en cómo conseguir que cualquier herramienta pudiera producir código que cumpliera unos estándares mínimos del equipo. No necesitábamos que todos usaran el mismo agente ni que resolvieran los problemas de la misma manera. Necesitábamos una base común que protegiera la calidad del producto sin importar quién escribiera el código o qué herramienta usara para hacerlo.
Lo que aprendí
La IA está haciendo que producir código sea cada vez más barato, y eso cambia dónde aparece el costo real de la ingeniería: cuando escribir código deja de ser la principal limitación, mantenerlo, entenderlo, validarlo y hacerlo evolucionar se convierte en el nuevo cuello de botella. Por eso creo que los equipos no deberían intentar controlar cada línea que producen sus desarrolladores o sus agentes. Deberían construir guardrails que permitan experimentar y moverse rápido sin perder las propiedades fundamentales de una buena codebase. No se trataba de estandarizar cómo programábamos. Se trataba de estandarizar las condiciones bajo las cuales el código podía entrar al producto.