Ir al contenido principal
Laravel, thinking fast.
Prefacio

Qué pasa cuando los ignoras

Julian Beaujardin

Puedo describir el fallo con precisión, porque he visto cada una de sus partes.

El SDK del proveedor va directo a un controlador, porque es lo que hacía el tutorial. Seis semanas después el proveedor cambia el nombre de un campo y el fallo aparece en cuatro funciones sin relación entre sí, porque no hay un único sitio donde se describa al proveedor.

Nadie pone tope a los tokens de salida, así que una respuesta se corta a media frase. No hay ninguna comprobación de por qué se detuvo, de modo que la media frase se muestra como si fuera una respuesta completa, y un usuario lee algo seguro de sí mismo, equivocado y sin terminar.

La petición se ejecuta en el proceso web, porque en desarrollo funcionaba. En producción tarda noventa segundos, retiene un worker de PHP todo ese rato y muere en el balanceador con un 504 —después de haber pagado el modelo.

El navegador llama directamente al servicio de IA, porque así había un salto menos. Ahora la credencial está en el cliente, el endpoint acepta cualquier cosa y tu gasto con el proveedor sólo está limitado por la paciencia de quien lo encuentre.

Y en algún punto de todo esto, un modelo al que se le ha dicho «crea un solo sitio por usuario» crea dos —porque se lo pidieron dos veces, con educación, y no había nada más que la instrucción para impedirlo.

Ninguno de esos es un fallo exótico. Todos son un martes cualquiera.

Cómo aprendí esto

La primera versión de nuestro agente funcionó a la primera, y ese fue el problema.

Era un chat. Le contabas cuál era tu negocio y te construía una web. En la demo resultaba genuinamente encantador. Hacía buenas preguntas, tomaba decisiones razonables y, más o menos un minuto después, había un sitio real en una URL real. Se lo enseñamos a todo el mundo.

Lo primero que se rompió fue el tiempo. Un turno en el que el modelo usaba varias herramientas pasaba holgadamente del minuto, y todo aquello corría dentro de la petición HTTP. Los usuarios miraban un indicador de carga hasta que algo más arriba se rendía, y entonces no veían nada: ni error, ni respuesta parcial, ni sitio, pese a que ya habíamos pagado cada token. El trabajo estaba hecho. Sencillamente no teníamos dónde ponerlo.

Así que lo movimos a la cola, y se rompió lo segundo: el job tenía un tiempo de espera y un turno largo lo alcanzaba. El job moría a mitad de turno sin haber escrito nada, mientras el widget consultaba educadamente una clave de caché que nunca iba a aparecer. El usuario se quedaba delante de un chat que simplemente había dejado de hablar.

Luego un turno volvió truncado. Habíamos puesto tope a los tokens de salida, con buen criterio, pero nunca mirábamos por qué se había detenido el modelo. Una respuesta cortada caía por la misma rama que una terminada y se mostraba como una respuesta. Se leía bien. Estaba mal.

Después un usuario pulsó el botón dos veces.

La herramienta que crea un sitio tenía escrito, en su propia descripción, que sólo debía hacerlo una vez. Y esa instrucción se cumplió a la perfección, hasta que llegaron dos peticiones lo bastante seguidas como para que «una vez» fuera ambiguo. Dos aprovisionamientos para una sola persona. El arreglo no fue una instrucción mejor. El arreglo fue un índice único.

Ninguno de estos era un problema del modelo. El modelo estaba bien. Cada uno de los fallos estaba en el código que lo rodeaba, y cada arreglo fue algo que yo ya sabía hacer —sólo que nunca se me había ocurrido hacerlo aquí, porque esta parte venía disfrazada.

Por eso los capítulos de este libro son como son. No van de escribir prompts. Van de colas, plazos, índices únicos, fronteras de confianza y registros estructurados, aplicados a un componente que resulta ser no determinista.

Qué significa «thinking fast»

El título no va de latencia, ni de lo rápido que responde el modelo.

Significa lo mismo que significaba «shipping fast» en el libro anterior: tomar una decisión una vez, al nivel correcto, para no tener que volver a tomarla. Dónde vive el proveedor. Dónde viven los prompts. Cuánto puede costar un turno. Qué pasa cuando el modelo se equivoca. Decide eso una vez, aplícalo en todas partes, y añadir tu quinta función de IA costará una fracción de lo que costó la primera.

La alternativa es una base de código donde cada función de IA es un caso especial con su propia política de reintentos, su propia idea de lo que es un tiempo de espera, su propio manejo de credenciales y su propio modo de fallar. Eso no es rápido. Eso son cuatro funciones y cuatro caídas.

Lo aburrido escala. Lo ingenioso se descompone. Era cierto antes de que hubiera un modelo en el bucle, y el modelo no lo ha derogado.