Deuda técnica de Vibe Coding: por qué las apps hechas con IA son difíciles de cambiar después
Un sistema de gastos con IA funcionó meses. Cuando cambió una norma fiscal, nadie se atrevió a tocar código no leído. Los sistemas duraderos necesitan definiciones revisables.
En resumen: el cuello de botella del código generado por IA no es la velocidad a la que se escribe, sino que medio año después nadie puede leerlo y no hay un autor a quien preguntar. Si la IA genera metadatos revisables en lugar de pura implementación, la deuda de comprensión baja mucho.
La historia empieza en el séptimo mes.
Mingxiang es una empresa minorista con cientos de tiendas. El año pasado, su equipo financiero (más de cincuenta personas) se hartó de esperar en la cola de planificación de TI y montó “con una frase” un sistema de gastos con IA. Formularios, aprobaciones, conexión con el libro mayor: en dos días estaba en marcha y todos lo celebraron. Durante el medio año siguiente, funcionó perfectamente.
En el séptimo mes cambió una norma fiscal: se ajustó el porcentaje deducible de cierto tipo de factura y la lógica de gastos tenía que cambiar en consecuencia. Una pequeñez.
Y entonces el equipo descubrió que nadie se atrevía a tocarlo. Detrás de aquella “frase” había más de doce mil líneas de código generado por IA, y ni una sola persona lo había leído entero. ¿En qué archivos estaba repartida la lógica de deducción? ¿Cambiarla afectaría de rebote a las aprobaciones y al cierre de mes? Nadie sabía decirlo. Y lo más incómodo: ni siquiera la IA que escribió ese código pudo ayudar; es sin estado, y de aquella generación no quedó ni rastro de los juicios, las concesiones ni el porqué de cada decisión. Lo único que podías hacer era volver a meter las doce mil líneas en una sesión nueva y dejar que “adivinara” lo que había sido de sí misma.
Aquella pequeñez acabó llevando tres semanas. Y el coste real fue más que tres semanas: en la revisión previa al despliegue, alguien descubrió que la IA, de paso, había modificado un fragmento de lógica de conciliación que no tenía nada que ver con la deducción, y por poco hace que una tanda de gastos se calculara mal y se colara con importes erróneos en el libro mayor. Esta vez se atajó de milagro, pero dejó algo claro: este sistema ya no tiene a nadie que pueda garantizar que “cambiar A no toque B”.
Esto es la deuda de vibe coding aterrizando sobre un equipo corriente.
Es una deuda especial: la contraes, pero no encuentras al acreedor
La deuda técnica no es un término nuevo. Pero el código generado por IA contrae un tipo de deuda que antes no existía.
El código escrito por personas también se pudre y también se queda sin documentar. Pero al menos el autor sigue ahí: puedes traerlo y preguntarle “¿por qué resolviste esto así en su momento?”. Por malo que sea el código, detrás siempre hay un cerebro humano que puede explicarlo.
El código generado por IA se lleva también ese último colchón. Su “autor” es un modelo sin estado que deja de existir en el instante en que termina de generar. No dejó el proceso de razonamiento, porque sencillamente no tiene “proceso” que dejar. Y así te quedas con un mazacote de implementación que funciona, pero que nadie puede explicar y a nadie se le puede preguntar. Esas doce mil líneas de Mingxiang son justo este tipo de deuda: no se debe en la calidad del código, se debe en que “ya nadie lo entiende de verdad”.
El patrón del sector es la proyección macro de este mecanismo: la IA aumenta la velocidad de generación, pero la revisión, el entendimiento y la responsabilidad no crecen al mismo ritmo. Los equipos reciben más código más rápido, pero menos personas pueden explicar qué decisión de negocio contiene. La velocidad es real, y la deuda también; solo que la deuda no se salda el día de la entrega, sino que llama a tu puerta en el séptimo mes.
¿Pero no está la generación de código mejorando a toda velocidad?
Aquí hay que recoger en serio una réplica, o no seríamos justos: los modelos no paran de fortalecerse, cada vez leen código más largo, y existen las revisiones de código por IA y las tuberías “autocurativas”. ¿No se saldará esta deuda automáticamente con herramientas más potentes dentro de un año?
Esta expectativa tiene su lógica, pero apuesta por el cuello de botella equivocado.
El avance de la generación de código resuelve el “escribir más rápido”. Y el problema de Mingxiang nunca fue escribir poco rápido; al contrario, fue escribir demasiado rápido. En pocos días había un sistema, y los cambios llegaban más rápido de lo que las personas podían entenderlos. El cuello de botella está del lado de “entender y asumir”, y eso no mejora de forma lineal con la capacidad de generación. Un modelo más potente genera más código, más rápido, lo que también puede acumular más implementación sin leer. La revisión por IA puede ayudar a pasar una mano, pero el juicio de “qué debería ser esta lógica de negocio” no lo puede dar con certeza, porque el acierto o el error solo existen en el contexto del negocio, no en el código.
Dicho de otro modo: poner la esperanza en “un modelo un poco más potente” es tratar un fallo de frenos pisando el acelerador.
Interés compuesto: cada cambio lo hace un poco más incomprensible
¿Por qué en el séptimo mes y no en el primero? Porque esta deuda es de interés compuesto.
En el primer cambio, la IA, sin haber entendido el código viejo, “añade otro trozo al lado”; en el segundo, se enfrenta a “código viejo + código nuevo que tampoco entendió la vez anterior”, así que añade otro trozo más. Cada capa se apila sobre una capa anterior que nadie comprende, y el coste de entendimiento sube de forma exponencial. Por eso la curva de riesgo no es una recta que sube poco a poco, sino una curva exponencial con un tramo inicial tranquilo y un repunte abrupto a mitad de camino: tan tranquilo que crees que no pasa nada, hasta que un cambio de lo más corriente la enciende.
Hay una autocomprobación sencilla que te deja ver con antelación en qué tramo de la curva estás. De los cinco puntos siguientes, si cumples tres, ya estás contrayendo deuda técnica de IA:
- En el sistema hay un fragmento de código que nadie del equipo sabe explicar “por qué está escrito así”.
- Cuando hay que cambiar algo, la primera reacción es “¿no romperé otra cosa?”, en lugar de cambiarlo directamente.
- El número de incidencias de seguridad / alertas sube cada mes, y la mayoría viene del código nuevo.
- Cada vez que hay que cambiar algo, hay que volver a meter el bloque entero en la IA para que lo “vuelva a leer”.
- Los PR son cada vez más grandes, tan grandes que nadie los revisa línea a línea de verdad; solo se mira “¿pasaron los tests?”.
Esta factura, ¿quién acaba pagándola?
La curva de interés compuesto acaba convertida en una factura concreta, que se reparten cuatro pagadores:
- El negocio paga con velocidad: aquel “pequeño cambio” de Mingxiang llevó tres semanas. Cuando cada cambio da miedo de que rompa otra cosa, la velocidad de iteración se desploma a ojos vista: creías que la IA te hacía más rápido y, medio año después, vas más lento.
- El control de riesgos paga con incidentes: aquel cálculo erróneo que casi se cuela en el libro mayor se atajó, pero la próxima vez no tiene por qué. Tarde o temprano habrá un cambio que no se atrape.
- El equipo paga con personas: nadie quiere mantener a largo plazo un mazacote que no entiende y que tiembla cada vez que lo tocas. En cuanto se va el que mejor lo conocía, el sistema se vuelve por completo una caja negra; y el código de IA, de entrada, ni siquiera tiene un “el que mejor lo conoce”.
- La empresa paga con la reescritura: cuando la deuda de comprensión llega a cierto punto, “cambiar” sale ya más caro y más arriesgado que “reescribir”, así que el proyecto se tira abajo y se empieza de cero. El poco tiempo que ahorró la primera versión se devuelve con intereses.
Ninguna de estas cuatro facturas aparecía en aquella sorpresa de “un sistema montado en dos días”. Todas se anotan en la cuenta de a partir del séptimo mes.
Aclaremos primero: cambiar a metadatos no sale gratis
Llegados aquí hay que parar honestamente, o esto vuelve a ser vender un elixir.
Hacer que la IA genere definiciones en lugar de código tiene su compromiso. Los metadatos declarativos cubren ese 90% que se repite una y otra vez en las aplicaciones empresariales: objetos, campos, relaciones, vistas, permisos, procesos, aprobaciones. La controlabilidad que te dan tiene como precio que renuncias a una parte de la libertad de “escribir como me dé la gana”. Si lo que vas a hacer es un motor de colaboración en tiempo real totalmente nuevo, o un algoritmo gráfico singular, ahí sí hace falta código de verdad: los metadatos no te sirven y forzarlos lo empeora. ObjectStack resuelve los sistemas de negocio que se reconstruyen una y otra vez en las empresas, no el próximo Figma.
Y hay otra honestidad: elegir un runtime de metadatos equivale a confiar una parte de la implementación a ese runtime; apuestas por su calidad y su disponibilidad a largo plazo. Es una dependencia real; solo que, frente a apostar por “doce mil líneas de código que nadie lee”, apostar por un runtime auditado una y otra vez, versionado y migrable es una apuesta mucho mejor.
Cambiemos lo que se genera: no la implementación, sino la definición
Volvamos al sistema de gastos de Mingxiang. Con la misma necesidad, ¿y si lo que la IA hubiera generado en su día no fueran doce mil líneas de implementación, sino una definición así?
export const ExpenseReport = ObjectSchema.create({
name: 'fin_expense_report',
label: 'Nota de gastos',
fields: {
amount: Field.currency({ label: 'Importe', min: 0 }),
invoice_type: Field.select({ label: 'Tipo de factura', options: ['Ordinaria', 'Especial'] }),
deductible_rate: Field.percent({ label: 'Porcentaje deducible' }),
},
});
Estas pocas decenas de líneas no son “una interfaz que aún hay que implementar”: son el sistema en sí. El runtime (ObjectOS) las lee y deriva automáticamente las tablas de datos, las API, las interfaces y las herramientas gobernadas que el agent puede invocar; los permisos y los flujos de aprobación son igualmente declaraciones colgadas de ella, no juicios escritos a mano.
Entonces, ¿qué pinta tiene aquel cambio de norma fiscal del séptimo mes? Ya no es una arqueología, sino un cambio de una línea que se entiende:
- deductible_rate: Field.percent({ label: 'Porcentaje deducible' }),
+ deductible_rate: Field.percent({ label: 'Porcentaje deducible', defaultValue: 70 }),
+ // la factura especial deduce el 70% según la nueva norma; la regla baja a la definición, y la aprobación y la conciliación la siguen automáticamente
Esto es un diff que se revisa en cinco minutos y se revierte con un clic, no un PR de cuatrocientas líneas que nadie se atreve a “fusionar”; y tampoco pasa eso de “romper la conciliación de paso”, porque la lógica de conciliación no está en esta definición, ni siquiera puede tocarla. La diferencia no está en cuál es más “avanzado”, sino en quién, medio año después, sigue entendiéndolo, puede cambiarlo y, si algo falla, puede rastrearlo.
Por qué se corta el mecanismo de interés compuesto
Tras cambiar a definiciones, ¿por qué se puede aplanar esa curva? Tres puntos, todos apuntando directamente a la historia de Mingxiang:
- No hay “implementación que nadie ha leído”. La implementación pertenece a un mismo runtime auditado una y otra vez y compartido por todas las aplicaciones, no se genera una copia por aplicación. En tu aplicación solo queda la definición, y la definición está hecha para que la lean las personas.
- No hay “nadie a quien preguntar”. La definición es declarativa, lleva la intención escrita en la cara: qué es
deductible_rate, de quién depende, a qué procesos afecta cambiarla, todo de un vistazo, sin necesidad de preguntarle a aquella sesión de generación que hace tiempo que desapareció. - La superficie de vulnerabilidad se reduce. Muchos riesgos del código generado aparecen en autenticación, construcción de consultas y procesamiento de entradas escritos a mano. Cuando de todo eso se encarga el runtime unificado, la capa de aplicación puede introducir muchas menos categorías de vulnerabilidades.
Cierre
El problema no es que la IA escriba código, sino que demasiados equipos han tomado una herramienta para “generar prototipos rápido” directamente como una forma de “construir sistemas a largo plazo”. Un prototipo puede ser un montón de código que nadie lee; un sistema que vas a usar tres años no debería serlo.
La próxima vez que vayas a montar con IA un sistema de negocio que vas a usar de verdad a largo plazo, antes de preguntar “¿qué tan rápido lo genera?”, hazte la pregunta que Mingxiang se vio obligada a afrontar solo en el séptimo mes: dentro de medio año, cuando cambie una norma, ¿me atreveré a tocarlo y podré rastrearlo? Hacer que la IA genere definiciones en lugar de código acerca esa respuesta a “sí”.
npm i -g @objectstack/cli && os start
Define un objeto, cambia un campo una vez y mira lo limpio que queda ese cambio en el git diff: eso es una deuda que no genera interés compuesto.