Skip to Content

KI-Jobbasis, TTS, Bild- und Textvorschläge

Das CMS erzeugt Vorlese-Audios für Kategoriebezeichnungen, Storytitel sowie Text- und Linkinhalte von Stories. Audio und Wort-Zeitmarken sind Bestandteil des veröffentlichten Inhalts; die Joblogik bleibt unabhängig vom gewählten Audioanbieter. Die zugrunde liegende private Queue und der Adaptervertrag sind für TTS-, Bild- und Textjobs gemeinsam aufgebaut. Alle drei Lanes besitzen produktive Worker. TTS-Aufträge entstehen beim Speichern betroffener Inhalte automatisch. Bild- und Textvorschläge erzeugt das CMS erst, wenn die Redaktion sie ausdrücklich startet.

TTS: vertonten Inhalt speichern | Bild/Text: Vorschlag ausdrücklich starten │ ▼ Eingabe + Quell-Hash │ ▼ private KI-Queue mit getrennten Lanes: tts | image | text │ ├── TTS-Worker: pending → running → done / failed / cancelled │ ├── Qwen3-TTS (lokales Python-Skript) │ ├── KugelAudio │ ├── ElevenLabs │ └── Audio + Wort-Zeitmarken → Media Library │ └── kompatible ttsJobs-Projektion am Inhalt ├── Bild-Worker: pending → running → done / failed / cancelled │ ├── MFLUX / FLUX.2 klein (lokal auf Apple Silicon) │ ├── fal.ai / GPT Image 2 oder FLUX Kontext Pro │ ├── betreiberseitig gewählter HTTP-Endpunkt │ └── privater Vorschlag → Auswahl → Media Library └── Text-Worker: pending → running → done / failed / cancelled ├── Ollama oder OpenAI └── privater Textvorschlag → redaktionelle Übernahme ins Formular

Gemeinsames Jobmodell

Jeder KI-Job enthält Modalität, Lane, Operation, Zielinhalt, Dokument-ID, optionale numerische Entity-ID, Feldpfad, Locale, Eingabe-Hash, Status, Anzahl der Versuche, Queue-, Start- und Endzeit sowie Lease und Fehler. Bei Bildaufträgen erhält jede Generierung einen eigenen Jobschlüssel, damit mehrere Vorschlagssätze für dasselbe Feld parallel bestehen können.

Modalitätsspezifische Ein- und Ausgaben liegen in Request- und Result-Payloads. Generierte Dateien werden als Artefakte mit einem Zustand wie temporary, proposal, accepted oder rejected referenziert. Bildvorschläge verwenden diesen Vertrag für private Dateien und ihre redaktionelle Auswahl. Textjobs verwenden Request- und Result-Payloads für bearbeitbare Vorschläge, ohne TTS-Felder oder Medienartefakte vorzutäuschen.

Der gemeinsame Adaptervertrag deklariert Modalität, unterstützte Operationen und Abbruchfähigkeit. Sein Ergebnis kann Provider, Modell, Adapter- und Promptversion, technische Nutzungswerte und Provenienz enthalten. Die Queue speichert keine API-Schlüssel. Nutzungswerte dienen der Nachvollziehbarkeit; eine automatische Preis- oder Budgetberechnung findet nicht statt. Eine vorgesehene Lizenz wird nur als optionale Betreiberangabe protokolliert und nicht vom CMS rechtlich bewertet.

Für TTS erkennt der Eingabe-Hash, ob ein gespeichertes Audio noch zum aktuellen Text passt. Audio, Wort-Zeitmarken und die für die App benötigten Metadaten werden weiterhin als ttsJobs an Story oder Kategorie projiziert. Die zentrale Queue gehört nicht zum öffentlichen Content-API-Vertrag und wird weder im Content-Type Builder noch im Content Manager als redaktioneller Inhalt angezeigt.

Automatische TTS-Auslöser

  • Beim Anlegen einer Kategorie oder Story werden alle benötigten Audiojobs eingereiht.
  • Beim Ändern einer Kategoriebezeichnung werden deren Jobs synchronisiert.
  • Beim Ändern von Storytitel oder Slides werden die Storyjobs synchronisiert.
  • Unveränderte Text-Hashes behalten ihr fertiges Audio; veränderte Felder werden wieder auf pending gesetzt.
  • Veröffentlichen und Zurückziehen lösen keine neue Generierung aus.
  • Eine Veröffentlichung wird abgewiesen, solange für die Locale Jobs den Status pending oder running haben.

