Cuando el asistente dice «vale, lo miro» antes de responder
Hasta el 12 de mayo, entre el momento en que soltabas el botón y el momento en que la voz respondía, la pantalla no mostraba nada. Cinco, diez, a veces quince segundos sin una señal, y la aplicación parecía colgada. Ese día se dedicó a esos silencios: halos que reaccionan a la voz, un estado «estoy pensando» que mantiene el orbe encendido, una burbuja retirada y una frase breve, «vale, lo miro», que el asistente dice enseguida cuando la respuesta va a tardar.
Una pantalla que no tiene otra cosa que hacer que tranquilizar
La aplicación tiene una sola pantalla, y en esa pantalla, un orbe. Cuando diseñamos esta interfaz para que no se viera, aceptamos una contrapartida: todo lo que hace la aplicación tiene que poder leerse en ese orbe, o en ningún sitio. Una aplicación corriente dispone de una rueda que gira, una barra de progreso, un botón en gris. Aquí solo hay el movimiento de una forma y una voz.
Mientras la conversación cabía en un intercambio corto, bastaba. Mantienes el botón, hablas, sueltas, la respuesta llega uno o dos segundos después. Pero en cuanto la petición exigía una búsqueda, una receta, un lugar, una avería que diagnosticar, la respuesta tardaba de cinco a siete segundos en arrancar. Y cuando la transcripción, el modelo y la síntesis de voz se sumaban, podías esperar quince segundos sin que se moviera un píxel. La pantalla volvía al reposo en el instante en que el dedo dejaba el botón, exactamente como si nadie hubiera oído nada.
La pregunta que plantearon las primeras pruebas cabía en una frase: «¿se ha colgado o está trabajando?». Se tocaba la pantalla, se cerraba una ficha, se repetía la petición. Y a veces la respuesta llegaba mientras se estaba repitiendo.
Ese 12 de mayo, entre dos pruebas de fotos para las fichas, se dedicó por tanto a esos silencios. Cuatro cambios, dos en la pantalla, dos en la voz, y un quinto para el caso en que de verdad no hay nada que decir.
Final de la mañana: bordes que se encienden con la voz
La primera señal que faltaba era la más simple. Mientras hablas, nada mostraba que el micrófono estuviera oyendo. El orbe latía a su ritmo, el mismo que en reposo.
A última hora de la mañana aparecieron dos bandas de luz a lo largo de los bordes izquierdo y derecho de la pantalla. Son azules mientras el usuario habla, y su intensidad no es una animación: sale del nivel sonoro medido por el micrófono varias veces por segundo, convertido de una medida en decibelios a un valor entre cero y uno, y luego suavizado para que el halo respire en lugar de parpadear. Cuando subes la voz, los bordes se encienden. Cuando te callas buscando una palabra, se calman sin apagarse. El botón mantenido y los bordes que siguen la voz dicen lo mismo: te oigo, sigue.
Para la voz del asistente no disponemos del mismo dato. El reproductor de audio que reproduce la respuesta no devuelve amplitud en tiempo real. En vez de inventar un nivel falso, los halos adoptan una oscilación estilizada, un ritmo cercano al habla, unos tres ciclos por segundo, en otro color. El resultado dice «está hablando» sin pretender medir el volumen. Es un compromiso asumido: un halo que latiera al ritmo de una voz real sería más exacto, pero un halo que late a un ritmo de voz ya es honesto.
Un detalle de fontanería importaba para que el efecto aguantara. La medida del micrófono no atraviesa el código de la aplicación en cada lectura: se deposita en un valor compartido que el motor de animación lee directamente en el hilo de dibujo. Sin ese atajo, cada lectura habría hecho un viaje de ida y vuelta más, y un halo que sigue la voz con retraso ya no sigue nada.
Mediodía: rectángulos azules en lugar de halos
La primera prueba en el teléfono mostró algo distinto de unos halos. Dos rectángulos azules, llenos, opacos, que se solapaban en el centro de la pantalla. La conversación era ilegible detrás.
La causa estaba en el degradado. La primera versión dibujaba los halos con un degradado radial vectorial cuyos radios horizontal y vertical se daban en porcentaje del área. En Android, esa forma de escribir los radios no se entiende: la biblioteca abandona el degradado y rellena todo el rectángulo con el color inicial. El mismo código, y el resultado era una placa.
Los halos se rehicieron en el motor de dibujo que ya renderiza el orbe. Solo conoce degradados radiales circulares; para obtener una elipse, se aplica al propio degradado una transformación que lo estira en vertical, sin tocar la geometría del rectángulo que lo sostiene. Lo que sale es un fundido elíptico, fiable en los teléfonos probados, con las dimensiones de la maqueta: cada halo ocupa algo más de la mitad del ancho de la pantalla y desborda por arriba y por abajo, para que el resplandor parezca venir de detrás del borde y no de un objeto puesto encima. El volumen no cambia el tamaño del halo, solo su opacidad: agrandar una forma en cada lectura habría costado caro en cálculo y dado un efecto de bombeo desagradable.
La paleta se revisó de paso. El azul sigue siendo el del usuario. Para el asistente, el cian inicial dejó paso a un resplandor más cálido, el mismo que el del halo del orbe cuando habla, de modo que el orbe y los bordes cuentan juntos la misma fase.
El estado que no existía: «estoy pensando»
El silencio más largo no era durante el habla. Empezaba al soltar el botón.
La pantalla conocía cuatro estados: el reposo, la escucha, el habla del asistente y la escritura con el teclado. Entre la escucha y el habla, nada. El dedo deja el botón, la grabación sale, la transcripción vuelve, el modelo razona, llama a sus herramientas, la síntesis de voz fabrica el audio, y durante todo ese tiempo el estado era «reposo». El orbe volvía a subir al centro y latía tranquilo, como antes de que le hablaran. De cinco a quince segundos de calma perfecta, justo cuando la aplicación más trabajaba.
Se añadió un quinto estado: «pensando». Se activa en el instante en que el mensaje del usuario se posa en el hilo, venga de la voz o del teclado. El orbe baja al fondo de la pantalla, al lugar que ocupa cuando el asistente habla, con una leyenda debajo: «estoy pensando…». Los halos laterales siguen encendidos, en el tono cálido del asistente, y siguen respirando despacio. El teclado se repliega si estaba abierto, para que el orbe quede visible. Y un toque en el orbe interrumpe, el mismo gesto que en mitad de una respuesta hablada, para que el usuario conserve el control en todo momento.
Dos detalles de transición importaban. Primero, solo se entra en «pensando» desde el reposo o la escucha: si una transcripción tardía llega cuando el asistente ya está hablando, no debe pisar esa fase. Segundo, se sale en cuanto llega el texto de la respuesta, y no cuando arranca el audio. Si el sonido está activado, la reproducción toma el relevo de inmediato y el orbe pasa a «hablando» sin que se vea la costura. Si el sonido está silenciado, no hay reproducción, y sin esa salida el orbe se habría quedado abajo pensando para siempre.
Tarde: una burbuja de más
El principio de la tarde estuvo ocupado por las fichas y sus imágenes. Al volver a la conversación, algo saltó a la vista: durante el dictado, una pequeña burbuja bajo el orbe decía «te escucho». Se había puesto ahí cuando era la única señal de que el micrófono estaba en marcha. Desde la mañana, los bordes de la pantalla decían lo mismo, y mejor, porque seguían la voz.
Dos señales para una sola información es una de más. La burbuja se retiró. La transcripción parcial que la alimentaba se sigue calculando, por si algún día sirve en otro sitio, pero ya no se muestra. Es la lección inversa del resto del día: decir lo que se hace no significa decirlo dos veces.
«Vale, lo miro»: la palabra de espera
Quedaba el silencio más incómodo, el que la pantalla sola no podía llenar.
Cuando una petición exige una búsqueda en la web, el modelo encadena varias herramientas antes de redactar: primero consulta la memoria, lanza la búsqueda, a menudo guarda el resultado en una ficha y solo entonces escribe su respuesta, que después pasa a la síntesis de voz. De cinco a siete segundos entre el final de la frase del usuario y la primera palabra del asistente. El estado «pensando» muestra que algo está en marcha, pero en una conversación siete segundos de silencio siguen siendo largos. Entre personas, nadie se calla siete segundos antes de responder: se dice «espera, lo miro».
Eso es lo que hace el asistente desde aquella tarde. El director de orquesta del lado del servidor, el que hace funcionar el modelo y ejecuta sus herramientas, observa la primera decisión del modelo. Si esa primera decisión incluye una búsqueda web, la única herramienta de la cadena que tarda sistemáticamente más de un segundo, dispara de inmediato una frase corta: «Vale, lo miro, dame un momento». Existen cinco variantes, sorteadas cada vez, «Un segundo, estoy buscando», «Me encargo, dos segundos», para que no se oiga la misma fórmula en cada búsqueda. Son cortas a propósito: el usuario solo necesita saber que la cosa avanza.
Lo importante es que esta frase no cuesta tiempo. El servidor no la espera: lanza la síntesis de la frase y, en paralelo, ejecuta las herramientas. El texto sale hacia el teléfono de inmediato, el audio le sigue medio segundo después, y mientras tanto la búsqueda ya está en curso. Cuando llega la respuesta de verdad, llega en el mismo momento que antes; simplemente, el silencio que la precedía se ha llenado. Para seguir siendo ágil, la frase de espera usa la voz pedida por el teléfono sin ir a releer las preferencias en la base de datos, al contrario que la respuesta final. Y si el usuario ha silenciado el sonido, ve la frase en el hilo sin que se fabrique ningún audio para nada.
Podríamos haber disparado esta palabra de espera en todas las peticiones. No lo hicimos: una herramienta sola responde en menos de medio segundo, y una frase de espera delante de una respuesta inmediata habría vuelto charlatán al asistente. La palabra de espera queda reservada al caso en que la espera existe.
Y cuando de verdad no hay nada que decir
Un último silencio se trató esa misma mañana, unos minutos antes de los halos, porque pertenecía a la misma familia: aquel en que el modelo no responde en absoluto.
Tres situaciones lo producían. El modelo se cae a mitad de camino, un error de red o un servidor remoto que rechaza. El modelo entra en bucle, llama a herramientas una y otra vez y alcanza el límite de iteraciones sin concluir nunca con texto. O el modelo devuelve una cadena vacía, algo que ocurre más a menudo de lo que se pensaría. En los tres casos el orbe se quedaba mudo, y el usuario no tenía manera de distinguir una avería de una espera.
Ahora cada uno de esos casos produce una frase hablada, distinta según la causa: un problema técnico de nuestro lado, un error al intentar hacer lo que se pedía, o una respuesta que no se pudo completar, siempre con la invitación a intentarlo de nuevo o a reformular. Si una herramienta ha fallado pero el modelo ha explicado él mismo el problema, conservamos su explicación, siempre más precisa que una fórmula hecha. La respuesta de emergencia no está para quedar bien: está para que el orbe nunca se calle sin un motivo dicho.
Lo que enseñó el día
Una aplicación sin pantalla de navegación no puede permitirse el silencio. Cada segundo en que nada se mueve es un segundo en que el usuario se pregunta si debe empezar de nuevo, y empezar de nuevo es el peor de los escenarios: dos peticiones en vuelo, dos respuestas, una ficha duplicada.
Ese 12 de mayo repartió la respuesta entre la pantalla y la voz. La pantalla dice la fase: te escucho, con bordes que siguen la voz; estoy pensando, con un orbe que sigue encendido; hablo, con un resplandor cálido. La voz dice la espera cuando va a ser larga, y dice el fallo cuando ocurre. Ninguna de esas señales añade latencia, y ninguna miente: el halo del asistente no pretende medir su voz, la frase de espera no promete nada más que una búsqueda en curso.
Es la regla que hemos conservado desde entonces para todo lo que toca a la voz y la conversación: un asistente que trabaja debe mostrarlo, un asistente que espera debe decirlo, y un asistente que falla también debe decirlo. Lo demás, la memoria, las fichas, las búsquedas, solo vale algo si mientras tanto no has cerrado la aplicación creyéndola muerta.
