- Aunque un LLM siga escribiendo código por ti, si fusionas tal cual condiciones duplicadas e implementaciones temporales, el código generado después puede seguir esa práctica como si fuera una regla del proyecto
- Si repites la lógica de verificación de permisos de acceso en route handlers, background jobs, API endpoints, webhooks, etc., las pruebas pueden pasar, pero la carga de mantenimiento seguirá ahí
- Como el modelo genera el siguiente código mirando los archivos abiertos, los patrones existentes y los cambios recientes, cuatro condiciones copiadas se vuelven una señal que invita a una quinta copia
- Incluso si más adelante pides una refactorización, es difícil garantizar que el LLM ordene correctamente todas las copias existentes, y los malos patrones se vuelven más parecidos al estilo del codebase que a un error puntual
- Si se acumulan condiciones duplicadas, funciones “god” y merges de “lo ordenamos después”, se vuelve difícil revertirlo solo con prompts y, al final, una persona tendrá que corregirlo directamente
Lo que el LLM toma como referencia es el codebase actual
- El LLM no escribe código “en el vacío”; lee el codebase del usuario
- Archivos abiertos
- Patrones ya existentes
- Cambios recientes
- Los atajos fusionados en el codebase se vuelven una señal de aprendizaje de “aquí se hace así”
- La misma condición de control de acceso puede repetirse en varios lugares
if (user.isActive && user.hasPermission('read') &&
!user.isSuspended && account.status === 'open') {
// do a thing
}
- Esta condición podría extraerse a un helper compartido, pero el código generado por el LLM puede fusionarse tal cual solo porque funciona y las pruebas pasan
- Si pides un quinto endpoint con la misma regla, es más probable que el modelo siga las copias existentes dentro del repositorio en lugar de diseñarlo desde cero
La ilusión de dejar el mantenimiento en manos del LLM
- Pensar “cuando haya que cambiarlo después, también lo hará el LLM” lleva a dejar pasar duplicación y code smells
- Unas cuantas condiciones duplicadas quizá no sean fatales, pero estos code smells se siguen acumulando
- Condiciones duplicadas
- Funciones “god”
- Merges que quedaron para “ordenar después”
- Cuando aumentan los malos patrones, también influyen en los resultados del siguiente prompt, y se vuelve difícil confiar en que más adelante el LLM corregirá todas las instancias sin omitir ninguna
- Aunque creas que estás tercerizando el mantenimiento al LLM, en la práctica podrías estar creando una situación en la que repite hábitos cada vez peores
- Hay que escribir código como si una persona fuera a mantenerlo, y mantener en buen estado los patrones de código que el LLM absorberá y devolverá
1 comentarios
Opiniones de Hacker News
Es buena idea crear un comando /review como un archivo Markdown vacío en
.claude/commands/review.mdy poner ahí una checklist que el agente deba revisar.Cuando necesites una revisión de código, escribes
/review; entonces mira esa checklist, planifica los puntos que valdría la pena corregir y luego pregunta.Mi archivo empieza con “entra en modo de planificación. Revisa las diferencias entre este branch y main. Cosas a considerar: ...”, y fui agregando continuamente los puntos que encontraba durante las revisiones de código y que hacía que el agente corrigiera; ahora ya son unos 200.
Al agente no le molesta recibir una pared de feedback genérico y va revisando los puntos uno por uno; me sorprendió que, al agregar “verifica que lo nuevo no duplique código existente”, de hecho empezó a planear tareas de limpieza.
Todavía apenas estamos rascando la superficie, y hay que darle herramientas para las herramientas para que la herramienta se convierta en una mejor herramienta.
Incluso ahora uso instrucciones bastante simples, pero Claude a menudo ignora las primeras, como “no hacer commits en git sin permiso” o “no firmar los mensajes de commit”.
Cuando se lo pregunto, responde “sí, esa instrucción existía, pero la ignoré”; si lo corrijo cortésmente durante la sesión, lo entiende, pero después a veces queda en un estado en el que ya no puede hacer commits en absoluto.
Si le pides que revise una checklist de 200 puntos, es muy probable que se le pasen silenciosamente una buena parte.
Un ingeniero humano no usaría en un test nuevo una librería de aserciones totalmente distinta si ya hay 200 tests existentes usando otra, pero Claude lo hizo varias veces.
Por eso termino agregando una y otra vez puntos como “revisa las convenciones de testing antes de escribir”.
En cambio, no hace falta decirle cosas básicas como qué es una función o que los tests deben cubrir el diff de cambios; pero no existe una lista clara de qué cosas hay que decirle y cuáles están bien, así que se siente como construir a base de prueba y error un método que sea utilizable.
En mi caso, suelo iterar con el agente hasta que “se vea bien para mis ojos y mi gusto”, pero todavía no he creado una lista así.
Dependiendo del proyecto, puedo permitir problemas menores o números mágicos; en otros proyectos, obligo a usar constantes con nombres significativos como
SECONDS_IN_A_DAY = 24 * 60 * 60, así que es dependiente del contexto.https://github.com/alibaba/open-code-review
https://layandreas.github.io/personal-blog/posts/beyond-vide...
Por ejemplo, hacer que elija los N roles más adecuados para el cambio a partir de una lista larga de roles como Senior Engineer, Security Engineer o especialista en WCAG.
Claude ejecuta esas revisiones en paralelo y luego combina el feedback.
Como hago desarrollo basado en especificaciones, voy agregando los issues encontrados a la especificación para dejar rastro de los problemas y las decisiones.
Es casi raro que tantos ingenieros aquí estén agregando otro prompt encima
En mi experiencia, mientras más se hace eso, peor resulta: abstrae, pero crea abstracciones equivocadas, y agrega demasiados comentarios, hasta confundir las llamadas posteriores al LLM
En una buena base de código funciona más o menos, pero va empeorando el código; si lo sigues usando y en algún momento deja de funcionar, te toca arreglarlo pagando el costo de no haberlo construido tú mismo
Cuando metes un agente en una base de código nueva, normalmente todavía hay un modelo mental del código y el código es relativamente conciso, pero con la repetición acumulada ambas cosas desaparecen y el rendimiento del LLM también baja
Por eso uso los LLM para exploración y revisión, y escribo el código yo mismo
Programar tampoco consume tanto tiempo y es la parte más divertida; me cuesta entender por qué querrían evitarlo, y cuando de vez en cuando hago una carrera de depuración contra la IA al mismo tiempo con el prompt
/bug, la IA no siempre es más rápidaEn los últimos años, el trabajo de software pasó de ser uno de los refugios de ingeniería práctica para curiosos que disfrutan trastear y adictos a los rompecabezas, a convertirse en una trayectoria profesional para gente inteligente que busca dinero, como finanzas, derecho o medicina
Muchas personas que hoy tienen el título de “ingeniero de software” nunca disfrutaron realmente el trabajo en sí; simplemente eran inteligentes y responsables, y cumplieron objetivos razonables que les dio su empleador
Esas personas son las que más quieren que los agentes de IA les eviten el diseño riguroso y el trabajo de rompecabezas, y les permitan aprovechar su inteligencia natural de una forma más perezosa
Como no internalizaron la programación ni los principios de ingeniería, cuando están rodeadas de colegas con la misma mentalidad es difícil predecir qué resultados producirá este enfoque a futuro
Si programar en sí fue desde el inicio una experiencia muy frustrante y llena de fricción, es fácil sentir que la IA es más rápida
No basta con leer el código; hay que padecerlo para internalizarlo
Los agentes suelen envolver defensivamente el código viejo en vez de preguntarse si ese camino existente todavía debería existir, lo que produce el efecto de cantidades enormes de código defensivo apiladas en capas como muñecas rusas
https://softwaredoug.com/blog/2026/07/09/write-code
Opus 4.8 fue el punto de inflexión y, sobre todo en problemas complejos, ahora ya no le gano mucho a Opus 4.8
Si todos usaran Opus 4.8 o superior para todas sus tareas y preguntas, el ambiente general sería muy distinto, y creo que quedarían muchos menos escépticos de la IA
Todavía escribo el código a mano, aunque algunas partes, no todas, las genera Opus
Puede sonar como una idea disparatada, pero simplemente puedes escribir el código tú mismo
En la era de la IA puede sonar como un concepto difícil de creer, pero si es código que personas tendrán que leer y mantener, es mejor escribirlo directamente para esas personas
Leer código demasiado verboso y copiado y pegado te va a irritar, y a los demás también
Si lo escribes tú mismo, lo corriges tú mismo y lo haces de una forma que tenga sentido para que otra persona lo mantenga
O también puedes apaciguar al agente y al loop creando una compleja red de archivos Markdown para que entiendan la forma de código que esperará el mantenedor del futuro
No sé qué camino será más fácil a largo plazo, y me da curiosidad si alguien ha heredado y entendido una base de código dirigida por agentes basados en loops
No estoy tan seguro de qué tan cierto sea eso de “la próxima vez que le pidas al LLM un endpoint con las mismas reglas de acceso, el modelo no piensa desde cero, sino que parte de las cuatro copias que ya existen en el repositorio”
En la práctica, parece haber un sesgo incorporado a repetir la estructura básica y a reutilizar o abstraer menos
Si el patrón existente es así, parece que lo siguiera, pero en realidad probablemente habría hecho eso de cualquier forma
Incluso cuando preparé primero una abstracción estricta y ejemplos de uso, y le indiqué explícitamente que usara solo cierta API de abstracción y que copiara la forma en que yo la había escrito, muchas veces los LLM recientes no hicieron ninguna de las dos cosas, reimplementaron la estructura básica desde abajo e ignoraron la abstracción parcial o totalmente
No sé exactamente por qué, pero sospecho que hay tanto código de este estilo en el código de entrenamiento que los pesos “saben” mejor cómo producir resultados de esa manera
Aun así, creo que está bien usar los LLM como motores de implementación rápidos
El reto es hacer que el modelo exponga primero esas decisiones de implementación antes de salir corriendo en la dirección equivocada
Después de un cambio grande, obtuve buenos resultados con el siguiente prompt
“Ahora haz una revisión final del código. ¿Está todo ordenado y los componentes siguen el principio de separación de responsabilidades? ¿Es comprensible y mantenible? ¿Está haciendo suposiciones que quizá ya no sean ciertas? ¿Quedó en la base de código algo sobrante de ediciones o experimentos anteriores? ¿La documentación todavía refleja el estado actual del código?”
Con eso por lo general infiere lo anterior y más
Lo que sí tengo que señalarle una y otra vez es que elimine todos los comentarios de “seguimiento del progreso” y deje solo los comentarios adecuados para mantenimiento a largo plazo
Claude deja comentarios como “hacer clic en el botón ahora dispara el guardado y ya no usa onBlur”, cuando el código real nunca usó onBlur y eso solo es un rastro de algo que Claude intentó hacer antes en la misma tarea/rama y que yo le hice revertir
El modelo lo interpretará a su manera, pero aun así muchas veces es mejor que no hacer nada
Consiste en enseñarle todo a la IA y preguntarle si lo aprendió bien, y el resultado es sorprendentemente bueno
Estoy siguiendo pasos parecidos a los de este artículo
https://www.lucasfcosta.com/blog/backpressure-is-all-you-nee...
Hay un viejo dicho:
“Comenta el código asumiendo que el próximo mantenedor es un asesino que sabe dónde vives”.
Hace poco, en una revisión de PR, me encontré con algo así por enésima vez y dejé un comentario enojado; hasta yo mismo me sorprendí.
No sabía que podía reaccionar así.
Es decir, que existen porque el código en sí no es claro. A veces es así, pero en general creo que es mejor tener más comentarios que menos.
Especialmente si explican cómo se conecta el código con el negocio real o con los requisitos funcionales, y no solo repiten lo que hace el código.
Hace unos años solía escribir primero los comentarios.
Explicaba el objetivo general, lo dividía en rutinas y una secuencia de tareas, y cuando quedaba conforme, rellenaba los bloques de código entre los comentarios.
Es algo parecido a la programación literaria, aunque ya lo hacía antes de conocer ese término; era más bien como darme prompts a mí mismo para avanzar hacia el objetivo.
La desventaja es que los comentarios pueden terminar siendo apenas una explicación en inglés de lo que hace el código, lo cual quizá no sea tan útil para futuros mantenedores.
El código debería explicarse por sí mismo, y los comentarios se usan donde hay dragones.
En una línea parecida, un prompt que me gusta es: “Revisa las pruebas que escribiste. ¿Estas pruebas realmente prueban lo que se pretende? Si el código se rompe, ¿también fallan las pruebas?”.
Es sorprendente la frecuencia con la que los LLM escriben pruebas vacías que no validan nada.
Me pregunto si todavía tenemos que discutir esto en serio.
Si ya se “experimentó” así con LLM, ¿no deberíamos darlo por asumido?
Me pregunto cuándo podremos volver a hablar de escribir código a mano sin tratarlo como un tabú.
Los LLM son útiles de muchas maneras, pero cuando veo a la gente delegar en agentes el tipeo de todo el código fuente, me parece aleccionador,
parecido a escuchar que deberíamos estar felices porque la web es buena.
Estoy pasando continuamente la base de código por varios modelos para que encuentren malos olores como código duplicado.
Ha sido bastante efectivo, y si no se mantiene con el tiempo, creo que se convertirá en una bola de suciedad que se irá acumulando.
También se pueden incorporar al pipeline de build y no consumen tokens en absoluto.
¿O será más importante el proceso de revisión y el reinicio del contexto?
En código mantenido por personas durante 20 años también he visto mucha duplicación y cosas peores.
Para ser sincero, en la mayoría de los casos el código escrito y mantenido por humanos era peor que el que generan hoy los LLM.
A veces se debe a falta de experiencia, y otras a negligencia deliberada, pero por lo general es por cronogramas ajustados y la presión de terminar ya.
La gente sabe cómo hacerlo mejor, pero en la práctica no tiene tiempo ni presupuesto para hacerlo así.
Los LLM también aprendieron eso.