AZURE · REALTIME · TRABAJO ASÍNCRONO
Event-driven,
pero con una verdad durable.
Así implementamos una plataforma RAG para sitios web donde el chat debía sentirse inmediato y la ingesta podía durar minutos. La solución no fue convertir todo en eventos: fue elegir dos canales asíncronos distintos y mantener una autoridad clara para el estado.
01 / LA DECISIÓN DE ARQUITECTURA
Dos planos de eventos.
Dos tipos de latencia.
La conversación necesita respuestas de baja latencia sobre conexiones persistentes. El crawling necesita buffering, reintentos y escala independiente. Un solo mecanismo habría mezclado garantías incompatibles.
Azure Web PubSub
Widget ↔ APIMensajes de chat y señales de actualización con baja latencia.
Queue Storage + Functions
API → workerCrawls desacoplados de la request, con reintentos y procesamiento independiente.
Azure SQL + REST
API → clientesEstado consultable y reconciliable después de una desconexión o un evento perdido.
REGLA DE DISEÑONo preguntamos “¿qué servicio de eventos usamos?”. Primero preguntamos “¿este mensaje notifica, ordena trabajo o representa verdad durable?”.
02 / PLANO DE CONVERSACIÓN
Web PubSub mueve la respuesta.
La API conserva el control.
El widget habla por WebSocket, pero no ejecuta lógica de negocio ni accede a modelos o datos. Web PubSub administra las conexiones; la API valida el contexto, orquesta Azure OpenAI, persiste el mensaje y devuelve una respuesta correlacionada.
- 01NEGOTIATE
La API resuelve al visitante y emite una URL de conexión de vida corta.
- 02CREATE MESSAGE
El widget publica un evento con conversación, sesión y hash del mensaje.
- 03ORCHESTRATE
El webhook llega a FastAPI, que ejecuta retrieval y el run de Azure OpenAI.
- 04COMMIT
La respuesta, las fuentes y el costo se guardan antes de entregarse.
- 05CORRELATE
La API publica al cliente original; el hash permite asociar y deduplicar.
03 / PLANO DE INGESTA
La request inicia.
La cola termina el trabajo.
Un crawl usa navegador, descubre enlaces, transforma contenido, genera embeddings y escribe en varios stores. Mantener la request HTTP abierta habría acoplado al operador con el tiempo de ejecución y con cada dependencia externa.
- 01API
Crea GlobalCrawl y LocalCrawl en INPROGRESS.
- 02QUEUE
Publica URL e identificadores de correlación.
- 03FUNCTION
Extrae, descubre y envía el resultado por callback interno.
- 04API
Guarda Markdown, genera metadata, embeddings y vectores.
- 05STATE
Recalcula estados y publica una notificación al panel.
El estado agregado es una función, no un evento
- INPROGRESS
- Si cualquier URL activa sigue procesándose.
- FAILED
- Si ninguna sigue activa y al menos una falló.
- COMPLETED
- Solo cuando todas las URLs activas terminaron.
04 / GARANTÍAS REALES
Diseñá para repetir.
Reconciliá lo que se separa.
Las colas y los canales realtime mejoran desacople y respuesta, pero introducen duplicados, retrasos, fallos parciales y estados intermedios. La confiabilidad aparece cuando esos casos forman parte del contrato.
IDEMPOTENCIA
Normalizar URLs y verificar existencia reduce duplicados. Un recrawl reutiliza la identidad existente. Los callbacks deben tolerar repetición.
CORRELACIÓN
Request ID, hash de mensaje, conexión, conversación, crawl global, crawl local y dequeue count conectan una operación distribuida.
REINTENTOS ACOTADOS
La Function reintenta fallos transitorios; al alcanzar el límite, informa FAILED en lugar de dejar una tarea eternamente pendiente.
RECONCILIACIÓN
SQL es autoridad, pero Blob y el índice vectorial pueden quedar desalineados. Métricas y jobs de reparación deben detectar esa deriva.
SEMÁNTICA HONESTAEl sistema no promete exactly-once. Acepta que una entrega puede repetirse y diseña efectos seguros para at-least-once.
05 / MODOS DE FALLO
La parte difícil aparece
después del happy path.
El valor de la arquitectura se mide por lo que hace cuando un canal, un worker o una escritura externa falla a mitad del recorrido.
Se pierde una notificación
El panel vuelve a consultar REST; el evento acelera la UI, no define el estado.
El worker falla
La cola habilita reintentos. El estado termina en FAILED cuando el presupuesto se agota.
SQL, Blob o vectores divergen
No se declara COMPLETED si falta un artefacto requerido; luego se reconcilian residuos.
Se elimina un crawl activo
La baja lógica no cancela mágicamente una Function en ejecución. Hace falta run ID, señal de cancelación y polling cooperativo.
06 / EL PLAYBOOK
Seis preguntas antes
de elegir el broker.
El producto define las garantías; Azure implementa el canal. Este orden evita usar la misma herramienta para problemas que solo se parecen en un diagrama.
- 01
¿El mensaje notifica un hecho o asigna trabajo?
- 02
¿Quién conserva la fuente de verdad?
- 03
¿Qué pasa si el mensaje llega dos veces?
- 04
¿Qué dato correlaciona todo el recorrido?
- 05
¿Cuándo dejamos de reintentar?
- 06
¿Cómo se detecta y repara un estado parcial?
Los eventos desacoplan.
El estado explica qué ocurrió.
Azure Web PubSub hizo inmediata la conversación. Queue Storage y Functions aislaron el trabajo pesado. Azure SQL mantuvo una historia consultable. La solución funcionó porque cada pieza tuvo una responsabilidad distinta y porque las garantías se diseñaron alrededor de fallos, no solo de flujos.
07 / REFERENCES
Fuentes y contexto
La implementación descripta es una síntesis sanitizada del documento de arquitectura provisto para este artículo. Las referencias externas documentan los servicios y patrones de Azure.