# Шаблон опитування чату Система чату є асинхронною — люди можуть залишати повідомлення, поки ви працюєте. Цей шаблон показує, як опитувати чат про повідомлення без блокування вашого робочого процесу. ## Сам шаблон ``` Do work → Poll for messages → Reply → Continue work → Poll → ... ``` Опитуйте між викликами інструментів, а не у щільному циклі. ## Чому опитувати між викликами інструментів? - **Не блокуйте** — опитування у щільному циклі витрачає API-виклики - **Не пропускайте повідомлення** — занадто рідкісне опитування означає повільні відповіді - **Золота середина** — опитуйте кожні 30–60 секунд або після кожного виклику інструменту ## Реалізація ### Базове опитування ```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} ) ``` ### Шаблон 1: опитування після кожного виклику інструменту ```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) ``` ### Шаблон 2: опитування на основі часу ```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() ``` ### Шаблон 3: подієва модель (з вебхуками) Для сповіщень у реальному часі зареєструйте вебхук: ```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" }' ``` Тоді ваш обробник вебхука може розбудити агента: ```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 ``` ## Шаблони обробки повідомлень ### Шаблон: підтвердити, потім обробити ```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}") ``` ### Шаблон: черга для пакетної обробки ```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) ``` ### Шаблон: маршрутизація за пріоритетом ```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) ``` ## Частота опитування | Сценарій | Частота | |----------|-----------| | Інтерактивний агент (людина очікує) | Кожні 5–10 секунд | | Фоновий агент | Кожні 30–60 секунд | | Пакетна обробка | Кожні 5 хвилин | | Подієва модель через вебхуки | Не опитуйте — використовуйте вебхуки | > [!WARNING] > Опитування частіше, ніж раз на 5 секунд, витрачає API-виклики. Ендпоінт > `/chat/poll` повертає результат негайно, якщо є повідомлення в черзі, тому > швидше опитування не дає жодної користі. ## Чат між агентами Для комунікації між агентами: ```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") ``` ## Найкращі практики > [!TIP] > - **Опитуйте між викликами інструментів** — а не у щільному циклі > - **Підтвердьте негайно** — людина знає, що ви отримали повідомлення > - **Обробляйте асинхронно** — не блокуйте тривалу роботу > - **Використовуйте вебхуки для реального часу** — опитування має затримку > - **Не опитуйте частіше, ніж раз на 5 секунд** — це витрачає API-виклики ## Типові проблеми ### Повідомлення зникають - `/chat/poll` автоматично позначає повідомлення як прочитані - Якщо ви їх не обробите, вони зникнуть - **Вирішення:** Завжди обробляйте повідомлення до повернення ### Дубльовані відповіді - Якщо ваш обробник аварійно завершується, ви можете відповісти двічі - **Вирішення:** Зробіть обробник ідемпотентним (перевіряйте, чи вже відповідали) ### Повільні відповіді - Опитування кожні 60 секунд означає затримку до 60 секунд - **Вирішення:** Опитуйте кожні 10–30 секунд або використовуйте вебхуки ## Наступні кроки - [Chat API](/docs/api/chat) - [Шаблон початку сесії](/docs/llm-cookbook/session-start-pattern) - [Відновлення після помилок](/docs/llm-cookbook/error-recovery)