- A medida que los agentes de IA pasan al centro de la escritura de código, prácticas recomendadas antes “opcionales” como pruebas, documentación y tipado estático ahora se vuelven elementos obligatorios
- Exigen 100% de cobertura de código, para que cada línea de código esté realmente verificada y respaldada por ejemplos ejecutables
- La estructura de directorios y los nombres de archivos deben ser claros para que el LLM pueda recorrer el código con facilidad, y se recomiendan archivos organizados en unidades pequeñas
- Es importante construir entornos de desarrollo rápidos, efímeros y capaces de ejecutarse en simultáneo, para que varios agentes puedan trabajar en paralelo
- La clave es mantener un ecosistema de código confiable para la IA mediante sistemas de tipos estáticos y herramientas automatizadas de control de calidad
IA y la necesidad del “buen código”
- Durante mucho tiempo, los desarrolladores han visto las pruebas, la documentación, los módulos pequeños y el tipado estático como criterios de buen código, pero en la práctica a menudo se omiten
- Sin embargo, como los agentes de IA no son buenos ordenando el código por sí solos, estas prácticas recomendadas se vuelven indispensables
- Para evitar que los agentes operen en una dirección equivocada, es esencial definir guardrails claros y hacerlos cumplir de forma estricta
- Con guardrails sólidos, los LLM convergen solo por el camino correcto; en un entorno incompleto, amplifican los problemas
100% de cobertura de código
- El equipo está imponiendo 100% de cobertura de código, no solo para prevenir bugs, sino para verificar el comportamiento de todo el código escrito por agentes
- Con 95% o 99.99% de cobertura, el origen del código no probado no queda claro, pero con 100% cada línea no verificada puede identificarse claramente
- Los reportes de cobertura se usan como lista de tareas de prueba, y cuando el LLM cambia código debe presentar ejemplos ejecutables obligatoriamente
- Este enfoque también trae efectos secundarios positivos como eliminar código inalcanzable, explicitar casos límite y mejorar la eficiencia de la revisión de código
Namespaces y estructura de archivos
- Los agentes exploran el código a través del sistema de archivos, por lo que la estructura de directorios y los nombres de archivo cumplen el papel de una interfaz importante
- Una ruta clara como ./billing/invoices/compute.ts transmite mucha más información que ./utils/helpers.ts
- Deben preferirse archivos pequeños y bien definidos, ya que eso permite al LLM cargar el archivo completo en contexto y evitar degradaciones de rendimiento
- Esta estructuración se traduce en mayor velocidad y precisión en la exploración de los agentes
Entornos de desarrollo rápidos, efímeros y concurrentes
- En lugar del entorno de desarrollo único tradicional, el desarrollo basado en agentes cambia hacia una forma de administrar múltiples procesos en paralelo
- Fast: las pruebas y los procedimientos de verificación deben ejecutarse rápido, y el equipo los ha optimizado para completar más de 10,000 assertions en menos de 1 minuto
- La velocidad se logra mediante paralelización intensiva, aislamiento fuerte y una capa de caché para llamadas a terceros
- Ephemeral: con el comando
new-feature <name> se crea un nuevo entorno en 1 a 2 segundos, con configuración automática y ejecución del agente
- Si se requiere configuración manual, la frecuencia de uso cae drásticamente, así que la automatización total es clave
- Concurrent: para ejecutar varios entornos de desarrollo al mismo tiempo, se necesitan configuraciones que eviten conflictos en puertos, bases de datos, cachés, etc.
- Se puede usar Docker o configurar aislamiento basado en variables de entorno
Sistema de tipos end-to-end y control de calidad automatizado
- Hay que automatizar la mayor cantidad posible de prácticas recomendadas para reducir el margen de libertad del LLM y mantener una calidad consistente
- Se deben configurar linters y formatters automáticos de forma estricta, para que se apliquen correcciones automáticas cada vez que el LLM termina una tarea
- Se recomienda usar lenguajes con tipado estático, en especial aprovechar un sistema de tipos potente centrado en TypeScript
- Nombres de tipos con significado como
UserId, WorkspaceSlug y SignedWebhookPayload expresan claramente la intención del código
- OpenAPI ayuda a mantener la coincidencia de tipos entre frontend y backend
- Aprovechar el sistema de tipos y los triggers de Postgres asegura la integridad de los datos, y Kysely permite generar clientes con seguridad de tipos
- Todos los clientes de terceros también deben usarse con definiciones de tipos precisas o mediante wrappers
Conclusión: redefinir la calidad del código en la era de la IA
- Los agentes son codificadores sobresalientes que no se fatigan, pero su rendimiento depende de la calidad del entorno
- El “buen código” ya no es opcional, sino una condición previa para que la IA funcione correctamente
- La configuración inicial puede sentirse como una carga, pero en realidad es una inversión indispensable que se ha postergado por mucho tiempo
- Con apoyo del liderazgo de desarrollo, el objetivo debe ser construir una base de código amigable para la IA
1 comentarios
Comentarios de Hacker News
La trampa de lograr 100% de cobertura es que, si el mismo agente escribe el código y las pruebas, puedes caer en una verificación auto-contradictoria
Si el agente crea una lógica incorrecta y también escribe mal las pruebas que la validan, las pruebas pasan, pero en realidad el código sigue teniendo errores
Ese tipo de cobertura solo tiene sentido cuando las pruebas se escriben antes que el código o cuando una persona las valida con rigor
De lo contrario, solo crea una ilusión de confiabilidad
La clave es que personas con formas de pensar distintas validen los puntos ciegos unas de otras
Aunque haya varios modelos de IA, al final hay que tratarlos como una sola “mente”
Lo ideal es pruebas de IA para código humano, pruebas humanas para código de IA, o revisión cruzada de código
Aun así, entre humanos también hay relaciones de poder que hacen que solo se refleje la opinión de una persona, y la IA no evita eso
Hay que introducir bugs a propósito y verificar que fallen
Esto no es un problema exclusivo de la IA; con las personas pasa igual
Aun así, es bueno que gracias a la IA muchos desarrolladores estén aprendiendo principios de ingeniería bien hechos
SQLite y el software aeronáutico apuntan a ese nivel
Aun así, esto todavía no es una hipótesis validada académicamente
Por eso hay que validar escenarios reales de usuario con pruebas de integración o pruebas automatizadas de UI
También ayuda usar datos traídos del entorno de producción o pruebas en un entorno sombra
Antes de los LLM configurarlas era engorroso, pero ahora el ROI ha mejorado
Como enfatizaba Uncle Bob, es importante invertir en estructurar bien las pruebas
Los LLM escriben pruebas repetitivas, pero si se les pide también aplican bien el principio DRY o patrones factory
Es un método que estoy probando desde ayer: primero escribo la especificación en TLA+/PlusCal y luego le pido a Codex que la implemente tal cual
Le indico que se apegue a la especificación y no sea creativo
El código resultante es feo pero correcto, y mucho más rápido que traducirlo yo mismo
A veces le hago algunos ajustes cuando la optimización es pobre o queda demasiado desordenado
En especial estoy experimentando con estructuras de datos lock-free, pero Codex todavía intenta usar locks, así que tengo que corregirlo a mano
Al final, yo me concentro en la lógica matemática y la IA se encarga de los detalles de implementación
Ese es justamente el flujo ideal de “primero la especificación, después el código”
Me identifiqué con el texto de Martin Kleppmann
En los modelos más recientes esto realmente funciona bien, y la eficiencia de costos también mejoró entre 10 y 100 veces
Esto parece una alucinación o un discurso de ventas
Si los bugs reales de producción y la carga de mantenimiento no logran forzar buen código, la IA tampoco podrá
Con la IA actual, es más probable que el código empeore
Cuando ni siquiera hay consenso sobre la longitud de un método, no existe un criterio universal de calidad
Métricas como la cobertura de pruebas también se pueden manipular fácilmente y, si se aplican mal, hasta pueden ser dañinas
Sobre todo cuando la IA escribe las pruebas, puede dar una falsa confianza
Creo que el desarrollo de software podría ser la única aplicación realmente práctica de los LLM
Permite crear un ciclo de retroalimentación más rápido que en otros campos
Planeas algo con un LLM y unas horas después verificas el fracaso, y el LLM te dice “por eso no había que hacerlo así”
Es como construir una casa con normas eléctricas de EE. UU. y descubrir el problema al instalar un lavavajillas canadiense
El software era relativamente seguro, así que se permitía el desarrollo anónimo, pero ahora está surgiendo una cultura de firma responsable
En adelante, tal vez solo quienes escriban código de alto riesgo e innovador reciban sueldos altos
La IA sigue generando código disparatado, nosotros lo depuramos, luego genera otra cosa disparatada, y así caemos en un bucle infinito
Solo hay que hacer que coincida la especificación de corriente para que sea seguro
Aun así, me alegra que con pruebas unitarias al menos tengamos un punto de contacto con la realidad
Yo estoy estudiando circuitos RLC e inerter con LLM
Mucha gente se sorprende al ver que los LLM generan código rápido, pero la velocidad o el volumen no son el cuello de botella de la calidad
La verdadera revolución llegará cuando la IA produzca código más preciso que el de los humanos
El valor real viene de saber cómo funciona el código
En reuniones llenas de ingenieros que solo especulan, el momento más valioso es cuando alguien abre el código real y lo muestra
Quizá el “buen código” sea código optimizado para la memoria de trabajo limitada de los humanos
Los modelos pueden ver todo el contexto de una vez, así que no tienen esa restricción
Si la ventana de contexto se vuelve 100 veces más grande, quizá este debate importe menos
Me preocupa que pedirle 100% de cobertura a un LLM fije supuestos incorrectos
Aun así, si hay revisión humana, supongo que se puede decir “esto está mal, borremos estas pruebas y reescribámoslas”, ¿no?
Incluso redactamos el PRD junto con el LLM, como si fuera una entrevista, para dejar claros el alcance y las expectativas
Las “mejores prácticas” cambian según el entorno técnico
Ahora que escribir código es más fácil, una cobertura del 100% puede ser más útil para los LLM
Las pruebas le dan al LLM un objetivo claro y vuelven más seguras las interacciones posteriores
Cada prueba referencia tickets de bugs del pasado y garantiza que las correcciones se mantengan
Si le das escenarios a un LLM, por lo general genera código de calidad similar
A diferencia del arte creativo, el software es una industria especialmente apta para la automatización
Al ver el artículo pensé que iba a decir que, para que la IA sea efectiva, tenemos que escribir buen código
En la práctica, Claude suele equivocarse con nombres de variables ambiguos o código ilógico
Si una variable se llama “iteration_count” pero guarda una suma, la IA se confunde
Al final, el código limpio ayuda tanto a la IA como a los humanos
Como la IA usa la documentación interna como recurso de aprendizaje, ahora se considera indispensable tener documentación actualizada
Antes tenía baja prioridad, pero ahora afecta directamente la calidad del modelo
Aun así, con el tiempo esto también mejorará
Así aumenta la probabilidad de que el LLM implemente correctamente a la primera
Este artículo revela la comprensión superficial de ingeniería que tienen las empresas de prompts
Tener 100% de cobertura no valida todas las combinaciones de entrada
Solo significa que se ejecutaron todas las líneas con algunos ejemplos
Al final, lo que hace falta es una prueba formal, pero eso cuesta una fortuna y los LLM no sirven para eso
Más bien, crear un entorno de desarrollo reactivo mediante pruebas podría abrir una nueva edad dorada
Si luego aparecen problemas de cobertura, se puede ampliar después
Lo mejor es dejar el entorno de pruebas lo más exhaustivo posible desde el inicio
Ya hay muchos intentos de conectarlos con proof assistant
Incluso si la especificación tiene pequeños errores, en general producen resultados bastante útiles