20 min de lectura

Emilio Carrión

Soltar el volante

Uncle Bob dice que ya no lee el código que escriben sus agentes. El debate que generó mezcla cuatro preguntas distintas: qué se puede automatizar de la revisión, de dónde sale el criterio que la alimenta, cuánto perdona tu sistema y qué está haciendo Bob en realidad.

iacalidad de softwarearquitecturaingeniería

Hace unos días, Robert C. Martin (Uncle Bob, el autor de Clean Code) escribió en X que su estrategia con los agentes de IA es no leer nada del código que escriben. Que es la única forma de aprovechar su productividad. Que lo que hace, en vez de leer, es rodearlos de lo que él llama "extreme constraints": tests unitarios, tests en Gherkin, procedimientos de QA, métricas de calidad, mutation testing, cobertura.

El tweet se viralizó, claro. No por el argumento, sino por quién lo decía: el tipo que se pasó veinte años diciéndonos que el código se lee muchas más veces de las que se escribe y que somos responsables de cada línea que entregamos. Verle decir que su estrategia es no leer nada del código que escriben sus agentes choca. Y como todo lo que choca en internet, generó dos bandos al instante: los que lo celebraron como prueba de que el futuro ya está aquí, y los que lo vieron como una traición a todo lo que él mismo predicó.

Llevo días leyendo el debate y me parece que los dos bandos hablan de cosas distintas sin darse cuenta. Se están mezclando, al menos, cuatro preguntas que conviene responder por separado: qué parte de la revisión se puede automatizar, de dónde sale el criterio que alimenta esa automatización, cuánto importa el sistema sobre el que trabajas, y qué está diciendo Bob en realidad. Mientras se discutan como si fueran una sola, el debate seguirá generando más calor que luz. Así que vamos a separarlas. Y para no discutir en abstracto, empiezo por un caso real que nos pasó en Mercadona Tech la misma semana del tweet.

El caso de las latas

Este verano, con el calor apretando, algunos packs de latas de refresco cambian de formato. El Red Bull pasa de pack de 6 a pack de 8. La lata individual mantiene su código de producto, pero cada formato de pack tiene un código distinto. En nuestras colmenas (los almacenes desde donde Mercadona Online sirve pedidos) esto rompe algo que nuestros flujos de control de stock daban por hecho: que la relación entre producto padre e hijo (el pack y la lata que contiene) es única y estable.

Deja de serlo. Durante la transición conviven el padre viejo y el padre nuevo, y para saber cuántas latas tienes en total necesitas mirar la familia completa del producto: la relación histórica, no solo la actual. Es una regla nueva, no deuda vieja: hasta este verano, la relación directa bastaba. Así que necesitábamos un resolver de familias, y había que usarlo en cuatro puntos distintos del sistema: cuadres, retiradas, transformaciones y algún rincón más donde el stock se reconcilia.

La familia de producto: lo que cambió este verano

ANTESLata Red Bullcódigo APack de 6código Brelación directa, única y estableAHORAfamiliaLata Red Bullcódigo APack de 6código Bde bajaPack de 8código Cde alta¿cuántas latas tengo?resolver de familias
La pregunta no cambió. La respuesta ya no está en la relación actual, sino en la familia completa del producto.

Implementamos el cambio con IA. Dos personas, cuatro pull requests en paralelo. Funcionó a la primera. Los tests pasaban. El comportamiento era correcto.

Y al revisar el código vimos que la lógica de resolución de familias estaba duplicada, casi idéntica, en los cuatro sitios.

Lo que hicimos después es un refactor obvio para cualquiera que lleve tiempo en esto: la resolución de familias pasó a ser un servicio de aplicación del contexto de transformaciones, y los cuatro puntos llaman a esa abstracción. Una sola fuente de verdad para una regla de negocio que, ya lo sabemos, va a volver a cambiar. Los formatos de producto cambian todos los años.

Lo que entregó la IA vs. el refactor

LO QUE ENTREGÓ LA IACuadresresolución de familias (copia)Retiradasresolución de familias (copia)Transformacionesresolución de familias (copia)Reconciliaciónresolución de familias (copia)misma regla, cuatro copias; los tests pasanDESPUÉS DEL REFACTORCuadresRetiradasTransformacionesReconciliaciónServicioresoluciónde familiasuna fuente de verdad: la regla se toca en un sitio
Ningún test distingue entre las dos columnas. El comportamiento es idéntico; lo que cambia es lo que cuesta el próximo cambio de formato.

