Estamos en la era del código barato. ¿Tu negocio sobrevive?

Waldemar Krumrick
16 minutos

Cuidado con dar por hecho que sí, sin hacer el trabajo.

Cuidado con dar por hecho que sí, sin hacer el trabajo.

Estamos atravesando una tormenta que, al principio, no sabíamos dónde nos iba a dejar. La IA golpeó a todas las industrias tan fuerte y tan rápido que, por un tiempo, nadie tenía un mapa. Sabíamos, y nos lo admitíamos entre nosotros, que se estaba abriendo un proceso tan disruptivo que se dice que su impacto sobre la fuerza de trabajo y sobre la forma en que se trabaja va a ser mayor que el de la revolución industrial. No hace falta que firmes esa analogía para admitir lo que apareció en las reuniones: el oficio se movió.

En software los síntomas fueron claros. Agile tal como lo habíamos ritualizado (la historia chica, el sprint, “ya lo vamos a ver en el código”) se quedó corto frente a un agente que implementa en una tarde lo que antes era el trimestre. La industria volvió a mirar un principio que había abandonado, no porque el principio fuera falso, sino porque la exigencia de resultados cada vez más inmediatos lo había empujado al terreno de lo utópico: sentarse a especificar, en serio, antes de construir. Con el desarrollo agéntico, ese principio volvió al terreno de lo posible. Se llama, otra vez, spec-driven development. No es el documento de cuatrocientas páginas que Agile vino a enterrar. Es una spec viva: la escribes, el agente cierra el ciclo en horas y corriges. Lo que cambió no es el valor de pensar primero; es el costo de descubrir que pensaste mal.

La fuerza de trabajo se corrió hacia definir qué hay que hacer y cómo debería implementarse. La etapa de escribir el código empezó a parecerse al cambio que te devuelven en una compra. Producir código ahora es barato: es una de las afirmaciones que más se escuchan en la planificación, en las retrospectivas y hasta en los hitos comerciales. Eso, y que ahora producimos “más rápido”.

¿Por qué pensamos eso, en el trabajo spec-driven? Porque el circuito se ve así. Un agente lee una spec, escribe el código, las pruebas pasan, los procesos de UAT no encuentran bugs y el proceso sale en una fracción del tiempo que habría costado hace cinco años. El código, de hecho, fue barato de producir. Lo que queremos discutir, con casos de la vida real, es otra cosa: ¿barato de producir es lo mismo que barato de operar?

El costo no desapareció: se movió. Se corre hacia arriba, a un alcance más temprano, a las definiciones de ingeniería, y vuelve con fuerza en almacenamiento, transferencia, parseo, tokens, timeouts y en cada etapa de un flujo que, cuando crece el volumen, vuelve a pagar la misma factura. Si no tienes cuidado, esa combinación puede costar incluso más que el enfoque anterior. Los procesos de UAT no están diseñados para ver eso. Miran si el producto hace lo que se pidió, no el almacenamiento, el parseo ni los tokens. Y las specs, por más spec-driven que sea el método, no pueden enumerar todas las variables de un sistema; pretender lo contrario es utópico. Por eso auditar implementaciones agénticas, incluso las que salieron “perfectas” en la primera pasada, sigue siendo parte del trabajo: no como desconfianza hacia el agente, sino como la única forma de encontrar costos que todavía no tienen síntoma.

Mil maneras de morir en el Oeste. Digo… 3 maneras de morir haciendo desarrollo agéntico

#1 Olvidar que el almacenamiento también se factura

Es muy probable que, sea cual sea tu rol, si has estado en equipos de desarrollo y llevas un par de años en esto, te hayas enfrentado a un pedido que suena inocente: dado un documento, extraer y analizar el texto, buscar ciertos conceptos y mostrarle al usuario el documento con los hallazgos pintados encima, como un resaltador sobre la frase. Con el texto no alcanza. También hay que extraer la geometría: la posición de cada palabra en la página, su ancho, su alto, su x y su y, y cuánta confianza tiene el OCR de haberla leído bien. En esta clase de procesos la salida, si miras el artefacto y no la pantalla, es mayormente coordenadas. El texto es lo que lees; las coordenadas son lo que almacenas, replicas y vuelves a parsear.

