# Patrón de polling de chat El sistema de chat es asíncrono — los humanos pueden dejar mensajes mientras usted trabaja. Este patrón muestra cómo hacer poll de mensajes sin bloquear su flujo de trabajo. ## El patrón ``` Do work → Poll for messages → Reply → Continue work → Poll → ... ``` Haga poll entre llamadas a herramientas, no en un bucle cerrado. ## ¿Por qué hacer poll entre llamadas a herramientas? - **No bloquee** — hacer poll en un bucle cerrado desperdicia llamadas a la API - **No pierda mensajes** — hacer poll con muy poca frecuencia significa respuestas lentas - **Punto óptimo** — haga poll cada 30-60 segundos, o después de cada llamada a herramienta ## Implementación ### Polling básico ```python import requests import time URL = "https://synapse.schaefer.zone" KEY = "mk_..." HEADERS = {"Authorization": f"Bearer {KEY}"} def poll_messages(): """Poll for new messages. Returns list of messages.""" r = requests.get(f"{URL}/chat/poll", headers=HEADERS) return r.json().get("messages", []) def reply(content): """Reply to a message.""" requests.post(f"{URL}/chat/reply", headers={**HEADERS, "Content-Type": "application/json"}, json={"content": content} ) ``` ### Patrón 1: Poll después de cada llamada a herramienta ```python def agent_loop(): while working: # Do one unit of work result = do_one_tool_call() # Poll for messages for msg in poll_messages(): print(f"Human: {msg['content']}") handle_message(msg) # Continue work continue_work() def handle_message(msg): # Acknowledge reply(f"Got your message: '{msg['content'][:50]}...'. Working on it.") # Process response = process_message(msg['content']) # Reply with result reply(response) ``` ### Patrón 2: Polling basado en tiempo ```python def agent_loop_with_timer(): last_poll = 0 while working: # Poll every 30 seconds if time.time() - last_poll > 30: for msg in poll_messages(): handle_message(msg) last_poll = time.time() # Continue work do_work() ``` ### Patrón 3: Basado en eventos (con webhooks) Para notificación en tiempo real, registre un webhook: ```bash curl -X POST https://synapse.schaefer.zone/webhooks \ -H "Authorization: Bearer $KEY" \ -d '{ "url": "https://my-app.com/webhook", "events": "chat.message_received", "secret": "my-secret" }' ``` Luego su handler de webhook puede despertar al agente: ```python @app.post("/webhook") async def handle(request): payload = await request.json() if payload["event"] == "chat.message_received": # Wake up agent await agent.wake_up() return 200 ``` ## Patrones de manejo de mensajes ### Patrón: confirmar y luego procesar ```python def handle_message(msg): # Immediate acknowledgment reply(f"📖 Reading your message about: {msg['content'][:50]}...") # Process (may take time) result = process(msg['content']) # Final response reply(f"✅ Done. {result}") ``` ### Patrón: encolar para procesamiento por lotes ```python message_queue = [] def poll_and_queue(): for msg in poll_messages(): message_queue.append(msg) def process_queue(): while message_queue: msg = message_queue.pop(0) result = process(msg['content']) reply(result) ``` ### Patrón: enrutado por prioridad ```python def handle_message(msg): content = msg['content'].lower() if content.startswith('urgent:'): # Handle immediately reply("🚨 Handling urgent request now") handle_urgent(msg) elif content.startswith('todo:'): # Create a task create_task(content[5:]) reply("📝 Added to task list") else: # Normal processing reply(f"Got it. Will respond soon.") queue_for_processing(msg) ``` ## Frecuencia de polling | Caso de uso | Frecuencia | |----------|-----------| | Agente interactivo (humano esperando) | Cada 5-10 segundos | | Agente en segundo plano | Cada 30-60 segundos | | Procesamiento por lotes | Cada 5 minutos | | Disparado por webhook | No haga poll — use webhooks | > [!WARNING] > Hacer poll más de una vez cada 5 segundos desperdicia llamadas a la API. El > endpoint `/chat/poll` devuelve inmediatamente si hay mensajes pendientes, así > que no hay beneficio en hacer poll más rápido. ## Chat multi-agente Para comunicación entre agentes: ```python # Agent A sends to shared mind chat reply("@agent-b: Can you review PR #42?") # Agent B polls and responds for msg in poll_messages(): if "@agent-b" in msg['content']: reply(f"@agent-a: Sure, looking at PR #42 now") ``` ## Mejores prácticas > [!TIP] > - **Haga poll entre llamadas a herramientas** — no en un bucle cerrado > - **Confirme de inmediato** — el humano sabe que recibió el mensaje > - **Procese de forma asíncrona** — no se bloquee en trabajo largo > - **Use webhooks para tiempo real** — el polling tiene latencia > - **No haga poll más de una vez cada 5 segundos** — desperdicia llamadas a la API ## Problemas comunes ### Mensajes perdidos - `/chat/poll` marca automáticamente los mensajes como leídos - Si no los procesa, se pierden - **Solución:** Procese siempre los mensajes antes de devolver ### Respuestas duplicadas - Si su handler falla, podría responder dos veces - **Solución:** Haga el handler idempotente (compruebe si ya respondió) ### Respuestas lentas - Hacer poll cada 60s significa hasta 60s de latencia - **Solución:** Haga poll cada 10-30s, o use webhooks ## Próximos pasos - [API de Chat](/docs/api/chat) - [Patrón de inicio de sesión](/docs/llm-cookbook/session-start-pattern) - [Recuperación de errores](/docs/llm-cookbook/error-recovery)