Resumable LLM‑Streaming: Technische Umsetzung mit Redis‑Streams
Resumable LLM‑Streaming ist technisch anspruchsvoll, lässt sich aber durch eine Kombination aus Redis‑Streams, Streamstraight und einer maßgeschneiderten Transport‑Klasse stabil realisieren. Das Ziel ist, dass die Unterbrechung bei Tab‑wechsel, Refresh oder kurzzeitiger Netzunterbrechung vermieden wird.
Key Takeaway
Resumable LLM‑Streaming ist technisch anspruchsvoll, lässt sich aber durch eine Kombination aus Redis‑Streams, Streamstraight und einer maßgeschneiderten Transport‑Klasse stabil realisieren.
Summary
- Problemstellung: Bestehende LLM‑Chat‑UI‑Anbieter (Gemini, Claude) zeigen bei Tab‑wechsel, Refresh oder kurzzeitiger Verbindungsabbrüche einen komplett stillen Stream.
- Erforderliche Kriterien: keine Unterbrechung bei Tab‑wechsel, Refresh, Navigieren in der App oder kurzzeitiger Netzunterbrechung; ausschließlich ein aktiver Stream pro Chat.
- MVP‑Phase (keine Resumption): Next.js Frontend + FastAPI Backend (Modal); Streaming per Server‑Sent Events (SSE); Antworten werden gleichzeitig im DB gespeichert.
- Problemidentifikation: Demo‑Nutzer tabben häufig weg und kehren zurück; der Chat erscheint als still, obwohl er noch läuft.
- Schritt 2 – Streamstraight: Integrierte Lösung, die unterbrochene Streams über WebSockets weiterleitet.
- Schritt 3 – Infrastruktur‑Rewrite: Für Demo‑Cards wurde ein separater Worker‑Prozess gestartet (Modal). Worker nutzt Redis‑Streams, um Chat‑Chunks in Echtzeit abzurufen und an das Frontend zu senden.
- Herausforderungen bei Schritt 4: React‑Hook
useChatliefert erst nach abgeschlossener Stream‑Antwortmessage_id;reconnectToStreamwird jedes Mal beim Remount des Components aufgerufen. - Lösungsansatz: Redis KV‑Store zur Zuordnung
chat_id → active_message_id; Redis‑Streams für jedechat_id&message_idPaarung. - Endarchitektur: Frontend: Next.js + useChat Hook, selbstdefinierte
StardriftTransportKlasse; Backend: FastAPI + Modal Worker, Redis‑Streams & KV‑Store; Streaming: Originell über SSE, fallback via Redis‑Streams. - Ausblick: Möglicher Ersatz des
useChatHooks; Implementierung verdeutlicht, dass ein robustes Stream‑Handling ein Zusammenspiel von Backend‑Worker, Nachrichtensystem (Redis) und Frontend‑Transport erfordert.
