De cuando la IA sugiere y los humanos no cuestionan
Una historia de humanos, IA y errores evitables
Nadie se sorprenderá al decir que estamos en un mundo cada vez más digitalizado y en búsqueda constante de la eficiencia. Y que vemos muchas bondades y posibilidades de hacer muchas más tareas con mejores beneficios usando sistemas de IA como ChatGPT o GitHub Copilot.
Éstas y otras herramientas se han vuelto indispensables para muchos profesionales en distintas áreas. En este post me gustaría mostrar cómo sería llevar a cabo una sencilla tarea con su ayuda y los riesgos a los que nos podemos enfrentar si no somos conscientes de lo que realmente estamos haciendo.
Imaginemos que nuestro desarrollador humano de software, al que llamaremos Elon, es una persona que confía plenamente en estas herramientas para agilizar su trabajo. Pero, ¿qué sucede cuando esa confianza se vuelve ciega? Elon está a punto de descubrirlo en sus propias carnes.
Una tarea sencilla
Estamos en un sprint crucial del ciclo de añadir nuevas funcionalidades a un proyecto que van usan varios clientes para ofrecer sus productos. A Elon se le encarga la tarea de implementar dos funciones de código que van a ser usadas para el cálculo de descuentos sobre los pedidos de los clientes.
Como tiene muchas otras tareas que atender va a usar una de sus herramientas favorita, Copilot. Tras leer la escasa documentación de la que dispone y cuál es el cometido de su misión define estos prompts o instrucciones que va a usar para solicitar lo que necesita a la IA y la respuesta de la herramienta:
Prompt 1:
Prompt 2:
■ Aquí lo que hace el código es calcular un porcentaje de descuento a cada producto de un carrito de la compra, y luego hace la suma de todas las líneas de productos con sus descuentos.
Como Elon es un rápido lector de código, acepta el código sugerido por Copilot sin revisarlo a fondo.
Por suerte en su proyecto no se acepta código que no tenga pruebas unitarias con lo que su PR (Pull request o solicitud de añadir código) ha sido rechazada de forma automática. Con lo que Elon tiene que añadir pruebas a su código antes de poder marcar su tarea como completada. Ni corto ni -poco- perezoso Elon, que tiene todo el contexto disponible en su IDE, decide pedírselo a Copilot:
class TestApplyDiscount(unittest.TestCase): def test_apply_discount(self):
cart = [ {'price': 100, 'discount': 10}, {'price': 50, 'discount': 5}, {'price': 75, 'discount': 15} ] self.assertEqual(apply_discount(cart), 202.5)
cart = [ {'price': 200, 'discount': 20}, {'price': 100, 'discount': 10} ] self.assertEqual(apply_discount(cart), 240)
cart = [ {'price': 50, 'discount': 0}, {'price': 75, 'discount': 0} ] self.assertEqual(apply_discount(cart), 125)
cart = [ {'price': 0, 'discount': 50} ] self.assertEqual(apply_discount(cart), 0)
cart = [ {'price': 100, 'discount': 100} ] self.assertEqual(apply_discount(cart), 0)
■ Con este código lo que está generando la IA son escenarios de prueba. En cada carrito (cart) hay una serie de artículos y un descuento. En la línea inferior simplemente ha calculado cual sería el precio de ese carrito con los descuentos correspondientes aplicados. En caso de que haya una discrepancia entre lo que espera que sea el resultado y lo que ha devuelto realmente se producirá un error, porque los valores no se corresponden.
Añadió las pruebas propuestas a su código sin mucha revisión pero ¡oh!, sorpresa: los propios tests que la IA ha generado en sus pruebas dan error. La primera pregunta a la que se enfrenta Elon es: ¿estará fallando el código de la función el código del test?
No le queda otra opción que ponerse a mirar qué es lo que está pasando en su código. Tras revisar las pruebas y entendiendo dónde está el desajuste de resultados entre lo que hace la función y el resultado esperado, descubre que el problema está en el propio test, que el número que espera como resultado no es correcto.
Para revisar los escenarios de las pruebas se ha hecho una tabla con los resultados que espera y los que tiene debe devolver el código:
Pero el test proporcionado indica que la salida es 202,5
self.assertEqual(apply_discount(cart), 202.5)
Y ahora Elon cargado de razón avisa a Copilot de que hay un error en el cálculo que está esperando el test, pero esta IA es un poco testaruda y tras dos infructuosos intentos, Elon tiene copiar el código que la misma IA ha generado previamente para que termine de “creérselo y entender el problema”. Finalmente detecta donde está el error:
Ahora ya su código pasa los test proporcionados y puede volver a enviar el código a revisión. Imaginemos que en este proyecto que ha sufrido varios recortes, no dispone de ningún desarrollador más que el propio Elon y que no dispone de un departamento de calidad de software (QAs) que puedan revisar y asegurar el nuevo código entregado, por lo que el código pasa a producción.
Semanas después, descubren en un foro especializado en descuentos que se está compartiendo un artículo de cómo un visitante de una tienda puede explotar un error en código y conseguir grandes descuentos en el proceso de compra. El código que era inicialmente inofensivo, o que al menos lo parecía, contenía una (o varias) vulnerabilidades de las que Elon se dio cuenta y que con una simple revisión consciente podría haber evitado este desastre.
¿Por qué caemos en esta trampa?
Elon reflexiona sobre por qué confió ciegamente en la IA. La presión por entregar rápidamente, la percepción de que la IA es infalible y el deseo de ser más productivo lo llevaron a bajar la guardia. Se da cuenta de que no está solo; muchos de sus colegas han caído en la misma trampa, seducidos por la aparente infalibilidad de la tecnología.
Cómo evitar caer en la trampa
Determinado a no repetir el error, Elon lidera un cambio en su equipo. Implementan un proceso de revisión de código más riguroso, especialmente para el código generado por IA. Establecen sesiones de pair programming con desarrolladores de otros proyectos y fomentar una cultura de cuestionamiento constructivo.
Elon aprende que la clave está en ver a la IA como una herramienta poderosa, pero no infalible, que requiere supervisión humana. La generación y uso de tests en el proceso de desarrollo ayuda a entender la funcionalidad y poder simular el uso que puede encontrar por los distintos tipos de usuarios cuando el software esté en producción.
Continuando con el ejemplo que no ha tenido en cuenta o que podrían ser explotados son los valores negativos en los descuentos o que la suma total nunca debería ser un valor negativo porque implicaría devolver dinero a un cliente que está comprando elementos, con lo que la pérdida para la empresa sería doble: uno por no cobrar los artículos, y otro por estar regalando dinero a quien compra sus artículos.
La lección aprendida y el futuro
Meses después, Elon observa cómo su equipo ha evolucionado. La colaboración entre humanos e IA es más fluida y segura. Comprenden que el verdadero poder reside en combinar la creatividad y el juicio crítico humano con la eficiencia de la IA.
Elon se da cuenta de que este equilibrio no solo mejora la calidad del software, sino que también los prepara para un futuro donde la simbiosis entre humanos y máquinas será cada vez más crucial.
Bonus Track
¿Te gustaría saber qué habría pasado si le hubiéramos dado esta misma tarea a un desarrollador bajo la misma presión de tiempo e información?
Para saberlo, le he pedido a un amable colaborador que haga el mismo ejercicio disponiendo de la misma información de la que disponía la IA y también que no tardara más de veinte minutos. Obviamente la IA tardó menos, pero creo que vale la pena ver el resultado: lo podéis consultar vosotros mismos en este repositorio.
Ahí podréis comprobar las diferencias de cómo la IA puede hacer cosas mejor o peor que un humano, y también cómo un código realizado por un humano tendrá sesgos y gustos personales. En eso se basa la personalización del código, en saber qué se está haciendo para personalizarlo a tu gusto y tener el control.
Si no se revisan correctamente los resultados, y no se entiende lo que se está adoptando, una mejora puede tener consecuencias catastróficas.
Cloud Híbrida
Ciberseguridad
AI & Data
IoT y Conectividad
Business Applications
Intelligent Workplace
Consultoría y Servicios Profesionales
Pequeña y Mediana Empresa
Sanidad y Social
Industria
Retail
Turismo y Ocio
Transporte y Logística
Energía y Utilities
Banca y Finanzas
Ciudades Inteligentes
Sector Público