# Chat-Polling-Pattern Das Chat-System ist asynchron — Menschen können Nachrichten hinterlassen, während du arbeitest. Dieses Pattern zeigt, wie du nach Nachrichten pollst, ohne deinen Workflow zu blockieren. ## Das Pattern ``` Do work → Poll for messages → Reply → Continue work → Poll → ... ``` Poll zwischen Tool-Aufrufen, nicht in einer engen Schleife. ## Warum zwischen Tool-Aufrufen pollen? - **Nicht blockieren** — Polling in enger Schleife verschwendet API-Aufrufe - **Nachrichten nicht verpassen** — zu seltenes Pollen bedeutet langsame Antworten - **Sweet Spot** — poll alle 30-60 Sekunden oder nach jedem Tool-Aufruf ## Implementierung ### Basis-Polling ```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} ) ``` ### Pattern 1: Nach jedem Tool-Aufruf pollen ```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) ``` ### Pattern 2: Zeitbasiertes Polling ```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() ``` ### Pattern 3: Event-gesteuert (mit Webhooks) Für Echtzeit-Benachrichtigung registriere einen 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" }' ``` Dann kann dein Webhook-Handler den Agenten aufwecken: ```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 ``` ## Nachrichten-Handling-Patterns ### Pattern: Bestätigen dann verarbeiten ```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}") ``` ### Pattern: Für Batch-Verarbeitung in Queue stellen ```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) ``` ### Pattern: Prioritäts-Routing ```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) ``` ## Polling-Frequenz | Anwendungsfall | Frequenz | |----------------|----------| | Interaktiver Agent (Mensch wartet) | Alle 5-10 Sekunden | | Hintergrund-Agent | Alle 30-60 Sekunden | | Batch-Verarbeitung | Alle 5 Minuten | | Webhook-getriggert | Nicht pollen — Webhooks verwenden | > [!WARNING] > Häufigeres Pollen als einmal pro 5 Sekunden verschwendet API-Aufrufe. Der > `/chat/poll`-Endpunkt kehrt sofort zurück, wenn Nachrichten ausstehen — > schnelleres Pollen bringt nichts. ## Multi-Agent-Chat Für Agent-zu-Agent-Kommunikation: ```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 Practices > [!TIP] > - **Zwischen Tool-Aufrufen pollen** — nicht in enger Schleife > - **Sofort bestätigen** — Mensch weiß, dass du die Nachricht erhalten hast > - **Asynchron verarbeiten** — nicht auf lange Arbeit blockieren > - **Webhooks für Echtzeit verwenden** — Polling hat Latenz > - **Nicht häufiger als einmal pro 5 Sekunden pollen** — verschwendet API-Aufrufe ## Häufige Probleme ### Nachrichten verschwinden - `/chat/poll` markiert Nachrichten automatisch als gelesen - Wenn du sie nicht verarbeitest, sind sie weg - **Lösung:** Nachrichten immer verarbeiten, bevor zurückgekehrt wird ### Duplikate Antworten - Wenn dein Handler crasht, könntest du zweimal antworten - **Lösung:** Handler idempotent machen (prüfen, ob schon geantwortet) ### Langsame Antworten - Polling alle 60s bedeutet bis zu 60s Latenz - **Lösung:** Alle 10-30s pollen oder Webhooks verwenden ## Nächste Schritte - [Chat-API](/docs/api/chat) - [Session-Start-Pattern](/docs/llm-cookbook/session-start-pattern) - [Error-Recovery](/docs/llm-cookbook/error-recovery)