La optimistic UI con agentes de IA solo funciona si deshacer es real

La optimistic UI aplicada a las acciones de un agente de IA es una forma de dar respuesta visual que enseña el resultado del trabajo del agente antes de que el servidor lo confirme, y solo es honesta si el producto puede deshacer ese resultado. Un botón de "me gusta" puede cambiar en 50 milisegundos porque la petición casi nunca falla y, cuando falla, no cuesta nada. Un agente que reembolsa un pedido, escribe al cliente y cierra el ticket no hace nada de eso en 50 milisegundos. Falla más a menudo y deja efectos fuera del producto que ninguna vuelta atrás del estado puede alcanzar.
Este artículo es para equipos de producto que están metiendo agentes en un SaaS y quieren que la pantalla reaccione en cuanto el usuario pide algo, sin escribir nunca "Hecho" sobre algo que no ha pasado. La regla que seguimos cabe en una línea: la intención se enseña al momento, un efecto solo cuando ya ha ocurrido.
¿Por qué un agente rompe la optimistic UI?
La optimistic UI clásica se apoya en tres supuestos. El servidor responde rápido. La petición casi siempre sale bien. Un error cuesta poco, porque deshacerlo es volver a poner en pantalla el valor anterior. Las acciones de un agente desmienten los tres.
Primero, la velocidad. Los tres límites de tiempo de respuesta de Nielsen Norman Group siguen describiendo bien el problema: 0,1 segundos dan la sensación de que el usuario ha causado el resultado, 1 segundo no corta el hilo del pensamiento y 10 segundos son más o menos el límite para mantener la atención en la tarea. A partir de ahí, dice el mismo artículo, el usuario necesita saber cuándo terminará el trabajo, y esa información pesa más cuando los tiempos varían mucho. La ejecución de un agente es variable por definición: la misma petición puede pedir una llamada a una herramienta o doce.
Después, la probabilidad de éxito. Una ejecución falla cuando el modelo entiende mal la petición, cuando una herramienta agota el tiempo, cuando falta un permiso. Cada paso es otra ocasión de fallar, así que una ejecución de siete pasos falla más a menudo que una sola escritura en tu propia base de datos.
Por último, la vuelta atrás, y es lo que más duele. useOptimistic de React enseña un valor temporal mientras una Action está en curso. Si la Action lanza un error, la Transition termina y React vuelve a pintar el valor real: el elemento optimista desaparece. La documentación deja en tus manos avisar al usuario. La pantalla vuelve atrás; la explicación no llega con ella. Y si el paso era un email que ya ha salido, volver a pintar el valor anterior no cambia nada en la bandeja del cliente.
Por qué un spinner tampoco lo arregla
La salida más habitual es un solo indicador de "Pensando..." para toda la ejecución. Es honesto y no sirve de nada. Cuarenta segundos de la misma animación no dicen qué paso está en marcha, no dan nada que cancelar e invitan a pulsar otra vez, lo que lanza una segunda ejecución. Escribir "Hecho" antes de tiempo es útil y falso. Las prácticas que siguen quedan en medio.
Clasificar cada acción según lo que cuesta deshacerla
Antes de diseñar ninguna pantalla, las acciones que el agente puede hacer se reparten en tres clases. La clase decide qué puede enseñar la interfaz antes de la confirmación.
| Clase | Ejemplos | Qué enseña la pantalla al momento | Cómo se deshace |
|---|---|---|---|
| Local y reversible | Redactar un borrador, etiquetar un registro, reordenar una lista dentro del producto | El resultado, al instante | Se recupera el estado anterior y se explica por qué |
| Envío diferido | Enviar un email, publicar un mensaje, programar una reunión | El efecto como pendiente, con cuenta atrás y botón de Deshacer | Se cancela antes de que cierre la ventana: todavía no ha salido nada |
| Externa e irreversible | Cobrar o reembolsar una tarjeta, borrar datos en otro sistema | El plan, después una confirmación, después el progreso real | Tras el envío no hay vuelta atrás: solo una segunda acción que compense |
Casi todos los problemas vienen de tratar una acción de clase 3 con la respuesta visual de una de clase 1. Las seis prácticas que siguen aplican la tabla.
1. Ser optimista con el plan
En menos de 100 milisegundos desde la petición, la pantalla enseña el plan del agente como una lista de pasos marcados como "previsto". Eso afirma algo cierto: la petición ha llegado y el agente sabe cómo tratarla. Sobre los resultados no afirma nada. Victor Yocco, en sus patrones para IA agéntica en Smashing Magazine, lo llama Intent Preview y lo sitúa antes de que el agente actúe, junto al Autonomy Dial, el control de cuánto puede hacer el agente sin preguntar. Si el modelo todavía no ha generado un plan, la primera línea repite la propia petición. La pantalla se mueve y nada de lo que enseña es falso.
2. Un estado para cada paso
Los estados son cinco: previsto, en curso, hecho, fallido, omitido. El servidor los envía uno a uno, en cuanto un paso cambia, y la lista se va llenando mientras el usuario mira. Una ejecución de siete pasos se lee como "paso 3 de 7, buscando el pedido", que responde a la pregunta de NN/g sobre cuándo terminará mejor que una barra de porcentaje, porque nadie sabe cuánto tardará el paso 5. Un solo spinner esconde justo lo que hace falta cuando la ejecución falla: dónde se ha parado.
3. Una ventana de espera para todo lo que sale del producto
La función para anular el envío de Gmail deja elegir un plazo de 5, 10, 20 o 30 segundos. Funciona porque el mensaje todavía no ha salido: Gmail espera antes de entregarlo. Los agentes necesitan el mismo mecanismo. El efecto hacia fuera entra en una cola, la pantalla lo enseña como "Enviando al cliente en 10 s" con el botón de Deshacer, y el envío se hace cuando acaba el tiempo. Deshacer es real porque todavía no ha pasado nada. Recuperar un mensaje ya entregado es otra función, mucho más débil.
4. Pedir confirmación antes de los efectos irreversibles
OpenAI lo metió en Operator: el agente pide confirmación antes de cerrar tareas con efectos externos, como confirmar un pedido o enviar un email. Las pautas de interacción entre personas e IA de Microsoft recogen el caso general en la G10: cuando el sistema no tiene claro el objetivo del usuario, pregunta antes de actuar. Un efecto irreversible es donde esa duda sale más cara. La confirmación nombra el efecto exacto: el importe, el destinatario, la cuenta. En una operación por lotes se pregunta una sola vez, con la lista completa, así que 40 reembolsos son una decisión y no 40 interrupciones.
5. Hacer seguro el reintento antes de hacer rápido el botón
Una respuesta rápida invita a reintentar, y quien duda pulsa otra vez. Cada acción del agente lleva una clave de idempotencia, creada junto con el plan, para que una ejecución repetida use la misma clave. Las peticiones idempotentes de Stripe enseñan el contrato: un reintento con la misma clave dentro de las 24 horas devuelve el primer resultado, y pasado ese plazo las claves se pueden eliminar. Sin clave, una pantalla optimista y un usuario nervioso acaban en un reembolso doble.
6. Cuando un paso falla, deshacerlo en pantalla y decir qué ha pasado
La pauta G9 de Microsoft pide facilitar la corrección: editar, ajustar o recuperar cuando el sistema se equivoca. En una ejecución eso significa que el paso fallido se pone en rojo con el motivo en palabras sencillas, los pasos ya hechos siguen marcados como hechos (el email ha salido, el reembolso no), los que dependían de él pasan a omitidos, y la pantalla ofrece una sola acción: reintentar el paso, cambiar la petición o pasársela a una persona. Para las palabras exactas está nuestro artículo sobre estados de error en UX.
Cómo se ve en una pantalla real
Pongamos un agente de soporte hipotético dentro de un software de helpdesk. El usuario escribe: "Reembolsa el pedido 4417 y avisa al cliente".
- A los 0,1 segundos aparece un plan: buscar el pedido 4417, reembolsar 84,00 € a la tarjeta guardada, escribir al cliente, cerrar el ticket. Los cuatro pasos aparecen como "previstos".
- El paso 1 arranca y queda hecho en unos dos segundos. Solo lee datos, así que no hay nada que proteger.
- El paso 2 se detiene en una confirmación con el importe y los cuatro últimos dígitos de la tarjeta. El usuario confirma. El reembolso sale con la clave de idempotencia creada junto con el plan, y el paso queda hecho cuando el proveedor de pagos confirma el reembolso, no cuando sale la petición.
- El paso 3 enseña "Enviando al cliente en 10 s" con el botón de Deshacer. El email espera en la cola detrás del paso 2.
- El paso 4 cierra el ticket. Vive dentro del producto y se puede reabrir, así que la pantalla lo enseña cerrado al momento.
Si el reembolso falla, el paso 2 queda como fallido con el motivo que da el proveedor, los pasos 3 y 4 pasan a omitidos y el email no sale nunca, porque estaba en cola detrás de un paso que no terminó. El usuario tiene delante una sola cosa que decidir.
Lo que cuesta este enfoque
Tres costes que conviene conocer antes de adoptarlo. La ventana de espera suma su duración a cada envío: con 10 segundos, cada email que escribe el agente llega 10 segundos más tarde. Las confirmaciones frenan a quien más usa el agente; la solución es un ajuste de autonomía con el que un equipo aprueba de antemano una clase de acciones, por ejemplo los reembolsos de menos de 50 €, y deja las confirmaciones para el resto. Y enviar el estado de cada paso pide un backend que emita un evento por paso, más trabajo que una petición y una respuesta. Si tu agente todavía es un único prompt detrás de un botón, las decisiones que van antes están en nuestro artículo sobre agentes de IA dentro de un SaaS.
A cambio, la pantalla reacciona en 100 milisegundos y nunca dice algo que el sistema tendrá que retirar después.
Preguntas frecuentes
Sí, mientras el texto se quede dentro del producto. Un borrador que escribe el agente es una acción local y reversible: se enseña al momento y sigue siendo un borrador hasta que el usuario lo acepta. Enseñar los tokens mientras el modelo los genera es progreso real, así que no hace falta ningún optimismo. La línea se cruza cuando el texto sale del producto, como email, mensaje o publicación. A partir de ahí es un envío diferido y lleva una cuenta atrás con Deshacer.
Gmail ofrece 5, 10, 20 o 30 segundos para anular un envío, un rango útil para empezar. Conviene la ventana más corta en la que los usuarios todavía se dan cuenta del error, y medir cuántas veces pulsan Deshacer y en qué segundo. Las operaciones por lotes merecen una ventana más larga que los envíos sueltos, porque un error se repite en cada elemento. Los pagos y los borrados no deben depender de una ventana: llevan una confirmación explícita antes de que salga nada.
No puede deshacerla, así que ofrece la acción que compensa: un reembolso para un cobro equivocado, una rectificación para un email equivocado, una restauración desde copia para un borrado equivocado. La acción original y la de corrección quedan en un registro que el usuario puede abrir, el patrón Action Audit and Undo que describe Smashing Magazine para productos agénticos. En pantalla, la segunda acción se marca como corrección para que nadie la lea como un evento nuevo y aparte. Y toca revisar por qué la confirmación no lo detectó.
Solo para el primer instante. useOptimistic mantiene un valor temporal mientras una Action está pendiente y lo suelta cuando la Action termina, así que encaja con la repetición del plan que aparece en los primeros 100 milisegundos. Una ejecución que dura minutos, sobrevive a una recarga de la página o sigue mientras el usuario trabaja en otra cosa necesita su estado guardado en el servidor y enviado al cliente paso a paso. La lista de pasos se pinta desde ese estado, y useOptimistic se queda para la respuesta inmediata.
Artículos relacionados
23 de mayo de 2026 · 7 min de lectura
12 de julio de 2026 · 7 min de lectura
11 de octubre de 2026 · 9 min de lectura