Uber borra un millón de líneas de código antiguo con agentes

El equipo de ingeniería de Uber ha publicado una entrada de blog en la que presenta su sistema interno AutoClean. Se conecta a la plataforma de gestión de feature flags de la empresa, localiza las que ya se pueden retirar con seguridad, genera automáticamente el diff que elimina el código y, una vez superadas las pruebas, lo pasa a un ingeniero para su aprobación. En los últimos años el sistema ha limpiado más de 16.000 feature flags y más de un millón de líneas de código, y sigue funcionando de forma continua en varios monorepos de Uber.

El artículo está firmado por los ingenieros de software sénior de Uber Daniel Ramos y Diego Marcilio y por el ingeniero de software Nikhil Parasaram.

Por qué es tan difícil borrar código

Las funciones nuevas de Uber se lanzan de forma gradual mediante feature flags, y en la plataforma conviven miles de ellas. Cuando el despliegue termina, las ramas condicionales, las funciones auxiliares, los puntos de llamada, la configuración y las pruebas suelen quedarse donde estaban. Retirar una flag obliga a tocar todos esos lugares a la vez y a garantizar que el comportamiento en producción no cambie lo más mínimo.

El blog señala un coste nuevo: el código muerto no solo cansa a quien lo lee, sino que los asistentes de programación con IA también dedican más tiempo y tokens a esas ramas cuando analizan la base de código.

Un pipeline en tres etapas

Primera etapa: reescritura. El agente recibe acceso a la base de código y, a través de MCP, invoca PolyglotPiranha, el motor de transformación de código desarrollado por Uber y publicado como código abierto, que se encarga de la simplificación booleana y de la eliminación de condiciones. El razonamiento de los autores es directo: un error en la simplificación booleana puede "can silently change program behavior", es decir, cambiar el comportamiento del programa sin avisar, así que dejan el máximo posible en manos de herramientas deterministas.

Segunda etapa: reparar el CI. Los fallos sencillos los resuelven reparadores deterministas, por ejemplo eliminando valores por defecto que ya no se usan o limpiando errores de lint; los complejos pasan al agente, como decidir si una prueba debe borrarse o modificarse. Los permisos de cada reparador están estrictamente acotados: el reparador de pruebas solo puede tocar archivos de prueba. El bucle se repite hasta que el CI pasa o se agotan los intentos.

Tercera etapa: verificación. Cuando el CI da el visto bueno, primero se ejecuta el análisis estático y después entra una capa de verificación llamada CodeCourt, en la que varios agentes revisores especializados comprueban el cambio en paralelo. Entre las reglas que enumera el blog figuran:

  • solo borrar, sin añadir ni introducir código nuevo;
  • el comportamiento observable no cambia;
  • tratar únicamente la flag indicada, sin aprovechar para eliminar otras flags relacionadas;
  • no dejar comentarios ni rastros del razonamiento del agente.

Si falla cualquiera de ellas, el diff se descarta directamente y nunca llega a una persona. Según los autores, varios subagentes especializados rinden mejor que un único agente que revise un diff completo de principio a fin.

De Piranha a los agentes

La base de AutoClean es Piranha, que Uber publicó como código abierto hace unos años. Esa herramienta nació precisamente para eliminar flags caducadas, mediante reescritura estática basada en reglas. PolyglotPiranha amplió después el motor de reglas a varios lenguajes. El cambio esta vez está en la capa exterior: el motor de reglas sigue encargándose de la lógica booleana, la más propensa a errores, los agentes asumen lo que las reglas no cubren, como reparar pruebas o completar puntos de llamada, y otro grupo de agentes hace de control cruzado.

El blog reconoce abiertamente varios modos de fallo: el agente puede modificar código de producción solo para que las pruebas pasen, borrar pruebas cuyo comportamiento debía conservarse o terminar demasiado pronto y dejar una limpieza a medias; con muchas instrucciones, además, se le puede escapar alguna restricción. El CI no detecta estos problemas semánticos, y tanto el recorte de permisos de los reparadores como la incorporación de CodeCourt van dirigidos a ellos.

El artículo no ofrece tasa de éxito, tiempo medio ni proporción de diffs descartados; el código de ejemplo está en Go y tampoco se detalla la cobertura de otros lenguajes. Según la descripción de los autores, quien revisa ahora solo tiene que responder a una pregunta: si esa flag debe eliminarse o no. La corrección a nivel mecánico ya se ha filtrado en las tres etapas anteriores.

Fuentes: blog oficial de Uber Engineering, CocoLoop, página del proyecto PolyglotPiranha en GitHub; las cifras de limpieza se basan en el criterio acumulado que figura en el blog de Uber.