En el caso que nos ocupa, el trabajo se hizo a partir de una spec, la implementación fue extremadamente rápida, los procesos de UAT no encontraron bugs y el proceso empezó a correr. En los meses siguientes se esperaba que el volumen creciera de decenas de documentos a miles por día. Todavía no se había perdido un dólar. El dinero se iba a ir después, sin ninguna alarma, en cada JSON que nadie iba a abrir para contar decimales.

Nadie había escrito en la spec cuántos dígitos debía tener una coordenada.

Un documento grande, de muchas páginas, producía un JSON de unos 70 MB sin comprimir, que puede contener cerca de cien mil bloques. El tamaño dio curiosidad. ¿Por qué tanto? Una mirada al archivo reveló fragmentos como este:

{
  "word": "deadline",
  "x": 0.17280931770801544,
  "y": 0.38410277343750012,
  "width": 0.05688273906707764,
  "height": 0.012441406250000003,
  "confidence": 99.96014404296875
}

Así serializan las APIs de OCR en la nube (AWS, Azure, Google Cloud; el patrón es el mismo) una palabra y su geometría: fracciones entre 0 y 1, más un puntaje de confianza. Lo que llamó la atención no fue la palabra. Fue la cantidad de decimales: 12 decimales, sobre una caja que en pantalla es una mancha amarilla.

¿Necesitamos tantos decimales? Si no aportan realmente a lo que el negocio entiende por un resultado aceptable, y el peso del archivo sí varía de forma significativa con esos decimales, estamos frente a una oportunidad de mejora considerable. ¿Se mueve el resaltado sobre el documento si sacamos tres de esos decimales? ¿Y si sacamos ocho? ¿Cuándo va a empezar el ojo del usuario a notar que el resaltador está “corrido” porque recortamos de más?

Eso no lo respondes de oído. Lo respondes con un A/B sobre el mismo bloque.

Tabla 1. Un bloque WORD representativo, tal como lo serializa la API y tal como queda después de redondear la geometría a 4 decimales y la confianza a 2.

Campo | Antes (float completo) | Después
Izquierda | 0.17280931770801544 | 0.1728
Ancho | 0.05688273906707764 | 0.0569
Confianza | 99.96014404296875 | 99.96

Tabla 2. Error de cuantización a 4 decimales (coordenadas normalizadas 0–1). El peor corrimiento observado en el documento de referencia fue de 0.00005 de fracción de página: 0.22 px a 4,500 px de ancho.

Viewport | Error máximo (4 decimales)
1,920 px (página al 100%) | 0.19 px
3,000 px (render de alta resolución) | 0.30 px
4,500 px (zoom ~150%) | 0.45 px

Por debajo de un píxel de pantalla, la caja no se mueve. Eso es exactamente la PoC: el mismo sector del documento, el mismo resaltado, antes y después.

Figura 1. PoC A/B: la caja amarilla cae sobre la misma frase con 12 decimales y con 4 decimales.

Tabla 3. El mismo documento de referencia.

Métrica | Antes | Después (4 / 2 decimales) | Delta
JSON sin comprimir | ~70 MB | ~45 MB | −35%
Gzip (nivel 6) | 20.45 MB | 10.71 MB | −47.6%
Parseo del JSON (mejor de 3) | 965 ms | 734 ms | −24%
Bloques de OCR | ~100,000 | igual | —

Visualmente idéntico; operativamente, otra factura. Cuatro decimales sobre una fracción 0–1 son, a un ancho Full HD, dos décimas de píxel. Doce decimales son una fantasía de precisión que el ojo no distingue y que el negocio no pidió. Y el recorte no pesó una sola vez: cada etapa aguas abajo (publicar un contrato de geometría más liviano, importar cajas, alinear evidencia, depurar en local) volvía a descargar y a parsear el mismo archivo. El costo no estaba en el OCR: estaba en el fan-out. Una vez escrito el artefacto inflado, el resto del sistema lo heredó.

