Mostrando entradas con la etiqueta Software. Mostrar todas las entradas
Mostrando entradas con la etiqueta Software. Mostrar todas las entradas

jueves, 21 de mayo de 2026

El desarrollo asistido por inteligencia artificial y la motivación del desarrollador

Parece que ningún campo de la actividad profesional es inmune a las transformaciones radicales que la inteligencia artificial trae consigo.

Una de esas actividades es el desarrollo software. Aunque ya desde hace un tiempo una de las modalidades típicas de los modelos generativos era el código, últimamente parece que hemos dado un salto enorme en calidad con aportaciones de agentes de IA integrados en cada vez más entornos de desarrollo, herramientas como Codex o Claude Code y soluciones de Vibe coding como Lovable, Windsurf o Cursor.

Cuando recuerdo mi etapa como desarrollador software, primero desarrollador aficionado y posteriormente como desarrollador profesional en los primeros pasos de mi carrera, no puedo dejar de reflexionar, no sólo acerca de cómo cambia la operativa de desarrollo sino también, lo que motiva a o puede motivar a un desarrollador actual.

Y de eso, de la motivación, es de lo que quería hablar en este post. 


La labor del desarrollador tradicional


La labor del desarrollador tradicional, la que yo pude hacer en los años ochenta, noventa o primeros años de este sigo XXI consistía, básicamente, en tomar un problema a resolver o una funcionalidad a conseguir, y trabajar para traducir la solución solicitada o imaginada a un conjunto de instrucciones expresadas en un lenguaje de programación de los denominados 'de alto nivel' como en su momento se hacía con C, C++, C#, Java, Visual Basic o similares. Hoy pensaríamos más, por ejemplo, en python.

A continuación se compilaba (entonces se trabajaba poco con lenguajes interpretados) y se depuraban los errores sintácticos cometidos. Cuando ya se superaba la fase digamos sintáctica, venía el probar el software desarrollado, primero individualmente, lo que uno había hecho y luego, cuando se trabajaba en equipo como era lo normal en entornos profesionales, conjuntamente con lo que habían hecho otros desarrolladores.

Pero destaco, por lo que a motivación se refiere, la fase en que tenías que imaginar cómo traducir a instrucciones de un lenguaje aquello que te habían solicitado o, mejor aún, aquello que habías imaginado que querías hacer.

Solo un apunte metodológico: aunque hablo de imaginar cómo traducir una necesidad u objetivo en instrucciones como parte de la tarea del desarrollador, conocí, por suerte un poco de lejos, entornos en que ese traducir un problema a instrucciones lo hacía un analista funcional, no el desarrollador, y el desarrollador era un mero codificador que no diseñaba, sino que creaba el código fuente a partir de lo que se le indicaba. Esto era común en los desarrollos de sistemas empresariales en lenguaje COBOL y ejecutados sobre mainframe IBM.

Pero los entornos en que yo trabajé, tanto profesionalmente como en forma de afición, eran abiertos y el desarrollador era también el analista y diseñador de lo que hacía.


Mis elementos de motivación


Con frecuencia comento que una de las etapas de mi carrera profesional en que más me divertí, que más disfrute, fue esa etapa de desarrollador.

Primero disfruté una barbaridad cuando trabajaba por puro 'hobby', haciendo código simplemente por divertirme y para conseguir las cosas que yo me imaginaba y usando el inolvidable Turbo PASCAL.

Luego de forma profesional, aunque con mucha libertad de diseño, primero en la empresa asturiana GADD y luego en Telefónica Investigación y Desarrollo.

He dicho que me divertía y que disfrutaba, y mucho.

¿Cuáles eran los elementos de ese disfrute? ¿Cuál era la motivación?

Aunque es difícil racionalizar mucho qué es lo que te motiva, qué es lo que te hace disfrutar, voy a concentrar en cuatro elementos lo que creo que eran mis motores, mis motivaciones, que supongo que compartirían muchos desarrolladores de entonces, puede que también actuales.


El reto


Hablaría, en primer lugar del reto. Encontrar la forma de traducir una idea que tenías en tu cabeza (cuando actuaba como desarrollador aficionado)  o que te habían solicitado, en un marco limitado de instrucciones que te ofrecía el lenguaje. Por supuesto, había traducciones obvias, pero lo interesante era cuando bordeabas lo evidente o te metías en campos nuevos. Hoy en día no impresiona, pero en aquella época, hacer elementos gráficos, o introducir música no era absolutamente nada evidente. En otros casos, conseguir eficiencia algorítmica, que el software se ejecutase a buena velocidad y buenos tiempos de respuesta no era tampoco fácil. 


El descubrimiento


El segundo elemento, muy relacionado con el anterior, tenía que ver con la investigación y el descubrimiento. Leías manuales, libros y revistas, preguntabas a compañeros, y experimentabas y experimentabas (entonces Internet no estaba generalizado) hasta conseguir lo que te proponías. Tras el reto, venía el descubrimiento de la solución. Aún recuerdo con orgullo cómo descubrí la forma de mezclar código ensamblador con PASCAL, y cómo apoyándome en eso y estudiando la arquitectura HW del ordenador personal, conseguí escribir directamente en la memoria de pantalla (la mayoría de los desarrolladores actuales no creo que sepan siquiera qué era eso, ni siquiera estoy seguro, calculo que no, que el mismo concepto de memoria de pantalla exista hoy en día) y con ello conseguir unas velocidades de escritura entonces casi inimaginables y que me permitieron trabajar con gráficos y animaciones en una época en que ninguna librería ni herramienta te lo daba. Aún recuerdo con orgullo cómo logré generar movimiento de elementos gráficos o cómo logré introducir música apoyada en partituras (si, partituras) que compraba en tiendas de música.


La maestría


Consecuencia de ese descubrimiento buscabas y alcanzabas, o al menos eso sentías, la maestría, el dominio del lenguaje de programación y del ordenador. Sentirte hábil, maestro, es extraordinario, al menos para mí que siempre he apreciado tanto el conocimiento.


El logro


Finalmente, hablaría de la sensación de logro. Un logro que se producía en un doble sentido. Un sentido personal, que tiene que ver con esa maestría que mencionaba en el punto anterior. Pero también una sensación de logro por lo que conseguías, por el programa que funcionaba. Sólo hacer el 'Hola mundo' en un nuevo lenguaje o entorno era altamente satisfactorio pero, mucho más allá de eso, conseguir realizar eso que te habías imaginado y que inicialmente no sabías cómo llevar acabo, como personalmente me sucedió en los casos que he relatado de los gráficos o la música, pero que en realidad fueron muchos más, era una sensación de emoción y plenitud extraordinarias.


Descremado


Con el tiempo, el desarrollo de software, los lenguajes y, sobre todo, las herramientas y entornos de desarrollo han evolucionado y crecido, en busca de hacer esa tarea mucho más fácil y mucho más productiva.

Esa mayor facilidad y productividad, que tiene todo el sentido del mundo desde un punto de vista de negocio, creo que, sin embargo, de cara al desarrollador, al profesional y sobre todo la persona 'desarrollador', ha supuesto una forma de 'descremado', de eliminación de parte de las esencias y diría que encantos, de lo que inicialmente fue el desarrollo de software y también de las exigencias y cualificación requeridas. 


Un gran paso de 'descremado': 'low-code' y 'no-code' 


Esa evolución hacia la simplificación y la productividad ha sido continua y ha adoptado muchas formas, empezando por el uso de lenguajes de alto nivel frente a ensambladores, la creciente existencia de librerías de componentes reutilizables incluyendo componentes gráficos, etc

Pero quizá un gran salto en el 'descremado' lo hayan supuesto los entornos 'low-code' y 'no-code' que, como su propio nombre indica, apuestan por disminuir e incluso eliminar el código fuente, convirtiendo el desarrollo de software en el uso de herramientas normalmente semi-gráficas, con plantillas y componentes reutilizables y donde se desdibuja la idea de código.

Y tanto se desdibuja que incluso Microsoft acuñó hace unos años el término 'Citizen developer' para designar a un desarrollador no profesional o no especializado, es decir, personas que sin formación en informática ni programación, personas pertenecientes quizá a departamentos de ventas o recursos humanos, capaces de construir sus propias aplicaciones. 

Aunque en teoría los elementos de motivación que describí en la sección anterior podrían mantenerse, tengo la sensación de que lo hacen en una medida mucho menor. El reto es menor, puesto que el entorno es mucho más sencillo, aunque siempre hay trucos y aspectos avanzados y el descubrimiento es limitado y, por tanto, la sensación de maestría, aunque calculo que existe, también es menor.

Sólo albergo alguna duda en cuanto a la sensación de logro. Calculo que inicialmente, o cuando utiliza una de estas herramientas un auténticos 'citizen developer' sí puede existir esa sensación de logro, acentuado por el hecho de que, al ser herramientas muy productivos se pueden conseguir aplicaciones muy interesantes. Pero también imagino que esa sensación de logro debe de disminuir a medida que el desarrollador se acostumbra y todas las aplicaciones comienzan a parecerse entre sí.


El desarrollador en tiempos de inteligencia artificial


Y ahora llega la inteligencia artificial a irrumpir, y de qué manera, en el campo del desarrollo software.