Esa duplicación la cazó una lectura. Sin ella el cuadro era perfecto: los tests en verde, el stock cuadrando, todo el mundo contento. Hasta el día, seis meses o un año después, en que alguien tuviera que cambiar esa lógica y necesitara acordarse (o confiar en que la IA encontrara) que vive en cuatro sitios. La probabilidad de dejarse uno es alta. Y el fallo resultante no sería un error de compilación: sería un descuadre silencioso de stock en producción, probablemente en pleno pico de demanda.

El código era correcto. Su sostenibilidad se había degradado. Y ningún test distingue entre las dos cosas.

Y hay una segunda factura, más difícil de ver, que me señaló mi compañero Alejandro Capdevila cuando le conté el caso. El código que generan los agentes no se queda quieto: se convierte en el contexto desde el que trabajan los agentes siguientes. Si aquellas cuatro copias se hubieran quedado ahí, el próximo agente que abriera el contexto de transformaciones habría aprendido, del propio repositorio, que la resolución de familias se escribe a mano donde haga falta. Y habría escrito la quinta.

Por eso la degradación no se suma, se compone. Cada decisión de diseño que no tomas se convierte en el ejemplo que copia la sesión siguiente. Se nota muchísimo si la base de la que partes está bien montada o si es un vertedero, y esa diferencia se amplifica con cada vuelta.

Con el caso encima de la mesa, vamos con las cuatro preguntas.

Primera pregunta: ¿qué parte de la revisión se puede automatizar?

La respuesta corta: mucha más de la que el bando escéptico admite, y menos de la que el bando entusiasta cree.

El argumento a favor de automatizar es sólido y merece tomárselo en serio. Primero por economía: si tienes que revisar línea a línea todo lo que produce la IA, tú eres el cuello de botella, y un cuello de botella se come la ventaja de la máquina que tiene detrás. Esto no es una opinión, es aritmética. Segundo, porque buena parte de lo que llamamos "criterio" son en realidad métricas: duplicación, acoplamiento, complejidad ciclomática, violaciones de arquitectura. El propio Bob ni siquiera delega eso en la IA: se construye herramientas deterministas que hacen ese trabajo, una por lenguaje, y las tiene publicadas en GitHub (dry4go, dry4java, dry4clj). Y tercero, por historia: lo automatizable solo crece. Hace diez años, "el formateo requiere criterio" era una opinión defendible; hoy es un linter. Apostar contra esa tendencia es mala estrategia.

Ahora bien, apliquemos todo eso a las latas y miremos qué habría pasado.

Un revisor de PRs (humano o IA, da igual) trabaja con el contexto de una PR. Dentro de cada una de nuestras cuatro, el código estaba bien: una implementación limpia y localizada de la resolución de familias, justo donde se necesitaba. No había nada que señalar. La duplicación solo existe cuando juntas las cuatro, y esa foto completa no la ve ningún proceso que trabaje PR a PR. Que conste que esto no lo inventó la IA: dos humanos en cuatro PRs paralelas sin coordinarse habrían duplicado la lógica exactamente igual. Es el problema de contexto compartido de toda la vida. Lo que cambia con la IA es la escala: más código, más rápido, generado por algo que tiene aún menos visión de conjunto que un compañero que te pregunta en la daily "oye, ¿esto no lo estás haciendo tú también?". La IA no crea el problema. Lo amplifica.

¿Y un detector de duplicados pasando periódicamente sobre toda la base de código? Ese sí: probablemente habría cazado este caso concreto en días, porque nuestra duplicación era de las fáciles, cuatro copias casi idénticas. Pero fijaos en qué hace el detector: encuentra y avisa. No decide. Y la decisión es la parte difícil, porque el código duplicado no es malo en sí mismo. A veces dos trozos idénticos solo se parecen por casualidad: sirven a razones de negocio distintas, van a evolucionar por separado, y si los abstraes creas un acoplamiento que pagarás caro. Y a veces son la misma regla de negocio repetida, que tiene que cambiar junta o el sistema miente. Distinguir un caso del otro exige saber por qué existe cada trozo y cómo va a evolucionar el negocio. En el nuestro, la respuesta era clara para cualquiera que sepa que los formatos de pack cambian cada temporada: regla de dominio, va a cambiar, un solo sitio. Pero esa claridad venía de conocer el negocio, no de leer el código. No estaba en ningún archivo que un agente pudiera consultar.