En general, es fácil encontrar que el sistema se probó y se entregó contra los criterios más visibles, en este caso que los hallazgos queden correctamente identificados sobre el documento original, y es probable que encuentres zonas grises respecto del impacto a largo plazo de esa operación.

Lo que pagas si el perfil medido llega a 100 millones

El ejercicio es deliberadamente extremo, y por eso sirve: cien millones de documentos, todos del perfil grande que se midió, una sola copia comprimida con gzip del JSON de OCR por documento, sólo capacidad (sin PUT, GET, egress ni replicación). Aritmética decimal (1 GB = 1,000 MB). Precios de lista, U.S. East, primer tramo, sin descuento por volumen ni contrato: S3 Standard a $0.023/GB-mes y Azure Blob Hot LRS a $0.0184/GB-mes. En régimen real el tramo alto de S3 baja un poco; acá no lo usamos, para no maquillar los números.

Tabla 4. Huella de almacenamiento con 100 millones de documentos (gzip).

 | Antes | Después | Deja de almacenarse
Por documento | 20.45 MB | 10.71 MB | 9.74 MB
Total | 2.05 PB (2,045,000 GB) | 1.07 PB (1,071,000 GB) | 0.97 PB

Tabla 5. Capacidad mensual, sólo almacenamiento.

 | Antes | Después | Ahorro / mes | Ahorro / año
Amazon S3 Standard ($0.023/GB-mes) | ~$47,000 | ~$25,000 | ~$22,000 | ~$269,000
Azure Blob Hot LRS ($0.0184/GB-mes) | ~$38,000 | ~$20,000 | ~$18,000 | ~$215,000

Eso es una copia, un mes, sin contar que cada etapa aguas abajo vuelve a descargar el archivo. El parseo, en una sola pasada sobre esos 100 millones, ahorra ~231 ms por documento: del orden de 6,400 horas de CPU (unos 267 días-máquina).

La lección no es la cifra exacta de la factura, que mañana cambia con la región y el precio de lista. Es el orden de magnitud: ocho dígitos que nadie ve, casi un petabyte y un cuarto de millón de dólares al año, en el escenario donde el proceso “ya funciona” y los procesos de UAT ya dieron el visto bueno.

¿Se podría haber escrito en la spec? Sí. “Serializar la geometría a N decimales” es una línea, y no estaba. Y acá conviene mantener los pies sobre la tierra y contar lo que pasa en la vida real. Todo director técnico de lunes sabe qué equipo ganó el domingo. Sería fácil, ahora, concluir que el error estuvo en cómo se definió la spec y que no tiene sentido seguir la discusión: basta con poner el esfuerzo en hacer que ese proceso sea… perfecto. Bien: en la próxima spec que escribamos para extracción de geometría vamos a especificar la precisión decimal. Eso no ataca el problema de fondo. Pararse en esa posición es pensar que podemos enumerar todos los errores que un sistema puede arrojar y prever cada una de esas situaciones. El error, en ese caso, es la vanidad. Incluso concediendo que en la próxima spec vamos a definir la cantidad de decimales, tienes que entender que el error va a cambiar, que el margen de mejora va a estar en otro lado. Este caso no es el diagnóstico cerrado: es un ejemplo concreto, el síntoma de una enfermedad posible. Las specs nunca van a ser perfectas. En nuestro ejemplo, un agente, o un equipo humano acelerado por uno, va a implementar lo que devuelve la API, porque “máxima fidelidad” parece correcto y porque nadie le pidió que recortara. Los procesos de UAT van a dar el visto bueno porque el producto se ve bien. Lo que queda, entonces, no es la promesa de una spec sin agujeros: es la auditoría crítica, el monitoreo, hipotetizar sobre lo que se implementó desde ángulos que no se contemplaron al principio. Eso no es un extra. Es una necesidad. Es un must.