Por un lado, tomando la forma de asistentes integrados en los entornos de desarrollo, tradicionales y 'low-code'. Asistentes que te sugieren qué hacer, crean secciones de código (o de flujos en ciertas herramientas low-code), depuran ese código o te hacen sugerencias de depuración.

Por otro lado, como una especie de entorno completo o casi completo de desarrollo donde el no sé si seguirle llamando desarrollador, pide en lenguaje natural lo que quiere, incluyendo entornos que prometen la capacidad de crear aplicaciones completas a partir de 'prompts'.


La motivación del desarrollador en tiempos de IA


Actualmente hay preguntas y debates acerca del propio futuro del desarrollador como puesto de trabajo o categoría profesional, sus perspectivas de empleo y si, incluso, desaparecerán.

Pero ahora me enfoco desde el punto de vista de la motivación. 

Parece que cuando te apoyas en IA de forma masiva para desarrollar, queda en cierto entredicho cuánto aportas tú realmente, cuánto hay de reto,  cuánto de descubrimiento o cuánto de maestría.

Tiendo a pensar que, de forma similar a lo que comentaba en el caso del 'low-code', algunos restos pueden quedar de los antiguos elementos de motivación. Al fin y al cabo, todavía hay que saber definir la solución y hay que saber proporcionar los prompts adecuados. Quedan vestigios de lo que, al menos en mi caso personal, eran los elementos de motivación, pero me parece que no son comparables en cuanto a intensidad.

Y planteo de nuevo lo relativo al logro. Por una parte, me parece que en cuanto a la aportación a la persona, se consigue mucho menos, que la persona se desarrolla menos y consigue menos para sí misma, pero es cierto que el desarrollo apoyado en IA, o incluso completamente hecho por IA, puede permitir conseguir cosas impresionante en poco tiempo. Puede ser enormemente satisfactoria en cuanto a logro entendido como resultados conseguidos. Y eso sí que puede ser un fuerte elemento de motivación.

Quizá, es que más que de desarrollador, convenga hablar de creadores de soluciones. Quizá es que los elementos de motivación que describía más arriba se centraban más en el propio proceso de creación del software y ahora haya que centrarse más en el producto final, en los resultados, en lo que se consigue.

No sé, se mueve todo tan rápido que es difícil llegar a conclusiones sólidas y, además, la motivación es algo tan personal que no creo que se deba pontificar demasiado al respecto.

Me encantaría saber lo que piensan desarrolladores jóvenes actuales, cuáles son sus factores de motivación y si este desarrollo apoyado, o incluso hecho completamente con IA, les proporciona motivación o no, y en caso afirmativo, con base en qué factores.


Conclusiones


El desarrollo software ha evolucionado muchísimo a lo largo de los años, siendo especialmente relevante la explosión de la inteligencia artificial como ayudante, e incluso casi sustituto, del desarrollador tradicional.

Si, al menos para mí, el desarrollo software ofrecía como elementos de motivación el reto, el descubrimiento, la maestría y el logro ¿Cuáles son los elementos de motivación para un desarrollador actual muy apoyado en IA? ¿Son los mismos? ¿Son otros? ¿Existen?


jueves, 14 de mayo de 2026

Operativizar la accesibilidad digital: de la ética a los resultados y la eficiencia

Por motivos que no viene al caso, desde hace un par de años o así, tengo la oportunidad de participar en acciones de formación en materia de accesibilidad digital.

Se trata de una formación bastante básica, que no me exige la profundización pero, a pesar de ello, esa actividad me ha llevado ya a leer varios libros y documentos en materia de accesibilidad.

Y justo por la superposición de una reciente lectura con una clase sobre accesibilidad, me surgió la reflexión que quisiera compartir en este post.


Accesibilidad digital


Antes de entrar en la reflexión, y para aquel posible lector o lectora poco conocedora del campo de la accesibilidad, un par de explicaciones poco académicas.

Siguiendo a la que probablemente sea la mayor autoridad española en esta materia, Olga Carreras, en su libro 'Accesibilidad Web. WCAG 2.2. de forma sencilla'  podríamos definir la accesibilidad (en este caso, 'sólo' accesibilidad web) como:


el conjunto de características que  debe incorporar un sitio web, una aplicación móvil o un documento digital para que el mayor número posible de personas en el mayor número posible de circunstancias  pueda acceder a él, usarlo y comprenderlo. 


Para que lo entendamos: se trata, fundamental, aunque no únicamente, de luchar contra la discapacidad, de hacer que cualquier persona, aunque tenga condiciones que afecten a su capacidad visual, auditiva, motora o cognitiva, pueda navegar, entender y trabajar con un sitio web o una aplicación móvil (y eventualmente con documentos como los PDF que se puedan encontrar en esa web).

Para conseguirlo hay que hacer un diseño web que tenga en cuenta aspectos como los colores (por ejemplo que sean perceptibles y distinguibles por personas con daltonismo), el tamaño de letra, el contraste de colores en texto e imágenes, el tamaño de botones y así un largo etcétera.

Aparte de estos elementos de diseño, y para conseguir que personas con condiciones diferentes puedan ajustar el sitio web a su situación particular, se necesita poder configurar o seleccionar esos tamaños, juegos de colores, tiempos de respuesta, etc

Además, y como apoyo a las denominadas tecnologías de asistencia, muy especialmente lectores de pantalla (JAWS, NVDA, VoiceOver, etc), teclados adaptados, líneas braille, etc, es necesario incluir utilizar de forma muy rigurosa (respectando su semántica) las etiquetas HTML y añadir atributos con información que pueda ser utilizada por estas tecnologías, como el famoso texto alternativo (atributo 'alt') en imágenes.  

Aún hay más, es necesario dar alternativas, digamos multimodales, a los contenidos: añadir subtítulos y, si es posible, lengua de signos a los vídeos para que puedan ser percibidos por personas con condiciones que afecten a su audición, añadir variantes tanto visuales como sonoras a cualquier aviso o alarma y así sucesivamente.


Un imperativo ético, a veces legal y con algún interés de negocio


Dotar a los sitios web de accesibilidad es, ante todo, un imperativo ético, porque contribuye a crear igualdad de oportunidades para todas las personas independientemente de su condición. Y en algún caso, como las administraciones públicas, puede ser también un imperativo legal. 

Pero, además, para aquellas empresas (o 'influencers') que compiten por la atención o para aquellas empresas que usen masivamente el marketing de atracción y el comercio electrónico puede tener beneficios de negocio al llegar a un público más amplio y facilitar la conversión (obtener pedidos, vaya).


Algunas dificultades objetivas de la accesibilidad digital


Sin embargo, hay que reconocer que, si lo miramos desde un punto de vista técnico y operativo, conseguir la plena accesibilidad de un sitio web no es una tarea ni sencilla ni ligera.

Dejando aparte la necesidad de disponer de diseñadores y desarrolladores de front-end formados en accesibilidad web, hay muchas otras dificultades o trabajos añadidos.

Hay que hacer trabajo adicional (por ejemplo añadir las etiquetas describiendo imágenes o añadir los subtítulos), hay que preparar al sitio web para que sea configurable, hay que añadir opciones multimodales que en otro caso podrían no ser necesarias, hay que añadir subtítulos y lengua de signos y así un largo etcétera. Lo que quiero decir es, eso, que hay trabajo adicional.

Además, hay que tener en cuenta muchísimos factores, porque las discapacidades y condiciones de las personas son muy variadas y llevan a necesidades diferentes que incluso pueden ser contradictorias.

Es muy aconsejable que las pruebas del sitio web se realicen, al menos en algunas fases, con personas con todo el abanico de condiciones sensoriales y cognitivas porque para una persona que no presente estas condiciones es muy difícil juzgar la experiencia que recibe una persona que sí las detente. Pero eso lleva a un equipo de pruebas no tan fácil de conseguir, no pequeño y a pruebas muy manuales, muy artesanales.

Y, por supuesto, hay que disponer de tecnologías de asistencia para probar con todas ellas.

En resumen, si somos realistas, hacer un sitio web accesible supone un equipo con cualificación especial, realizar trabajo adicional y que una parte de ese trabajo sea muy artesanal.


El 'quid' de la cuestión


El 'quid' de la cuestión, la clave de mi argumento y opinión es que, si aspiramos a que se generalice la accesibilidad digital, si queremos que todos los sitios web sean plenamente accesibles, tenemos que dar un gran salto de eficiencia, tenemos que aplicar tecnología y conceptos rigurosos de ingeniería software y de operación.


Un benchmarking con el 'mainstream' de ingeniería de software


Pero tenemos espejos donde mirarnos y muchas tecnologías y metodologías que nos pueden echar una mano. 

Algunas son casi, la aplicación directa de técnicas usadas en otros ámbitos, fundamentalmente del software, y otras sería algo más específicas, aunque siempre inspiradas en lo que ya se hace o ya se dispone a nivel metodológico o técnico.

Un poco a bote pronto, propongo, y luego explicaré brevemente, siete vías, siete soluciones o buenas prácticas que creo que se podrían y deberían aplicar. Son las siguientes:


  • Reutilización y componentes accesibles
  • Low-code accesible
  • Un 'responsive' para la accesibilidad
  • Accesibilidad por diseño
  • DevOps y automatización
  • Aprovechar la multimodalidad de la IA
  • LLMs entrenados en accesibilidad 


