- En un entorno de desarrollo que colabora con IA, para mantener la calidad los humanos deben definir con claridad la dirección del proyecto y la toma de decisiones
- Mediante una documentación precisa, tanto la IA como otros desarrolladores deben poder comprender con claridad los requisitos y las restricciones
- Se debe construir un sistema de depuración y un proceso de revisión de código para reforzar la confiabilidad y la validación del código generado por IA
- Con medidas como marcar funciones de riesgo de seguridad, separar las pruebas y aplicar reglas estrictas de linting, se asegura la estabilidad y la consistencia del código
- Mediante la división del trabajo en unidades pequeñas y la minimización de la complejidad, se mantiene el control sobre la generación de código con IA y se maximiza la eficiencia
1. Establecer una visión clara
- Los humanos entienden el mundo, al equipo y el comportamiento de los usuarios, pero la IA no tiene experiencia, por lo que necesita instrucciones explícitas
- En un proyecto, las decisiones que no estén documentadas terminarán siendo tomadas por la IA
- Se deben discutir de antemano la arquitectura, las interfaces, las estructuras de datos y los algoritmos, y definir cómo se harán las pruebas
- Las decisiones a largo plazo y difíciles de cambiar deben ser gestionadas directamente por humanos
2. Mantener una documentación precisa
- Para que la IA genere código acorde al objetivo, es indispensable transmitir requisitos detallados
- Como otros desarrolladores también deben poder entregar a la IA la misma información, se debe incluir en el repositorio documentación en un formato estandarizado
- Registrar en detalle requisitos, restricciones, arquitectura, estándares de codificación, patrones de diseño, etc.
- Usar diagramas UML, flujogramas y pseudocódigo para representar visualmente estructuras complejas
3. Construir un sistema de depuración que apoye a la IA
- Se debe preparar un sistema de depuración eficiente para que la IA pueda verificar rápidamente la funcionalidad del código
- Ejemplo: recopilar los logs de todos los nodos de un sistema distribuido y proporcionar información resumida como “los datos se enviaron a todos los nodos”
- Esto permite reducir el costo de ejecutar comandos y acelerar la identificación de problemas
4. Indicar el nivel de revisión de código
- Según la importancia del código, se debe distinguir la intensidad de la revisión
- Ejemplo: agregar el comentario
//A después de una función escrita por IA para indicar si ya fue revisada por un humano
- Este sistema facilita la identificación y gestión del código no revisado
5. Escribir especificaciones de alto nivel y probar directamente
- La IA puede hacer trampa con objetos simulados o valores hardcodeados para pasar las pruebas
- Para evitarlo, se deben escribir directamente pruebas basadas en propiedades (property-based testing)
- Ejemplo: reiniciar el servidor y verificar la consistencia de los valores en la base de datos
- El código de pruebas debe separarse en un área aparte para que la IA no pueda modificarlo
6. Separar las pruebas de interfaz
- Se debe hacer que la IA escriba pruebas de interfaz sin conocer el contexto del resto del código
- Así se mantiene la objetividad de las pruebas, al no verse afectadas por la IA que implementó el código
- Estas pruebas también deben protegerse para que la IA no pueda modificarlas arbitrariamente
7. Reglas estrictas de linting y formateo
- Un estilo de código consistente y reglas de linting son esenciales para mantener la calidad y detectar errores de forma temprana
- Tanto la IA como los humanos pueden revisar con facilidad la calidad del código
8. Usar prompts de agentes de código según el contexto
- Usar archivos de prompts por proyecto, como
CLAUDE.md, reduce el costo de entendimiento inicial de la IA
- Al incluir estándares de codificación, patrones de diseño y requisitos, se mejora la calidad y eficiencia de la generación de código por parte de la IA
9. Identificar y marcar funciones con riesgo de seguridad
- Se deben marcar explícitamente las funciones sensibles de seguridad, como autenticación, permisos y procesamiento de datos
- Ejemplo: usar comentarios
//HIGH-RISK-UNREVIEWED, //HIGH-RISK-REVIEWED
- Si la IA modifica esas funciones, se debe configurar el sistema para cambiar automáticamente el estado de revisión
- Los desarrolladores siempre deben verificar que ese estado sea correcto
10. Minimizar la complejidad del código
- Incluso una sola línea de código innecesaria ocupa espacio en la ventana de contexto de la IA y aumenta el costo
- Se debe mantener una estructura lo más simple posible para mejorar la comprensión tanto de la IA como de los humanos
11. Explorar problemas mediante experimentos y prototipos
- Aprovechando la naturaleza de bajo costo de la generación de código con IA, se pueden probar distintas soluciones
- Crear varios prototipos con especificaciones mínimas para explorar el mejor enfoque
12. Evitar la generación masiva indiscriminada
- Las tareas complejas deben dividirse en unidades pequeñas para que la IA las procese paso a paso
- Ejemplo: generar funciones o clases individuales en lugar de todo el proyecto
- Se debe verificar que cada componente cumpla con la especificación, y
si no se logra controlar la complejidad del código, se debe revertir el proyecto a su estado inicial
1 comentarios
Opiniones de Hacker News
Sigo sintiendo que es importante escribir el código uno mismo para ordenar las ideas
Para mí, el código funciona como una especie de mecanismo que me obliga a pulir los detalles
Siento que solo escribir la especificación no me da esa misma profundidad
Si le delego ese proceso a un LLM, es como si mi mente se quedara en pérdida, como un avión entrando en stall
Reduce el estrés de resolver problemas, pero también desaparece la motivación para pensar y crear
A mi alrededor hay gente a la que le encanta que la IA escriba el código por ellos, pero yo no estoy en ese grupo
Me cuesta creerles a quienes dicen que crean un SaaS tomando café mientras corren 5 agentes
Si quieres código de buena calidad, creo que hace falta meterse a fondo en el código uno mismo
Aun así, la IA me ha servido bastante para tareas simples y repetitivas como escribir tests o resolver problemas de configuración
Por ejemplo, reviví con Claude un proyecto que había abandonado hace 5 años, y en unas horas sentí que ya iba por la mitad
Pero últimamente siento que volví a un enfoque centrado en especificaciones
Gracias a los agentes, puedo repetir rápido el ciclo de intentar y descartar, así que sigo manteniendo un flujo de desarrollo iterativo
Veo la especificación y las pruebas como el trabajo real, y ahí mismo sigo corrigiendo cosas mientras ordeno mis ideas
Solo con la especificación no se puede capturar toda la complejidad del mundo real
El código escrito por LLM a menudo es verboso y se va por direcciones raras, así que hace falta gestionarlo directamente
En cambio, como compañero para discutir y pulir ideas, el LLM funciona bastante bien
Ahora que escribir código se volvió más barato y rápido, quizá incluso haga falta reforzar la etapa formal de diseño
Creo que lo que más impacto tuvo en la calidad de mi código fue configurar de forma sistemática herramientas de análisis estático
En TypeScript, combiné
tsc,eslint,sonarjs,knip,jscpd,dependency-cruiserysemgrep, e integré todo con el comandopnpm checkLo hago correr automáticamente con un pre-commit hook para evitar problemas que el LLM no detectó
Gracias a eso, cuando el LLM se queda atascado también puedo corregir a mano con facilidad
Si el estilo del código es consistente, revisar se vuelve mucho más simple, y aunque se mezcle código de IA con código humano, hay menos confusión
Pero incluso si pasan todos los lint y tests, igual aparece código que funciona distinto a la intención
Por ejemplo, una API que devuelve un arreglo vacío en vez de un 404: sintácticamente está bien, pero semánticamente está mal
Esa evaluación de corrección conductual sigue siendo la parte más difícil por ahora
A veces creo que la mantenibilidad debería ir primero, incluso por encima de las reglas de lint
Yo hago refactorización periódica cada vez que agrego funciones nuevas
Cada ciertos cambios reviso y ordeno toda la base de código
Llevo 40 años programando, y el código que tengo ahora es el que más me satisface
Pero gracias a los LLM, el costo de refactorizar se volvió casi cero
Ya no hay motivo para dejar código malo tal como está
Creo que el verdadero valor está en usar las herramientas que aumentan la eficiencia para mejorar la calidad
Construí una herramienta interna que en cada commit marca las líneas de código como buenas (verde) / necesitan refactor (amarillo) / necesitan reescritura (rojo)
Es más limpio y sistemático que dejar comentarios de “TODO refactor”, y pronto planeo publicarla como open source
Ahora mismo creo que, para trabajar con IA, el desarrollo guiado por especificaciones es lo más estable
Dedico más tiempo a pulir las especificaciones y a intercambiar ideas con el equipo y con la IA
Si la especificación está incompleta, la IA genera código en cualquier dirección
Cuando la comprensión del dominio se profundiza, a veces siento que es mejor hacer que lo implemente de nuevo desde cero
En ese entonces existía la visión de que “si defines los requisitos, el sistema se construye solo”
Al final fracasó y Agile pasó a dominar, pero ahora parece que la tecnología podría volver a hacer posible ese sueño
El verdadero valor de la IA está en la velocidad y su capacidad para manejar ambigüedad
Pero si pasas por todos los procedimientos, al final todo se vuelve tan lento como waterfall
Creo que es mejor escribir el código directamente y usar la IA como revisora de primera pasada
Seguir avanzando validando rápido en unidades pequeñas sigue siendo un enfoque ágil
En especial me gustó la sugerencia de marcar funciones relacionadas con seguridad. Eso ayuda a mantener el contexto cuando luego cambia el código
“Dividir en partes pequeñas” es básico, pero los principiantes suelen pasarlo por alto
Da risa que últimamente, gracias a la IA, la gente esté redescubriendo buenas prácticas básicas
En realidad, son cosas que ya se deberían haber hecho desde antes
Ahora que el tiempo de programación se redujo, hay más margen para dedicarlo a estas tareas
Además, la IA sí aprovecha la documentación de verdad, así que escribir buena documentación ahora tiene un valor directo
Antes escribías docs y nadie las leía, pero los LLM sí las leen
Antes escribía especificaciones detalladas antes de programar, pero luego me di cuenta de que ir directo al código era más rápido
Entonces, ¿ahora estamos volviendo otra vez a centrarnos en especificaciones?
Si escribes una especificación sin entender por completo el problema, al final igual terminas aprendiendo mientras programas
Parece que ahora estamos en algún punto intermedio
Pero ahora, gracias a la IA, el costo de producir código incorrecto es casi cero, así que se siente como si el valor de la especificación hubiera bajado
Eso se parece a la forma de programar de la que hablaba Joe Armstrong
Ahora vivimos en una época en la que eso sí es factible en la práctica
Cuando estuve en un puesto de lead, yo redactaba tickets con muchísimo detalle
Era también por los juniors, pero sobre todo para no olvidarme yo mismo de los detalles
Sin embargo, la gerencia se oponía diciendo que era “una pérdida de tiempo”, y al final perdí ese hábito
Ahora, en cambio, me piden que escriba especificaciones todavía más elaboradas y más rápido
Al usar agentes de IA, me da curiosidad la proporción entre Markdown y código, y también la legibilidad del resultado
También me pregunto si el tiempo de revisión no termina siendo mayor que si uno escribiera el código directamente
Es irónico ver a desarrolladores que defienden con entusiasmo una IA que podría reemplazarlos
Este tuit relacionado satiriza ese fenómeno
Quizá por eso empujan tanto el mensaje de que “si no usas Claude, te vas a quedar atrás”
pero en realidad es muy probable que eso termine en menos demanda y menor compensación para los desarrolladores
Sobre todo corren más riesgo los desarrolladores que apenas se dedican a combinar paquetes de NPM