Saltar al contenido principal
onext technology
IA 1 octubre 2026 - 11 min de lectura

Antes de que un agente toque tu código legacy: especifica lo que hace, no lo que debería hacer

La IA ya es muy buena explicando qué hace un sistema heredado. El riesgo empieza cuando esa explicación se trata como un requisito y un agente «corrige» lo que alguien necesita tal como está. En legacy hacen falta dos documentos, no uno: lo que el código hace hoy y lo que va a cambiar.

Jordi García
Tech Lead en onext
Un desarrollador compara un listado de código antiguo impreso en papel continuo con el mismo módulo en la pantalla, al anochecer en una oficina: especificar el comportamiento del código legacy antes de que lo modifique un agente de IA

Un ejemplo inventado, pero verosímil: se le pide a un agente que añada un campo a un módulo de facturación de hace quince años. El agente lee el código, ve que el redondeo se hace en un orden poco habitual, lo «arregla» de paso y deja los tests en verde. Tres semanas después, el informe que un cliente concilia cada mes con su contabilidad descuadra en unos céntimos por línea. El redondeo raro no era un error: era el comportamiento del que dependía ese cliente.

Nadie hizo nada mal, en apariencia. El agente encontró algo que parecía un fallo y lo corrigió. El problema es que nadie le había dicho qué comportamiento no podía cambiar, porque nadie lo había escrito nunca. En un sistema legacy, la documentación más fiable es el propio código, con sus casualidades incluidas. Y un agente que trabaja sin saber cuáles de esas casualidades son contrato es un riesgo, por bueno que sea el modelo.

Lo que la IA ya hace bien con el legacy

Conviene empezar por lo que funciona, porque funciona mucho. En noviembre de 2025, el Technology Radar de Thoughtworks colocó en «Adopt», su categoría más alta, el uso de IA generativa para entender código legacy: según su experiencia con varios clientes, ha pasado a ser «una opción práctica por defecto, no un experimento». Herramientas como Claude Code, Cursor o Copilot sacan a la luz reglas de negocio, resumen la lógica e identifican dependencias en sistemas que nadie del equipo actual escribió. Lo contamos con más detalle en GenAI para comprender código legacy.

El caso más citado es el de Morgan Stanley. Según publicó The Wall Street Journal en junio de 2025, recogido por Entrepreneur, la herramienta interna DevGen.AI había revisado nueve millones de líneas de código antiguo en cinco meses, con un ahorro estimado de 280.000 horas de desarrollo. Lo interesante es qué hace exactamente: traduce código en lenguajes antiguos a especificaciones en inglés llano, que los desarrolladores usan después como referencia para reescribirlo. No escribe el código nuevo; eso sigue siendo trabajo de personas.

Es decir, el valor no está en que la IA reescriba el sistema, sino en que produzca un texto que diga qué hace. Ese texto es el punto de partida correcto. Lo que hay que entender es qué tipo de texto es.

Una descripción no es una especificación

Cuando una IA lee código legacy y explica lo que hace, produce una descripción. Dice lo que el código hace, no lo que debería hacer. Incluye el redondeo raro, el campo que se rellena con ceros cuando viene vacío y el caso límite que se resuelve de forma inesperada porque en 2011 alguien tenía prisa. Una especificación es otra cosa: dice lo que el sistema debe hacer y alguien la firma.

La diferencia importa porque en un sistema con usuarios reales, buena parte de lo que parece un error es, en la práctica, un contrato. Lo formuló Hyrum Wright, y hoy se conoce como la ley de Hyrum: con suficientes usuarios de una API, da igual lo que prometa el contrato, alguien dependerá de cualquier comportamiento observable del sistema. Un sistema legacy lleva años acumulando usuarios de comportamientos que nadie prometió.

El propio Radar de Thoughtworks lo apunta en otra de sus entradas de noviembre de 2025, en la que propone usar descripciones generadas por IA como paso intermedio para reescribir sistemas: el objetivo no es ocultar los detalles de implementación, sino introducir «una abstracción temporal» que permita razonar sobre qué hace el sistema antes de decidir cómo rehacerlo. Temporal es la palabra clave. La descripción es una herramienta para pensar, no un requisito.

Dos documentos, no uno

De ahí sale la idea central de esta pieza. Antes de que un agente modifique un módulo heredado, hacen falta dos documentos distintos, con reglas distintas:

