▶️ Дивіться відеоурок (10 хвилин)
Досі ми тестували агента через JSON-маршрути, де повна відповідь приходить лише після завершення обробки запиту AI. Це зручно для розробки, але критично для UX: ніхто не хоче п’ять секунд дивитися на спінер і гадати, чи працює сервіс.
У цьому епізоді ми створимо чат-віджет, де відповідь з’являється поступово, як у ChatGPT. Користувач надсилає запитання, і текст від агента починає генеруватися миттєво, слово за словом.
Завдяки SDK це реалізується одним рядком коду. Замість методу prompt() ми викликаємо stream(), а SDK передає дельти токенів у браузер через Server-Sent Events (SSE). Я додав метод stream до ChatController для обробки SSE з відповідними заголовками та використав приватний метод resolveAgent, щоб створювати або продовжувати діалоги для авторизованих користувачів.
Фронтенд побудований на Livewire (керування станом), Blade (інтерфейс) та Alpine.js для логіки стрімінгу. Код на Alpine.js відкриває fetch-потік, парсить кожен фрагмент даних у реальному часі та додає текст у бабл повідомлення. Жодних зовнішніх залежностей — лише Livewire, Alpine та можливості SDK.
Також я розібрав нюанс із отриманням ID розмови під час першого повідомлення. Рішення — callback-функція завершення, що спрацьовує після фіналізації стріму та дозволяє зберегти ID для подальшого листування.
У підсумку чат виглядає як повноцінний продукт: той самий агент, інструменти та база знань, але з динамічним виводом.
У наступній серії ми надамо агенту доступ до мережі за допомогою WebSearch, щоб він міг відповідати на запитання про події в реальному часі, наприклад, про затримки поштових операторів.