Harness engineering
Cómo desarrollo Eurmes con IA sin que el código se degrade: un arnés de guías y sensores alrededor del modelo que le dice cómo hacer las cosas antes de actuar y comprueba después que las ha hecho bien.
Harness engineering: que la IA no te llene el código de deuda técnica
7 capítulos
La IA genera código en minutos, pero también deuda técnica a la misma velocidad. Con un caso real de Eurmes, en el que la IA rompe la arquitectura aunque todo funciona, vemos qué es un harness: guías que orientan al modelo antes de actuar (AGENTS.md, skills, MCP, TypeScript) y sensores que lo revisan después (linters, tests, revisión con IA), y por qué con IA los tests y los linters ya no son opcionales: son obligatorios. Es el primer vídeo de una serie sobre harness engineering. Vídeo en castellano, con subtítulos en castellano, inglés, francés, alemán e italiano.
Ver transcripción del vídeoTranscripción
Normalmente, hace varios años, desarrollar soluciones software de complejidad baja o media llevaba días o incluso semanas. Sin embargo, con el auge de la IA generativa hemos pasado de días y semanas a minutos o segundos en desarrollar este tipo de soluciones software. Pero no siempre barato y rápido deriva en un código y una arquitectura que siga buenas prácticas, sino lo contrario: la IA suele ser tan rápida generando código como generando deuda técnica, errores, una arquitectura que se degrada a medida que crece, etcétera. Bienvenidos a este vídeo en el que vamos a ver el harness engineering. Igual que utilizamos un arnés sobre un caballo para intentar orientarlo y guiarle hacia un buen camino, pues de ahí viene la palabra harness engineering: el arnés que se le pone a un caballo. Bueno, vamos a ver directamente un ejemplo. Si nosotros tenemos una lección teórica de Eurmes, cada lección teórica tiene una visibilidad, y en cada una de sus diferentes versiones vemos que ha podido ser generado puramente con inteligencia artificial, que ha sido escrito puramente por un profesor o una mezcla de ambos. Al final, este sistema de autoría en nuestro código se traduce de la siguiente forma. Lo primero que vemos es que todo el código y funcionalidad desarrollado para la gestión de autoría, es decir, si una lección teórica y sus ejercicios están hechos con IA o están hechos por un profesor o ambas, está dentro del módulo de academia. Entonces nosotros ahora hemos evolucionado el sistema y tenemos también exámenes oficiales, y estos exámenes oficiales pueden ser generados por inteligencia artificial o por profesores. Sin embargo, ya la parte de lecciones teóricas y prácticas tiene suficiente dominio como para separarlo del área de exámenes. El área de exámenes es un módulo hermano, y yo le he pedido a la IA que esta funcionalidad que está aquí, la autoría de contenido, la haga reutilizable para no repetir todo el código de quién es el autor de esto, si una IA o una persona. Pero sin arnés, es decir, sin control: yo le he dicho a la IA que lo haga y ya está, simplemente que reutilice toda esta funcionalidad. ¿Qué ha pasado? Pues yo, como persona que controla arquitectura, he visto que lo que ha hecho es cometer diferentes errores. Primero, ha importado cosas de un módulo hermano, y aquí ya estamos rompiendo principios de una buena arquitectura. Hay muchos principios que nos dicen que no hay que hacer importaciones entre módulos funcionales hermanos, sino que tienen que estar separados, desacoplados. Uno de ellos es el principio de separate business context, que lo que viene a decirnos es que cada contexto de la empresa, de negocio, tiene que ser independiente: no pueden depender unos de otros. Y aquí estamos reventando todo ese principio, porque vemos aquí que un archivo que se llama upsert exam bank, que concretamente dentro de toda esta área de aquí de exámenes, está importando código propio de academia. Estamos rompiendo el principio de independencia. Entonces, ¿cómo podríamos haber detectado todo esto con un arnés, es decir, un mecanismo que controle que lo que ha hecho la IA está bien? Y lo primero que vemos nosotros es que a nivel de código está todo verde, o sea, que no es algo que se pueda detectar a nivel funcional, porque a nivel funcional funciona; es decir, la autoría de los exámenes probablemente esté funcionando bien, pero a nivel de arquitectura software no estamos cumpliendo. Esto lo podemos solucionar utilizando ESLint, que lo que viene a hacer es comprobar que todo nuestro proyecto cumple unos mínimos de calidad de código, y dentro de esos mínimos nosotros podemos añadir todas las reglas que queramos. Una de las reglas que yo he añadido es que nunca puede haber importaciones entre carpetas hermanas: tiene que haber importaciones a la carpeta shared, que es compartido. Es decir, si dos o más submódulos necesitan una misma funcionalidad, tiene que ir en shared; no puede ir en una carpeta hermana. Ya en el vídeo de arquitectura back y en arquitectura front veremos más al detalle cómo implementar esta regla, pero por ahora lo que tenemos que quedarnos es que tenemos que aplicar ciertas técnicas que nos permiten identificar estos errores, porque ya hemos visto que a nivel de software no lo hemos detectado todo bien, pero a nivel de control de calidad de código sí que lo hemos detectado, y hemos detectado que no puede haber importaciones entre exámenes y academia. Y además de eso también hemos detectado que no se pueden importar librerías de terceros en una capa de application. Vale, esto son reglas de la clean architecture, que pone restricciones de importaciones entre capas. Entonces aquí hemos detectado dos, pero además yo, a nivel de ojo humano, he detectado que aquí ha puesto en la capa de aplicación algo que debería ir en domain, ¿no? Realmente aquí. Entonces estamos viendo ya errores que la IA nos ha hecho. Más conceptualmente, lo primero que podemos ver es que los harness en general tienen guías y sensores. Las guías son todo aquello que utilizamos para guiar a la IA en el proceso de creación de nuevo software: por ejemplo, habilidades, podemos añadirle la habilidad de crear un nuevo tipo de ejercicio y que se integre en todo el ecosistema; o podemos darle una base de conocimiento a través de un MCP; o podemos controlar con TypeScript que el nuevo código generado esté bien. Una vez la IA ha recibido todas estas guías, nos genera una salida, que son todos esos archivos de código reescritos, y pasamos esa salida por lo que llamamos sensores. Los sensores pueden ser pruebas unitarias, pruebas end-to-end, linters que controlan reglas, como hemos visto en el ejemplo anterior, de que no haya cruces entre diferentes capas verticales, revisión con inteligencia artificial, etcétera, e incluso el TypeScript: la IA, una vez ha generado la salida, intenta construir con TypeScript, y si le genera algún error, pues se le avisa y el modelo corrige el archivo. Este sistema se retroalimenta y no es estático: evoluciona a lo largo del tiempo. Es decir, vamos a añadir nuevas pruebas end-to-end, vamos a corregir nuevas pruebas unitarias, vamos a mejorar los linters añadiendo nuevas reglas, vamos a añadir nuevos agentes de IA ligeros o no tan ligeros para revisar, y lo mismo por el lado de las guías: vamos a añadir nuevas skills, perfeccionar el MCP, etcétera. Entonces esto es un sistema que está en continua evolución, y a medida que vamos encontrando fallos le vamos dando más robustez. Entonces, el objetivo de este vídeo es dar paso a una serie de vídeos que explicarán cómo implementar el harness engineering desde diferentes perspectivas. La primera de ellas es dándole contexto a la inteligencia artificial, es decir, proporcionarle archivos de tipo AGENTS.md, entre otras cosas, para que la IA se oriente más en la creación o mantenimiento de nuevo software, así como servidores MCP, que nos permiten navegar el código de manera más eficiente. Continuamos con habilidades, que permiten darle habilidades a la IA, como crear software modular: concretamente veremos cómo crear bloques de teoría o ejercicios de manera modular, haciéndolos encajar en el ecosistema sin romper buenas prácticas y directrices. Continuaremos con TypeScript avanzado para forzar a nivel de compilación que, si la IA hace algo mal, el compilador de TypeScript grite y nos diga: «oye, que algo va mal». Ya más a nivel de sensores, es decir, una vez la IA ha generado el código nuevo, pasamos linters, que lo que hacen es controlar con diferentes reglas la calidad del software, y también con tests unitarios, pruebas end-to-end y con otras guías vamos a controlar que todo nuestro software cumple unos requisitos mínimos de calidad. A modo de recapitulación, sobre todo lo que quiero transmitir es que, si desarrollamos proyectos con inteligencia artificial, tenemos que rodear esa inteligencia artificial con un ecosistema que garantice unos mínimos de calidad de software, así como que, si la IA modifica algo, no rompa otras áreas de nuestra aplicación. Es por ello que en este caso, es decir, cuando desarrollamos con IA, ya no es opcional desarrollar pruebas end-to-end, pruebas unitarias o linters, sino que es obligatorio, porque tenemos que controlar de alguna manera que todo el volumen que genera la IA de alguna manera cumple con una calidad. Espero que te haya gustado este vídeo y nos vemos pronto.