Quellengestützte Blog-Redaktion: technische Umsetzung
Schichten, Agentenkette, Guards und Freigabe-Gates der Blog-Redaktion, dazu Sonderfälle, Dienste und Tests.
- Studien im Korpus
- 173
- spezialisierte Subagenten
- 6
- deterministische Guards ohne KI
- 3
- Korrekturrunden bis zur Eskalation
- 2
- automatisierte Tests
- 309
Von der Studie zum Draft
Jeder Schritt lässt sich aufklappen.
Berechtigungen des Modells
Kein Zugriff
- Einen Beitrag live schalten
- Neue Kategorien ohne ausdrückliche Freigabe anlegen
- Inhalte aus Modellwissen statt aus geladenen Quellen schreiben
- Die Pro-Stufe der Bildgenerierung ohne Freigabe nutzen
Erlaubt ohne Freigabe
- Korpus lesen und durchsuchen
- Entwürfe und Pipeline-Zustand speichern
- Learnings schreiben
- Hero-Bilder erzeugen
- Drafts an die Website pushen
- Den veröffentlichten Bestand lesen
Kontrollen
Kontrakt-Guard
Deterministisch, ohne KI: Pflichtfelder, keine H1 außerhalb von Code-Blöcken, lückenlose Zitatnummerierung, jede Quelle zitiert, Slug-Format, Länge der Meta-Description und Mindestangaben je Quelle.
Humanize-Diff-Guard
Der Glättungsschritt darf nur Prosa ändern. Überschriften, Quellenblock, Zitatmarker als Multimenge, Linkziele und Tabellen müssen identisch bleiben.
Links-Guard
Jeder Link /blog/<slug> muss auf einen veröffentlichten Beitrag zeigen. Das Inventar holt der Server selbst, das Modell liefert es nicht mit.
Unabhängige Faktenprüfung
Der Faktenprüfer liest die Originalextraktion jeder zitierten Quelle, nicht die Zusammenfassung des Schreibers, und urteilt pro Aussage.
Vier Freigabe-Gates
Thema, Ergebnis der Faktenprüfung, Hero-Bild und Live-Schaltung entscheidet ein Mensch. Das Bild wird bewusst nicht von einer KI geprüft, weil deren Plausibilitätsurteil unzuverlässig ist.
Format ist Daten
Redaktionelle Regeln stehen in einem Style-Guide-Dokument im Store und sind ohne Deploy änderbar. Nur die Struktur-Invarianten stecken im Code.
Sonderfälle
- Wenn der Faktenprüfer nach zwei Korrekturrunden noch nicht belegte Aussagen findet, eskaliert er an den Menschen, statt weiter umzuschreiben.
- Wenn ein interner Link auf einen Beitrag zeigt, der nur in der Deckungskarte, aber nicht live existiert, lehnt der Links-Guard ihn ab, weil er gegen den Live-Bestand prüft.
- Wenn der MCP-Server neu deployt wurde und eine alte Session-ID ankommt, antwortet er mit 404 statt 400, damit sich der Client neu initialisiert.
- Wenn ein laufender Chat-Turn abgebrochen werden soll, beendet !stop ihn per AbortController und Prozess-Kill, die Sitzung bleibt fortsetzbar; !abbrechen verwirft den Vorgang. Ein Guard verhindert doppelten Start.
- Wenn einem Agenten keine Shell zur Verfügung steht, liest er Learnings über den Fallback, das MCP-Werkzeug learning_find, statt auf einen falschen Store auszuweichen.
- Wenn der Publish-Endpunkt direkt statt über die Hauptdomain aufgerufen wird, liefert er 404, weil erst das CDN am Rand den Auth-Header setzt.
Technische Hürden
- 01
Problem
Die deutsche Volltextsuche traf Umlaut- und ASCII-Formen nicht symmetrisch: „Handtücher“ fand „handtuecher“ nicht.
Lösung
Eine gemeinsame, unveränderliche Normalisierungsfunktion search_norm (Kleinschreibung, ä→ae, unaccent) läuft auf der gespeicherten Spalte und auf dem Suchbegriff.
- 02
Problem
Vektor-Retrieval liefert die ähnlichste Quelle, der Faktencheck braucht aber exakt die zitierte.
Lösung
Bewusst kein Vektor-Retrieval: exaktes Lesen per Kennung plus Stichwort-Volltextsuche. pgvector ist nicht aktiviert.
- 03
Problem
Der erste Extraktionspass übersah in den 69 klinischen Studien 8 schwere Fehler, etwa vertauschte Gruppen, verwechselte Zeitpunkte und einen Standardfehler, der als Standardabweichung gelesen wurde.
Lösung
Ein zweiter, adversarialer Pass mit einem stärkeren Modell prüft gegen den PDF-Volltext. Gefundene Fehler werden dokumentiert statt still korrigiert.
- 04
Problem
Der Publish-Vertrag zeigte Details erst im Live-Betrieb: Kategorie ist Pflicht, und ein Update validiert den vollen Payload.
Lösung
Der Publish-Client sendet immer den vollständigen Payload mit Kategorie; ein Live-Verifikationsskript prüft den Pfad bis zur Veröffentlichung und zurück auf Draft.
Dienste und Datenschutz
| Aufgabe | Anbieter |
|---|---|
| Server, Betrieb über Coolify | Hetzner |
| Studien-PDFs und Bild-Assets | Hetzner Object Storage (Nürnberg) |
| Datenbank | PostgreSQL, selbst betrieben |
| Text-Agenten und Verifikation | Anthropic Claude über Claude Code |
| Bildgenerierung | Google Gemini API |
| Bildauslieferung und Edge-Gate vor dem Publish-Endpunkt | Bunny CDN |
| Chat-Cockpit und Push | Matrix (Synapse, selbst gehostet), ntfy mit UnifiedPush |
- Soft-Delete mit Papierkorb und Wiederherstellung für alle Domänen
- Mandantentrennung per owner_id
- Presigned URLs für den Zugriff auf S3-Objekte
Verarbeitet werden veröffentlichte wissenschaftliche Studien, keine personenbezogenen Kundendaten.
Betrieb und Tests
Drei Prozesse aus einem Repository: der MCP-Server, der Kopf-Container mit Claude Code und die Chat-Brücke mit Cron. Deploy über Coolify automatisch bei Push auf main.
38 Testdateien mit 309 Tests (Vitest) decken Repositories, Werkzeuge, Migrationen, Guards, den Publish-Client mit Signer, Chat-Bot und Grammatik, HTTP-Verdrahtung, Korpus- und PDF-Ingest sowie S3 ab.
Live-Verifikationsskripte laufen gegen die Produktion, unter anderem für MCP, Learnings, Content, Blog-Publish, interne Links, Kopf und Bot. Der Publish-Test legt einen Draft an, schaltet ihn live und setzt ihn wieder auf Draft.
Betriebsmodus ist assistiert, mit einem Menschen im Chat. Ein vollautomatischer Autopilot ist bewusst nicht gebaut.