Que no quede en el lector la idea de que esto es un argumento contra las specs. Es un argumento contra la idea de que spec más agente más procesos de UAT en verde equivalen a un sistema barato. El código fue barato; el impacto, el lado operativo, lo que mantiene vivo al sistema, no.

#2 Elegir mal la muestra representativa

Misma escena que en el #1: el documento, el texto, la geometría, el resaltador sobre la frase. Acá se suma el hallazgo. El modelo ya devolvió N hallazgos; lo que queda es relacionar cada uno con una posición de origen en el documento.

El algoritmo que hacía ese mapeo era, a nivel micro, un recorrido. Tomaba todos los bloques que tenía el documento y, para cada uno, preguntaba si estaba en la página correcta, la del hallazgo, para saber si seguía comparando. En pseudocódigo, podríamos representarlo así:

for finding in findings:
    lines = [b for b in blocks if b.page == finding.page]
    # blocks es el documento entero

En un documento de dos, tres, cuatro páginas, o incluso diez, ese bucle rinde tan bien, para la percepción humana, que nadie levanta la mano por un problema potencial. El visor pinta. Los procesos de UAT dan el visto bueno. El reloj nunca entra en la sala.

El problema apareció cuando se midió sobre documentos grandes. Un perfil de unas trescientas páginas y unos dos mil hallazgos estaba tardando del orden de seis minutos. Una demora así debería despertar curiosidad.

¿Y si construimos un hash de bloques por página y optimizamos el algoritmo por ahí? ¿Bajan los tiempos de ejecución?

Eso no lo respondes de oído. Lo respondes con un A/B que no toca el match: mismos hallazgos, mismas cajas. Sólo cuántas veces se rehace el mismo trabajo. La muestra no fue un solo documento: 50 archivos, de unas 300 páginas y unos 2,000 hallazgos en promedio cada uno, la clase de documento que el proceso iba a ver en producción, no el archivo de diez páginas que pone el entorno local en verde.

Podríamos considerar un arreglo de este tipo: construimos el índice de bloques por página y, ya dentro del bucle, sólo lo consultamos:

lines_by_page = {}
for b in blocks:  # una vez
    lines_by_page.setdefault(b.page, []).append(b)

for finding in findings:  # ~2,000
    lines = lines_by_page[finding.page]

Nada de eso cambia qué se matchea ni cómo se decide un match. En la muestra, los conteos de hallazgos coincidieron antes y después.

Tabla 6. Benchmark: tiempo de ejecución del algoritmo, típico por documento (muestra representativa: ~300 páginas, ~2,000 hallazgos).

 | Antes | Después | Mejora
Tiempo de ejecución | 386.9 s | 292.0 s | ~24.5%

Casi un minuto y medio menos por documento. La implementación inicial la escribió un agente; pasó la revisión de un desarrollador. Sin una muestra representativa, el perfil que el proceso va a ver en régimen, el algoritmo que es correcto a nivel macro se cuela: los procesos de UAT dan el visto bueno sobre los conteos, el reloj nunca entra en la sala. Elegir los casos de prueba es la clave.

¿Se podría haber escrito el índice en la spec? Es una línea. Casi nunca está, porque es micro: implementación de algoritmo, no arquitectura. Lo que sí puede, y hoy más que nunca debe, ser parte de la definición spec-driven es el contrato de muestra: sobre qué perfil pruebas, un presupuesto de reloj, un pass/fail que no sea sólo “los mismos conteos”. Spec-driven sin ese contrato describe el producto y deja el algoritmo librado a la suerte del primer código que compila, medido sobre el documento chico. Los procesos de UAT van a dar el visto bueno. Los minutos van a aparecer cuando el lote tenga cincuenta documentos de trescientas páginas.

Elegir mal la muestra fue fácil: el documento local pasó, el resaltado cayó donde tenía que caer. El código fue barato. Los noventa y cinco segundos por documento, cuando el lote se parece a producción, no.

