← Todos los artículos

“Code is cheap”: el engaño moderno que podría salir carísimo

2026-04-278 min de lecturasoftware-developmenttechnical-debtsoftware-architecturesoftware-designsoftware-engineering
PorFederico Sawady O'ConnorRagnagrok Academy

Hace unos meses vi a un dev senior pelearse durante horas con Claude para que le arreglara un bug en algunas funciones no tan extensas. El problema no estaba en ninguna de ellas, sino que vivían en un módulo que importaba de otros siete, cada uno con su propia idea de qué era un “usuario”. El modelo de lenguaje, por más avanzado que parezca, no entendía nada, porque, honestamente, ahí no había nada que se pudiera entender.

Esa escena resume el malentendido del momento. Se popularizó la idea de que code is cheap: los LLMs generan miles de líneas en segundos, así que el costo de producción tiende a cero. Es una verdad a medias, y las verdades a medias en ingeniería son las más caras de todas.

Como dice Matt Pocock en un video reciente:

El código puede ser barato de generar, pero hoy el mal código es más caro que nunca.

Y la IA, esa que supuestamente nos salva, es la primera que paga el precio.

La entropía que estamos automatizando

En The Pragmatic Programmer, Hunt y Thomas hablan de la entropía del software: el desorden de un sistema tiende a aumentar salvo que invirtamos energía (generalmente en diseño) de forma constante. Generar código con IA sin un marco de diseño sólido no detiene la entropía; la acelera.

Y acá aparece la paradoja: una IA es tan útil como la base de código que intenta entender. En un repo sucio, fragmentado, con abstracciones de juguete, el modelo quema tokens buscando contexto, y empieza a alucinar con más confianza. Le pedimos que arregle el caos que el propio caos le impide ver.

Esa entropía tiene un nombre concreto en el día a día: deuda técnica. Y no es una sola cosa amorfa. Hay deuda estructural (módulos que ya no escalan), de testing (lo que no podés verificar), de observabilidad (lo que no podés ver), de procesos (lo que depende de que alguien se acuerde). Cada una pesa distinto y se paga distinto. Confundirlas en un solo cajón mental — “hay que refactorizar” — es justamente lo que hace que nunca se aborden.

Y acá hay algo importante que conviene decir antes de avanzar: un sistema es mucho más que su código. Es el código, sí, pero también el diseño, los nombres que usamos, el modelo de dominio, la documentación, los tests, la infraestructura, los flujos del negocio, e incluso la forma en la que se organiza el equipo que lo construye. Cuando hablamos de “trabajar con IA” solemos pensar solo en el código, pero la IA opera — bien o mal — sobre todo ese tejido. Por eso no alcanza con escribir mejor: hay que diseñar mejor, nombrar mejor, separar mejor, y hacer visible lo que hoy vive solo en la cabeza del equipo. El resto del artículo es básicamente eso, mirado desde cuatro ángulos: cómo modularizamos, cómo cerramos el feedback loop, cómo decidimos entre táctica y estrategia, y cómo gestionamos la deuda que inevitablemente vamos generando.

Módulos profundos: diseño como economía de tokens

El primer ángulo es el más estructural: cómo dividimos el sistema en piezas. John Ousterhout, en A Philosophy of Software Design, propone una distinción que envejeció increíblemente bien en la era de los LLMs: módulos profundos vs. módulos superficiales.

Los módulos profundos son aquellos que definen interfaces simples que esconden una gran complejidad interna. Y, por el contrario, podemos llamar superficiales a aquellos que definen piezas chicas con interfaces complejas que exponen sus tripas (estado interno, detalles de implementación que convendría ocultar, etc.).

Para un modelo de lenguaje, navegar un sistema de módulos superficiales es una pesadilla de contexto. Cada llamada arrastra detalles que no debería conocer; cada cambio toca varios lugares. La modularización profunda dejó de ser solo un principio estético: hoy es una optimización económica. Menos contexto, sugerencias más robustas, menos alucinaciones.

Si tu interfaz necesita un docstring de veinte líneas para explicarse, no estás ayudando ni a tu equipo ni a tu copilot.

El límite de velocidad no lo pone la IA

Pero modularizar bien no alcanza si después no podés ver lo que está pasando. Y ahí entra la segunda dimensión: el feedback.

La velocidad real de un equipo no la define qué tan rápido escribe el modelo. La define el feedback loop. The Pragmatic Programmer lo llama no correr más rápido que tus faros: si das pasos demasiado grandes, perdés el rastro de la lógica y terminás debuggeando a ciegas.

Pero el feedback loop no es solo tests, pipelines de CI/CD o revisión manual, que al fin y al cabo son todos procesos. Las buenas bases de código son fáciles de testear precisamente porque están diseñadas para devolver feedback rápido y barato. El otro feedback, el más invisible, es semántico. Y ahí está el problema: lo que solo vive en la cabeza del equipo, para la IA no existe. Por eso el lenguaje ubicuo del DDD ya no es solo para que humanos se entiendan entre sí: es el puente semántico que garantiza que vos y el modelo están construyendo el mismo concepto de dominio. Si en tu código Order, Pedido y Cart son lo mismo según el archivo, no esperes que el LLM lo descubra por vos.

