Rembrr es un asistente de voz y chat que ejecuta tareas sobre cuentas conectadas: leer y redactar en Gmail, agendar en Calendar, consultar Drive, buscar en la web con citas y gestionar tareas.
Mi parte: el backend de voz y agentes en tiempo real — el pipeline que sostiene una conversación en vivo, la capa de tool calling, la memoria a largo plazo y el cifrado de secretos. La app móvil y la automatización las lleva el resto del equipo. En el producto desde septiembre de 2025.
En producción: App Store · Google Play · rembrr.net.
El problema
Un pipeline STT → LLM → TTS se siente lento y se rompe con interrupciones. Gemini Live no permite mezclar google_search con function_declarations. Los tokens de Gmail y Calendar no pueden ir en claro. La memoria no puede inflar el request de voz.
Arquitectura
App Flutter
→ LiveKit (audio / WebSocket proxy)
→ Gemini Multimodal Live
→ tool dispatcher (FastAPI)
→ Gmail / Calendar / Drive / Tasks
→ sub-agente de búsqueda (REST, modelo solo-search)
→ RAG: embeddings Gemini + pgvector + ranking híbrido
(extracción de hechos en background)
→ secretos: envelope KEK/DEK, AES-256-GCM, KEK en Cloud KMS
Voz en tiempo real
La voz corre sobre Gemini Multimodal Live en vez de una cascada STT → LLM → TTS: menos hops, menos latencia acumulada y barge-in nativo. El audio viaja por LiveKit.
Memoria a largo plazo (RAG)
Embeddings de Gemini sobre pgvector y ranking híbrido (denso + léxico). La extracción de hechos corre fuera del request para no sumar latencia. La recuperación se inyecta como contexto acotado por relevancia, no como historial completo.
Decisiones
- Sub-agente de búsqueda aislado — un camino REST corre el modelo solo con búsqueda y devuelve
{ respuesta, citas }. Voz y chat citan fuentes sin romper function calling. - Cifrado envelope con KMS — tokens de cuentas conectadas cifrados en aplicación (KEK/DEK, AES-256-GCM); la KEK vive en Cloud KMS.
- Prompts como datos — de f-strings a un loader en Supabase, editables sin redeploy.
- Ciclo de vida de conexión explícito — en voz realtime, controlar la sesión pesa más que un servicio gestionado opaco.
Qué descarté
- Historial completo en el prompt vs. contexto acotado por relevancia.
- Extraer hechos en el request de voz vs. un job en background.
- Un único modelo con search + tools vs. un sub-agente de búsqueda separado (la API no lo permite).
Operación
El trabajo continuo es latencia de turno, estabilidad de sesiones LiveKit y evolución de tools. Los prompts se editan sin redeploy. Los secretos no viajan en plaintext. Si Gemini o LiveKit fallan, la sesión tiene un ciclo de vida explícito — no un socket “hasta que se caiga”.
Sistemas similares (voz + tools + memoria + secretos) se pueden encargar. Rembrr es un producto existente; yo construí esta capa.