Queue-Lanes und Worker

Die Lanes tts, image und text besitzen getrennte Einstellungen für Parallelität, Lease-Dauer und Ausführungszeit. Dadurch blockiert ein langer Job nicht automatisch andere Modalitäten. Innerhalb einer Lane reserviert ein Worker den ältesten offenen Auftrag nach queuedAt und anschließend nach der technischen ID. Ein bedingtes Update von pending auf running verhindert, dass mehrere CMS-Instanzen denselben Auftrag gleichzeitig übernehmen. Die TTS-, Bild- und Text-Worker laufen im Strapi-Prozess. Der Textworker startet nur bei aktivierter Textgenerierung.

Jede Reservierung besitzt eine zeitlich begrenzte Lease. Ein aktiver Worker verlängert sie während längerer Provideraufrufe. Beim regulären Herunterfahren stellt der Worker seinen aktiven Auftrag sofort wieder auf pending. Beim Neustart erkennt das CMS außerdem verwaiste Leases nicht mehr laufender Node-Prozesse auf demselben Host und reiht sie erneut ein, ohne aktive Parallel-Worker anzutasten. Nach einem harten Abbruch auf einem anderen Host greift spätestens die Lease-Grenze; eine abgelaufene Lease wird ebenfalls wieder pending. Dieser technische Retry behält queuedAt und damit die bisherige Queue-Position. Manueller Retry und erzwungene Neugenerierung stellen einen Auftrag dagegen mit einem neuen queuedAt hinten an; Cancel beendet ihn als cancelled.

Bildvorschläge und redaktionelle Übernahme

Für Kategorie- und Story-Icons sowie Bilder von Text-Slides startet die Redaktion die Generierung ausdrücklich an einem bereits angelegten Eintrag. Titel und Slide-Text werden dabei aus dem aktuellen Formular übernommen und müssen vor der Generierung nicht erneut gespeichert werden. Ein vollständig neuer Eintrag benötigt zunächst durch einmaliges Speichern eine technische Dokument-ID. Zielinhalt, Locale, Feldtyp, redaktionelle Zusatzanweisung und ein festes Stilprofil bilden die Eingabe. Die Stilprofile können betreiberseitig auf freigegebene Medien aus der Media Library verweisen. Ob der Betreiber ein lokales Modell oder eine API verwendet, ändert den redaktionellen Ablauf nicht. Unterstützte Rasterbilder und SVG-Dateien werden für lokale Referenzaufrufe in größenbegrenzte PNG-Dateien umgewandelt; die ursprünglichen Medien bleiben unverändert.

Das Seitenpanel zeigt den aktiven Auftrag, weitere wartende Aufträge und verfügbare Vorschläge. Der eigentliche Workflow öffnet sich als Overlay und benennt die Felder mit ihrem inhaltlichen Kontext. Dort wählt die Redaktion das Bildfeld, eines der vom Betreiber freigeschalteten Modelle, die Vorschlagsanzahl und optional eine je Feld getrennte Bildanweisung. Nach der Generierung lässt sich der tatsächlich verwendete Prompt einsehen. Eine Bildanweisung dient zugleich als bearbeitbarer Ausgangspunkt für den Alternativtext; ohne Bildanweisung wird er aus dem Zielinhalt vorgeschlagen.

Ein Bildjob kann bis zu vier Vorschläge liefern. Sie bleiben außerhalb der Media Library in einem privaten Vorschlagsspeicher und sind nur über eine aktive Admin-Session mit passender Content-Manager-Berechtigung abrufbar. Erst die ausdrückliche Auswahl mit geprüftem Alternativtext lädt genau einen Vorschlag in die Media Library und setzt ihn in das Formular ein. Das Formular muss danach gespeichert werden. Ein vorher verwendetes Medium wird dabei weder automatisch überschrieben noch gelöscht.