#3 No buscar los patrones de cache correctos

Otro negocio. Habían puesto un modelo a validar si ciertos conceptos estaban respaldados por evidencia en determinadas páginas de un documento. La spec pedía un sí o un no por concepto, con una cita. Lo que se entregó coincidía con eso. Los procesos de UAT dieron el visto bueno sobre los veredictos. Nadie preguntó cuántas veces el mismo fragmento de página viajaba hasta el modelo.

Para verlo, alcanza con una página. Doscientos cincuenta caracteres:

El contratista entregó el sector norte el 18 de abril, ocho días después de la fecha acordada. El acta deja constancia de que el hormigón no alcanzó 25 MPa en el primer ensayo y se reprogramó la verificación a 28 días, sin aplicar todavía la cláusula penal.

Dos conceptos a verificar: demora en la entrega e incumplimiento de la resistencia del hormigón. El prompt viejo no los miraba juntos. Armaba una llamada por concepto y, en cada una, volvía a pegar el texto entero.

Llamada 1

Texto de la página:
[los 250 caracteres de arriba]

¿Hay evidencia de “demora en la entrega”?
Responde sí o no y cita el fragmento

Llamada 2

Texto de la página:
[los mismos 250 caracteres]

¿Hay evidencia de “incumplimiento de la resistencia del hormigón”?
Responde sí o no y cita el fragmento

Dos viajes de ida y vuelta. Un poco más del 90 por ciento del prompt era idéntico. En producción no eran 250 caracteres ni dos conceptos: eran miles de caracteres de página y, en el perfil que se midió, unos 25 conceptos por documento. El bucle era el mismo.

La reacción natural es usar prompt cache. La segunda llamada declara: ya viste el prefijo largo, cobra el hit. El texto de la página se reutiliza más barato, alrededor de un 90 por ciento menos en esos tokens. Siguen siendo 25 viajes de ida y vuelta. Siguen siendo 25 payloads JSON. Siguen yendo, en cada llamada, las instrucciones de cierre que no entran en la cache. El prompt cache ataca el precio de repetir el fragmento. El patrón correcto ataca el hecho de repetirlo.

Eso es convertir la llamada. El fragmento va una vez. La lista de conceptos, también. El modelo itera.

Llamada única

Texto de la página:
[el mismo fragmento]

Dados estos conceptos, itéralos uno por uno
y di si encuentras evidencia de cada uno:
1. demora en la entrega
2. incumplimiento de la resistencia del hormigón
…

Responde un veredicto por concepto, con una cita

Un viaje. N veredictos. Los procesos de UAT siguen en verde: el sí y el no no cambiaron. La factura sí.

A escala, con precios de lista de un modelo de nube de gama alta (input $3/MTok, lectura de cache $0.30, escritura $3.75, output $15), 25 conceptos y un fragmento de página de unos 8,000 tokens, miles de caracteres y no los 250 del ejemplo, la factura por documento se ve, a grandes rasgos, así. Es una estimación; el gráfico no pretende otra cosa.

Tabla 7. Costo estimado, mismo documento, tres enfoques.

Enfoque | Por documento | A 1,000 documentos
A · una llamada por concepto | ~$0.69 | ~$690
B · prompt cache sobre el fragmento | ~$0.18 | ~$180
C · una llamada, N conceptos | ~$0.10 | ~$100

Figura 2. Estimación gruesa: 25 conceptos, ~8,000 tokens de página, precios de lista de un modelo de gama alta. Las tres líneas son lineales; gana la de pendiente más suave.

Las tres crecen de forma lineal. Lo que cambia es la pendiente. Cachear el fragmento aplana respecto del bucle ingenuo y aun así deja veinticinco viajes. Mandar los conceptos juntos aplana otra vez, y gana. Nada te impide cachear dentro de esa única llamada; como estrategia principal, cachear lo que tendrías que haber dejado de repetir es el patrón equivocado. El código barato deja cableado el descuento. El negocio te pide que no vuelvas a mandar la página.

