Zum Inhalt springen
EN DE

Custom Data Parts streamen

Data Parts transportieren strukturierte Daten neben dem LLM-Text im selben Stream. Statt Fortschritt, Status oder Quellen in den Text einzubetten, sendest Du typisierte JSON-Objekte, die das Frontend direkt rendern kann.

Es gibt zwei Kategorien: Persistent Data Parts werden in message.parts gespeichert und bleiben Teil der Message-Historie. Transient Data Parts sind nur waehrend des Streams über den onData-Callback verfügbar und werden nicht persistiert.

Auf der Server-Seite nutzt Du createUIMessageStreamResponse (oder createUIMessageStream) mit einem execute-Callback. Der writer bietet eine write()-Methode für Custom Data Parts und writer.merge() fuegt den LLM-Stream ein.

import { createUIMessageStreamResponse, streamText } from 'ai';
import { anthropic } from '@ai-sdk/anthropic';
export async function POST(req: Request) {
const { messages } = await req.json();
return createUIMessageStreamResponse({
execute(writer) {
// Persistent Data Part (wird in message.parts gespeichert)
writer.write({
type: 'data-weather',
data: { city: 'Berlin', status: 'loading' },
});
const result = streamText({
model: anthropic('claude-sonnet-4-5-20250514'),
messages,
onFinish() {
writer.write({
type: 'data-weather',
data: { city: 'Berlin', status: 'success', temp: 22 },
});
},
});
writer.merge(result.toUIMessageStream());
},
});
}
import type { UIMessage } from 'ai';
// Generics definieren die erlaubten Data Part Typen
type MyUIMessage = UIMessage<
never, // Metadata-Typ
{
weather: { city: string; status: 'loading' | 'success'; temp?: number };
notification: { message: string; level: 'info' | 'warning' };
}
>;
MethodeBeschreibung
createUIMessageStreamResponse({ execute })Erstellt eine Response mit UI Message Stream
createUIMessageStream({ execute })Erstellt einen rohen UI Message Stream
writer.write({ type: 'data-${NAME}', data })Schreibt ein Persistent Data Part
writer.write({ type: 'data-${NAME}', data, id })Schreibt ein Data Part mit ID (für Reconciliation)
writer.write({ ..., transient: true })Schreibt ein Transient Data Part (nicht persistiert)
writer.merge(result.toUIMessageStream())Fuegt den LLM-Stream in den Writer ein

Part of AI Learning — free courses from prompt to production. Jan on LinkedIn