Phase 19 - Lesson 09
Proyecto Final 09 — Agente de Migración de Código (Actualización de Lenguaje / Runtime a Nível de Repositorio)
MigrationBench de Amazon (Java 8 a 17) y el migrador Py2-a-Py3 de App Engine de Google establecen el estándar para 2026. OpenRewrite de Moderne realiza reescrituras deterministas de AST a escala. Grit aborda el mismo problema con una DSL al estilo codemod. El patrón de producción combina ambos: un sustrato determinista para reescritas seguras más una capa de agente para los casos ambiguos, un sandbox para construcciones por rama y un arnés de pruebas que valida todo con éxito antes de abrir el PR. El proyecto final consiste en migrar 50 repositorios reales y publicar una tasa de aprobación con una taxonomía de fallas.
Tipo: Proyecto Final Idiomas: Python (agente), Java / Python (objetivos), TypeScript (panel) Prerrequisitos: Fase 5 (Procesamiento de Lenguaje Natural), Fase 7 (Transformers), Fase 11 (Ingeniería de LLM), Fase 13 (Herramientas), Fase 14 (Agentes), Fase 15 (Sistemas Autónomos), Fase 17 (Infraestructura) Fases ejercitadas: P5 · P7 · P11 · P13 · P14 · P15 · P17 Tiempo: 30 horas
Problema
La migración de código a gran escala es una de las aplicaciones de producción más objetivas para los agentes de programación en 2026. La verdad fundamental (ground truth) es obvia (¿la suite de pruebas pasa después de la migración?), las recompensas son reales (la migración de una flota de Java 8 es un proyecto que requiere equipos enteros) y los benchmarks son públicos (subconjunto de 50 repositorios de MigrationBench). OpenRewrite de Moderne maneja el lado determinista. La capa del agente se encarga de todo lo que las recetas de OpenRewrite no pueden: reescrituras ambiguas, desvío en el sistema de construcción (build-system drift), sintaxis poco común y ruptura de dependencias transitivas.
Construirá un agente que reciba un repositorio de Java 8 (o Python 2) y genere una rama migrada con un CI exitoso (verde). Medirá la tasa de aprobación, la preservación de la cobertura de pruebas, el costo por repositorio y construirá una taxonomía de fallas. La comparación directa con una línea base puramente determinista le indicará dónde reside realmente el valor del agente.
Concepto
El pipeline consta de dos capas. El sustrato determinista (OpenRewrite para Java, libcst para Python) ejecuta la mayor parte de las reescrituras mecánicas de forma segura: importaciones, firmas de métodos, ajustes de null-safety, try-with-resources y reemplazos de APIs obsoletas. Es rápido y genera diffs auditables. La capa del agente (OpenAI Agents SDK o LangGraph sobre Claude Opus 4.7 y GPT-5.4-Codex) maneja los casos que las recetas no cubren: actualizaciones de archivos de construcción (Maven/Gradle/pyproject), conflictos de dependencias transitivas, pruebas intermitentes (test flakes) y anotaciones personalizadas.
Cada repositorio obtiene un sandbox de Daytona con el entorno de ejecución (runtime) de destino preinstalado. El agente realiza un bucle: ejecutar construcción, clasificar fallas, aplicar corrección, volver a ejecutar. Límites estrictos: 30 minutos por repositorio, costo de $8 por repositorio y 20 turnos de agente. Si todas las pruebas pasan y la variación de cobertura de pruebas no es negativa, la rama abre un PR. De lo contrario, el repositorio se clasifica bajo una clase de falla con la evidencia correspondiente.
La taxonomía de fallas es el entregable de este proyecto. A lo largo de 50 repositorios, ¿qué falló? ¿Dependencias transitivas? ¿Anotaciones personalizadas? ¿Versión de la herramienta de construcción? ¿Pruebas intermitentes no relacionadas con la migración? Cada clase recibe un conteo y un diff de ejemplo. Los futuros autores de recetas podrán enfocarse en las tres categorías principales detectadas.
Architecture
target repo
|
v
OpenRewrite / libcst deterministic recipes
(safe, fast, auditable, ~70-80% of fixes)
|
v
Daytona sandbox per branch
|
v
agent loop (Claude Opus 4.7 / GPT-5.4-Codex):
- run build -> capture failures
- classify failures (build, test, lint)
- apply fix (patch or retry recipe)
- rerun
- budget: 30 min, $8, 20 turns
|
v
test + coverage delta gate
|
v (passed)
open PR
|
v (failed)
file under failure class + attach repro
Pila Tecnológica
- Sustrato determinista: OpenRewrite (Java) o libcst (Python)
- Agente: OpenAI Agents SDK o LangGraph sobre Claude Opus 4.7 + GPT-5.4-Codex
- Sandbox: Devcontainers de Daytona por rama, con el runtime de destino preinstalado (Java 17 / Python 3.12)
- Sistemas de construcción: Maven, Gradle, uv (Python)
- Benchmarks: Subconjunto de 50 repositorios de Amazon MigrationBench (Java 8 a 17), repositórios de Google App Engine Py2-a-Py3
- Arnés de pruebas: ejecutor en paralelo, cobertura mediante Jacoco (Java) o coverage.py (Python)
- Observabilidad: Langfuse + paquete de rastreo por repositorio con cada fragmento de diff
- Panel: panel de taxonomía de fallas con conteos por clase y diffs de ejemplo
Paso a Paso del Desarrollo
Paso de recetas. Ejecute primero las recetas de OpenRewrite (Java) o libcst (Python). Resuelva el 70-80% de las migraciones puramente mecánicas. Realice un commit identificando esta etapa como "receta".
Prueba de construcción. En el sandbox de Daytona: instale el runtime de destino y ejecute la construcción. Si pasa (verde), continúe directo a las pruebas. Si falla (rojo), transfiera el control al agente.
Bucle del agente. LangGraph con herramientas:
run_build,read_file,edit_file,run_test,git_diff. El agente clasifica la falla (dependencia, sintaxis, prueba, herramienta de construcción) y aplica una corrección dirigida. Vuelva a ejecutar.Límites de presupuesto. 30 minutos de tiempo real por repositorio, costo de $8, 20 turnos de agente. Cualquier incumplimiento detiene el proceso y clasifica el repositorio como "budget_exhausted" (presupuesto agotado) adjuntando el diff actual.
Compuerta de prueba + cobertura. Una vez que la construcción se ponga en verde, ejecute la suite de pruebas. Compare la cobertura con la del repositorio base. Si la cobertura disminuye más de un 2%, clasifíquelo como "coverage_regression".
Apertura del PR. En caso de éxito, envíe la rama y abra el PR detallando el diff y un resumen de qué recetas se aplicaron y qué commits fueron creados por el agente.
Taxonomía de fallas. Para cada repositorio fallido, etiquételo con una clase:
dep_upgrade_required,build_tool_drift,custom_annotation,test_flake,syntax_edge_case,budget_exhausted. Construya un panel visual.Ejecución en lote de 50 repositorios. Ejecute el pipeline sobre el subconjunto de MigrationBench. Informe la tasa de aprobación por clase, el costo por repositorio, la preservación de la cobertura y compare el resultado final con la línea base puramente determinista.
Use It
$ migrate legacy-java-service --target java17
[recipe] 27 rewrites applied (JUnit 4->5, HashMap initializer, try-with-resources)
[build] FAIL: cannot find symbol sun.misc.BASE64Encoder
[agent] turn 1 classify: removed_jdk_api
[agent] turn 2 apply: sun.misc.BASE64Encoder -> java.util.Base64
[build] OK
[tests] 412/412 passing; coverage 84.1% -> 84.3%
[pr] opened #1841 cost=$3.20 turns=4
Entrega
outputs/skill-migration-agent.md es el entregable. Dado un repositorio, ejecuta recetas deterministas y luego un bucle de agente para producir una rama migrada y funcional (CI verde), o clasifica el repositorio en una clase de taxonomía de fallas.
| Peso | Criterio | Cómo se mide |
|---|---|---|
| 25 | Tasa de aprobación en MigrationBench | pass@1 en el subconjunto de 50 repositorios |
| 20 | Preservación de la cobertura de pruebas | Variación promedio de cobertura vs base |
| 20 | Costo por repositorio migrado | $/repositorio en ejecuciones exitosas |
| 20 | Integración agente / herramienta determinista | Proporción de soluciones manejadas por OpenRewrite vs las creadas por el agente |
| 15 | Análisis descriptivo de fallas | Completitud de la taxonomía con ejemplos |
| 100 |
Ejercicios
Ejecute el pipeline de migración usando solo OpenRewrite (sin el agente). Compare la tasa de aprobación obtenida con la del pipeline completo. Identifique las situaciones en las que el agente marca la diferencia.
Implemente una verificación de estilo de código: después de la migración, ejecute un linter (spotless para Java, ruff para Python). Rechace el PR si aparecen nuevos errores de estilo o formato. Mida la proporción de repositorios que mantienen la cobertura pero fallan en el estilo.
Desarrolle un optimizador de diff mínimo: después de que la rama generada por el agente pase las pruebas, realice una segunda pasada para revertir cambios innecesarios. Presente la reducción obtenida en el tamaño del diff.
Extienda a una tercera migración: Node 18 a Node 22. Reutilice la estructura de sandboxes y reemplace la capa de recetas por un codemod personalizado.
Mida el tiempo transcurrido hasta la primera construcción exitosa (TTFGB) como métrica de experiencia de usuario (UX). Meta: p50 inferior a 10 minutos.
Términos Clave
| Término | Lo que la gente dice | Lo que realmente significa |
|---|---|---|
| Deterministic substrate | "Motor de recetas" | OpenRewrite / libcst: reescrituras declarativas de AST con garantías de seguridad |
| Codemod | "Programa de modificación de código" | Una regla de reescrita que cambia el código fuente mecánicamente |
| Build drift | "Desviación de versión de herramienta" | Cambios sutiles de comportamiento en Maven, Gradle o uv entre versiones principales |
| Failure class | "Categoría de taxonomía" | Un motivo etiquetado por el cual un repositorio no se migró: dep, sintaxis, prueba, herramienta de construcción o presupuesto |
| Coverage delta | "Preservación de cobertura" | Variación porcentual en la cobertura de pruebas entre el código original y la rama migrada |
| Agent turn | "Ciclo de llamada de herramienta" | Una iteración de planificar -> actuar -> observar en el bucle del agente |
| Budget exhaustion | "Límite alcanzado" | El repositorio consumió su límite estipulado de 30 minutos / $8 / 20 turnos sin pasar los criterios de éxito |
Lecturas Adicionales
- Amazon MigrationBench — el benchmark canónico de 2026
- Moderne.io OpenRewrite platform — la referencia para el sustrato determinista
- OpenRewrite documentation — desarrollo de recetas
- Grit.io — DSL alternativa de codemod
- OpenAI sandboxed migration cookbook — la referencia del SDK de agentes
- Google App Engine Py2 to Py3 migrator — benchmark alternativo de migración
- libcst — sustrato determinista en Python
- Daytona sandboxes — referencia para sandboxes por rama