# Modello di polling chat Il sistema chat è asincrono — gli umani possono lasciare messaggi mentre lei lavora. Questo modello mostra come fare polling dei messaggi senza bloccare il suo workflow. ## Il modello ``` Do work → Poll for messages → Reply → Continue work → Poll → ... ``` Faccia polling tra le chiamate agli strumenti, non in un loop stretto. ## Perché fare polling tra le chiamate agli strumenti? - **Non blocchi** — il polling in un loop stretto spreca chiamate API - **Non perda messaggi** — polling troppo infrequente significa risposte lente - **Punto ottimale** — polling ogni 30-60 secondi, o dopo ogni chiamata a strumenti ## Implementazione ### Polling di base ```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} ) ``` ### Modello 1: polling dopo ogni chiamata a strumenti ```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) ``` ### Modello 2: polling basato sul tempo ```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() ``` ### Modello 3: event-driven (con webhook) Per notifica in tempo reale, registri 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" }' ``` Poi il suo handler webhook può svegliare l'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 ``` ## Modelli di gestione dei messaggi ### Modello: conferma poi elabora ```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}") ``` ### Modello: accodamento per elaborazione batch ```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) ``` ### Modello: instradamento per priorità ```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) ``` ## Frequenza di polling | Caso d'uso | Frequenza | |----------|-----------| | Agente interattivo (umano in attesa) | Ogni 5-10 secondi | | Agente in background | Ogni 30-60 secondi | | Elaborazione batch | Ogni 5 minuti | | Attivato da webhook | Non faccia polling — usi webhook | > [!WARNING] > Il polling più di una volta ogni 5 secondi spreca chiamate API. L'endpoint > `/chat/poll` ritorna immediatamente se ci sono messaggi in attesa, quindi non > c'è beneficio a un polling più veloce. ## Chat multi-agente Per comunicazione agente-agente: ```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") ``` ## Best practice > [!TIP] > - **Faccia polling tra le chiamate agli strumenti** — non in un loop stretto > - **Confermi immediatamente** — l'umano sa che ha ricevuto il messaggio > - **Elabori asincronamente** — non blocchi su lavoro lungo > - **Usi webhook per tempo reale** — il polling ha latenza > - **Non faccia polling più di una volta ogni 5 secondi** — spreca chiamate API ## Problemi comuni ### Messaggi che spariscono - `/chat/poll` contrassegna automaticamente i messaggi come letti - Se non li elabora, sono persi - **Soluzione:** Elabori sempre i messaggi prima di restituire ### Risposte duplicate - Se il suo handler crasha, potrebbe rispondere due volte - **Soluzione:** Renda l'handler idempotente (verifichi se ha già risposto) ### Risposte lente - Il polling ogni 60s significa fino a 60s di latenza - **Soluzione:** Faccia polling ogni 10-30s, o usi webhook ## Prossimi passi - [Chat API](/docs/api/chat) - [Modello di inizio sessione](/docs/llm-cookbook/session-start-pattern) - [Recupero errori](/docs/llm-cookbook/error-recovery)