Algunas de estas propuestas entiendo que ya existen y se aplican, aunque probablemente no de forma generalizada) pero alguna podría resultar novedosa. Paso a describir cada una muy brevemente.


Componentes accesibles


La reutilización de componentes forma parte del ABC de la ingeniería software, algo que se viene promoviendo y llevando a cabo desde hace décadas en el desarrollo de software.

Es una técnica básica de productividad, mantenibilidad y robustez de una arquitectura software. Y presenta otro beneficio y es que, en el caso de algoritmos o tecnologías complejas, un desarrollador muy especializado puede crear ese componente reutilizable, que luego puede ser empleado por desarrolladores con menos conocimientos. específicos.

Aparte de la mera productividad, la reutilización haría que si los componentes básicos son accesibles, los desarrolladores menos expertos podrían construir soluciones  accesibles sólo mediante la reutilización de componentes accesibles.


Low-code / No-code accesible


Ya desde hace años existen soluciones denominadas 'Low-code' / 'No-code' que permiten construir software sin apenas conocer, o sin conocer en absoluto, un lenguaje de programación. El 'truco' es, básicamente, que la lógica se define de manera gráfica  y que, además, se apoya en componentes y elementos ya predefinidos y de alto nivel (alto nivel en el sentido de ser fáciles de usar pero que implementan lógica compleja).

Por un lado, es una mecánica de desarrollo muy productiva y, por otro, un uso intensivo, consciente o no, de la reutilización que hemos visto en el punto anterior.

La idea sería que las herramientas Low-Code / No-code, muy especialmente las orientadas a front-end, como  WebFlow o Bubble, o aquellas que crean interfaces de usuario como Glide o PowerApps, por ejemplo, ya generasen 'de serie', una interfaz accesible o, 'lo más accesible posible'. 

La verdad es que no he comprobado ni investigado si ya lo hacen o cuáles sí y cuáles no, pero no soy demasiado optimista. Ojalá me equivoque.


Un 'responsive' para la accesibilidad


Desde hace años, básicamente desde que se generalizó el uso de smartphones y tablets, existe el concepto del diseño 'responsive' (responsivo, en castellano)

Básicamente se tarta de adaptar el tamaño y distribución de los elementos de la interfaz de usuario al tamaño y orientación de la pantalla. Para eso, el código detecta el tipo de dispositivo en que se encuentra y reacciona presentando la interfaz de usuario adecuada.

Se me ocurre que, dado que la accesibilidad lleva a sitios web que se deben poder configurar para que el usuario elija las opciones que mejor le resultan, se podría pensar una forma de 'responsive' en que la interfaz de usuario se adapta a unos perfiles.

Podrían existir perfiles predefinidos para, por ejemplo, personas con daltonismo y la capacidad de definir perfiles personalizados. 

La interfaz de usuario, además de averiguar el dispositivo, debería averiguar el perfil para para adaptarse.  

¿Existe ya algo así? Es posible, pero no lo he oído mencionar.


El ciclo de vida y la accesibilidad por diseño 


Existe un cierto patrón que podríamos denominar 'metodológico' que promueve que, aspectos concretos de una solución software se tengan en cuenta, no al final, en la fase de pruebas, sino en todo el ciclo de vida del desarrollo software, desde el diseño a las pruebas y puesta en producción pasando por el desarrollo.

Así, por ejemplo, en el ámbito de la ética de la inteligencia artificial, se habla de la ética por diseño o, de forma más específica, de la privacidad por diseño.

En el ámbito de la ciberseguridad, nos encontramos con la filosofía 'shift-left' que va un poco en la misma línea, tener en cuenta los aspectos de seguridad en la parte 'izquierda' es decir, el principio) del ciclo de vida.

Pues bien, de una forma más metodológica que técnica, debería hacerse, no sé hasta qué punto se hace, en materia de accesibilidad y podríamos hablar, parafraseando el caso de la ética, de una 'accesibilidad por diseño'.


Automatización de pruebas de accesibilidad


Una gran dificultad son, como hemos dicho, las pruebas de accesibilidad, tanto porque hay que probar casuísticas muy diferentes como porque resulta aconsejable el concurso de personas con diferentes condiciones y discapacidades.

Algo en que se ha avanzado mucho en software es, precisamente, en la automatización de pruebas, un trabajo otrora tremendamente artesanal e intensivo en mano de obra. 

Deberíamos de conseguir la automatización 'extrema' de las pruebas de accesibilidad disminuyendo al mínimo la manualidad.

Lo cierto es que existen ya herramientas de evaluación de accesibilidad (por decir una, WAVE, de WebAIM) pero, hasta donde percibo, son relativamente simples y creo que no evitan la necesidad de que sean complementadas por bastantes pruebas manuales.

Creo que harían falta tres cosas.

Por un lado, y suponiendo que yo esté en lo cierto, habría profundizar en las capacidades de las herramientas de prueba (que probasen más cosas). 

Por otro lado creo (y a lo mejor esto ya está hecho, pero no me lo parece) habría que darles un, digamos, 'formato', que permitiese integrarlas más fácilmente en el ciclo del software. Por ejemplo, podría disponerse de ellas como librerías python, o como contenedores en entornos cloud o como conectores y/o APIs para entornos Low-Code. No sé, habría que ver la mejor solución (o conjunto de soluciones) pero creo que se entiende la idea.

El tercer punto, puede que sea el más difícil... o no: sería evitar al máximo posible la necesidad (o conveniencia) de emplear como 'testers' a personas con discapacidad. Aunque esto es una apuesta, creo que hay buena base para pensar que se podrían hacer usando inteligencia artificial generativa, sólo entrenando modelos de manera adecuada. Me apoyo para decirlo que ya existen modelos generativos que sirven para 'simular' expertos que prueben otros modelos.

Pues bien, se trataría de preparar a modelos, mediante el entrenamiento o 'fine-tunning' adecuado que actuasen como personas con diferentes condiciones sensoriales o cognitivas (probablemente aplicando luego una especie de 'Mixture of experts'). Es posible que crear estos modelos sea costoso, pero una vez hecho por 'alguien' (Google, ¿Qué te parece?) , podría usarse como una herramienta más.

Ya puestos, hasta podríamos pensar en agentes que comprobasen la accesibilidad, incluso de sitios ya en producción.


DevOps


Y, diría que por supuesto, habría que aplicar la filosofía DevOps, o mejor aún, integrar la accesibilidad como un aspecto más en los pipelines DevOps.

De la misma forma que, en el ámbito de la ciberseguridad se habla de DevSecOps, para una forma de DevOps que tiene en cuenta todos los aspectos de ciberseguridad, debemos hacer una DevAccOps que tenga en cuenta los elementos de la accesibilidad.

Y si hemos hecho los deberes anteriores, convirtiendo los elementos de accesibilidad en componentes estándar, y si hemos logrado automatizar las pruebas de accesibilidad, parece que el resto viene casi por añadidura.

Pero es fundamental: DevOps es, probablemente uno de los mayores saltos en productividad y eficiencia en ingeniería software. No deberíamos dejar la accesibilidad fuera de este marco.


Vibe coding para la accesibilidad


Y ahora que estamos en el 'boom', no solo de los agentes, sino también del código generado con inteligencia artificial, ahora que nos asombran Codex o Claude Code, que se usan cada vez más Lovable, Cursor o Windsurf, qué tal si entrenamos a los modelos que hay por detrás para que el código que generen en materia de interfaz de usuario sea accesible?

Aquí debo apuntar que, quizá, ya lo generen, la verdad es que no lo he podido investigar. Si ya generan interfaces de usuario accesibles, entonces sería fantástico que se usasen cada vez más y, si no es así, sería bueno que sus creadores tomasen nota y tuviesen en cuenta la accesibilidad a la hora de entrenarlos y probarlos


Unas palabras de prudencia y una invitación a la retroalimentación


Unas palabras de prudencia antes de ir concluyendo. 

No he podido materialmente investigar hasta qué punto las soluciones y prácticas actuales utilizan las tecnologías, técnicas y metodologías que he propuesto.

Mi sensación es que, caso de que ya se haga, no es de manera generalizada... pero puedo estar equivocado.

En ese sentido, me encantaría recibir 'feedback' y comentarios.


La ética, la voluntad y la inteligencia


La accesibilidad digital, aunque, como he dicho, puede en algunos casos reportar beneficios económicos, es ante todo una aspiración y un deber de base ética.

Pero hablar de ética no debe llevarnos a pensar sólo en buenos deseos o aspiraciones, hablar de ética no debe suponer sólo acciones heroicas o buena voluntad.

Hace unas semanas en mi podcast 'Divergencias' publicaba un episodio que titulaba 'Caridad e inteligencia' que, en esencia, venía a defender el uso de la inteligencia en el ámbito de la caridad, en forma de criterios prácticos orientados a los resultados, la eficiencia y la escalabilidad.

La idea es la misma para el caso de la accesibilidad.

Soy ingeniero y enormemente orgulloso de serlo. Ingeniería es tecnología sí, pero es también resultados, eficacia y eficiencia.

Y creo que en el caso de la accesibilidad, aunque nuestra inspiración sea ética, debemos de actuar como ingenieros y aplicar las tecnologías, metodologías y buenas prácticas que nos lleven a resultados masivos, escalables y eficientes.