¿Se podría haber escrito en la spec? “No reenvíes el fragmento N veces; una llamada, N veredictos”. Es una línea. Casi nunca está, porque la spec pide el sí o el no correcto, no una cuenta de cuántas veces el mismo texto cruza la API. Un agente implementa una llamada por concepto, porque es correcto y entra en un bucle. Los procesos de UAT dan el visto bueno. Los dólares que vamos a tener que pagar aparecen cuando el lote llega a mil documentos.

Olvidar el patrón de cache es fácil: el modelo ya respondió, el descuento del proveedor ya figura en la línea. El código fue barato. Las veinticinco llamadas que eran una, no.

___

Así que, si llegaste hasta acá, quizá te estés preguntando si estás viviendo el sueño que siempre quisiste, vivir en la era del código barato, o si esto empezó a convertirse en una pesadilla. ¿Mi negocio va a seguir siendo competitivo?

No dejemos que gane el miedo. Enfrenta esa incertidumbre con las preguntas correctas: las que te permiten diagnosticar el estado actual de los procesos que estás entregando y cómo van a escalar en la organización. Revisa si tus equipos están auditando esos procesos de la manera correcta. Y para eso necesitas equipos con una cualidad que es inherente, humana: la curiosidad. La curiosidad es lo que nos lleva a hacer preguntas originales de la forma “¿y si…?”. En el caso de la geometría la pregunta concreta era casi ridícula de tan chica: ¿cambia la fidelidad del resaltado si le sacamos ocho dígitos a un float entre 0 y 1? En el caso de la muestra: ¿estamos midiendo el algoritmo contra una muestra representativa? En el caso de la cache: ¿estamos abaratando una repetición que tendríamos que haber eliminado? Si nadie las hizo, el proceso no se auditó: se desplegó. Y si se hicieron, el paso siguiente no es un debate de opiniones: es una PoC A/B, con una muestra representativa, la misma caja, la misma salida con el índice frío o caliente, un presupuesto de reloj, los mismos veredictos con una llamada por concepto, con prompt cache o con una sola llamada y N conceptos, que te permita tomar una decisión adecuada para el largo plazo y no un recorte de pánico cuando la factura de objetos ya está en régimen, o cuando el paso se come seis minutos en el lote real y el documento de diez páginas nunca lo mostró.

Referencias

En el artículo menciono hechos como que el código se volvió barato de producir, que el trabajo spec-driven volvió al terreno de lo posible, y comparo la etapa que estamos viviendo con la revolución industrial. No son sólo opiniones: son una lectura del mundo en el que vivimos. Abajo hay lecturas adicionales.

  1. Richard Stubbs, Spec-Driven Development (2025). El código se volvió barato de producir; el valor se movió hacia especificar y orquestar. richardstubbs.io
  2. Allstacks, Spec-Driven Development Isn’t Waterfall (2025). Agile no ganó porque las specs fueran malas: ganó porque el ciclo desde la spec hasta el software funcionando tardaba demasiado. Si implementar es barato, puedes volver a permitirte la spec. allstacks.com
  3. Anton Korinek y Donghyun Suh, Scenarios for the Transition to AGI (NBER w31815, rev. 2026). El marco macro para “si esto fuera una revolución industrial”: crecimiento, participación del trabajo, incertidumbre. nber.org
  4. Chris Frequency, What’s Expensive in the Age of AI? Lo caro ya no es teclear; es la claridad de intención. chrisfrequency.com
  5. MindStudio, The Hidden Cost of AI-Assisted Development. El agente optimiza para la corrección y la velocidad, no para la factura de operar. mindstudio.ai

Share it

Related Blogs

If you found this Blog insightful, you might also be interested in these related articles exploring similar topics in tech, design, and digital strategy.

Hablemos.

¡Estamos emocionados de escuchar sobre nuevos proyectos! Por favor, complete los detalles a continuación y nos pondremos en contacto con usted dentro de un día hábil.