Start · Sprachen · JavaScript · Referenz · Summarizer.summarizeStreaming()

Summarizer.summarizeStreaming()

Methode

Fasst einen Text mit dem im Browser eingebauten KI-Modell zusammen und liefert das Ergebnis schrittweise als <code>ReadableStream</code> von Textstücken.

seit JavaScript Experimentell: Chrome/Edge 138+ (Desktop), kein Ba Kategorie: webapi

Signatur

Summarizer.prototype.summarizeStreaming(input, options)

Beschreibung

summarizeStreaming() gehört zur Summarizer API, einer der „Built-in AI“-Schnittstellen, bei denen ein lokal im Browser laufendes Sprachmodell (in Chrome z. B. Gemini Nano) genutzt wird. Anders als summarize(), das erst nach Abschluss der gesamten Generierung ein Promise<string> auflöst, gibt diese Methode sofort einen ReadableStream zurück, aus dem die Zusammenfassung Stück für Stück gelesen werden kann.

Das lohnt sich vor allem bei längeren Texten oder Zusammenfassungen im Format "markdown" bzw. mit length: "long": Nutzer sehen die ersten Wörter nach Sekundenbruchteilen, statt auf das komplette Ergebnis zu warten. Art, Format und Länge der Zusammenfassung (z. B. "key-points", "tldr", "teaser", "headline") werden nicht hier, sondern beim Erzeugen der Instanz über Summarizer.create() festgelegt.

Der Stream lässt sich bequem mit for await…of konsumieren oder klassisch über getReader(). Über ein AbortSignal kann die Generierung jederzeit abgebrochen werden – etwa wenn der Nutzer einen neuen Text einfügt oder die Ansicht verlässt.

Parameter

Name Typ Default Beschreibung
$input Pflicht string Der zusammenzufassende Text. Er darf das Eingabekontingent (summarizer.inputQuota) nicht überschreiten.
$options object {} Optionales Konfigurationsobjekt für diesen einzelnen Aufruf.
$options.context string Zusätzlicher Kontext speziell für diese Eingabe, z. B. "Produktbewertung eines Onlineshops". Ergänzt den bei create() gesetzten sharedContext.
$options.signal AbortSignal Signal eines AbortController, mit dem die Generierung abgebrochen wird. Der Stream wird dann mit einem AbortError beendet.

Rückgabewert

Typ
ReadableStream<string>
Beschreibung
Ein ReadableStream, dessen Chunks Textfragmente der Zusammenfassung sind. In aktuellen Chrome-Versionen (ab 138) sind die Chunks inkrementell – sie müssen also aneinandergehängt werden. Fehler (z. B. Kontingent überschritten, Abbruch) werden über den Stream gemeldet.

Beispiele

Einfache Streaming-Zusammenfassung mit for await

const text = document.querySelector('#artikel').textContent;

if ('Summarizer' in self && (await Summarizer.availability()) !== 'unavailable') {
  const summarizer = await Summarizer.create({
    type: 'key-points',
    format: 'plain-text',
    length: 'short',
    outputLanguage: 'de'
  });

  let summary = '';
  for await (const chunk of summarizer.summarizeStreaming(text)) {
    summary += chunk;
  }
  console.log(summary);
  summarizer.destroy();
} else {
  console.log('Summarizer API nicht verfügbar');
}
- Kernaussage 1 … - Kernaussage 2 … - Kernaussage 3 …

Live-Ausgabe im UI mit Abbruch-Möglichkeit

const output = document.querySelector('#zusammenfassung');
const cancelBtn = document.querySelector('#abbrechen');
let controller;

const summarizeLive = async (summarizer, text) => {
  controller?.abort(); // laufende Generierung stoppen
  controller = new AbortController();
  output.textContent = '';

  try {
    const stream = summarizer.summarizeStreaming(text, {
      context: 'Kundenbewertung eines Elektronik-Onlineshops',
      signal: controller.signal
    });
    for await (const chunk of stream) {
      output.textContent += chunk;
    }
  } catch (err) {
    if (err.name === 'AbortError') {
      output.textContent += ' [abgebrochen]';
    } else {
      console.error('Zusammenfassung fehlgeschlagen:', err);
    }
  }
};

cancelBtn.addEventListener('click', () => controller?.abort());

Stream manuell mit getReader() lesen und Kontingent prüfen

const summarizer = await Summarizer.create({ type: 'tldr', length: 'medium' });
const text = 'Sehr langer Besprechungstext …';

const benoetigt = await summarizer.measureInputUsage(text);
if (benoetigt > summarizer.inputQuota) {
  throw new Error(`Text zu lang: ${benoetigt} von ${summarizer.inputQuota}`);
}

const reader = summarizer.summarizeStreaming(text).getReader();
let result = '';
while (true) {
  const { done, value } = await reader.read();
  if (done) break;
  result += value;
}
console.log(result);
Das Meeting beschloss … (TL;DR-Zusammenfassung)

// Wichtig · Fallstricke

  • Experimentell & begrenzte Unterstützung: Aktuell nur in Chromium-Browsern (Chrome 138+ auf Desktop) mit ausreichender Hardware verfügbar; Firefox und Safari unterstützen die API nicht. Immer per 'Summarizer' in self und Summarizer.availability() prüfen.
  • Inkrementelle vs. kumulative Chunks: Frühe Vorabversionen lieferten in jedem Chunk den bisherigen Gesamttext. Ab Chrome 138 sind die Chunks inkrementell – Code, der mit output.textContent = chunk arbeitet, zeigt dann nur das letzte Fragment.
  • Modell-Download: Beim ersten Summarizer.create() muss das Modell ggf. heruntergeladen werden; dafür ist eine Nutzeraktivierung (z. B. Klick) nötig. Fortschritt über die monitor-Option verfolgen.
  • Kontingent: Überschreitet input das inputQuota, schlägt der Stream mit einem QuotaExceededError fehl. Vorab mit measureInputUsage() prüfen oder Text aufteilen.
  • Kontext & Berechtigung: Nur in sicheren Kontexten (HTTPS) und im Hauptfenster; in iframes muss die Permissions Policy summarizer erlaubt sein. Nicht in Web Workern verfügbar.
  • Sicherheit: Ausgaben des Modells nie ungeprüft per innerHTML einfügen – bei format: "markdown" das Ergebnis mit einem sicheren Markdown-Renderer und Sanitizer verarbeiten, um XSS zu vermeiden.
  • Ressourcen freigeben: Nicht mehr benötigte Instanzen mit summarizer.destroy() beenden.