Puedo detectar cuándo haces "vibe coding"
(alexkondov.com)- En mi equipo últimamente es fácil reconocer cuándo un código fue generado por un LLM
- Aunque este tipo de código sea claro y tenga buenas pruebas, no respeta la convención del proyecto
- Ignora múltiples patrones o bibliotecas existentes y crea una implementación nueva directamente
- Crece la preocupación por la tendencia de buscar solo la velocidad en el desarrollo de software
- Al final, lo que importa son la calidad y la coherencia, así como la mantenibilidad
Rastros del "vibe coding"
- Aunque parte del código que escribió un miembro del equipo parece claro y funcionalmente perfecto, se puede reconocer de inmediato que fue generado por un LLM al no respetar la convención propia del proyecto
- Por ejemplo, aun cuando ya existe una biblioteca para obtener datos en el proyecto, se implementa directamente una solicitud HTTP que cubre todos los casos de excepción
- Se siguen creando desde cero de nuevo funciones utilitarias de módulos existentes o, aun teniendo un mecanismo de cambio de configuración por módulo, se termina modificando la configuración global
- Aunque la cultura de escribir código de forma funcional esté asentada, se vuelve a escribir código basado en clases
- Este tipo de código es un estilo que nadie habría escrito hace unos años
Importancia del mantenimiento y los principios de software
- En el desarrollo de software hemos invertido esfuerzo en establecer patrones y estándares que funcionen a largo plazo
- En la práctica, cualquiera puede escribir código que solo funcione, pero el verdadero reto es hacerlo fácil de gestionar y modificar a largo plazo
- Lo importante no es la implementación de la funcionalidad en sí, sino una base de código mantenible con el tiempo
- El "vibe coding" puede socavar esta clase de filosofías y estándares
¿Colocar la velocidad como la máxima prioridad?
- A través de la comparación con un barista nuevo en una cafetería que, por apresurarse, derrama café, se destaca que la obsesión con la velocidad no conduce a un resultado correcto
- De igual manera, los equipos de desarrollo de hoy también terminan con una baja de calidad al intentar crear software nuevo demasiado rápido
- Lo que la gente realmente busca es un resultado hecho correctamente, aunque implique esperar un poco más
- Pensaba que preocuparse solo por la velocidad era un problema de ocupaciones no técnicas, pero me decepciona ver que incluso colegas desarrolladores están abandonando los principios y persiguiendo solo la velocidad
Lo que realmente se busca
- No importa cómo se insertó el código en el IDE
- Lo importante es la actitud del desarrollador de preocuparse por la calidad
- Aunque reconoce que los LLMs son una gran innovación técnica, enfatiza que la responsabilidad de construir software real sigue recayendo en el desarrollador
- Se recomienda conocer y aplicar los principios existentes como “escritura de mejores prompts”, “especificar la biblioteca correcta”, “proveer ejemplos” y “trabajar en unidades de archivo pequeñas”
- Se advierte que no se debe confiar únicamente en el “peso” del modelo para la calidad del código y la mantenibilidad
2 comentarios
Opinión de Hacker News
Nadie rehace una implementación de HTTP fetching si la librería de fetching de datos que ya existe en el proyecto cubre todos los casos excepcionales, nadie reimplementa algo si ya existe un módulo de funciones utilitarias, nadie cambia algo desde un módulo individual si ya puede hacerse desde la configuración global, y nadie crea una clase nueva en un equipo que usa principalmente un enfoque funcional; me gustaría trabajar en un equipo así, pero en la práctica muchos desarrolladores repiten este tipo de cosas con frecuencia
Siendo sinceros, en proyectos grandes esto pasa muy fácilmente cuando la documentación es deficiente. En el proyecto de investigación académica donde trabajo, la documentación del código básicamente dice que el propio código es autoexplicativo, y solo menciona brevemente cosas como la configuración de CMake, el build o cómo correr benchmarks. Las reglas internas o convenciones hay que descubrirlas viviéndolas. Cuando llega alguien nuevo, es común que vuelva a implementar cosas que ya existen o cambie configuraciones globales. Al final, lo mejor termina siendo indexar el codebase y preguntarle directamente a un LLM (porque la gente clave del proyecto ya se fue o responde muchísimo después)
Creo que se están perdiendo el punto del autor. Si la velocidad es la mayor virtud, estas cosas van a seguir repitiéndose. Si la velocidad fuera un valor absoluto, la producción tendría que crecer exponencialmente para compensar la deuda técnica. Si además de la velocidad importan otros factores, entonces hay que gestionar y pagar la deuda con inteligencia. Pero últimamente la sensación es más bien de acumular deuda enorme y confiar en que de alguna manera se resolverá. Y mucha gente realmente es mala gestionando deuda
Mucha gente reinventa la rueda cada vez que tiene oportunidad, ignora convenciones esperadas o usa patrones mezclados. El autor llamaría a eso "vibe coding", pero en realidad no es un problema exclusivo de los LLM; pasa con cualquiera cuando solo quiere sacar resultados rápido o le falta experiencia. La frase "código que nadie del equipo escribiría así" sugiere que quizá hay una molestia dirigida a alguien en particular. Conviene ser cuidadosos al aplicar esta visión a otros casos
También he visto desarrolladores meter otra librería ORM. La primera ORM ya era suficiente, pero agregan una segunda porque "está de moda". Tanto los desarrolladores como los LLM tienen sus propios sesgos. Es muy importante conocer las reglas o patrones del proyecto y trabajar dentro de ese marco. Construir las cosas a tu manera sin considerar el contexto es muy riesgoso. En el caso de las personas, esto puede resolverse fomentando la cultura de code review y la lectura de código, pero en el caso de los LLM hay que guiarlos explícitamente con todos los patrones y reglas. Si no, el riesgo de que generen código desalineado con el proyecto es alto. Lo importante es establecer de forma explícita los valores y criterios claros
Yo sí he trabajado en equipos así de buenos. Eran muchos proyectos pequeños (2-4 personas) pero de alta importancia. En un entorno así es más fácil construir una cultura y un consenso de desarrollo que equilibren calidad y velocidad. En esos equipos, nadie, ni humano ni LLM, conseguiría que le aprobaran un PR con código como ese
Personalmente veo al LLM como un desarrollador muy junior. Quiere hacer bien el trabajo y sigue instrucciones, pero entiende poco del codebase y de los patrones. Hay que guiarlo en todo el proceso, explicarle incluso los errores potenciales, asignarle tareas concretas y pequeñas, y revisar el código con mucho cuidado. Yo, por ejemplo, primero me formo el modelo de datos en la cabeza y después paso al código. Las explicaciones concretas son importantes. Una regla no escrita que sigo es hacer que siempre ponga un comentario de bloque al inicio del archivo explicando su contenido. Eso funciona como un segundo prompt cuando la sesión se reinicia. Así este método funciona bien sin sentirse "mágico", aunque a mitad del proceso todavía hay que dedicar como un 30% a ordenar código, renombrar y refactorizar para que quede presentable. Aun así, con LLM trabajo mucho más rápido que escribiéndolo todo completamente a mano
A veces expresiones como "desarrollador junior" o "copiloto" no reflejan bien ni las ventajas ni las desventajas de un LLM. A diferencia de una persona normal, olvida las cosas con facilidad y a veces comete errores muy básicos, pero también hay áreas en las que es mejor que yo (por ejemplo, temas de off-by-one en arreglos). Y además conoce de forma enciclopédica casi todo lo que hay en internet. Después de usarlo de verdad, me da la impresión de que un LLM se parece a un perro de caza: el dueño dirige la cacería y tiene que rematarla personalmente
La diferencia entre un LLM y un desarrollador junior está en la capacidad de aprendizaje. Un junior puede ir aprendiendo y creciendo, pero un LLM no. Mientras más instrucciones metes en el prompt, más probable es que olvide cosas y vuelva a respuestas genéricas. Cada vez que empieza un prompt nuevo, hay que volver a guiarlo desde cero
Siento que usar un LLM no es tan diferente de buscar código en internet y copiarlo y pegarlo. Al final el desarrollador igual tiene que revisar el código por sí mismo y verificar que funcione bien. Últimamente, por temas de salud visual, tengo que trabajar en bloques de 20 minutos y descansar, así que la eficiencia se volvió todavía más importante. Los LLM generan código muchísimo más rápido que un humano, así que incluso si solo se les deja cubrir lo básico, ya aportan mucho. Ahora mismo estoy generando structs para SIMD con Unity C# y LINQ, y simplemente decirle al LLM las condiciones que quiero me da el código o las cadenas que necesito mucho más rápido que copiando y pegando manualmente. Cada vez se siente más real la idea de usar la IA como un HUD. Más que una IA que construya programas enteros, necesito una herramienta de apoyo potente para desarrollo en unidades pequeñas
Para mí, un LLM es un sustituto mucho mejor que StackOverflow. Le pregunto algo y me responde de inmediato con precisión. Tomo la respuesta como referencia y luego la reescribo en mi propio código, o a veces solo genero una función. Antes de copiar cualquier cosa, procuro entender completamente el código. A veces incluso he pensado si, para la carrera profesional, no convendría más subir PRs de 400 mil líneas a proyectos open source en lenguajes que uno ni conoce, en vez de trabajar de manera honesta y orientada a la calidad. Eso se debe a que, en la práctica, los años de experiencia suelen valorarse más que la habilidad real
Para lograr que un LLM trabaje bien, me ha funcionado limitarlo no al pensamiento sino a la etapa real de codificación. Hay que dividir la tarea, pasarle especificaciones concretas, qué archivos modificar, dónde están los ejemplos de referencia, etc., con el mayor detalle posible para aumentar la tasa de éxito. No hace falta exagerar, pero mientras más pistas tenga, más probable es que funcione. El código que genera igual lo reviso bloque por bloque con
git add -p. Preparar y revisar toma tiempo, pero aun así ahorra claramente tiempo y energía frente a escribir todo solo o dejar código flojo tal cualEl mayor riesgo del vibe coding es que, mientras un desarrollador competente apenas se vuelve un poco más rápido, uno con poca capacidad puede producir muchísimo más código malo a mucha mayor velocidad. La cuestión es si esos desarrolladores pueden mejorar sus habilidades mediante el vibe coding o si simplemente se quedan estancados ahí
Por experiencia, incluso un desarrollador mediocre puede convertirse muy rápido en uno malo. La razón es la falsa confianza y el aumento brusco en la cantidad de código producido. El código generado por IA casi no considera la arquitectura general, el flujo de información ni el principio de responsabilidad única. Para producir código "seguro", se arma de forma que devuelve placeholders en vez de excepciones. Entonces el código que llama eso tiene que revisar cada vez si el resultado es un placeholder o no. Encima, si los parámetros de entrada son malos, la IA intenta corregirlos por su cuenta, ignorando la estructura
gather_parameters → call → process_results. Y cuando se llega a los tests, el problema se vuelve mucho peorAhora mucha gente va a redescubrir el concepto de net-negative programmer (un desarrollador cuya mera existencia reduce la calidad del proyecto)
Desde mi punto de vista, el recurso que más falta aquí es el cuidado. El vibe coding en sí no es la causa de esa falta de cuidado; la IA es solo una herramienta. Todos los problemas que menciona el autor aplican igual a desarrolladores humanos junior, y pueden mejorar con mejor guía o mejor comunicación. No creo que la IA esté haciendo que disminuya el interés por la calidad (la gente a la que no le importaba ya era así desde antes). Una respuesta habitual es decir que "se pierden oportunidades de formar juniors", pero muchas veces simplemente no hay margen y se usa la IA como solución temporal (también pasa en mi startup, donde contratar no está saliendo bien). Las herramientas de IA podrían cambiar los estándares de calidad del software, y me parece que ahí todavía queda mucho por cambiar en el futuro
Los LLM deberían usar como contexto no solo el estado actual, sino también el historial de commits. Muchos codebases están migrando gradualmente del patrón A al B y conviven múltiples patrones a la vez. Como esas migraciones no pueden hacerse de golpe, normalmente lo viejo y lo nuevo siguen mezclados durante mucho tiempo. Como en el ejemplo de HTTP, aunque el LLM detecte los patrones, elegir cuál seguir termina dependiendo de la suerte
He trabajado en codebases grandes que pasaron por más de 20 años de fusiones, cambios de nombre y adquisiciones. Siguen quedando ejemplos de llamadas a APIs antiquísimas, y aunque existe código más nuevo en otra parte, mucho de lo viejo se dejó ahí para ciertos clientes. También hay muchas APIs parecidas sin ninguna documentación, así que hay que investigar una por una cuál usar para obtener los datos que uno necesita
Una forma de ayudar es usar archivos como
CLAUDE.mdpara indicar claramente "sigue este patrón, evita aquel"Más que eso, resulta más efectivo explicar con mucho detalle cómo trabajar en cada parte y dar ejemplos concretos
El problema es que esa misma capacidad de entender el contexto suele faltar bastante en quienes hacen vibe coding. Mucha gente ya tenía poca experiencia programando incluso antes de los LLM
Eso solo es posible cuando los mensajes de commit están bien escritos. En la práctica, la mayoría son cosas como "modificar este archivo" o "arreglar bug"
Al usar LLM, herramientas automáticas como linters, formatters y type checking estricto ayudan muchísimo. Especialmente cuando las contribuciones vienen de alguien (o de un agente LLM) que no conoce el estilo de código ni las reglas implícitas, estas herramientas permiten revisar el código automáticamente y corregir de inmediato lo que sí se puede arreglar. Lo mismo aplica a los tests. Los sistemas de validación automatizada son muy útiles para mantener la calidad, ya sea que el autor sea humano o agente
Creo que, en la práctica, esas herramientas no bloquean la mayoría de los casos de vibe coding mencionados en el artículo
A veces esas herramientas solo tapan el problema y dejan la superficie limpia
Todos los principales AI assistants ya traen por defecto formas de mitigar estos problemas, como
/initde Claude Code o/Generate Cursor Rulesde Cursor, y pueden aplicarse a toda una organización de manera más automatizada que con simple context engineering. Al final, también es interesante cómo estas herramientas terminan dividiendo a la comunidad de desarrolloEn la práctica, por más claro que lo dejes en
CLAUDE.md, muchas veces CC (Claude Code) lo ignora. A medida que la conversación sigue, se siente que repite los mismos problemas, y hasta ahora no he encontrado una solución completamente satisfactoria. Por eso no creo que sea correcto descartar este artículo como si fuera simplemente anti-IAEstoy reevaluando Cursor. No está yendo tan rápido como esperaba, no solo por errores pequeños (como que el LM cambie
:por,), sino porque el codebase es demasiado grande, viejo y con una calidad muy dispar. Al final, el LLM toma con más frecuencia los patrones más comunes (= los malos). Incluso si le indicas claramente "usa esto como referencia", sigue viéndose influido por todo el codebase. Aunque lo pongas como rule, no parece muy distinto de meterlo directamente en el prompt. Me pregunto si existe alguna soluciónEl núcleo del problema no es la herramienta sino el "coder" obsesionado con el vibe. No le importa de verdad y además escribe código de forma descuidada
En mi experiencia, casi todos estos problemas son resultado de una ventana de contexto limitada y de un "context engineering" subóptimo. Si al LLM se le entrega bien el contexto importante, como funciones globales, suele aprovecharlo relativamente bien. El problema es cómo mantener y suministrar ese contexto sin cortes. Espero que ahí haya mucho avance con cosas como sub-agents
Creo que todo esto es cierto. La mejor manera de usar un LLM es como cuando un compilador ofrece un nivel superior al ensamblador: si describes claramente los requisitos y las entradas y salidas, produce código como una traducción lógica. Por eso hay que minimizar al máximo la confusión (entropía) en la entrada. Un LLM es, en esencia, un motor de traducción. Es más eficiente usarlo para "traducir" que para "generar". Aun así, siguen apareciendo modelos que evolucionan y se vuelven más inteligentes e intuitivos, y por eso cada vez hace falta preocuparse menos para obtener mejores resultados. Al final, llegará una época en la que un LLM dará mejores resultados que un desarrollador humano en cualquier tarea, y lo mismo pasará con otros roles humanos
Es una analogía equivocada. Un LLM no es un motor que "compila" lenguaje natural a código de alto nivel. Los lenguajes de programación y el lenguaje de máquina exigen un sistema de significados claro y consistente, pero el lenguaje natural tiene desde el inicio un nivel de abstracción distinto. Incluso el mismo LLM puede dar resultados diferentes con otra seed o versión. En cambio, un compilador siempre debe producir la misma salida para la misma entrada
No puedo aceptar la idea de que un LLM sea una capa de abstracción como un compilador. En realidad, un LLM no es más que un generador arbitrario de tokens. Nunca he visto un resultado hecho con LLM que sirva de verdad. El tecnooptimismo sobre la singularidad o sobre conseguir datos infinitos no tiene una base realista. Obtener datos de alta calidad cuesta enormemente. Por ahora, hacer predicciones esperanzadoras no tiene mucho sentido
Entendí más tarde que el autor eso de que "mucha gente prefiere café rápido y barato antes que buen café". En el mundo real, la mayoría valora más la velocidad y el precio que la calidad
La publicación en HN está más sabrosa que el artículo en sí.