Creo que la única manera de conseguir que la accesibilidad sea una realidad, una realidad generalizada, es que sepamos dar el salto de la ética a la ingeniería, que optimicemos y automaticemos, que logremos ser eficaces y, sobre todo, eficientes.


Conclusiones


La accesibilidad digital es una aspiración de base ética en algunos casos reforzada por elementos legales. Pero, por desgracia, estamos lejos, probablemente muy lejos, de conseguir que esté generalizada.

Y me parece, estoy convencido en realidad, de que si queremos que se generalice es preciso ser realistas y prácticos, es preciso simplificar y automatizar, es preciso ser baratos, es preciso aplicar las mejores tecnologías y las mejores prácticas para conseguir ser eficaces y eficientes y conseguir así que el construir sitio web o una solución digital accesible sea rápido y barato.

lunes, 23 de febrero de 2026

Una aparente paradoja: el retorno de la programación de bajo nivel

En los dos últimos post he hablado de dos fenómenos, en apariencia independientes y casi contradictorios y que, precisamente, van a colisionar en este artículo. 

Hablo, por un lado, de la evolución del desarrollo software que explicaba en 'La evolución del desarrollo software: productividad frente a deskilling' y que nos muestra una clara evolución a una programación cada vez más alejada de los detalles técnicos y más centrada en la productividad y cercanía a las necesidades funcionales. Una programación, en fin, de alto nivel.

Por otro, en el último post, 'El retorno del hardware: razones y perspectivas', destacaba cómo el hardware, al que hacía años que apenas dábamos importancia, ha vuelto a cobrar valor técnico, económico y estratégico, debido en buena medida a las demandas técnicas y de volumen que impone la inteligencia artificial generativa.

En este post examino un fenómeno en cierto modo sorprendente y contradictorio: el retorno, no ya del hardware, sino de la programación de bajo nivel.


Programación de bajo nivel


Como paso previo, y por si algún lector no esta suficientemente advertido, aclarar a qué nos referimos con lo de la programación de bajo nivel.

La programación de bajo nivel es la creación de un software que trabaja en temas de detalle y, sobre todo, muy cerca del procesador, ya sea un microprocesador de tipo CPU ('Central Processing Unit') tradicional, o los modernos GPU ('Graphical Processing Unit') o TPU ('Tensor Processing Unit'). La programación de bajo nivel suele implicar conocer bien el hardware, tanto los procesadores como la estructura de registros y de la memoria o cómo relacionarse directamente con dispositivos y periféricos.

Con la programación de bajo nivel normalmente no podemos resolver grandes problemas funcionales, pero, a cambio, podemos conseguir nuevas capacidades y, sobre todo, si se hace bien, unas altísimas prestaciones y una gran optimización computacional. Y eso es así porque al trabajar muy cerca del hardware y conociendo cómo funciona, explotamos al máximo sus capacidades y, además, hacemos ´únicamente lo que se necesita'.

El software de alto nivel, por su lado, en su búsqueda de generalidad y facilidad de uso, añade ingentes cantidades de lógica adicional no estrictamente necesaria en muchos casos y, además, al alejarse del hardware no optimiza su uso. Prima la productividad y facilidad de uso frente a la optimización computacional.


¿Por que realizar programación de alto nivel?


En realidad lo acabamos de mencionar y lo vimos también en un post anterior: favorecemos la programación de alto nivel porque es muchísimo más productiva en términos de cantidad de software producido, porque además es más sencilla de llevar a cabo (lo que redunda en productividad y, además, elimina barreras de entrada de profesionales) y, finalmente, porque permite concentrarse más en los problemas de negocio o en lo que realmente queremos proporcionar.

Por eso, una vez que el hardware alcanzó una potencia tal que ya no nos exigía su optimización para tener buenos resultados de prestaciones, se ha ido favoreciendo la programación de alto nivel


¿Y por qué realizar programación de bajo nivel?


Y, entonces ¿Por qué podríamos interesados, a estas alturas, en hacer programación de bajo nivel?

Bueno, en algunos casos no hay más remedio. Por ejemplo, para relacionarse con un nuevo dispositivo o periférico, hay que comenzar trabajando en el bajo nivel, aunque luego, de cara a otros programadores se preparen ya APIs o conectores simplificados.

Un poco en esa misma línea, si estás programando un sistema operativo no tienes más remedio que enfrentarte al bajo nivel porque una de las funciones principales de un sistema operativo es precisamente relacionarse con el hardware y ofrecer, hacia el exterior, un modo abstracto, una máquina virtual que independice a aplicaciones y programadores de ese hardware. Los programadores de esas aplicaciones pueden trabajar en el alto nivel, pero los del sistema operativo están obligados a relacionarse con el bajo nivel.

Pero hay algo que me importa mucho más ahora mismo, en relación con lo que quiero exponer en este artículo: utilizas la programación de bajo nivel porque cuando quieres optimizar el funcionamiento, cuando quieres maximizar las prestaciones, cuando quieres 'exprimir al máximo' la capacidad del hardware, tienes que acercarte al hardware, tienes que conocerlo, tienes que, en fin, realizar programación de bajo nivel.


Nuevas arquitecturas de procesadores


Durante bastantes años, los procesadores, aunque evidentemente evolucionaban, y no poco, eran de tipo CPU.

Con el auge de aplicaciones de gran riqueza gráfica como los videojuegos, nacieron y cobraron importancia las GPU ('Graphical Processing Unit'). Pero la auténtica explosión ha venido de la mano del machine learning al 'descubrir' que las operaciones algebraicas que se utilizan en el mundo gráfico, son similares a las que se utilizan en machine learning, fundamentalmente en redes neuronales. En ambos mundos abundan las operaciones con vectores, matrices y tensores. Y las GPU lo que hacen es optimizar esas operaciones.

En un paso más allá en especialización, existen las TPU ('Tensor Processing Unit') o los 'tensor cores' de NVIDIA que, pese a que suenen a algo muy potente, en realidad se especializan en una única operación: la multiplicación de dos matrices y acumulación del resultado en una de ellas. En cierto modo, son elementos muy sencillos, pero altamente especializados y optimizados.


La nueva programación de bajo nivel


Aunque la programación de bajo nivel, pese a su escasa visibilidad, nunca se había ido, ahora cobra una gran importancia para explotar estos nuevos procesadores.

¿Por qué?

Pues porque estos procesadores son muy especializados pero, para que produzcan los resultados esperados, hay que programarlos conociendo cómo funcionan. Así, para explotar bien las GPU hay que convertir la resolución de nuestros problemas en operaciones de algebra lineal y, además ser capaces de definir la resolución de un problema en términos de unas funciones, los denominados 'kernel', en que la misma lógica pueda trabajar en paralelo sobre diferentes datos (por ejemplo, sobre diferentes partes de una misma matriz).

Más específico aún es el caso de los 'tensor cores' en que, para aprovecharlos, hay que ser capaces de identificar o forzar operaciones que consistan en una multiplicación de matrices seguidas por una acumulación.

Y esto no se puede hacer con sólo conocer un problema de negocio o la sintaxis de un lenguaje de programación. Para ello hay que comprender el hardware con que se trabaja y la mejor forma de obtener todo su rendimiento.

Es decir, hay que trabajar en el bajo nivel.


Deshaciendo la aparente contradicción


Y llega el momento de deshacer la aparente contradicción.

¿No habíamos dicho que la evolución del software nos conducía a una visión cada vez más alejada del hardware, una visión que en sus vertientes 'No Code' o 'Vibe coding' ni siquiera trabajaba con código fuente e incluso que en las soluciones de más alto nivel el desarrollador expresaba sus necesidades en lenguaje natural?

Si, lo habíamos dicho y así es.

Lo que ocurre que el trabajo en el bajo nivel lo realizan, comparativamente, muy pocas personas organizadas en equipos especializados. Esas pocas personas programan el software más exigente y, además, preparan componentes optimizados para su uso en el alto nivel por desarrolladores menos especializados.