Acta del comportamiento actual Especificación del cambio
Qué afirma Lo que el código hace hoy, errores incluidos Lo que va a ser distinto después del cambio, y nada más
Quién la produce La IA lee el código; una persona revisa y marca lo sospechoso Una persona, con quien conoce el negocio
Cómo se verifica Con tests de caracterización que fijan cada comportamiento Con tests nuevos que fallan antes del cambio y pasan después
Quién la firma Nadie: es un acta, no un requisito Quien responde del cambio
Qué puede hacer el agente Nada que la contradiga, salvo lo que diga la especificación del cambio Implementar exactamente eso
Cuánto vive Mientras exista el módulo; se actualiza con cada cambio aprobado Hasta que el cambio se integra; después pasa al acta

Propuesta de onext. Los nombres son lo de menos; lo que importa es no mezclar los dos documentos

La regla que hace funcionar el par es simple: el agente sólo puede cambiar un comportamiento del acta si la especificación del cambio lo nombra. Todo lo demás se queda como está, aunque parezca un error. Si el agente encuentra algo sospechoso, lo apunta; no lo arregla. Arreglarlo es una decisión de negocio, y entra en la siguiente especificación del cambio con su firma y su test.

En el ejemplo del redondeo, el acta habría dicho «el importe se redondea por línea antes de sumar, no sobre el total», con un test que lo fija y una marca de «sospechoso, preguntar a finanzas». El agente habría añadido el campo sin tocar el redondeo. Y alguien habría preguntado, en lugar de enterarse por el cliente.

Es la misma lógica que defendemos para código nuevo en la especificación es donde se firma, con una diferencia: en legacy hay un documento previo que nadie firma, porque nadie lo decidió. Sólo se constata.

La red: tests de caracterización

Un acta en texto es una hipótesis. La IA puede haber entendido mal una rama, y el texto no lo va a decir. Lo que convierte el acta en algo fiable es fijar cada afirmación con un test que se ejecuta.

Para eso existe desde hace veinte años una técnica con nombre propio. Michael Feathers acuñó el término test de caracterización en 2004, en Working Effectively with Legacy Code: un test que describe el comportamiento real de un código existente para protegerlo de cambios no intencionados. No dice si el código es correcto; dice si ha cambiado. Cuando uno falla, alguien decide si el cambio era el buscado.

Aquí hay un giro que conviene señalar, porque contradice algo que hemos escrito. En tests generados por IA explicamos que un test escrito a partir del código no lo prueba: sólo lo describe, y por eso no detecta errores. En código nuevo es un problema. En legacy es justo lo que se busca. Un test de caracterización es, por definición, una descripción del código. Que la IA los genere deprisa y en cantidad es una ventaja real, con una condición: alguien revisa qué comportamientos se han fijado y marca los que son errores conocidos, para que dentro de un año nadie los lea como requisitos.

La pregunta antes de pedir un cambio a un agente: si este módulo empieza a comportarse de otra forma en algo que la especificación del cambio no menciona, ¿qué test fallaría? Si la respuesta es «ninguno», el agente no está trabajando sobre una red, sino sobre la confianza en que no tocará nada más.

Especificar la costura, no el sistema

La objeción obvia es el coste. Especificar un sistema legacy entero antes de tocarlo es un proyecto de meses que se queda obsoleto antes de terminar. Y las herramientas de Spec-Driven Development no ayudan tanto como cabría esperar: en su análisis de Kiro, Spec Kit y Tessl de octubre de 2025, Birgitta Böckeler apuntó que introducir dos de ellas en un código existente parecía costar todavía más trabajo, y al probar Kiro con un error pequeño el flujo completo le pareció como usar un mazo para cascar una nuez.

La salida es la que usa la modernización gradual desde hace veinte años. Martin Fowler la llama strangler fig: en lugar de reescribir de golpe, se identifican costuras por las que dividir el sistema y se va moviendo funcionalidad poco a poco, de forma que la inversión y el retorno llegan también poco a poco. Aplicado a las especificaciones, significa especificar sólo la costura por la que entra el cambio: el módulo que se va a tocar, sus entradas y salidas, y los comportamientos que sus vecinos esperan de él. El acta crece al ritmo de los cambios, no antes.

En la práctica, el orden es este. Primero, la IA lee el módulo y redacta el acta. Segundo, se generan los tests de caracterización y una persona marca lo sospechoso. Tercero, se escribe la especificación del cambio, corta, nombrando cada comportamiento del acta que va a cambiar. Y sólo entonces actúa el agente, con la instrucción explícita de no cambiar nada más. El review del resultado ya no pregunta «¿esto está bien?», que en legacy casi nadie puede responder, sino «¿ha cambiado algo que no estuviera en la especificación?», que los tests contestan solos. Es la pregunta que propusimos en el review que sigue esperando a un autor.