"Pues escríbelo", dirá alguien, y con razón: para eso existen los archivos de contexto. Pero mirad lo que acabamos de hacer: para que el agente decida bien, alguien tiene que saber qué escribir, darse cuenta de que es relevante antes de que haga falta, y mantenerlo al día cuando el negocio cambie. El conocimiento se puede volcar en un archivo; el saber qué volcar, cuándo y por qué, no. Eso tiene un nombre, y es la siguiente pregunta.

La primera frontera, entonces: lo automatizable es la detección; la decisión, hoy, no. Y conviene sacarle la consecuencia práctica, porque juega a favor de las herramientas, no en contra: un buen detector no sustituye la lectura, te dice dónde leer. Convierte "revisar todo el código" en "juzgar veinte hallazgos", que es un trabajo que un humano con criterio sí puede absorber. Correcto no es lo mismo que sostenible, y esa diferencia no la paga quien mergea; la paga quien mantiene seis meses después.

Detección vs. decisión

Base decódigoDetectorautomatizablehallazgo:duplicación ×4¿Deuda oduplicaciónlegítima?juicio humano · no automatizable hoyAbstraer enun servicioDejar las copiasy documentar por quéla respuesta no está en el código; está en cómo evoluciona el negocio
Un buen detector no sustituye la lectura: te dice dónde leer. Convierte "revisar todo el código" en "juzgar veinte hallazgos".

Segunda pregunta: ¿de dónde sale el criterio?

Hay una estructura de argumento que se repite en este debate y que conviene señalar: "no necesitas leer el código si tienes suficientes guardarraíles". Presentas un contraejemplo y la respuesta es "eso demuestra que te faltaba un guardarraíl". Cualquier fallo, siempre, se explica como configuración insuficiente; nunca como límite del enfoque. Un argumento que no puede perder debería hacernos sospechar, no convencernos.

Pero el problema de fondo no es retórico. Es este: ¿de dónde salen los guardarraíles? De hecho, la pregunta se la hicieron a Bob en su propio hilo, y en latín: quis custodiet ipsos custodes. ¿Quién escribe el gauntlet, esa carrera de obstáculos que Bob les monta a sus agentes? Si los constraints hacen el trabajo pesado, la calidad de esos constraints pasa a ser el verdadero problema de ingeniería. Alguien tiene que decidir qué invariantes proteger, qué patrones prohibir, qué métricas vigilar y con qué umbrales, qué es aceptable en este contexto y qué no. Esa decisión es exactamente el criterio que, según el eslogan, ya no hace falta. "No necesito judgment porque lo he metido en constraints" necesita el judgment para escribir los constraints, para mantenerlos al día cuando el negocio cambia (y el nuestro cambia cada verano) y para darse cuenta de que falta uno antes de que su ausencia explote en producción.

La revisión humana no se elimina. Se muda un nivel más arriba, donde se ve menos. Y mudarla puede ser un movimiento excelente, muchas veces lo es. Pero mudarla y eliminarla son cosas distintas: el trabajo de criterio sigue existiendo, solo que ahora vive en los constraints, y hay que mantenerlo con el mismo rigor con el que antes se mantenía el código.

Newsletter Semanal

¿Te gusta lo que lees?

Unete a otros ingenieros que reciben reflexiones sobre carrera, liderazgo y tecnologia cada semana.

Tercera pregunta: ¿en qué sistema estás?

Esta es la pregunta que casi nadie hace, y sospecho que es la que explica la mayor parte del desacuerdo. Buena parte de la discusión sobre cuánta autonomía darle a la IA va disfrazada: por debajo se está discutiendo de dominios. Cada uno generaliza desde su bucle de feedback, y los bucles de feedback no se parecen en nada.

No es que unos trabajen en software difícil y otros en software fácil. Es que hay sistemas que perdonan y sistemas que no.

