eduardweb.
AI & LLMsIntermediar#nextjs#react#openai#vercel-ai-sdk

Cum am implementat streaming de la LLM în Next.js fără să-mi prind urechile în Server-Sent Events

De Cosmin Rotaru, 9 iul. 2026 · 18 vizualizări · 3 like-uri

Postat 9 iul. 2026
typescript
import { openai } from '@ai-sdk/openai';
import { streamText } from 'ai';

// Evităm timeout-ul rapid pe serverless
export const maxDuration = 30;

export async function POST(req: Request) {
  const { messages } = await req.json();

  const result = await streamText({
    model: openai('gpt-4o'),
    messages,
  });

  return result.toDataStreamResponse();
}

Am lucrat recent la o aplicație internă unde trebuia să aducem răspunsuri de la GPT-4 pentru vreo 1.200 de utilizatori activi. Prima versiune aștepta răspunsul complet de la OpenAI și dura uneori și 15 secunde. UX-ul era pur și simplu de nejucat, oamenii credeau că s-a blocat pagina. Soluția evidentă a fost streaming-ul, dar implementarea manuală mi-a mâncat o zi întreagă din viață degeaba.

Coșmarul Server-Sent Events (SSE) scris de mână

Când încerci să scrii SSE de mână în Next.js Route Handlers, dai rapid de probleme. Trebuie să te joci cu ReadableStream, să formatezi manual liniile cu prefixul data: și să gestionezi corect caracterele de rând nou (\n\n).

Cel mai enervant moment? Gestionarea deconectărilor bruște ale clientului. Dacă userul închide tab-ul în timp ce LLM-ul încă scrie, te poți trezi cu memory leaks pe server pentru că stream-ul nu s-a închis cum trebuie. Am reușit să o fac să meargă, dar codul arăta ca un motor de Dacie cârpit cu sârmă.

Cum ne salvează Vercel AI SDK

După ce am pierdut destul timp, am decis să șterg cele peste 120 de linii de cod custom și să trec pe @ai-sdk/openai împreună cu hook-ul useChat din frontend. Diferența a fost uriașă. Am redus codul de pe backend la doar câteva rânduri, iar pe client am scăpat definitiv de parsarea manuală de JSON-uri parțiale.

Hook-ul useChat din frontend îți dă la cheie starea chatului (messages), funcția de trimitere (handleSubmit) și un flag extrem de util pentru loading (isLoading). Am economisit cam 30% la timpul de dezvoltare pe partea de UI doar pentru că nu a mai trebuit să scriu stările de loading și eroare de la zero.

Trade-off-urile de care nu vorbește nimeni

Nimic nu e gratis în producție, așa că iată de ce trebuie să ții cont:

  1. Vendor Lock-in: Vercel AI SDK este excepțional dacă rămâi în ecosistemul React/Next.js. Dacă peste 6 luni echipa de Data Science decide că vrea să mute tot backend-ul de chat pe un serviciu FastAPI scris în Python, va trebui să rescrii complet clientul care consumă stream-ul, deoarece SDK-ul folosește un protocol de streaming specific.
  2. Timeout-urile din Serverless: Pe Vercel Hobby tier, funcțiile serverless au un timeout de 10 secunde. Dacă GPT-4 are o perioadă de latență mare și nu începe să trimită primele token-uri rapid, funcția ta va crăpa cu eroarea 504. Pe planul Pro limita este de 30 de secunde (sau mai mult dacă configurezi maxDuration), dar asta înseamnă costuri suplimentare.

Pentru noi, trecerea la Vercel AI SDK a fost un win clar. Am curățat codul și am oferit o experiență fluidă userilor fără să ne batem capul cu protocoale de rețea de nivel jos.

Voi cum gestionați streaming-ul de la LLM-uri? Preferați să scrieți wrappere native peste fetch ca să rămâneți independenți de framework, sau mergeți pe mâna SDK-urilor dedicate?

Răspunsuri 0

Se încarcă răspunsurile…

Loghează-te pentru a răspunde

Doar membrii comunității pot lăsa comentarii.