Táctica vs. estrategia

Modularizar bien y cerrar bien el feedback loop tienen algo en común: ninguno se hace en un día. Son decisiones que se toman — o se postergan — todos los días, y ahí aparece la tercera dimensión.

Ousterhout también separa dos modos de programar: táctico (parchear para que funcione hoy) y estratégico (invertir en el diseño para el futuro). Kent Beck lo dijo más corto: “Invest in the design of the system every day.”.

Los LLMs son excepcionales en reconocimiento de patrones — refactors locales, boilerplate, traducciones entre frameworks — y bastante peores en lógica compleja sostenida en muchos pasos, porque su cómputo por token es fijo. Pueden ser un sargento brillante ejecutando tácticas, pero claramente no son el estratega.

Ese rol, al menos por ahora, sigue siendo nuestro. Mantener la coherencia del sistema, decidir dónde poner las costuras, qué abstracción merece existir y cuál es deuda disfrazada de elegancia: eso no se delega.

Hacer visible lo invisible

Pero ser estratégico no significa no ensuciarse las manos. Toda decisión táctica deja un rastro, y ese rastro es la cuarta dimensión: cómo gestionamos lo que vamos dejando atrás.

En este sentido es importante entender que lo que no se nombra, no se gestiona. Y lo que no se gestiona, se acumula hasta que un viernes a las seis de la tarde explota en producción.

La estrategia no es escribir código perfecto — eso no existe — sino capturar la deuda como un artefacto de primera clase del backlog, al mismo nivel que las features. Cada decisión que tomás “para salir del paso” es una hipoteca; el problema no es tomarla, es no anotarla. Una deuda no documentada no desaparece: se vuelve folklore del equipo, esa cosa que “todos sabemos que está mal” pero nadie tiene el tiempo — ni el permiso implícito — de arreglar.

Clasificarla por tipo (arquitectura, testing, datos, observabilidad, dependencias, procesos) no es burocracia. Es lo que te permite priorizar honestamente: una deuda de seguridad no compite con una deuda de legibilidad. Y es lo que le da al negocio una conversación adulta sobre por qué el próximo sprint no es solo features.

En la era de la IA esto no es opcional, es supervivencia. Porque la deuda que antes te costaba en horas de developers, ahora te cuesta también en tokens, en alucinaciones, y en sugerencias que parecen razonables y no lo son.

Parar la pelota

Desarrollar software se parece a un partido de fútbol. Salimos con ansias a la cancha pensando en meter un gol tras otro (features, releases, valor). Pero cuando el partido se complica, o incluso venís con una mala racha, lo peor que podés hacer es seguir corriendo detrás de la pelota. Y como en el fútbol, lo más inteligente a veces es parar la pelota, levantar la cabeza y mirar el campo.

De esa pausa salen las jugadas ganadoras. Las que no se ven en el highlight pero ganan partidos: el módulo que decidiste no escribir, la abstracción que sacaste a tiempo, la deuda que anotaste antes de que se volviera folklore.

El código no es barato. Su costo real nunca estuvo en escribirlo: estuvo siempre en mantenerlo coherente, en hacer visible lo invisible, en diseñar un sistema — no solo un repositorio — que tenga sentido para nosotros y para las máquinas con las que lo construimos.

Y hay una última razón, quizás la más incómoda. La Ley de Conway dice que las organizaciones diseñan sistemas que reflejan su propia estructura de comunicación. Lo que se suele pasar por alto es que la flecha también va al revés: un sistema mal diseñado termina deformando a la organización que lo mantiene. Equipos que evitan ciertos servicios porque “nadie los entiende”. Squads que se vuelven dueños de complejidad accidental. Reuniones que existen solo para sincronizar lo que un buen módulo habría desacoplado. La entropía del software no se queda en el repositorio: se filtra en los rituales, en los organigramas, en quién le pregunta qué a quién.

En la vorágine de la producción de código con IA, parar la pelota se siente como perder tiempo. Pero es exactamente al revés: es la única forma de no quedar sepultados bajo la entropía que nosotros mismos estamos automatizando — en el código, y en todo lo que el código termina arrastrando con él.

  • Software Fundamentals Matter More Than Ever — Matt Pocock (AI Engineer Europe, 2025)
  • A Philosophy of Software Design — John Ousterhout (Yaknyam Press, 2.ª edición, 2021)
  • The Pragmatic Programmer: From Journeyman to Master — Andrew Hunt & David Thomas (Addison-Wesley, 1999)
  • Extreme Programming Explained: Embrace Change — Kent Beck (Addison-Wesley, 1999)
  • How Do Committees Invent? — Melvin E. Conway (Datamation, abril 1968)

Publicado también en Medium