Bildvorschläge sind zusätzlich an die Person und die flüchtige Sitzung des geöffneten Editors gebunden. Ein anderer Tab oder ein neu geöffneter Editor erhält eine andere Sitzungskennung und kann frühere Vorschläge weder auflisten noch als Datei abrufen oder übernehmen. Mehrere Aufträge für dasselbe Feld bleiben während einer Editorsitzung getrennte Vorschlagssätze. Die Jobs und Entscheidungsmetadaten bleiben für die technische Auswertung erhalten. Ungenutzte temporäre Bilddateien können nach dem Schließen noch im geschützten Speicher liegen; die serverseitige Bereinigung entfernt sie nach 30 Tagen. Bereits übernommene Medien bleiben in der Media Library. Textvorschläge haben einen eigenen Verlauf für unveränderte gespeicherte Felder.

Icons werden als quadratische Vollformatbilder mit Farbe bis an alle Dateiränder erzeugt. Eine defensive Randnormalisierung entfernt typische modellseitige Außenränder. Die einheitlichen rundlichen Ecken entstehen erst bei der Darstellung in der App, sodass kein weißer Hintergrund Bestandteil der Bilddatei wird.

Verwerfen, Abbruch, verlorene Leases und das Löschen des Zielinhalts entfernen betroffene private Dateien am jeweiligen Zustandswechsel. Eine weitere Generierung lässt frühere Vorschlagssätze derselben Editorsitzung bestehen. Nach deren Ende sind ungenutzte Dateien nicht mehr abrufbar; die regelmäßige Bereinigung entfernt sie nach 30 Tagen. Provider, Modell, Adapter- und Promptversion, technische Nutzung, Referenzmedien, Erzeugungszeit und redaktionelle Auswahl bleiben am privaten Job nachvollziehbar. Für ein übernommenes Medium wird zusätzlich ein privater Provenienzdatensatz angelegt, der die Zuordnung auch nach späteren Jobänderungen erhält. Eine konfigurierte Lizenz- oder Rechteangabe ist Metadatum und keine automatische rechtliche Freigabe.

Der fal.ai-Adapter verwendet die persistente Provider-Queue. Seine Request-ID wird direkt nach dem Submit am Job gespeichert, damit ein CMS-Neustart denselben externen Auftrag weiter abfragt und keine zweite kostenpflichtige Generierung startet. Bei Abbruch und lokalem Timeout wird die externe Stornierung versucht. Qualität, Ausgabegröße, Prompt und Anzahl der Referenzbilder beeinflussen die Providerkosten. Das CMS speichert technische Nutzungsmetriken und vorhandene fal-billableUnits. Aktuelle Einheitspreise werden ausschließlich serverseitig beim Provider abgefragt. Einen Betrag zeigt die Admin-Oberfläche nur bei einem festen Preis je Ergebnis oder auf Basis vergleichbarer abgeschlossener Aufträge. Der dabei ermittelte Kosten-Snapshot bleibt am Queue-Job über Serverneustarts hinweg erhalten. Das CMS führt weder ein Budget noch eine tatsächliche Abrechnung.

Textvorschläge und redaktionelle Übernahme

Die Redaktion wählt in einer bereits angelegten Kategorie oder Story genau ein Textfeld. Für Vereinfachung stammt der Quelltext aus dem aktuellen Formular, auch wenn eine Slide noch nicht erneut gespeichert wurde. Übersetzungen verwenden eine gespeicherte Ausgangslocale und ein ausdrücklich gewähltes Quellfeld; die Ziellocale und das Zielfeld müssen bereits angelegt sein. Der Textworker fragt Ollama oder OpenAI an und speichert einen privaten, bearbeitbaren Vorschlag mit Warnungen. Eine Übernahme setzt nur den Wert im ungespeicherten Admin-Formular. Speichern und Veröffentlichen bleiben separate Schritte. Frühere offene Vorschläge werden nur für eigene, unveränderte gespeicherte Felder erneut angeboten; Entwürfe ungespeicherter Slides bleiben an die aktuelle Editorsitzung gebunden.

Textjobs behalten Provider, Modell, Adapter- und Promptversion sowie technische Nutzung und Entscheidungen. Vorschlagstexte und Quelltexte werden nach Abschluss zeitlich begrenzt aufbewahrt. Details zu Einrichtung, Rechten, Datenschutz und Bereinigung stehen in der Betriebsanleitung.

