La métrica equivocada

La mayoría de las conversaciones sobre la calidad del código generado por IA se centran en la corrección al momento de la generación. ¿Compila la salida? ¿Pasa las pruebas? ¿Cumple con la especificación?

Esos son requisitos mínimos. No dicen nada sobre el costo real.

La verdadera métrica es la reemplazabilidad: ¿qué tan barato es eliminar este module y reimplementarlo detrás del mismo contract cuando los requisitos cambian?

Si la respuesta es “trivialmente”, la velocidad de la IA se multiplica. Si la respuesta es “primero necesitamos rastrear seis dependencias implícitas”, ya has perdido la ventaja de velocidad que creías estar comprando.

Por qué el código generado por IA tiende al acoplamiento

Los modelos de lenguaje grandes optimizan para la solicitud inmediata. No optimizan para el cambio futuro.

Cuando solicitas un flujo de inicio de sesión, obtienes un flujo de inicio de sesión que funciona. No obtienes un flujo de inicio de sesión detrás de una interface de autenticación que pueda intercambiarse de Firebase a Supabase o a un servicio JWT personalizado sin tocar ninguna pantalla que lo consume.

Esto no es un fallo del modelo. Es un fallo de contexto. No se le pidió al modelo que optimizara para la reemplazabilidad, así que no lo hizo.

El resultado: el código generado por IA tiende al acoplamiento fuerte por defecto. No porque el modelo sea malo, sino porque el aislamiento nunca es el camino de menor resistencia para un predictor de siguiente token.

La reemplazabilidad es una decisión de arquitectura

La reemplazabilidad no ocurre por accidente. Es una elección estructural deliberada:

  • Cada dependencia externa se encuentra detrás de una interface que la aplicación posee.
  • Cada module generado expone un contract, no una implementación.
  • Cada capacidad opcional se inyecta, nunca se importa directamente.
  • Cada decisión de composición vive en un único composition root, no dispersa en cincuenta archivos.

Esto no es nuevo. Es inversión de dependencias básica. Lo que es nuevo es que el código generado por IA hace que violar estos principios sea sencillo e invisible hasta que necesitas cambiar algo.

El efecto compuesto

Cuando cada module es reemplazable:

  • Las generaciones malas cuestan minutos, no días.
  • Los cambios de proveedor son intercambios de interface, no rewrites.
  • La velocidad de la IA se mantiene lineal entre iteraciones, no logarítmica.
  • El equipo puede decir “regenera esto detrás del mismo contract” y hacerlo en serio.

Cuando los módulos están entrelazados:

  • Cada cambio requiere entender el grafo completo de dependencias.
  • Cada refactor asistido por IA corre el riesgo de romper sistemas no relacionados.
  • El equipo gradualmente deja de confiar en la salida de la IA porque el radio de impacto es impredecible.
  • La velocidad colapsa de vuelta a niveles pre-IA, pero ahora con más código que mantener.

La prueba práctica

Antes de aceptar cualquier module generado por IA en un codebase, aplica una prueba:

¿Puedo eliminar este archivo y reimplementarlo desde cero, usando solo la interface que expone, sin modificar ningún consumidor?

Si la respuesta es sí, publícalo. Si no, corrige el límite antes de publicar.

Esto es barato de aplicar. Un composition root más un diseño orientado a interfaces te da esta propiedad estructuralmente. No necesitas gobernanza elaborada. Necesitas una regla arquitectónica aplicada consistentemente.

La conexión con la arquitectura AI-native

Escribí sobre este problema más amplio en Stanford CS146S tiene razón sobre la programación con IA — El tema ausente es la arquitectura. El principio de reemplazabilidad es el mecanismo específico que hace que los codebases AI-native sobrevivan más allá de la versión uno.

Stanford está enseñando a los desarrolladores cómo usar herramientas de IA de manera efectiva. Eso importa. Pero la fluidez con herramientas sin reemplazabilidad es una trampa: publicas más rápido hasta que el codebase se vuelve costoso de cambiar, y entonces publicas más lento que equipos que nunca usaron IA.

La disciplina no es “hacer mejores prompts”. La disciplina es “arquitectar para que los errores de prompting sean baratos de deshacer”.

Preguntas frecuentes

¿Qué significa “arquitectura reemplazable” para el código generado por IA?

Arquitectura reemplazable significa que cada module generado por IA se encuentra detrás de una interface de la que el resto del sistema depende — no de la implementación en sí. Cuando los requisitos cambian o la generación es incorrecta, eliminas el module y lo reimplementas sin tocar a los consumidores.

¿Cómo se aplica la reemplazabilidad en un codebase generado por IA?

Tres mecanismos: interfaces propiedad de la aplicación (no de la dependencia), un único composition root donde todas las implementaciones se conectan, y una verificación en CI que falla si algún module importa directamente los internos de otro module.

¿La reemplazabilidad ralentiza el desarrollo inicial?

No. Definir una interface antes de generar una implementación añade segundos. El costo de no hacerlo aparece semanas después cuando un cambio de proveedor o un refactor se convierte en un rewrite completo.

¿Es esto lo mismo que la inyección de dependencias?

La inyección de dependencias es un mecanismo para lograr la reemplazabilidad, pero no es el panorama completo. La reemplazabilidad también requiere contract tests, validación de límites y un composition root — no solo parámetros de constructor.