Así, las típicas librerías python usadas en machine learning y deep learning, están fuertemente optimizadas a nivel interno, aunque el común de los programadores las utilicen directamente sin preocuparse de los detalles. Y no digamos ya nada cuando ni siquiera se trabaja con las librerías sino con componentes gráficos que las abstraen (caso del 'low-code / 'no-code') o cuando incluso es la inteligencia artificial la que general el código que invoca a las librerías, sin que el desarrollador sea necesariamente consciente de ello.

En el fondo, esa ha sido siempre la relación entre al bajo y el alto nivel: unos pocos equipos especializados trabajan en el bajo nivel, cerca del hardware, y preparan componentes optimizados reutilizables en el alto nivel.

Lo único que ocurre es que ahora, con la enorme demanda computacional existente y procedente de la inteligencia artificial, muy especialmente en su vertiente generativa., cobra nueva importancia el  contar con algunos de esos equipos especializados para sacar jugo a un hardware especializado y que, pese a las enormes inversiones, se nos está quedando corto en volumen. 


Conclusiones


La gran demanda computacional exigida por la inteligencia artificial generativa ha llevado al desarrollo de procesadores especializados a nivel hardware, pero el uso adecuado y óptimo de ese hardware implica el trabajo en el bajo nivel aunque luego los resultados puedan ser reutilizados vía librerías y APIs, en la programación de alto nivel.

miércoles, 11 de febrero de 2026

La evolución del desarrollo software: productividad frente a deskilling

El desarrollo de software ha sido siempre una actividad que me ha encantado y con la que, en su momento, he disfrutado muchísimo. Y digo en su momento porque tanto en los últimos años de mis estudios universitarios, como en los primeros de mi carrera profesional, dediqué muchísimas horas a esta actividad, como aficionado como ingeniero de software.

Y he podido asistir, dada mi edad, a casi toda su historia (me perdí un poco del principio) y a cómo ha ido evolucionando. Y lo cierto es que la transformación es enorme. Ha cambiado en filosofía, lenguajes, herramientas y requisitos profesionales del desarrollador.

En este post quisiera revisar esa evolución, y lo que los cambios suponen, de bueno y de malo


Un análisis en cinco fases


Y, para ello, propongo identificar las fases principales de la evolución.

Que yo sepa, no existe ninguna forma de marco concreta para clasificar esta evolución de la forma de construir software, (aunque sí se habla a veces de generaciones, sobre todo tercera y cuarta, pero con base en mi percepción personal, hablaría de cinco fases, a saber:


  • Fase 1: código máquina
  • Fase 2: ensamblador
  • Fase 3: lenguajes de alto nivel
  • Fase 4: 'low-code' / 'no-code'
  • Fase 5: 'vibe coding' o 'prompt based coding'


Veamos brevemente lo que significa y aporta cada una de ellas.


Fase 1: código máquina


En esta fase, que sinceramente creo que pocos desarrolladores han vivido salvo, como mucho, durante sus estudios, se trabaja directamente con el hardware, con el microprocesador y se expresa el programa en los famosos unos y ceros que caso nadie ha visto.

Es una programación muy, muy cercana al hardware, e implica conocer en detalle el microprocesador, sus registros, las instrucciones que maneja y cómo se codifican, las direcciones de la memoria etc. Los programas son, a poco que el programador sepa lo que hace, extraordinariamente eficientes en recursos computacionales y rápidos en ejecución, pero eso sí, son muy dificultosos de desarrollar y depurar y, por tanto, en general de un alcance muy modesto.  


Fase 2: ensamblador


En realidad, es muy similar a la anterior, pero ahora hay un cierto lenguaje, el ensamblador, que al menos expresa las instrucciones mediante nemónicos textuales (típicamente de tres letras) con lo que, aunque con criterios de hoy en día siguen siendo enormemente crípticos, para su momento fueron una gran aportación en cuanto a claridad.


Fase 3: lenguajes de alto nivel


Son, quizá, el primer tipo de lenguajes ampliamente conocidos. En ellos el lenguaje de programación se basa en formas textuales más o menos destiladas del inglés, pero circunscritos a una serie de instrucciones muy concretas y con una estructura en general muy bien definida. Aunque hable de una forma de inglés no tiene nada que ver con el lenguaje natural: se trata de lenguajes muy acotados, muy estructurados y muy ligados a gramáticas estrictas.

Introducen ya los tipos de datos, las variables, las estructuras de control del tipo de bucles y condiciones o la capacidad de crear funciones. Con el tiempo, con el auge de la orientación a objetos, se introduce también esta idea de los objetos (que unen datos y comportamiento) y a capacidad de crearlos y utilizarlos.

Son lenguajes ya independientes del microprocesador e incluso del sistema operativo en que se ejecutan y un programa auxiliar, el compilador o el intérprete según el caso, se encarga de traducir esas instrucciones textuales de alto nivel al código máquina.

Se fueron acompañando de entornos de desarrollo del tipo IDE ('Integrated Development Environment') que incluyen capacidades de control y organización del código, capacidades de depuración, ayudas, etc. 

En esta categoría caben casi todos los lenguajes de programación más conocidos, desde algunos más antiguos como COBOL o Pascal, y pasando por Basic, C, C++, Java o python, por decir algunos.

El salto de productividad es inmenso respecto a la programación en ensamblador, una productividad que se refuerza por la posibilidad de creación y reutilización de librerías de funciones u objetos que proporcionan, ya empaquetadas y listas para ser usadas, capacidades más o menos sofisticadas. Creo que es con base estos lenguajes que se produce el verdadero 'boom' del software.

Aunque en varios momentos me he referido a ellos en pasado, siguen estando muy presentes hoy en día, muy especialmente python.


Interludio: los lenguajes de cuarta generación 4GL


No los he llegado a proponer como una fase diferenciada, pero por encima de los lenguajes de alto nivel (que a estos efectos se consideran de tercera generación), proporcionan mayores niveles de abstracción y un enfoque algo más declarativo, normalmente orientados a software de características bastante comunes y estructuradas como la gestión de bases de datos.

Hay quien los considera como un antecedente de lo que veremos a continuación: el 'low-code'.


Fase 4: low-code / no-code


La fase 4 nos conduce a la filosofía y soluciones 'low-code' o, en su extremo, 'no-code'. 

La idea es que el desarrollador ya no trabaje con código fuente (que se expresa en un lenguaje de tercera generación) o que lo haga en la menor medida posible. ¿Cómo se consigue eso? Pues proporcionando entornos de desarrollo gráficos o semi-gráficos, donde con frecuencia los bloques de ejecución se representan por cuadrados o círculos, que se unen mediante líneas o flechas para representar una lógica completa. Además, el entorno de desarrollo ofrece ya una amplia librería (normalmente ampliable) de bloques constructivos

En general el desarrollo tiende a convertirse en 'dibujar' la lógica de ejecución complementada por la configuración (habitualmente mediante cuadros de diálogo) de los parámetros y variantes de ejecución de cada uno de los bloques constructivos, así como la definición de variables.

En los casos más extremos ('no-code') no es necesario incluir código fuente tradicional y en otros casos ('low-code') sí existen determinados puntos donde se complementa la lógica, digamos gráfica, con pequeños elementos de lenguaje de programación de tercera generación. 

Esta filosofía es cada vez más común para construir todo tipo de soluciones, pero, por citar algunas muy representativas, tendríamos, en el ámbito de la automatización, casi todos los entornos RPA ('Robotic Process Automation') o BPMS ('Business Process Management Systems'), así como soluciones de automatización de workflow (como Make o N8N) e, incluso, algún entorno de construcción de agentes IA como LangFlow. También es común, por ejemplo, en visualizadores de datos como Power BI.

En este salto, no es ya que nos hayamos alejado del hardware y el microprocesador, es que incluso nos hemos alejado de los lenguajes de programación como tales, si entendemos los lenguajes de programación como algo con base textual. Incluso, gran parte de la lógica detallada, viene resuelta por los bloques constructivos disponibles sinq ue el desarrollador la conozca en detalle, sino sólo por su comportamiento externo.


Fase 5: Vive coding o 'prompt based coding'


El último salto, es la creación de software a partir de prompts usando herramientas de inteligencia artificial generativa. En el primer post de este blog que dediqué al 'vibe coding', comentaba la diferenciación entre el uso de inteligencia artificial como una especie de ayuda o copiloto, lo que Addy Osmani denominaba 'Ingeniería de software asistida por IA' frente al uso de la IA para construir toda la aplicación, siendo esto último a lo que asignaba el término 'Vibe coding'.

En realidad, si usamos la IA como copiloto, estamos realmente reforzando una de las dos fases anteriores (lenguaje de alto nivel o 'low-code'/'no-code') pero no sería una fase realmente diferenciada. 

Lo que considero como una fase diferenciada es cuando usamos la herramienta para la generación completa de aplicaciones o módulos a partir de prompts en lenguaje natural.  Como en este caso la forma de actuar que tiene el desarrollador es únicamente mediante 'prompts', me he querido inventar el término 'prompt based coding'.

En este caso el alejamiento ya es total: el desarrollador no es que no conozca el hardware o el sistema operativo, y no es ya que no utilice un lenguaje de programación, es que, incluso, salvo que se preocupe por ello, hasta desconoce la lógica interna del software que ha generado o cómo está estructurado. El desarrollador, en teoría, se centra sólo en la necesidad, que expresa mediante lenguaje natural, no en los detalles internos del software.

Se trata de una fase probablemente poco madura en estos momentos y que hay que ver hasta dónde es capaz de llegar, pero, en teoría, es una fase de altísima productividad y, además, casi al alcance de cualquiera, una fase donde el propio término 'desarrollador', al menos tal y como lo hemos entendido hasta ahora, puede que pierda sentido.


Consecuencias


A medida que se avanza en las diferentes fases, creo que se producen los siguientes efectos:


  • Se aumenta (y mucho) la productividad del desarrollo software
  • Se baja la barrera de entrada (los conocimientos y la especialización necesarios) para crear software
  • El desarrollador pierde conocimiento del detalle de lo que está haciendo (el hardware, el sistema operativo, las lógicas internas, etc)
  • Debido a esa pérdida de conocimiento (y gestión) del detalle, en general el software generado es menos eficiente en el uso de recursos computacionales: memoria, tiempo de CPU, disco, etc 


En general, la evolución de la industria ha apostado por los dos primeros beneficios (productividad y bajada de la barrera de entrada) frente a los dos últimos inconvenientes (perdida de conocimiento y menor eficiencia en recursos computacionales).

Voy pararme un momento en dos aspectos.


La productividad y las barreras de entrada


En efecto, el gran beneficio de esta evolución es, sobre todo, la altísima mejora de productividad en la construcción de software, no sólo en cuanto a cantidad de código creado sino en cuanto a potencia y capacidades de las soluciones generadas. Por ejemplo, hace  20 o 30 años, hacer la interfaz de usuario (las ventanas, por entendernos) de un sistema, era tremendamente trabajoso... y hoy es casi trivial en algunos casos. 

A esto se une, especialmente en las dos últimas fases, en unos menores requisitos, una menor cualificación, para ser creador de software, llegándose ya hace unos años al concepto acuñado por Microsoft de 'Citizen developer' (un concepto muy ligado al 'low-code') en que ya parte del software empresarial podría ser creado, no por desarrolladores profesionales del departamento de IT, sino por profesionales del ámbito del negocio (ventas, marketing, operaciones, etc)


El deskilling


Sin embargo, ese menor conocimiento requerido supone en parte un peligro para el propio software en el sentido de que el desarrollador puede ser mucho menos capaz de hacer un software eficiente, escalable e incluso seguro, o que le puede costar depurar los errores más extraños. 

De cara al desarrollador, como profesión, el avance en estas fases, muy especialmente la última, pone en riesgo la profesión en sí misma, en riesgo de desaparición o, quizá más probable, de profunda redefinición y, quizá, sólo quizá, menor cualificación y por tanto consideración profesional.

En el fondo, se produce una forma particular de 'deskilling' (término del que he hablado en los dos últimos posts), en que el desarrollador cada vez sabe menos de sistemas, cada vez sabe menos, por supuesto del hardware, pero también sabe menos de las mejores arquitecturas, de los mejores criterios y mejores prácticas de construcción de software. Y eso es un riesgo potencial para la propia calidad del software y para su mantenibilidad y, quizá, un empobrecimiento personal y profesional del desarrollador.


Conclusiones


El desarrollo de software ha sufrido a lo largo de las últimas décadas, una enorme transformación en su forma de realización, una evolución que le ha conducido, a través de cinco fases, a recorrer un camino en el que ha ganado una enorme productividad y sencillez, pero a cambio de una menor eficiencia en recursos computacionales y en una progresiva descualificación técnica de los profesionales que la ejercen. 


lunes, 29 de septiembre de 2025

Lo que no reluce en el 'Vibe coding': retos, limitaciones y equilibrios

Aunque la promesa de productividad y facilidad del 'vibe coding' es muy importante, y hasta cierto punto bastante creíble, conviene ser realistas y tomar consciencia de que la generación de código mediante inteligencia artificial, al menos hoy en día, tiene limitaciones que hay que conocer y gestionar.

En un post anterior decía por ello que 'no era oro todo lo que relucía'. En este post, precisamente, quiero sacar a colación aquello que 'no reluce' en el 'vibe coding'.

Y para ello me baso, como en posts anteriores, en las aportaciones de Addy Osmani en su libro 'Beyond Vibe Coding: From Coder to AI-Era Developer'.


Recordatorio 'express'


Antes, un recordatorio brevísimo, express. El término 'Vibe coding', acuñado por Andrej Karpathy, y de fronteras difusas, designa la generación de código mediante el uso de inteligencia artificial, normalmente grandes modelos de lenguaje generalistas o especializados en generación de código. Es decir, el desarrollador expresa en lenguaje natural lo que quiere que haga una aplicación, función o lo que sea, y el modelo de lenguaje genera el código correspondiente.

Como digo, las fronteras del término no son claras, pero personalmente creo que se aplica más a cuando esa generación de código es completa o casi completa, es decir, que se genera una aplicación completa o gran parte de ella. De forma más general, podemos hablar de ingeniería de software asistida por IA donde el nivel de ambición puede ser menor y lo que el desarrollador puede solicitar al modelo de lenguajes es, a lo mejor, sólo una función, o una pantalla o que le ayude a resolver un error sintáctico o de ejecución.

En cualquier caso, hablamos de generación de código y un código que el desarrollador solicita a la IA mediante lenguaje natural.


Bajando un poco a la realidad


Si bajamos un poco a la realidad, al menos actualmente, no resulta posible generar aplicaciones que sean completas, fiables, seguras y escalables sólo mediante un 'prompt', por largo, sofisticado y bien elaborado que éste sea.

Se pueden conseguir resultados espectaculares generando aplicaciones sencillas en modo demostración o prototipo, pero no aplicaciones pensadas para producción real.

La realidad actual apunta más a un trabajo conjunto entre un desarrollador y la IA, donde la IA genera grandes partes del código e incluso ayuda a corregirlo pero con intervención, supervisión y modificaciones por parte del desarrollador humano.


Aspectos que aún le cuestan al 'vibe coding'


Osmani, en su libro, destaca cinco facetas, como aspectos que le cuestan (que no suele conseguir) el 'vibe coding' actual:


  • Sistemas complejos: El 'vibe coding' funciona bien con aplicaciones sencillas y típicas, como ventanas web que recubren operaciones CRUD (Create, Read, Update, Delete) en bases de datos. En general, aplicaciones sencillas y comunes que los LLMs 'han visto' con frecuencia en sus datos de entrenamiento. Pero lo tienen muy difícil ante el caso de algoritmos complejos o planteamientos novedosos que no existen en los datos de entrenamiento o que se encuentren poco representados. En estos casos, la IA tiende a generar un código que se acerca al correcto, pero no lo es en realidad.

  • Optimizaciones de bajo nivel y programación a nivel sistema: Los LLMs actuales están fundamentalmente entrenados con código escrito en lenguajes de alto nivel y problemas también de alto nivel, cercanos al negocio o la funcionalidad. Sin embargo, la optimización de ciertos algoritmos implica la programación a muy bajo nivel, muy cerca del sistema, para reducir complejidad algorítmica y tiempos de procesamiento, optimizar el uso de recursos hardware, para adaptar los algoritmos al hardware subyacente, etc. Por tanto, el código que generan suele ser subóptimo. Para muchas aplicaciones no críticas puede ser más que suficiente, pero para otras más especiales no tanto.

  • Frameworks únicos o de nicho: De nuevo, estos modelos están entrenados con base en código fuente basado en librerías y frameworks más o menos populares y, por tanto, pueden ser incapaces de generar un código correcto en el caso de frameworks o librerías muy nuevos o muy de nicho (y con pocos ejemplos en los datos de entrenamiento)

  • Interfaces de usuario creativas: Una vez más, los modelos generan correctamente código para formas de resolver un problema comunes. En lo relativo a la interfaz de usuario, generan correctamente, por ejemplo, formularios, dashboards y otras formas comunes y probadas de interfaz de usuario. Pero les resulta muy complicado generar una experiencia nueva, especial, diferente, inspiradora.

  • Interpretación de intenciones y requisitos: En este caso, el problema puede estar más en el lado del desarrollador, pero lo cierto es que los modelos no siempre resuelven bien unas especificaciones con requisitos implícitos o contradictorios.


Limitaciones y equilibrios


Además de las facetas vistas más arriba, Osmany también nos alerta de algunas limitaciones de los LLMs o de algunas circunstancias que pueden precisar de adoptar algún tipo de equilibrio, de solución de compromiso:


  • Calidad variable de la salida: Como sucede en otros ámbitos de su aplicación, los LLMs pueden generar un código que parezca correcto pero que no funcione del todo bien, o que, por ejemplo, no reaccione bien ante errores. También puede producir un código funcional pero ineficiente. Por tanto, parece inevitable una supervisión responsable y real por parte del desarrollador humano de todo lo que genera mediante IA.

  • La ambigüedad en los 'prompt's conduce a ambigüedad en el código: Como ocurre en general con la ingeniería de instrucciones ('prompt enmgineering') y como , en el fondo, también ocurre con la especificación de requisitos tradicional, si las instrucciones (que actúan como requisitos) son ambiguos, incompletos o incorrectos, el resultado también presentará carencias.

  • Confianza excesiva y atrofia de habilidades: Quizá aún sea pronto para ver con claridad este efecto, pero parece previsible que si un desarrollador confía en exceso en la IA y apenas hace aportaciones propias, poco a poco sus habilidades se irán deteriorando y con ello su capacidad de detectar errores, de optimizar el código, de depurar el resultado y, en general, se empobrecerá como desarrollador. Y también se empobrecerá el código que genere, cada vez más apoyado en la IA

  • Aspectos de seguridad y privacidad: Con frecuencia, los entornos de 'vibe coding' se apoyan en el envío de código a terceros en la nube, lo cual puede plantear preocupaciones en cuanto a privacidad. Igualmente, existe el riesgo de que el código que genere la IA sea casi una copia de un código real quizá protegido por propiedad intelectual.

  • Sesgos en las salida: Los LLMs usados para generar código, también pueden presentar sesgos como otros modelos de IA o como estos mismos modelos en otros ámbitos de aplicación. En el ámbito de la generación de código suelen ser sesgos 'inocentes' como tener preferencia por dar ciertos nombres a las variables, pero conviene estar vigilantes de que no se introducen sesgos más graves.

  • Factores humanos y confianza: Finalmente entra el factor humano que puede hacer que los desarrolladores no acepten esta forma de trabajar, quizá por desconfianza en los resultados, o quizá, incluso, porque cambia la naturaleza de su trabajo que hasta ese momento, antes del 'vibe coding', quizá percibían como más divertido, independiente y creativo.


Conclusiones


Como en el fondo cabía imaginar, el 'vibe coding' no es algo mágico, sino que tiene sus limitaciones y problemáticas, unas limitaciones y problemáticas que tienden a resolverse, en la mayor parte de los casos, siendo conscientes de que el trabajo de desarrollo basado en IA implica una importante supervisión por parte de desarrolladores humanos de cara a la verificación, optimización, depuración, etc. Y unos desarrolladores humanos que, además, deben estar mentalizados y tener altas capacidades por que, si no, seguramente les pasarán inadvertidos los errores o soluciones subóptimas que les proponga la IA.


Artículos de este blog relacionados


miércoles, 24 de septiembre de 2025

Doce reglas de oro del 'Vibe coding'

En el post anterior, hice una pequeña introducción a lo que es este nuevo concepto del 'vibe coding', un tema novedoso (aunque con presente y mucho futuro) y que cambia la forma de desarrollar software.

En este artículo voy a aportar unas buenas prácticas, en forma de reglas de oro, que propone Addy Osmani en su libro 'Beyond Vibe Coding: From Coder to AI-Era Developer'. 

 

Un breve recordatorio: qué es el 'vibe coding'


Antes, y a modo de muy breve recordatorio, decir que el término 'vibe coding' denomina, de una forma que hay que reconocer que algo confusa, el uso de la inteligencia artificial para la generación de código software.

Aunque, como digo el término no es académico ni de límites claros, personalmente tiendo a asimilarlo al caso en que la IA hace gran parte del trabajo, que genera todo o gran parte del código fuente, mientras que para otras situaciones en que es una ayuda pero más atomizada, generando secciones relativamente limitadas de código o ayudando en depuración de errores concretos y cosas así, podríamos adoptar el término de ingeniería de software asistida por IA que propone el propio Osmani.

En cualquier caso, creo que no vale la pena en este caso 'ponerse estupendos' con las definiciones. Hablamos de generación de código (e incluso de intervención en todo el ciclo de vida de la ingeniería software) basado en inteligencia artificial y, en concreto, en grandes modelos de lenguaje. 

Para más detalles, invito al lector a visitar mi post anterior 'Conociendo el vibe coding', incluyendo la referencia bibliográfica al libro de Osmani, o a las aportaciones de Andrej Karpathy, creador del término 'vibe coding' 


Las doce reglas de oro del 'vibe coding'


Bueno, y sin más dilación éstas son las doce reglas de oro que propone Osmani en su libro, a las que me tomo la libertad de añadir algunos comentarios propios:


  • Sé claro y específico en lo que quieres: Se trata de proporcionarle instrucciones muy claras a la IA sobre la aplicación, función o lo que sea que se le está solicitando. Esto, en realidad, es la fusión de dos buenas prácticas: la de la especificación de requisitos clara, propia de la ingeniería de software tradicional (sobre todo en el modelo en cascada) y la de proporcionar instrucciones claras y precisas propio del 'prompt engineering'

  • Valida siempre la salida de la IA frente a tu intención: Osmani utiliza el término intención ('intent') para indicar aquello que realmente queremos, aquello que esperamos del software que vamos a crear. Y lo que propone, en el fondo, es algo que también se realiza en ingeniería de software tradicional bajo el término 'validación', y que significa asegurarse de que el software satisface los requisitos del negocio. En este caso, lo que creo que es más relevante es la llamada de atención a 'no fiarse' sin más de lo que genera de IA, sino realizar una validación activa y por humanos del resultado.

  • Trata a la IA como a un desarrollador junior: Básicamente, significa, de nuevo, no fiarse directamente del código generado por la IA. Con la metáfora del desarrollador junior, se traslada la idea de supervisar las tareas. Es decir, delegar tareas de desarrollo pero revisar el resultado.

  • Usa la IA para expandir tus capacidades no para sustituir tu pensamiento: Una juiciosa llamada de atención a no renunciar a la propia capacidad de resolución de problemas y de toma de decisiones. Aparte de lo que para la persona supone, el propio estado del arte de la generación automática de código requiere actualmente que el humano asuma muchas de las decisiones o planteamientos más complejos.

  • Coordina por anticipado con el equipo antes de generar código: Se trata de un lógico establecimiento de ciertas reglas de juego comunes, tanto de estilo como de operación. Pero, además, hay que tener en cuenta que la IA puede decidir modificar módulos (eventualmente desarrollados por otra persona o por otra persona ayudada por IA), por lo que es necesario coordinar y poner reglas.

  • Trata el uso de la IA como una parte normal de la conversación del desarrollo: De igual forma que los equipos de desarrollo hablan de herramientas, hallazgos y buenas prácticas, lo que propone Osmani es algo tan lógico y natural como que en esas conversaciones se incluyan experiencias, éxitos, fallos etc encontrados en el trabajo con la IA.

  • Separa los cambios en Git mediante 'commits' diferentes: Se trata de gestionar de forma separada, en lo que a control de versiones se refiere, el código generado por humanos del generado de la IA: Es una regla de orden práctico para facilitar revisiones, vueltas atrás, etc

  • Asegura que todo el código pasa por una revisión de código: La revisión de código ('code review') es una buena práctica tradicional en ingeniería software. Se trata de que el software  generado, no sólo se prueba en funcionamiento, sino que el propio código fuente es inspeccionado y revisado, en general por otro desarrollador o por un arquitecto de soluciones. Personalmente aseguraría que esta práctica está bastante en desuso y, sin embargo, Osmani la propone como una regla de oro. Por un lado, propone usarla para que una persona revise el código generado por la IA, lo cual puede estar perfectamente alineada con esa metáfora del desarrollador 'junior' que mencionábamos antes. Pero además, propone también revisar el código generado por humanos. Es decir, es una apuesta general y en toda regla por la revisión de código.

  • No hagas 'merge' de código que no entiendes: Para aquellos no familiarizados con el trabajo en software, indicar que  'hacer un merge' significa fusionar en una sola instancia dos versiones del código fuente del mismo módulo para lo cual de alguna forma hay que decidir (automáticamente o por una persona) qué parte sobrevive de cada versión en el resultado unificado. Cuando Osmani propone esta regla, lo que propone en el fondo es no fiarse sin más de un código generado por la IA, sino primero entenderlo como haría el desarrollador con el código generado por él mismo, y sólo entonces incorporarlo al repositorio común de código y eventualmente mezclarlo o fusionarlo con otro código.

  • Prioriza los comentarios y documentación: De nuevo, se trata de rescatar, y aplicar al caso del código generado por IA, una buena práctica de la ingeniería de software tradicional. Una práctica que consiste en insertar comentarios y generar documentación que ayude a entender a un tercero (o al propio desarrollador pasado un tiempo) el código fuente. Eso es fundamental sobre todo de cara al mantenimiento y evolución.

  • Comparte y reutiliza los prompts efectivos: una vez más, la adaptación de una buena práctica del mundo del software que consiste en generar módulos reutilizables, aunque en este caso aplicada a los prompts. En este caso, también, se trata de una buena práctica de ingeniería de instrucciones. Si un prompt (una instrucción) ha demostrado que ha generado buenos resultados, un código que funciona y hace lo que tiene que hacer, es bueno reutilizarlo y compartirlo con el resto del equipo.

  • Reflexiona regularmente e itera: Propone una revisión periódica de todo la mecánica y 'workflow' de desarrollo como una forma de mejora. Se trata un poco de la adaptación de la filosofía de la calidad total o de las llamadas 'retrospectivas' usadas en enfoques agile como Scrum.


No es oro todo lo que reluce


En cierto modo, en estas reglas de oro que propone Osmani, observamos muchas dosis de revisión,  intervención humana y aplicación de buenas prácticas de ingeniería de software tradicional.

¿Por qué?

Pues porque aunque no sabemos a dónde puede llegar el 'vibe coding', en la actualidad, y pese a los extraordinarios avances y aportaciones, y pese a lo que ya aporta en el proceso de desarrollo de software, todavía no te puedes fiar, en muchos sentidos, del código generado por la IA, y es preciso revisar, probar y mejorar el proceso.

En algún post futuro, comentaré algunas de estas limitaciones actuales.


Conclusiones


El 'vibe coding' permite, de forma muy sencilla, obtener código generado por inteligencia artificial. Sin embargo, en este momento no es mágico, y de cara a una creación de sofware efectiva y de calidad, es preciso aplicar ciertas pautas metodológicas y ciertas buenas prácticas procedentes muchas de ellas de la propia ingeniería de software tradicional o de la ingeniería de instrucciones ('prompt engineering') 


Artículos de este blog relacionados


lunes, 22 de septiembre de 2025

Conociendo el 'Vibe coding'

En este dinámico y acelerado mundo de la tecnología en que nos movemos, no sólo surgen nuevas tecnologías, sino también nuevos planteamientos, nuevos conceptos y nuevos términos, no todos ellos de fronteras definidas, no todos realmente novedosos y no todos llamados a perpetuarse en el tiempo y superar la mera moda, pero que ahí están, para nuestro estudio y asimilación.

Uno de los conceptos con cierta 'tracción mediática', al menos en ambientes tecnológicos, y uno de los términos de surgimiento muy reciente es el de 'vibe coding'.

En este post busco sólo hacer una introducción rápida a la idea


Un inciso: lenguajes de programación y desarrollo de software


Probablemente muchos de los lectores de este blog conozcan cómo funciona el mundo del software, y además lo he abordado hace poco en el post titulado 'Exactitud vs. flexibilidad en modelos de inteligencia artificial (III): ingeniería software y 'vibe coding'' pero, no obstante, recuerdo alguna idea básica.

Como sabemos, los ordenadores digitales tratan todo, tanto información como algoritmia, en lenguaje binario (los famosos unos y ceros). Por tanto, para programar un ordenador, al final tenemos que darle el código binario que representa la lógica y los datos. Pero, claro, esto no es fácil ni práctico. Por ello hace ya muchos años, se inventaron primero los lenguajes ensambladores (que hacían una ligera abstracción de ese código binario) y no mucho después los entonces denominados 'lenguajes de programación de alto nivel', unos lenguajes de programación que, aunque son lenguajes formales, se aproximaban bastante más a cómo una persona se expresa y piensa desde un punto de vista lógico o matemático que le mero código binario o el ensamblador. Los lenguajes de programación de alto nivel incorporaron en seguida las buenas prácticas de la programación estructurada y unos años después de la programación orientada a objetos. Los lenguajes de programación más conocidos, y que se usan abundantemente hoy en día, son lenguajes de alto nivel donde encontramos nombres tan conocidos como C, C++, Java o python.

Con estos lenguajes, el trabajo del desarrollador, en buena medida, se centraba (y se sigue centrando en muchos casos) en traducir la lógica o el algoritmo que él/ella mismo/a ha pensado (o que le ha trasladado el analista que lo ha pensado) a los elementos e instrucciones que le proporciona el lenguaje de programación. Lo que escribe el desarrollador es un texto, un texto expresado en un lenguaje de programación y que se denomina código fuente. Ese texto se traduce luego a binario por medio de los programas compiladores o se ejecuta mediante los intérpretes.

Y, aunque en su visión más básica el desarrollo se puede acometer con poco más que un editor de texto para generar el código fuente y un compilador para traducirlo a binario, lo cierto es que existen muchas capacidades interesantes adicionales para ordenar el código fuente, depurarlo, compartirlo, etc, que lleva a la creación de los denominados IDE ('Integrated Development Environment'), aplicaciones completas con toda una suite de utilidades para uso por parte del desarrollador. De todas formas, en esencia, la parte nuclear del desarrollo sigue siendo el crear el código fuente para expresar una lógica o algoritmo.

Cierto es que desde hace unos años existen las plataformas de desarrollo 'low-code' que incluyen herramientas de aún más alto nivel para que los desarrolladores puedan expresar la mayoría de las veces la lógica que pretenden no como instrucciones de un lenguaje de programación sino como flujos, o diseños visuales y más cercanos a la aplicación final


El fundamento: grandes modelos de lenguaje y generación de código


Pues bien, lo que yo identifico como punto de partida del 'vibe coding' es la capacidad actual de los grandes modelos de lenguaje para generar código fuente.

Ya lo he comentado con cierta frecuencia pero recuerdo de nuevo que un lenguaje de programación es un lenguaje, como el humano, con sus reglas y sus gramáticas. Y digo que igual que el humano pero en realidad es más sencillo, acotado y formal, con las reglas mucho más claras que el lenguaje humano.

Y por ello, en seguida los grandes modelos de lenguaje se han adaptado para la generación de software, para la creación de código fuente. De forma similar a como le solicitas a un modelo generativo que, por ejemplo, te sugiera actividades para el fin de semana, le puedes pedir que te genere un software que haga algo.

Lo 'único' (y pongo 'único' con comillas a propósito) que tienes que hacer es explicarle al modelo de lenguaje en tu instrucción, en tu 'prompt', qué es lo que quieres que haga el programa.

Nótese lo siguiente: más arriba decía que el trabajo fundamental del desarrollador tradicional es traducir a las instrucciones de un lenguaje de programación la lógica que el desarrollador ha pensado o que ha recibido de un analista. Pues bien, cuando se utiliza un modelo generativo para crear el código, no es el desarrollador quien hace la traducción de la lógica a las instrucciones, es el propio modelo generativo quien lo hace.


Una explicación


Buscando profundizar en los planteamientos y herramientas del 'vibe coding' me encuentro finalizando la lectura del libro 'Beyond Vibe Coding: From Coder to AI-Era Developer' de Addy Osmani. En el primer capítulo, el autor expresa esta idea de la siguiente forma:


Imagine writing software by simply describing what you want it to do—almost like talking to a teammate—while an AI translates those ideas into code.


Ahí está el 'quid' de la cuestión: la IA (el modelo de lenguaje) traduce tus ideas en código. Acto seguido, el autor explica, casi define, de una manera un poco más formal, lo que es el 'Vibe coding'.


This is the essence of vibe coding, a prompt-first, exploratory approach where you describe what you want in natural language and let a large language model (LLM) fill in the blanks.


De nuevo se repite la idea: se comienza por un prompt ('prompt-first') en que se describe lo que se desea y es un gran modelo de lenguaje el que genera el código.

A lo mejor el lector avezado nota el uso de los términos 'exploratory' y 'fill in the blanks'.

Ese uso tiene 'más miga' de la que parece, pero de momento me abstendré de entrar en ello.


El origen del término


Esta nueva capacidad de los modelos generativos, de los grandes modelos de lenguaje, está con nosotros, aunque mejorando, desde hace unos años. Pero el término 'Vibe coding' como tal, fue acuñado hace unos meses, en Febrero de este 2025, por Andrej Karpathy, intuyo que sin ser consciente de que ese término iba a hacer fortuna, en un post en la red X en que comenzaba diciendo: 


There's a new kind of coding I call "vibe coding", where you fully give in to the vibes, embrace exponentials, and forget that the code even exists. It's possible because the LLMs (e.g. Cursor Composer w Sonnet) are getting too good.


Es interesante la mención a que el desarrollador casi se olvida de que el código existe, puesto que es el LLM el que lo genera. Veremos que ese olvido del código fuente por parte del desarrollador, al menos hoy en día, no es realista del todo, pero como filosofía y aspiración esa es la idea: la inteligencia artificial, a través de uno o varios modelos de lenguaje seguramente especializados, se encarga de generar el código fuente.

Un poco más abajo en el mismo post en X, Karpathy dice:


The code grows beyond my usual comprehension, I'd have to really read through it for a while


De nuevo, como llamada de atención, como explicación de una sensación e, incluso, de una filosofía o una aspiración, la frase es muy interesante y descriptiva pero, de nuevo, veremos que un desarrollador responsable no puede permitirse demasiado que ese código generado por el LLM se escape a su comprensión.


Hasta dónde llega la IA en la generación de código


Dado que el término 'vibe coding' no tiene un origen académico ni mucho menos, ni siquiera es un término surgido de la un fabricante como Open AI o Google, o una gran consultora, su significado y fronteras son algo difusos.

Personalmente, y no sé si con acierto, tiendo a pensar en 'Vibe coding' cuando el LLM asume una gran parte, si no toda, de la generación de una aplicación, un escenario que aunque no es completamente impensable, pero que hoy día tiene serias limitaciones prácticas que ya veremos.

En el libro que mencionaba más arriba, el autor también tiende a reservar el término 'vibe coding' para las situaciones en que la IA se hace cargo de toda gran parte de la generación del código.

Cuando lo que hace la IA es estar integrada dentro de los entornos de desarrollo (los IDEs), y actuar como una suerte de ayudante (un copiloto) para generar pequeñas secciones de código, corregir o hacer sugerencias de corrección de errores, etc, este autor, Addy Osmani, opta por denominarlo una ingeniería de software asistida por IA. Ignoro si Karpathy estaría de acuerdo con esta diferenciación o si para Karpathy toda generación de código mediante una IA es 'Vibe coding'.


Lo de las vibraciones


Un punto que me resulta algo confuso es el por qué Karpathy utiliza este termino 'Vibe' que, creo que la traducción adecuada es 'vibración', pero no vibración en el sentido físico del término sino en el de un ambiente o una sensación (como cuando decimos que algo nos transmite 'buenas vibraciones' o 'buen rollo'). En alguna otra acepción, se podría quizá hablar de relax.

Creo, pero confieso que no estoy seguro, que lo que Karpathy quiere transmitir es que la IA, el LLM, está ahí para ayudarte y, sobre todo, que le pides más o menos (una aplicación completa o sólo una función o la corrección de un error) en función de cómo se encuentre el propio desarrollador.

Admito, no obstante, que no tengo claro cien por cien si ese es el sentido que Karpathy le ha querido dar. Espero averiguarlo en breve.


Conclusiones: la esencia del Vibe coding


En cualquier caso, y como ya decíamos, en la esencia del Vibe coding se encuentra en que la IA, a través de modelos de lenguaje más o menos especializados es ya capaz de asumir y con razonable eficacia muchas tareas de generación de desarrollo software y eso cambia, seguramente de forma radical e irreversible, la disciplina de la ingeniería de software y, sobre todo, la forma en que los desarrolladores tenían hasta ahora de ejercer su labor.

No se acaba aquí la disertación sobre 'Vibe coding'. En próximas fechas hay algún tema más relacionado con el 'vibe coding' y que querría publicar en este medio.