Beim Start synchronisiert das CMS vorhandene ttsJobs idempotent in die zentrale Queue. Die bestehende technische Strapi-UID und Tabelle bleiben für Rolling Deployments erhalten, obwohl neue Zugriffe den gemeinsamen KI-Vertrag verwenden. Dadurch bleiben ältere Datenexporte importierbar; vorhandene Audios, Zeitmarken und abgeschlossene Zustände bleiben erhalten. Ein zuvor laufender Job ohne gültige Lease wird erneut als pending eingereiht.

Medienbereinigung

Die Bereinigung läuft an den relevanten Zustandswechseln: nach Textänderung oder Neugenerierung, Recovery, Übernahme des veröffentlichten Audios, Publish und Löschen eines Inhalts sowie bei einem nicht festgeschriebenen Upload.

Vor dem Löschen prüft das CMS alle Draft- und Published-Stände von Stories und Kategorien sowie relevante Queue-Einträge. Gemeinsam verwendete oder noch veröffentlichte Audios bleiben erhalten. Das bisher veröffentlichte Audio wird daher während der Draft-Bearbeitung nicht gelöscht und erst nach dem Publish erneut geprüft. Bei Recover wird je Feld der neueste Fund übernommen; ältere unreferenzierte Kandidaten werden anschließend entfernt.

Zugriffsschutz

Status, Enqueue, Cancel, Recover, die Übernahme des veröffentlichten Audios und das zentrale Audio-Dashboard verwenden dieselbe aktive Admin-Session wie die Strapi-Oberfläche. Der Admin-Fetch-Client sendet das kurzlebige Zugriffstoken automatisch; ein eigenes TTS-Secret wird weder benötigt noch in das Browser-Bundle eingebettet. Öffentliche Requests, abgelaufene Sessions und Content-API-Tokens erhalten keinen Zugriff.

Nach der Authentifizierung greift Strapis Content-Manager-RBAC. Lesen von Statusdaten erfordert read, Änderungen erfordern update für den jeweiligen Content-Type. Das Dashboard setzt die Rechte für Stories und Kategorien voraus. Verändernde Routen sind zusätzlich auf zehn Requests je Route und IP innerhalb von 60 Sekunden begrenzt. Ein vorgeschalteter Reverse Proxy kann für mehrere CMS-Instanzen ergänzend ein verteiltes Limit durchsetzen.

Locale-Konfiguration

Provideroptionen können pro vollständiger Locale, Sprache oder global gesetzt werden. Für en-US gilt beispielsweise:

..._EN_US → ..._EN → globaler Wert

Qwen3-TTS

Qwen wird über ein separates Python-Skript aufgerufen. Modellgewichte, Python-Umgebung, Referenzaufnahmen und optionaler Forced Aligner werden nicht mit npm install installiert. Für Voice Cloning muss das Transkript exakt zur Referenzaufnahme passen. Der Forced Aligner liefert Wort-Zeitmarken; ohne lokale GPU ist die Generierung je nach Modell deutlich langsamer.

KugelAudio

KugelAudio wird als Cloud-Dienst über API-Key, Modell und Voice-ID angebunden. Die WebSocket-Übertragung ist der Standard, weil die Wort-Zeitmarken darüber mitgeliefert werden. Mit KUGELAUDIO_REQUIRE_TIMESTAMPS=true gilt ein Audio ohne Zeitmarken als fehlgeschlagen. Sample-Rate, Normalisierung, Sprache und Stimme können global oder je Locale konfiguriert werden.

ElevenLabs

ElevenLabs erzeugt über die API PCM-Audio, das der Adapter als WAV speichert. Für die in der App verwendete wortweise Hervorhebung ruft der Adapter bei ELEVENLABS_FORCE_ALIGNMENT=true zusätzlich Forced Alignment auf. API-Key, Voice-ID, Modell, Ausgabeformat und Sprachcode können global oder je Locale gesetzt werden.

Änderungen an Worker, Lifecycle-Hooks, Wiederherstellung oder automatischem Löschen von Medien sind datenrelevant und benötigen gezielte Tests.