Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як не блокувати запит довгою генерацією LLM: стримінг, черги й трансляція подій?

Відповідь моделі може генеруватися десятки секунд, а з інструментами - ще довше. Синхронний prompt() у контролері тримає PHP-воркер увесь цей час і впирається в тайм-аути проксі та PHP.

Три підходи:

1. Стримінг (SSE) - користувач бачить текст по мірі генерації:

Route::post('/assistant', function (Request $request) {
    return SupportAssistant::make(user: $request->user())
        ->stream($request->validated('message'))
        ->then(function (StreamedAgentResponse $response) {
            // повна відповідь: зберегти, порахувати токени
        });
});

StreamableAgentResponse повертається з маршруту як потокова відповідь. Перший токен приходить за секунду-дві, але воркер зайнятий до кінця генерації.

2. Черга - запит повертається одразу, генерація йде у воркері:

ReviewClassifier::make()
    ->queue($review->body)
    ->then(fn (AgentResponse $response) => $review->update([...]))
    ->catch(fn (Throwable $e) => report($e));

return back()->with('status', 'Аналіз запущено');

Підходить для фонових задач: класифікація, резюме, обробка документів. Результат - у базу, а інтерфейс опитує статус чи отримує подію.

3. Трансляція подій - генерація у черзі, а потік подій іде в браузер через WebSocket (Reverb):

SupportAssistant::make()->broadcastOnQueue($message, new PrivateChannel("chat.{$chat->id}"));

Поєднує обидва: воркер вебсервера звільняється одразу, а користувач бачить текст у реальному часі.

Як обрати:

Сценарій Підхід
чат, де користувач чекає відповідь стримінг або черга + трансляція
фонова обробка без очікування черга
багато одночасних користувачів черга + трансляція (не займати вебворкери)

Інфраструктурні деталі:

  • тайм-аути: #[Timeout] агента, timeout воркера черги й retry_after підключення мають бути узгоджені, інакше задачу візьме другий воркер, і модель відповість двічі (і двічі буде оплачено);
  • буферизація: Nginx, Cloudflare й інші проксі можуть буферизувати SSE - потрібні X-Accel-Buffering: no і відповідні налаштування;
  • окрема черга для LLM-задач з власним лімітом воркерів - щоб повільні виклики моделі не затримували листи й сповіщення;
  • повтори: при збоях провайдера краще резервний провайдер (provider: [...]), ніж повтор задачі цілком;
  • Octane / FrankenPHP - стримінг утримує воркер так само; рахуйте кількість воркерів під одночасні потоки.

Докладніше в документації: AI SDK: стримінг

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання