Migrar un sistema antiguo no consiste simplemente en cambiar palabras de un lenguaje de programación por otras. Mistral trabajó con un operador energético europeo para llevar 40.000 líneas de Fortran 77 a C++, un proceso que muestra cómo los agentes de IA pueden ayudar a rescatar software científico difícil de mantener.
El código pertenecía a un simulador de reservorios utilizado en cálculos físicos. Tenía décadas de historia, no contaba con una suite de pruebas y buena parte de su conocimiento estaba dispersa entre comentarios, documentos PDF y la experiencia de ingenieros especializados.
El reto no era traducir, sino modernizar
Fortran 77 fue estandarizado en 1977 y refleja las limitaciones de esa época. El lenguaje no tenía módulos ni espacios de nombres como los que hoy son habituales. Además, utilizaba bloques COMMON, una forma de compartir memoria global entre distintas partes del programa.
También permitía que las variables se tiparan de manera implícita según su primera letra. Un error de escritura podía crear silenciosamente una variable nueva en lugar de detener la compilación. Los nombres, por si fuera poco, estaban limitados a seis caracteres, lo que hacía más difícil entender la intención original del código.
Convertir ese sistema a C++ exigía tomar decisiones de arquitectura. Los datos globales debían transformarse en estructuras claras, los tipos tenían que declararse de forma explícita y algunos flujos de control basados en GOTO podían reorganizarse en bucles y retornos más fáciles de mantener.
Traducir código puede producir un programa que funciona. Modernizarlo implica hacerlo comprensible, comprobable y preparado para evolucionar.
La prueba de paridad fue el primer paso
Antes de dejar que los agentes modificaran el código, el equipo construyó un mecanismo para demostrar que la versión nueva producía los mismos resultados que la versión original.
La estrategia consistió en comparar tanto los resultados finales como valores intermedios importantes, seleccionados junto con los ingenieros de reservorios. Para ello, el equipo:
- Añadió subrutinas al código Fortran para exportar el estado del programa.
- Creó un marco de pruebas en C++ capaz de cargar esos puntos de control.
- Preparó archivos
Skill.mdpara orientar a los agentes sobre el uso correcto de las herramientas.
Por ejemplo, el código original podía guardar el valor de una variable como RHOG durante una ejecución. La versión en C++ debía producir ese mismo valor en el punto equivalente. Así, el equipo podía comprobar una migración con datos concretos, no solo con una revisión visual del código.
Este paso también redujo el riesgo de las ejecuciones largas de los agentes. Si una modificación rompía la equivalencia numérica, las pruebas podían detectarlo rápidamente.
Agentes de IA para recuperar el conocimiento perdido
La documentación no estaba organizada junto al código. Parte se encontraba en documentos antiguos y otra parte aparecía escondida en comentarios. Para resolverlo, Mistral generó un árbol de relaciones entre procedimientos, mostrando qué partes del programa llamaban a otras.
A partir de ese mapa, desplegó más de cien agentes mediante Vibe CLI para documentar el sistema. Cada agente podía consultar los PDF relevantes utilizando bibliotecas de documentos y Mistral OCR, la herramienta de reconocimiento óptico de caracteres de la compañía.
El trabajo avanzó desde las partes más pequeñas del programa hacia las superiores. Cada agente documentaba un nodo del árbol y abría una solicitud de cambios en el repositorio original. Otro agente revisaba periódicamente esas solicitudes y pedía correcciones cuando era necesario.
El resultado no fue solo una base de código parcialmente migrada. También se creó una explicación más cercana al código, algo fundamental cuando los autores originales ya no forman parte del equipo.
La autonomía total no fue suficiente
En el primer intento, Mistral asignó un agente a cada subrutina y le permitió traducirla de manera independiente durante una semana. El programa resultante funcionaba, pero conservaba demasiadas características del diseño original.
Los bloques COMMON se convirtieron en estructuras globales casi idénticas. El control basado en GOTO permaneció prácticamente intacto. En lugar de C++ moderno, el resultado parecía Fortran escrito con otra sintaxis.
En el segundo intento, el equipo organizó varios roles para cada módulo: un agente planificador, uno de programación, otro de pruebas y uno dedicado a la calidad del código. La estructura mejoró de forma notable, aunque los agentes podían quedarse bloqueados después de varios intentos de corregir un error complejo.
La solución final combinó autonomía y supervisión humana. Un profesional coordinaba un flujo compuesto por agentes de programación, pruebas y revisión. Cuando el sistema encontraba un problema difícil, una persona intervenía para desbloquear el proceso.
Un flujo de trabajo por módulos
Con la documentación y las pruebas listas, el equipo dividió el código en módulos independientes. Cada módulo era un subárbol del sistema y, según la experiencia del proyecto, debía tener menos de unas 10.000 líneas de Fortran para ser manejable.
El proceso seguía estos pasos:
- Diseñar la arquitectura equivalente en C++.
- Revisarla con un ingeniero especializado en reservorios.
- Convertir la arquitectura aprobada en una lista de tareas.
- Ejecutar ciclos de planificación, implementación y pruebas.
- Revisar las solicitudes de cambios antes de incorporarlas al repositorio.
- Repetir el proceso hasta obtener código aceptable y resultados numéricamente equivalentes.
Este enfoque permitió que los agentes trabajaran con objetivos concretos, en lugar de enfrentarse de una sola vez a todo el sistema heredado.
Tres lecciones para cualquier sistema antiguo
El primer sprint cubrió 40.000 de las 300.000 líneas totales del código Fortran. El proyecto partía de una condición favorable: el programa era autocontenido y podía ejecutarse. Otros sistemas, especialmente los que dependen de servicios externos o contienen conocimiento científico que nunca fue documentado, pueden requerir mucho más trabajo.
De la experiencia de Mistral se desprenden tres ideas prácticas:
- Construye las pruebas de paridad antes de migrar. Poder demostrar que la versión nueva coincide con la anterior ofrece una señal clara de progreso.
- Ordena la documentación primero. Un agente puede procesar mucho código, pero no puede interpretar con seguridad un sistema que nadie entiende.
- Combina agentes con revisiones humanas. La autonomía total puede producir resultados funcionales pero poco modernos, mientras que el trabajo manual completo no escala bien.
La inteligencia artificial no eliminó la complejidad del proyecto. Lo que hizo fue ayudar a dividirla, documentarla y verificarla. Esa diferencia es importante: en sistemas críticos, la IA no reemplaza el criterio de los expertos, sino que permite que ese criterio se aplique a más partes del problema.