Lo que se gana, además del cambio

Hay un efecto secundario que suele valer más que el propio cambio: después de unas cuantas iteraciones, el equipo tiene por primera vez un documento fiable de lo que hace el sistema, respaldado por tests que lo demuestran. Es lo que casi ningún sistema legacy tiene, y lo que hace posible todo lo demás, desde la siguiente modificación hasta una migración completa. Y es exactamente el tipo de artefacto que Spec-Driven Development pone en el centro: no el código, sino la descripción verificable de lo que debe hacer.

Lo que no se gana es velocidad en el primer cambio. El primero cuesta más que pedirle al agente que lo haga directamente. El segundo, en el mismo módulo, cuesta menos. Y el tercero es el que se puede delegar con tranquilidad, porque la red ya está ahí. Es también una buena forma de ver qué sabe hacer un desarrollador: quien encuentra un comportamiento raro y lo apunta en lugar de arreglarlo está demostrando el criterio que describimos en qué medir al contratar desarrolladores.

Preguntas frecuentes

¿Se puede aplicar Spec-Driven Development a un sistema legacy?

Sí, pero no empezando por especificar el sistema entero. Las herramientas de SDD se pensaron sobre todo para código nuevo, y Birgitta Böckeler, de Thoughtworks, apuntó en octubre de 2025 que introducir dos de las tres que analizó en un código existente parecía costar todavía más trabajo. Lo que funciona es especificar sólo la parte que se va a tocar, con dos documentos distintos: uno que describe lo que el código hace hoy y otro que dice qué va a cambiar.

¿Qué diferencia hay entre una descripción del código y una especificación?

Una descripción dice lo que el código hace, incluidos sus errores y sus casualidades. Una especificación dice lo que debe hacer, y alguien la firma. Cuando una IA analiza código legacy produce descripciones, y son muy útiles. El problema aparece cuando se tratan como especificaciones y un agente «corrige» un comportamiento que alguien en producción necesita tal como está.

¿Qué es un test de caracterización?

Es un test que fija el comportamiento real de un código existente, no el que debería tener. El término lo acuñó Michael Feathers en 2004, en «Working Effectively with Legacy Code». No sirve para saber si el código es correcto, sino para saber si ha cambiado: si un test de caracterización falla después de una modificación, alguien tiene que decidir si ese cambio era el buscado o un efecto secundario.

¿Puede la IA generar los tests de caracterización?

Sí, y es uno de los pocos casos en los que un test generado a partir del código es exactamente lo que se necesita. En código nuevo, un test escrito desde la implementación sólo la describe. En legacy, describir el comportamiento actual es el objetivo. La condición es que una persona revise qué comportamientos se han fijado y marque los que son errores conocidos, para que nadie los confunda con requisitos.

¿Qué hago con los bugs que encuentra la IA al analizar el código legacy?

Apuntarlos, no arreglarlos en la misma pasada. Un comportamiento extraño puede ser un error o algo de lo que depende un cliente, un informe o una integración que nadie recuerda. Se fija con un test de caracterización marcado como sospechoso, se pregunta a quien conoce el negocio y, si se decide corregirlo, entra en la especificación del cambio como una modificación explícita, firmada y con su propio test.

¿Cuánto del sistema hay que especificar antes de empezar?

Lo mínimo para el cambio que se va a hacer: el módulo o la costura por la que entra la modificación, sus entradas y salidas y los comportamientos que no pueden cambiar. Especificar un sistema legacy entero antes de tocarlo es un proyecto de meses que se queda obsoleto antes de acabar. Se especifica por trozos, al ritmo de los cambios, como en una migración gradual.

Fuentes

Jordi García
Escrito por
Jordi García
Tech Lead en onext

Jordi García es Tech Lead en onext. Trabaja en llevar la IA a producción gobernada en equipos de desarrollo y de producto —con Spec-Driven Development, ingeniería de contexto y verificación humana en cada paso— y firma los insights técnicos de onext sobre método, calidad y coste de la IA aplicada.

LinkedIn →

El primer módulo heredado que pongáis en manos de un agente, con red

Elegimos con tu equipo una costura, redactamos el acta del comportamiento actual, la fijamos con tests de caracterización y hacemos el primer cambio especificado. El método queda en tu equipo para el siguiente.

Ver cómo trabajamos

Sin reescribir el sistema. Sin parar entregas.