En muchos productos digitales, el error es barato y ruidoso. El código falla, salta una excepción, la ve una alerta, haces rollback y despliegas el fix en minutos. El estado vive en una base de datos: si el código mintió, corriges el código y migras los datos. El propio sistema te avisa rápido y te deja deshacer. En un entorno así, dar mucha autonomía a los agentes es bastante razonable: el coste de equivocarte es pequeño y te enteras enseguida.

Con un matiz que no hay que perder: ese feedback rápido te salva de los errores de comportamiento, no de los de estructura. La duplicación de las latas no habría lanzado excepciones en ningún dominio; la degradación de un diseño es muda en todas partes. El problema existe en todos los sistemas; lo que cambia es cuánto cuesta cuando por fin muerde: en un SaaS se paga en velocidad de desarrollo; en logística se paga en velocidad de desarrollo y en latas que no cuadran.

En un sistema de logística, el estado vive en el mundo físico. La verdad no está en la base de datos: está en la colmena, en cuántas latas hay de verdad en una ubicación. Y eso lo cambia todo. Un fallo no lanza excepciones: descuadra, y el descuadre se acumula en silencio. No te enteras en minutos: te enteras días o semanas después, cuando un pedido no se puede servir o un cuadre manual saca a la luz la diferencia. Corregirlo es trabajo físico, gente contando latas. Y no hay rollback de la realidad: las latas que se retiraron mal, retiradas están. Súmale que el dominio cambia por razones que no controlas (el calor de julio, un proveedor que cambia el formato del pack) y tienes un sistema donde el error es caro, silencioso, lento de detectar y caro de corregir. Las cuatro cosas a la vez.

Cuánto cuesta el fallo, cuánto tarda en detectarse, cuánto cuesta corregirlo y cada cuánto te cambia el negocio las reglas: esas cuatro variables son las que deberían fijar cuánto criterio humano pones entre la IA y producción. En un extremo, la disciplina te la pone el sistema: falla rápido, avisa fuerte, se deshace solo. En el otro, la disciplina la tienes que poner tú antes del merge, porque después ya no hay red.

¿Tu sistema perdona?

Mueve las cuatro variables que deciden cuánto criterio humano poner entre la IA y producción.

Anclas:
molestomuy caro
minutossemanas
un deploytrabajo físico
establecada temporada
perdonano perdona

Tu sistema perdona a medias

autonomía con red por debajo

parte de la disciplina la pone el sistema; el resto lo pones tú antes del merge

El objetivo no es la precisión, es ubicarte: buena parte del desacuerdo sobre cuánta autonomía dar a la IA es un desacuerdo sobre dominios, no sobre la IA.

Un apunte que me hizo notar mi compañero Sergio Revilla y que corrige un exceso de este razonamiento: el dial no es solo del sistema, también es de la tarea. Aunque trabajes donde no se perdona, no todos los cambios tienen el mismo radio de explosión, ni sabes lo mismo de todas las zonas del sistema. Un refactor mecánico bien cubierto por tests y una migración del flujo de pagos viven en el mismo repositorio y no piden ni de lejos la misma revisión.

Así que son dos preguntas encadenadas, y en este orden: cuánto perdona mi sistema, y dentro de él, cuánto perdona este cambio concreto. La primera fija el suelo de revisión; la segunda dice cuánto subes por encima de ese suelo. Aplicar el máximo a todo es tan mal criterio como no aplicarlo nunca: te comes el coste de la desconfianza sin comprar nada con él, y acabas mirando con lupa un cambio de copy mientras el que descuadra el stock pasa con la misma mirada distraída.

Por eso, cuando alguien cuente que ya no lee el código de sus agentes, la pregunta interesante no es cuánto confía en la IA. Es cómo de rápido y de barato le avisa su sistema cuando la IA se equivoca. Sospecho que mucha gente que cree estar en desacuerdo en este debate, en realidad solo está respondiendo por sistemas distintos.

Cuarta pregunta: ¿qué está diciendo Bob en realidad?

Esta es la parte que más me interesa, porque el titular ha viajado sin el contexto que lo sostiene.

