Lektion 2 von 6·10 Min Lesezeit

Streaming & UI Integration

Streaming ist das Kernfeature des Vercel AI SDK — es verwandelt langsame LLM-Responses in interaktive, sofort sichtbare Ausgaben. In dieser Lektion vertiefen wir Server-Side Streaming, React Server Components und Generative UI.

Server-Side Streaming

Streaming-Architektur

Das AI SDK nutzt den Web Streams API-Standard:

Client (useChat) → HTTP POST → Route Handler → AI SDK → LLM Provider
                 ← ReadableStream ← streamText ← Token-Stream

StreamText im Detail

import { streamText } from 'ai'
import { anthropic } from '@ai-sdk/anthropic'

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

  const result = streamText({
    model: anthropic('claude-sonnet-4-20250514'),
    system: 'Du bist ein hilfreicher Assistent für deutsche Nutzer.',
    messages,
    maxTokens: 2000,
    temperature: 0.7,
    onFinish: async ({ text, usage }) => {
      // Logging, Datenbank-Speicherung, Analytics
      console.log(`Tokens: ${usage.totalTokens}`)
      await saveToDatabase(text)
    },
  })

  return result.toDataStreamResponse()
}

Stream Callbacks

Das AI SDK bietet granulare Callbacks für den Stream-Lebenszyklus:

  • onChunk: Wird für jeden Chunk aufgerufen (Text, Tool Call, etc.)
  • onFinish: Wird aufgerufen, wenn der Stream endet — ideal für Logging und Persistenz
  • onStepFinish: Wird nach jedem Multi-Step-Schritt aufgerufen (bei Agent-Loops)

React Server Components

Streaming mit RSC

React Server Components ermöglichen Server-Side-Rendering mit Streaming:

// app/[locale]/ai/page.tsx
import { generateText } from 'ai'
import { openai } from '@ai-sdk/openai'

export default async function AIPage() {
  const { text } = await generateText({
    model: openai('gpt-4.1'),
    prompt: 'Erstelle eine Zusammenfassung der neuesten AI-Trends.',
  })

  return (
    <article>
      <h1>AI-Trends 2026</h1>
      <div>{text}</div>
    </article>
  )
}

Suspense + Streaming

Für progressive Loading-Erfahrungen:

import { Suspense } from 'react'

export default function Page() {
  return (
    <div>
      <h1>Dashboard</h1>
      <Suspense fallback={<LoadingSkeleton />}>
        <AIInsights />
      </Suspense>
    </div>
  )
}

Generative UI

Was ist Generative UI?

Statt nur Text zu streamen, generiert das AI SDK React-Komponenten als Antwort:

import { streamUI } from 'ai/rsc'
import { openai } from '@ai-sdk/openai'

const result = await streamUI({
  model: openai('gpt-4.1'),
  prompt: 'Zeige mir das aktuelle Wetter in Berlin.',
  tools: {
    getWeather: {
      description: 'Zeigt das aktuelle Wetter für eine Stadt an',
      parameters: z.object({ city: z.string() }),
      generate: async function*({ city }) {
        yield <WeatherSkeleton />
        const weather = await fetchWeather(city)
        return <WeatherCard data={weather} />
      },
    },
  },
})

Der Nutzer sieht: Erst ein Loading-Skeleton, dann eine fertige Wetter-Karte — nicht nur Text "Es ist 15°C in Berlin", sondern eine interaktive UI-Komponente.

Loading States & Error Boundaries

Loading-Strategien

StrategieUXImplementierung
SkeletonPlatzhalter-LayoutCSS/Tailwind Animate
Typing Indicator"AI tippt..."Einfacher Indikator
Progressive RenderingText erscheint wortweiseStream-basiert (Standard)
Optimistic UISofortige Platzierung, Update bei AntwortReact Optimistic

Error Handling

'use client'
import { useChat } from 'ai/react'

export function Chat() {
  const { messages, error, reload } = useChat()

  if (error) {
    return (
      <div className="text-red-500">
        <p>Fehler: {error.message}</p>
        <button onClick={reload}>Erneut versuchen</button>
      </div>
    )
  }

  // ... Chat-UI
}

Error Boundaries für AI

Wrappen Sie AI-Komponenten in Error Boundaries:

  • Rate Limit Errors: Nutzerfreundliche Meldung + Retry nach Countdown
  • Model Errors: Fallback auf alternatives Modell
  • Network Errors: Offline-Indikator + automatischer Retry
  • Content Filter: "Diese Anfrage kann nicht beantwortet werden" + Vorschlag zur Umformulierung

UX-Regel: Der Nutzer sollte niemals eine leere Seite sehen. Jeder Zustand — Loading, Error, Empty, Success — braucht ein dediziertes UI. Streaming macht die Loading-Phase angenehm, aber Error States müssen Sie selbst designen.