Si lees el hilo completo y lo que Bob lleva contando estos meses, su proceso real es este: escribe especificaciones informales a mano, un agente las convierte en especificaciones duras divididas en tareas, y esas tareas las revisa él. Luego se convierten en Gherkin, en lenguaje natural, que es lo que define el comportamiento del sistema. Y mide de todo, desde la cobertura hasta el mutation testing. Es un verification loop de manual: señales externas, no introspección. Y cuando en el hilo le preguntan cuánta productividad queda después de montar semejante andamiaje, responde que el gasto manual grande está en dos sitios: la especificación inicial y el testing final. Todo lo de en medio, el código, se lo deja a la IA.

Lo que Bob hace de verdad

lo que eltitular cuentalo que el titularno cuentaSpecs informales a manohumanoAgente: specs duras + tareasautoRevisión humana de tareashumanoGherkin (lenguaje natural)autoAgentes escriben el códigoautoGauntlet: tests, mutation, métricasautoTesting final manualhumano
El criterio no desapareció del proceso: se mudó a los extremos del pipeline, que es justo la parte que el titular no lleva consigo.

Hay otra respuesta suya en el hilo que me parece la más reveladora de todas. Alguien le pregunta qué le da confianza en que los agentes vayan a respetar los guardarraíles, y responde que vienen a ser más o menos tan fiables como las personas, así que los vigilas. Ahí está todo. El hombre del "no leo el código" vigila a sus agentes como vigilaría a un equipo. Y cuando otro le acusa de haber dejado de ser ingeniero, contesta que es el ingeniero precisamente porque es el responsable. Que es otra manera de decir lo de siempre: ningún agente da la cara por ti.

O sea: Bob no ha dejado de revisar. Ha cambiado qué revisa. Sus ojos ya no están en la sintaxis, sino un piso más arriba. Su criterio no ha desaparecido: está codificado en qué constraints eligió, qué umbrales puso y qué specs aprueba. Trabaja a jornada completa, solo que donde no se ve.

Lo que Bob hace es de lo más sensato que se puede hacer hoy. El problema es la distancia entre eso y lo que su titular invita a hacer. El titular ha llegado a miles de personas sin las specs revisadas a mano, sin el mutation testing, sin las herramientas construidas a medida durante años de carrera. La mayoría de quienes aplauden la frase no tienen nada de eso debajo. Van a soltar el volante sin haber construido antes la carretera por la que el coche iría solo. Y ese código lo vamos a mantener entre todos.

Qué hacer con el próximo PR de tu agente

Un análisis que no cambia lo que haces el lunes es entretenimiento, así que vamos a bajarlo.

Lo primero no es un paso, es una condición: si esto lo vas a hacer a mano todos los días, el cuello de botella eres tú, y ya hemos dicho que eso no es una opinión. Buena parte de lo que ibas a mirar con los ojos (duplicación, acoplamiento, complejidad, violaciones de arquitectura) es una métrica, y una métrica no se mira: se automatiza y te avisa sola. Detectores que pasen sobre toda la base de código, no PR a PR. Tests que fallen cuando la arquitectura se rompe.

Montar eso cuesta la primera vez y se paga a partir de la tercera. Y no es accesorio al procedimiento: es lo que decide cuánto cuesta el procedimiento. Cuanto mejor sea tu gauntlet, más cambios caen en marcha alta y menos veces tienes que bajar.

Con eso montado, sitúa el cambio antes de abrir el diff. El suelo ya lo fijaste en la tercera pregunta, con lo que perdona tu sistema; lo que falta es la tarea. Dos preguntas, treinta segundos: ¿qué pasa si esto está mal y nadie se entera en dos semanas?, y ¿cuánto sé yo de esta parte del sistema? Radio de explosión y certeza. De ahí sale la marcha.

En marcha alta, con radio pequeño y terreno conocido, revisas el diff final y poco más. Aquí el detector hace el trabajo y tú das el visto bueno.

En marcha baja, con radio grande o terreno nuevo, no revisas el resultado: intervienes antes. Acuerdas la abstracción antes de que se escriba, partes el cambio en trozos que puedas juzgar de uno en uno, y miras cada uno. No porque la IA sea poco fiable, sino porque el coste de enterarte tarde es el más caro de la lista.

En las dos marchas, lo que lees es lo mismo, y no es la sintaxis: es el diseño. Es lo que los tests no ven y, peor, lo que la siguiente sesión del agente va a tomar como ejemplo.

Y cada cierto tiempo, mira el conjunto en vez del cambio. Las latas no se vieron en ninguna PR: se vieron al juntar las cuatro. Ninguna marcha te salva de eso, porque el problema no estaba dentro de ningún cambio, estaba entre ellos. Es la pregunta que hay que hacerle al repositorio de vez en cuando: qué regla de negocio se ha escrito más de una vez este mes, y cuál de ellas va a volver a cambiar.

Y cuando te toque tomar una decisión porque el contexto no estaba escrito en ningún sitio, escríbelo. Ese es el trabajo que queda. Cada regla que consigues sacar de tu cabeza y meter en el sistema es una que no vuelves a tomar y una que el agente ya no necesita preguntarte. Ahí es donde se sube el nivel, y por ahí es por donde esto deja de ser una discusión de internet y pasa a ser trabajo de ingeniería.

Subir el nivel al que conducimos

Junta las cuatro respuestas y el debate se ordena solo.

¿Se puede automatizar la revisión? La detección sí, cada vez más; la decisión de diseño, hoy no. ¿Desaparece el criterio con los guardarraíles? No: se muda a escribirlos y mantenerlos. ¿Da igual el sistema? Al contrario: el coste y la velocidad del fallo son las variables que más deberían pesar, y casi nadie la menciona. ¿Ha soltado Bob el volante? No: conduce un piso más arriba, sobre una infraestructura de criterio que lleva años construyendo.

La conclusión práctica para hoy no es ninguno de los dos eslóganes. "Leo todo el código" no sale a cuenta. "No leo nada" solo funciona con años de infraestructura de criterio debajo, y aun así deja fuera las decisiones de diseño que las métricas no ven. La postura defendible está en otro eje: qué decides que merece tus ojos, con independencia de cuánto código pase por delante. Yo ya no leo el código de mis agentes línea a línea buscando el bug; leo las abstracciones que se crean o se dejan de crear, las fronteras entre contextos, los sitios donde una regla de negocio se convierte en estructura. Leo diseño, no sintaxis. Y sí, recortada, esa frase suena exactamente igual que la de Bob: la diferencia está en lo que va después del punto y coma, y lo que va después del punto y coma ocupa este artículo entero. Y automatizo con ganas todo lo demás, porque gastar atención humana en lo que una máquina verifica mejor es tan irresponsable como no gastarla en lo que no puede.

El criterio que construyes en años de ver código romperse no sirve para leer más rápido que la IA. Nunca vas a leer más rápido que la IA. Sirve para saber dónde mirar. Esa es hoy la diferencia entre un senior con agentes y un junior con agentes, y sospecho que va a ser la última habilidad de esta profesión en automatizarse. Y no por magia: es la que decide qué se automatiza.

El verano que viene volverá a cambiar el formato de algún pack. Y el siguiente. Cuando pase, alguien va a tener que tocar esa regla y la va a encontrar en un sitio, no en cuatro, porque una tarde de julio nos paramos a leer un código que ya funcionaba y que ningún test tenía nada que reprochar. En la colmena no se va a notar. Ese es exactamente el punto: el trabajo de criterio bien hecho no se ve nunca, solo se echa de menos.

No hemos soltado el volante. Hemos subido el nivel al que conducimos. Y a quien os diga que el coche ya se conduce solo, preguntadle primero cuántos años ha dedicado a construir la carretera.

P.D. Transparencia: tengo interés en que este tema te importe, porque imparto un taller sobre exactamente esto: Antes del LGTM, un protocolo para revisar código generado por IA en menos de 10 minutos por cambio. No te va a dar el criterio: eso lo dan los años y los descuadres. Te va a dar el protocolo: qué delegar, en qué orden mirar y cómo escribir un no. El argumento de arriba se sostiene igual si no te apuntas nunca. Pero si al leerlo has pensado "esto es justo lo que no sé hacer cuando apruebo el PR de mi agente", ahí está.

Compartir:
Emilio Carrión
Sobre el autor

Emilio Carrión

Staff Engineer en Mercadona Tech. Ayudo a ingenieros a pensar en producto y a construir sistemas que escalan. Obsesionado con la arquitectura evolutiva y los equipos de alto rendimiento.