KI-Email-RAG-System: Automatisierte Postfach-Verarbeitung

Ein vollständiges System für ein einzelnes Postfach: Emails automatisiert kategorisieren, verarbeiten und halb- oder vollautomatisch beantworten. Mit lokalem LLM, SQL-, Vektor- und Graph-Datenbank, account-spezifischen Prompts, Protokollierung und GUI.

Ziel, Scope und Entscheidungsgrenzen

Vor der Implementierung müssen 14 Definitionsblöcke formal festgelegt werden. Jeder Block beantwortet Fragen, die die Architektur, die Entscheidungslogik und die Qualitätskriterien des Systems bestimmen. Ohne diese Definitionen ist jede technische Entscheidung beliebig.

Die zentrale Frage lautet nicht: Welche Technik verwenden wir? Die zentrale Frage lautet: Welche Entscheidungen darf das System unter welchen Bedingungen mit welchen Daten und mit welcher Nachweisbarkeit treffen?

BlockThemaKernfrage
1Zielbild des SystemsWas soll das System leisten und was ausdrücklich nicht?
2Scope des ersten ReleasesWas wird in V1 umgesetzt und was ist bewusst verschoben?
3Automationsgrad und EntscheidungsrechteWann darf das System eigenständig handeln?
4Fachliche ObjektdefinitionenWelche Objekte existieren und welche Felder haben sie?
5Prozessgrenzen und SollprozessWie sieht der vollständige Verarbeitungsweg einer Email aus?
6Kategorien, Prioritäten und AktionsmatrixWelche Kombination aus Kategorie, Priorität und Konfidenz löst welche Aktion aus?
7Datenquellen und WahrheitsquellenWelche Datenbank ist für welche Daten maßgeblich?
8Retrieval und WissenslogikWelche Inhalte werden wie gechunkt, eingebettet und durchsucht?
9LLM-Aufgaben und Prompt-ArchitekturWelche LLM-Aufgaben existieren und wie ist jede spezifiziert?
10Sicherheits- und DatenschutzmodellWelche Daten werden wie geschützt und wer darf was?
11Betriebsmodell und LastannahmenWie viele Emails pro Stunde, welche Latenz, welches RAM-Budget?
12Fehlerklassen und Fallback-RegelnWas passiert bei welchem Fehler?
13API- und IntegrationsgrenzenWelche Endpunkte, Rollen und Idempotenzregeln gelten?
14Qualitätsmodell und AbnahmeWoran erkennen wir messbar, dass das System funktioniert?

Block 1: Zielbild des Systems

Das Zielbild definiert den exakten Zweck des Systems. Ohne diese Definition ist jede spätere Architekturentscheidung beliebig.

FestlegungDefinition
PrimärzielEin einzelnes Email-Postfach vollständig verarbeiten: Emails automatisiert kategorisieren, Wissen extrahieren, in drei Datenbanken speichern und Antwort-Entwürfe generieren. Alle Daten bleiben lokal.
SekundärzieleAbsender-Profile aufbauen, Beziehungsnetzwerk aus Email-Kommunikation ableiten, Suchbarkeit über alle historischen Emails herstellen, Antwortqualität durch Feedback-Loop verbessern.
Nicht-ZieleKein Multi-Postfach-System. Kein Ticketsystem. Kein CRM. Kein Newsletter-Versand. Keine Kalenderverwaltung. Kein Spam-Filter (Vorfilterung durch Mailserver). Kein Cloud-LLM.
Erfolgskriterien90% der Emails werden korrekt kategorisiert. Antwort-Entwürfe werden in weniger als 50% der Fälle substanziell geändert. Substanziell bedeutet: Diff-Anteil über 30% der Zeichenlänge oder inhaltliche Korrektur (nicht nur Formatierung, Anrede oder Signatur). Durchschnittliche Verarbeitungszeit unter 90 Sekunden pro Email (dominiert durch sequentielle LLM-Aufrufe). Keine Email geht verloren.
AbbruchkriterienKategorisierungsgenauigkeit unter 70% nach 500 verarbeiteten Emails. Mehr als 5% Fehlzustellungen, die nicht innerhalb von 24 Stunden durch Audit-Log-Prüfung oder Absender-Rückmeldung erkannt werden. LLM-Antworten werden in über 80% der Fälle verworfen.
Maximal erlaubte FehlerklassenFalsch-positive Automatik-Antwort: 0 (darf nicht passieren). Falsche Kategorisierung: tolerierbar mit manueller Korrektur. LLM-Timeout: tolerierbar mit Fallback in manuelle Queue.

Block 2: Scope des ersten Releases

V1 hat einen harten Scope. Alles außerhalb wird bewusst verschoben, nicht vergessen. ArangoDB und Relationsextraktion sind von Anfang an integraler Bestandteil des Systems. Der Knowledge Graph ist kein optionales Feature, sondern Kern der Architektur. Gleichzeitig ist das System so gebaut, dass ein temporärer ArangoDB-Ausfall den Betrieb nicht blockiert: Emails werden weiterhin kategorisiert, eingebettet und beantwortet — der Graph-Kontext fehlt dann im Retrieval, bis ArangoDB wieder verfügbar ist.

DimensionV1 ScopeBewusst verschoben
PostfächerEin einzelnes IMAP-PostfachMulti-Postfach, Exchange/Graph-API
MailtypenEingehende Emails, Antworten auf eigene MailsKalendereinladungen, Lesebestätigungen, Bounces
AnhängePDF, Bilder (JPEG/PNG)DOCX, XLSX, ZIP, Audio, Video
SprachenDeutsch, EnglischWeitere Sprachen
KategorisierungAutomatisch mit LLM, manuell korrigierbarTrainierbare Klassifikatoren, Fine-Tuning
AntwortgenerierungEntwürfe zur manuellen FreigabeVollautomatischer Versand (erst ab V2 nach Qualitätsnachweis)
GUIDashboard, Email-Ansicht, Antwort-Editor, KonfigurationMobile App, Echtzeit-Benachrichtigungen
APICRUD für Emails, Threads, Kategorien. Hybrid Search. Freigabe-EndpointWebhooks, externe Integrationen, Batch-Operationen
BetriebSystemd-Service, Health-Check, Cron-basiertes PollingIMAP IDLE (Push), Kubernetes, Horizontale Skalierung

Block 3: Automationsgrad und Entscheidungsrechte

Für jede Aktion, die das System ausführen kann, muss festgelegt sein, ob sie automatisch, nach Freigabe oder gar nicht erlaubt ist.

AktionV1 AutomationsgradBedingung
Email abrufen und speichernVollautomatischImmer
Email parsen (MIME, Header, Body)VollautomatischImmer
Thread zuordnenVollautomatischÜber Message-ID/References-Header
Anhänge extrahieren und speichernVollautomatischNur unterstützte Formate (PDF, Bilder)
KategorisierenVollautomatischLLM-Klassifikation + Regelvorfilter. Ergebnis immer sichtbar und korrigierbar
Priorität zuweisenVollautomatischAus Kategorie, Absender-Profil und Sentiment abgeleitet
Stimmung analysierenVollautomatischLLM-basiert, gespeichert als Metadatum
In Wissensbasis aufnehmen (Ingest)VollautomatischChunking, Embedding, NER, Relationsextraktion
Antwort-Entwurf generierenVollautomatischFür Kategorien anfrage, beschwerde, bestellung, intern — wenn Klassifikation erfolgreich. Kein Entwurf für information, newsletter, spam. Nur als Entwurf gespeichert, nie direkt versendet
Antwort freigeben und versendenNur nach manueller FreigabeIn V1 keine Vollautomatik. Mensch prüft und gibt frei
Email verschieben/labeln/archivierenNur nach manueller FreigabeSystem schlägt vor, Mensch bestätigt
Email löschenNicht erlaubtSystem darf keine Emails löschen
Externes System anstoßenNicht erlaubt in V1Keine Webhooks, keine API-Calls nach außen

Entscheidungsrecht: Der Mensch hat in V1 das letzte Entscheidungsrecht über jede ausgehende Kommunikation und jede destruktive Aktion.

Block 4: Fachliche Objektdefinitionen

Jedes zentrale Objekt im System muss eindeutig definiert sein, bevor das Datenmodell entworfen wird.

ObjektDefinitionPflichtfelderErzeugt durchLebensdauer
MailboxDas angebundene IMAP-Postfach mit Zugangsdaten und Konfigurationhost, port, user, password_encrypted, display_nameAdmin bei EinrichtungPermanent
EmailEine einzelne empfangene oder gesendete Nachrichtmessage_id, from, to, subject, date, body_text, body_html, raw_mimeIMAP-AbrufGemäß Aufbewahrungsfrist
ThreadEine Konversation aus zusammengehörigen Emailsthread_id, subject_normalized, email_ids[], participant_ids[]Thread-ZuordnungslogikSolange zugehörige Emails existieren
KontaktprofilAggregiertes Profil eines Absenders/Empfängersemail_address, display_name, first_seen, last_seen, email_countAutomatisch bei erster EmailGemäß DSGVO-Löschfrist
AnhangEine Datei, die einer Email beigefügt istfilename, mime_type, size_bytes, email_id, storage_pathMIME-ParsingAn Email gebunden
KategorieKlassifikation einer Email nach Typname, parent_category_id (nullable), descriptionAdmin-KonfigurationPermanent, versioniert
KlassifikationZuordnung einer Email zu einer Kategorieemail_id, category_id, confidence, source (rule|llm|manual), created_atRegelengine oder LLMAn Email gebunden
PrioritätDringlichkeitsstufe einer Emaillevel (critical|high|normal|low), email_id, reasonPrioritätslogikAn Email gebunden
StimmungSentiment-Bewertung einer Emailemail_id, sentiment (positive|neutral|negative|angry), confidenceLLM-AnalyseAn Email gebunden
EntitätErkannte benannte Entität aus Email-Textname, normalized_name, type (PER|ORG|LOC|MISC), source_email_idSpaCy NER + RegexPermanent im Graph
RelationBeziehung zwischen zwei Entitätensource_entity_id, target_entity_id, relation_type, source_email_idLLM-ExtraktionPermanent im Graph
PromptSystem-Prompt für eine LLM-Aufgabetask_type, prompt_text, model, temperature, max_tokens, versionAdmin-KonfigurationPermanent, versioniert
TemplateWiederverwendbare Antwortvorlagename, body_template, placeholders[], category_id (nullable)Admin-KonfigurationPermanent, versioniert
Antwort-EntwurfVom LLM generierter Antwortentwurfemail_id, draft_text, prompt_id, confidence, status (draft|approved|rejected|sent)AntwortgenerierungAn Email gebunden
FreigabeMenschliche Entscheidung über einen Entwurfdraft_id, action (approve|reject|edit), editor_id, edited_text (nullable), created_atMensch über GUIPermanent (Audit)
Audit-EintragUnveränderliches Protokoll einer Systemaktiontimestamp, action_type, entity_type, entity_id, actor (system|user), details_jsonJede SystemkomponentePermanent (append-only)
RegelRegelbasierte Zuordnungslogik (vor LLM)name, condition_type (regex|sender|keyword), condition_value, action, priority_orderAdmin-KonfigurationPermanent, versioniert
Queue-EintragEmail in der Verarbeitungswarteschlangeemail_id, status (pending|processing|done|failed|dead), priority, retry_count, next_retry_atIMAP-AbrufBis Verarbeitung abgeschlossen
LLM-LogRequest/Response-Paar eines LLM-Aufrufstask_type, prompt, response, model, tokens_in, tokens_out, latency_ms, email_idLLM-AufrufeGemäß Aufbewahrungsfrist
VerarbeitungslaufEin vollständiger Pipeline-Durchlauf für eine Email. Bündelt alle Schritte (Parsing bis Entwurf) als nachvollziehbare Einheitrun_id, email_id, status (pending|running|done|failed|partial), started_at, finished_at, steps_completed[], error_step (nullable)Queue-Worker bei VerarbeitungsbeginnPermanent (Audit). Ermöglicht gezieltes Reprocessing einzelner Emails
Account-RegelwerkGebündelte Konfiguration pro Mailbox: Prompts, Regeln, Templates, Schwellwerte als zusammengehörige Einheitmailbox_id, name, prompt_ids[], rule_ids[], template_ids[], confidence_thresholds{}, version, activeAdmin-KonfigurationPermanent, versioniert. Wechsel zwischen Regelwerk-Versionen ohne Datenverlust
FeedbackDiff zwischen LLM-Entwurf und menschlich editierter Antwort. Datengrundlage für Prompt-Optimierungdraft_id, email_id, original_text, edited_text, diff_ratio, edit_type (formatting|content|tone|rejected), created_atAutomatisch bei Versand eines editierten EntwurfsPermanent
ZusammenfassungEinzeiler-Zusammenfassung einer Email. Feld in der Email-Tabelle, nicht eigenständiges ObjektGespeichert als summary-Feld in Email (nullable VARCHAR(500))LLM-Aufruf (gebündelt mit Klassifikation)An Email gebunden

Verhältnis der drei Status-Systeme

Das System verwendet drei getrennte Status-Felder, die unterschiedliche Perspektiven abbilden:

Block 5: Prozessgrenzen und Sollprozess

Der vollständige Verarbeitungsweg einer eingehenden Email, Schritt für Schritt. Jeder Schritt hat definierte Ein- und Ausgaben, Vorbedingungen und Fehlerverhalten.

SchrittInputOutputVorbedingungFehlerverhalten
1. IMAP-AbrufIMAP-VerbindungsdatenRohe Email (RFC 5322)IMAP erreichbar, Credentials gültigRetry mit Backoff. Nach 5 Fehlversuchen: Alert
2. Rohdaten-SpeicherungRohe EmailEmail-Datensatz in MariaDB mit raw_mimeMariaDB erreichbarTransaktion rollback. Email bleibt auf IMAP unmarkiert
3. MIME-Parsingraw_mimeStrukturierte Felder: body_text, body_html, headers, attachment_listEmail in DB gespeichertParsing-Fehler: Email als unparseable markieren, in manuelle Queue
4. Thread-ZuordnungMessage-ID, In-Reply-To, Referencesthread_id (existierend oder neu)Email geparstKein Match: neuen Thread erstellen. Mehrdeutig: manuell zuordnen
5. Anhang-ExtraktionMIME-Parts mit Content-Disposition: attachmentGespeicherte Dateien + Anhang-DatensätzeEmail geparstNicht unterstütztes Format: Anhang als unsupported markieren, Metadaten trotzdem speichern
6. Kontaktprofil-UpdateFrom, To, CC HeaderAktualisierte KontaktprofileEmail geparstUnkritisch: bei Fehler nur loggen
7. Regelbasierte VorfilterungEmail-Felder + RegelkatalogKategorie (wenn Regel greift) oder weiter zu LLMRegeln konfiguriertFehler in Regel: überspringen, LLM entscheidet
8. LLM-KlassifikationEmail-Body + Thread-Kontext + PromptKategorie + Unterkategorie + KonfidenzOllama erreichbar, Modell geladenTimeout: Email als unclassified in manuelle Queue. Ungültiges JSON: Retry 1x, dann manuell
9. Priorität + SentimentKategorie + Absender-Profil + Email-BodyPrioritätsstufe + StimmungsbewertungKlassifikation abgeschlossenUnkritisch: Defaults (normal/neutral) bei Fehler
10. NER + EntitätsextraktionEmail-Body (bereinigt)Entitäten-Liste (PER, ORG, LOC, MISC)SpaCy geladenSpaCy nicht verfügbar: überspringen, ohne Entitäten weiter
11. Chunking + EmbeddingEmail-Body + MetadatenChunks mit Vektoren in Qdrant + MariaDBsentence-transformers geladen, Qdrant erreichbarEmbedding-Fehler: Email als not_embedded markieren, manuell nacharbeiten
12. RelationsextraktionEmail-Body + erkannte EntitätenRelationen im ArangoDB-GraphEntitäten vorhanden, ArangoDB erreichbarLLM-Fehler: überspringen, Graph bleibt unvollständig
13. RAG-AnreicherungEmail + Thread-Historie + Hybrid Search ErgebnisKontextdokument für AntwortgenerierungMariaDB erreichbar (Pflicht). Qdrant und ArangoDB optional (graceful degradation: ohne Qdrant kein Dense Search, ohne ArangoDB kein Graph-Kontext)Teilfehler: mit verfügbarem Kontext weitermachen. Nur Sparse Search wenn Qdrant fehlt
14. Antwort-EntwurfKontextdokument + Account-Prompt + TemplateAntwort-Entwurf mit KonfidenzKlassifikation + RAG abgeschlossenLLM-Fehler: kein Entwurf, Email wartet auf manuelle Antwort
15. FreigabeEntwurf in GUI angezeigtFreigabe/Ablehnung/Bearbeitung durch MenschEntwurf generiertKein Fehler möglich (menschlicher Schritt)
16. SMTP-VersandFreigegebener Entwurf + Email-HeaderGesendete Antwort mit korrekten Reply-HeadernFreigabe erteilt, SMTP erreichbarVersand-Fehler: Retry 3x mit Backoff. Danach: manuelle Eskalation
17. ProtokollierungAlle Ergebnisse der Schritte 1-16Audit-Einträge (append-only)KeineLogging-Fehler: stderr + Alert, Verarbeitung geht weiter
18. Feedback-SpeicherungDiff zwischen Entwurf und finaler AntwortFeedback-Datensatz für Prompt-OptimierungAntwort versendet UND Entwurf wurde editiertUnkritisch: bei Fehler nur loggen

Zustandsmaschine einer Email

Jede Email durchläuft definierte Zustände. Übergänge sind atomar — ein Zustand wird erst gesetzt, wenn der zugehörige Schritt erfolgreich abgeschlossen ist.

ZustandBedeutungCommit-GrenzeIMAP-Flag
fetchedRohdaten in MariaDB gespeichertNach INSERT in emails-Tabelle + raw_mime gespeichertNoch nicht als gesehen markiert
parsedMIME zerlegt, Header/Body/Anhänge strukturiertNach UPDATE der strukturierten Felder in emailsNoch nicht als gesehen markiert
classifiedKategorie, Priorität, Sentiment zugewiesenNach INSERT in classifications + UPDATE priority/sentimentJetzt als gesehen markiert auf IMAP
indexedChunks in MariaDB + Vektoren in Qdrant + Entitäten/Relationen in ArangoDBNach erfolgreicher Synchronisation aller drei DatenbankenBereits markiert
partially_indexedMariaDB-Chunks vorhanden, aber Qdrant oder ArangoDB fehlgeschlagenSofort bei Teilfehler gesetztBereits markiert
draft_readyAntwort-Entwurf generiert und gespeichertNach INSERT in drafts-TabelleBereits markiert
awaiting_reviewEntwurf wartet auf menschliche FreigabeSofort nach draft_ready, wenn kein FehlerBereits markiert
approvedMensch hat Entwurf freigegebenNach INSERT in approvals-TabelleBereits markiert
sentAntwort per SMTP versendetNach SMTP-Bestätigung + UPDATE statusBereits markiert
rejectedEntwurf verworfen, neuer Entwurf möglichNach INSERT in approvals mit action=rejectBereits markiert
archivedEmail ohne Antwort-Bedarf abgeschlossen (information, newsletter, spam)Nach manueller Bestätigung oder automatisch bei Kategorie ohne EntwurfBereits markiert
failedKritischer Fehler, manuell zu prüfenSofort bei unkompensiertem FehlerNicht markiert, wenn vor classified

Entscheidende Grenze: Die Email wird auf IMAP erst als gesehen markiert, wenn der Zustand classified erreicht ist. Scheitert die Verarbeitung vorher, wird die Email beim nächsten Polling erneut abgerufen. Ab classified ist die Email in MariaDB als Source of Truth gesichert und der IMAP-Zustand ist unkritisch.

Block 6: Kategorien, Prioritäten und Aktionsmatrix

Die Entscheidungslogik des Systems wird als Matrix formalisiert. Jede Kombination aus Kategorie, Priorität und Konfidenz ergibt eine definierte Aktion.

Hauptkategorien (V1)

KategorieBeschreibungUnterkategorien (Beispiele)
anfrageFrage oder Informationsanforderungprodukt, preis, termin, allgemein
beschwerdeUnzufriedenheit oder Reklamationlieferung, qualitaet, service, rechnung
bestellungKaufabsicht oder Auftragserteilungneu, aenderung, stornierung
informationMitteilung ohne direkten Handlungsbedarfstatusupdate, bestaetigung, weiterleitung, benachrichtigung, automatische-antwort
internInterne Kommunikationabstimmung, freigabe, info
newsletterAutomatisierter Massenversandmarketing, branche, service
spamUnerwünschte oder irrelevante Emailwerbung, phishing, irrelevant

Prioritätsstufen

StufeKriteriumMax. Reaktionszeit
criticalBeschwerde + negatives Sentiment + VIP-Absender1 Stunde
highBeschwerde oder Bestellung oder kritischer Absender4 Stunden
normalStandardanfrage, interne Kommunikation24 Stunden
lowNewsletter, Information ohne HandlungsbedarfKeine Frist

Aktionsmatrix (V1)

Die Aktionsmatrix verwendet die korrigierte Konfidenz (nach heuristischer Anpassung gemäß Block 9, Abschnitt Konfidenz-Herkunft).

KategoriePrioritätKonfidenzAktion
anfragenormal/high≥ 0.8Entwurf generieren, Freigabe anfordern
anfragebeliebig< 0.8Nur kategorisieren, manuelle Bearbeitung
beschwerdecritical/highbeliebigEskalation: sofort in GUI hervorheben, Entwurf generieren
beschwerdenormal≥ 0.8Entwurf generieren, Freigabe anfordern
beschwerdenormal/low0.5-0.79Kategorisieren, in manuelle Queue, kein Entwurf
bestellungbeliebig≥ 0.7Entwurf generieren (Bestätigung), Freigabe anfordern
informationbeliebig≥ 0.9Archivieren (nach Freigabe), kein Entwurf
internbeliebig≥ 0.8Entwurf generieren, Freigabe anfordern
newsletterlow≥ 0.95Automatisch als gelesen markieren (nach Freigabe)
spamlow≥ 0.95In Spam-Ordner verschieben (nach Freigabe)
beliebigbeliebig< 0.5Keine automatische Aktion, nur in manuelle Queue

Block 7: Datenquellen und Wahrheitsquellen

Bei drei Datenbanken muss eindeutig festgelegt sein, welche Datenbank für welche Daten die Wahrheit enthält.

DatenbankEnthältIst Source of Truth fürBei Konflikt
MariaDBEmails, Threads, Kontaktprofile, Kategorien, Entwürfe, Audit-Log, Queue, Chunks, Entitäten, Relationen, LLM-Logs, Regeln, Prompts, TemplatesAlle transaktionalen und Konfigurations-DatenMariaDB gilt immer
QdrantVektoren der Email-Chunks, Metadaten pro VektorSemantische ÄhnlichkeitssucheVektor-Neuberechnung aus MariaDB-Chunks
ArangoDBEntitäten als Knoten, Relationen als KantenGraph-Traversal und BeziehungsabfragenNeuaufbau aus MariaDB-Entitäten und -Relationen

Synchronitätsregeln:

Block 8: Retrieval und Wissenslogik

Was wird gechunkt, eingebettet und durchsucht — und was nicht.

FestlegungDefinition
Chunk-QuelleNur der bereinigte Email-Body (Text-Version). Keine HTML-Tags, keine Signatur, kein Quoted-Text aus vorherigen Antworten
Chunk-StrategieAbsatzbasiert. Jeder Absatz ist ein Chunk, es sei denn er überschreitet 512 Zeichen — dann wird am nächsten Satzende geteilt
Chunk-OverlapKein Overlap. Absätze sind natürliche Sinneinheiten
Chunk-Metadatenemail_id, thread_id, sender_email, date, category, priority, chunk_position
Embedding-Modellintfloat/multilingual-e5-large-instruct, 1024 Dimensionen
Embedding-Prefixe"query: " für Suchanfragen, "passage: " für Email-Chunks
Was wird eingebettetBereinigter Body-Text als Chunks. Betreff als separater Chunk mit Metadatum subject=true. Anhänge (PDF-Text) als eigene Chunks mit Metadatum attachment_id
Was wird nicht eingebettetHTML-Markup, Signaturen, Disclaimer, Quoted-Text, Header-Rohdaten
Hybrid Search GewichtungDense (Qdrant): 0.5, Sparse (MariaDB FULLTEXT): 0.3, Graph (ArangoDB): 0.2. Fusion via Reciprocal Rank Fusion
Graph-KontextBei Antwortgenerierung: Graph-Traversal Tiefe 1 ab erkannten Entitäten der aktuellen Email. Ergebnis als zusätzlicher Kontext im Prompt
DublettenverhinderungVor Ingest: Prüfung auf message_id in MariaDB. Identische message_id wird nicht erneut verarbeitet
Re-EmbeddingNur bei Modellwechsel. Alle Chunks werden aus MariaDB gelesen und neu eingebettet. Alte Qdrant-Collection wird nach erfolgreicher Neuindexierung gelöscht
Thread-Kontext in KlassifikationBetreff + aktueller Body + Zusammenfassungen der letzten 3 Emails im Thread. Bei knappen Antworten (Body unter 50 Zeichen) wird der Betreff und die letzte vollständige Email im Thread als Primärkontext verwendet
Thread-Kontext in AntwortgenerierungVollständiger Body der letzten 5 Emails im Thread (bereinigt, ohne Quoted-Text). Zusätzlich: Hybrid Search Ergebnisse + Graph-Kontext. Maximales Kontextfenster: 4096 Tokens, danach Truncation der ältesten Emails

Block 9: LLM-Aufgaben und Prompt-Architektur

Jede LLM-Aufgabe ist ein eigenständiger Aufruf mit eigenem Prompt, eigenem Output-Schema und eigener Fehlerbehandlung.

AufgabeZielOutput-FormatModellTemperaturMax TokensFallback
Klassifikation+Sentiment+Zusammenfassung (gebündelt)Kategorie, Unterkategorie, Konfidenz, Stimmung, Einzeiler-Zusammenfassung in einem AufrufJSON: {category, subcategory, confidence, sentiment, sentiment_confidence, summary}qwen3:8b0.1512Manuelle Queue (bei Totalfehler). Betreff als Zusammenfassung, neutral als Sentiment-Default (bei Teilfehler)
EntitätserkennungErgänzend zu SpaCy: Vertragsnummern, Rechnungsnummern, FachbegriffeJSON: {entities: [{name, type}]}qwen3:8b0.1512Nur SpaCy-Ergebnisse
RelationsextraktionBeziehungen zwischen EntitätenJSON: {relations: [{source, target, type}]}qwen3:8b0.1512Keine Relationen für diese Email
Antwort-EntwurfKontextbasierte Antwort unter Einhaltung des Account-PromptsFreitext (Email-Body)qwen3:8b0.51024Kein Entwurf, manuelle Bearbeitung
QualitätsprüfungPrüfung des Entwurfs auf Halluzination und TonalitätJSON: {quality_ok, issues[]}qwen3:8b0.1256Entwurf trotzdem anzeigen, mit Warnung

Denkmodus: Klassifikation, Sentiment und Entitätserkennung laufen mit /no_think (schnell, deterministisch). Relationsextraktion und Antwort-Entwurf laufen mit /think (Reasoning für komplexe Aufgaben).

Konfidenz-Herkunft

Die Konfidenzwerte werden vom LLM als Teil der JSON-Ausgabe geliefert (self-reported confidence). LLM-Konfidenz ist nicht kalibriert — ein Wert von 0.9 bedeutet nicht, dass 90% der Klassifikationen mit diesem Wert korrekt sind. Deshalb wird die LLM-Konfidenz durch zwei heuristische Korrekturen ergänzt:

Prompt-Injection-Schutz

Email-Body wird vor Übergabe an LLM-Prompts in einen markierten Kontext-Block eingeschlossen (z.B. <email_content>...</email_content>). Der System-Prompt enthält eine explizite Anweisung, Anweisungen innerhalb des Kontext-Blocks nicht als System-Anweisungen zu interpretieren. Zusätzlich: Output-Validierung gegen das definierte JSON-Schema. Freitext-Felder (summary, draft) werden auf maximale Länge begrenzt.

Halluzinationsprüfung: Grenzen

Die Qualitätsprüfung des Antwort-Entwurfs verwendet dasselbe Modell (qwen3:8b), das den Entwurf generiert hat. Das ist eine strukturelle Schwäche: Das Modell erkennt eigene Halluzinationen nicht zuverlässig. Die Prüfung kann Formatfehler, fehlende Pflichtbestandteile und offensichtliche Widersprüche zum Kontext erkennen. Sie kann nicht garantieren, dass alle Fakten im Entwurf korrekt sind. Deshalb bleibt in V1 die menschliche Freigabe die primäre Halluzinationsschranke.

Block 10: Sicherheits- und Datenschutzmodell

FestlegungRegel
DatenverarbeitungAlle Email-Inhalte, Vektoren, Graph-Daten und LLM-Prompts/Responses bleiben auf dem lokalen Server. Kein externer API-Aufruf für Inhalte
Personenbezogene DatenEmail-Adressen, Namen, Absender-Profile, Kommunikationsinhalte sind personenbezogen im Sinne der DSGVO
LöschpflichtAuf Anfrage: Alle Emails eines Absenders, dessen Kontaktprofil, zugehörige Vektoren in Qdrant, zugehörige Knoten/Kanten in ArangoDB, zugehörige Audit-Einträge (anonymisiert, nicht gelöscht)
AuskunftspflichtAuf Anfrage: Welche Emails, Kategorisierungen, Entwürfe und Entitäten zu einer Person gespeichert sind. Export als JSON oder PDF
Verschlüsselung TransitTLS für IMAP und SMTP. HTTPS für GUI und API
Verschlüsselung RuheDatenbank-Verbindungen verschlüsselt. Email-Bodies optional AES-256-verschlüsselt in MariaDB (konfigurierbar)
CredentialsIMAP/SMTP-Passwörter AES-256-verschlüsselt in Konfigurationsdatei. Nicht in Versionskontrolle. Environment-Variablen als Alternative
RollenAdmin: Konfiguration, Prompts, Regeln, API-Keys. Operator: Freigabe, Email-Ansicht, Suche. Viewer: Nur lesen, kein Versand
API-AuthentifizierungBearer-Token im Authorization-Header. Tokens mit Scope-Einschränkung (read, write, admin). Token-Rotation erzwungen alle 90 Tage
Token-LifecycleErstellung nur durch Admin-Rolle. Jeder Token hat: Erstellungsdatum, Ablaufdatum (max. 90 Tage), letzter Zugriff, Scope, Ersteller-ID. Widerruf sofort wirksam (Token-Blacklist in MariaDB). Alle Token-Operationen werden im Audit-Log erfasst
Interner vs. externer ZugriffLokale Anfragen (127.0.0.1, ::1) dürfen den Health-Endpoint ohne Token nutzen. Alle anderen Endpoints erfordern immer einen gültigen Token, unabhängig von der Herkunft. Kein impliziter Trust für lokale IPs bei schreibenden Operationen
IP-EinschränkungOptional konfigurierbar pro Token: Whitelist erlaubter IP-Adressen oder CIDR-Bereiche. Wenn gesetzt, werden Anfragen von nicht-gelisteten IPs abgelehnt (403), auch mit gültigem Token
Audit jeder API-NutzungJeder API-Aufruf wird protokolliert: Zeitstempel, Token-ID (nicht Token-Wert), Endpoint, Methode, Response-Code, IP-Adresse. Bei schreibenden Operationen zusätzlich: Request-Body-Hash für Nachvollziehbarkeit

Block 11: Betriebsmodell und Lastannahmen

Das Zielprofil ist ein aktives Geschäftspostfach mit etwa 1.000 Emails pro Tag. Die Architektur muss dieses Volumen mit akzeptabler Latenz verarbeiten können, ohne dass die Queue dauerhaft wächst.

ParameterAnnahme V1Begründung
Mails pro Tag~1.000Aktives Geschäftspostfach mit Kundenanfragen, internem Verkehr und automatisierten Benachrichtigungen
Peak pro Stunde200Morgenstunden 08:00-10:00 nach Nacht-Akkumulation, Montag nach Wochenende
Durchschnitt pro Stunde~421.000 Mails / 24h = ~42/h über 24h. Reale Verteilung: 80% zwischen 07:00-19:00 = ~67 Mails/h in Geschäftszeiten, ~17/h nachts
Gleichzeitige Verarbeitungen2 Worker (Pipeline) + 1 LLM (sequentiell)Parsing, Embedding und NER parallelisierbar. LLM-Aufrufe sequentiell wegen RAM. Worker füllen die LLM-Queue vor
Max. LLM-Aufrufe pro Email3-5Klassifikation+Sentiment+Zusammenfassung (gebündelt, 1 Aufruf) + Entitäten + Relationen + Entwurf + optional Qualitätsprüfung
LLM-Durchsatz erforderlich~800 Aufrufe/Stunde im Peak200 Mails × ~4 Aufrufe = 800. Bei 10s/Aufruf und 1 LLM: 360/h Kapazität. Peak-Rückstand wird in Nebenzeiten abgebaut. Queue-Backlog von ~2h im Worst Case akzeptabel (Block 11: Max. Rückstand 2h)
Max. Anhangsgröße25 MBStandard-Email-Limit
Max. Threadtiefe50 Emails pro ThreadDarüber hinaus: nur letzte 50 für Kontext
Max. Verarbeitungszeit pro Email90 Sekunden (ohne Anhänge)Parsing (~1s) + 3-5 LLM-Aufrufe à ~10s (~30-50s) + Embedding (~5s) + NER (~2s) + Graph (~2s) + Overhead. LLM dominiert
Max. Verarbeitungszeit mit OCR180 SekundenOCR für Bilder/Scans ist CPU-intensiv, läuft parallel zum LLM-Worker
Queue-Kapazität50.000 EinträgeMehrtägiger Puffer bei Ausfall oder Wartung
Max. erlaubter Queue-Rückstand2 StundenWenn Queue-Alter > 2h: Alert. System muss schneller verarbeiten als Mails eingehen
RAM-Budget LLM (qwen3:8b)6 GBQ4_K_M-Quantisierung, 5.2 GB Download + Overhead
RAM-Budget Embedding2 GBmultilingual-e5-large-instruct
RAM-Budget gesamt32 GB empfohlenLLM (6) + Embedding (2) + MariaDB (2) + Qdrant (2) + ArangoDB (2) + SpaCy (1) + FastAPI (1) + Worker (2) + OS (4) + Reserve (8)
Disk I/OSSD/NVMe erforderlichBei 1.000 Mails/Tag mit Anhängen: ~2-5 GB/Tag neue Daten. HDD zu langsam für parallele DB-Zugriffe
Recovery-Zeit nach Ausfall< 5 MinutenSystemd-Restart. Emails auf IMAP bleiben erhalten, Queue wird ab letztem Stand fortgesetzt
IMAP-Polling-Intervall30 SekundenBei 200 Mails/h im Peak: 30s-Intervall erfasst ~2 Mails pro Poll. Reduziert Queue-Latenz gegenüber 60s

Block 12: Fehlerklassen und Fallback-Regeln

FehlerklasseErkennungRetryBackoffFallback
IMAP nicht erreichbarConnection TimeoutJa, unbegrenztExponentiell: 1m, 2m, 4m, max 15mAlert nach 3 Fehlversuchen. Emails bleiben auf Server
SMTP nicht erreichbarConnection Timeout3xExponentiell: 30s, 60s, 120sEntwurf bleibt als approved, Retry per Cron
MIME-Parsing fehlgeschlagenException im ParserNein-Email als unparseable markieren, manuelle Queue, raw_mime erhalten
Anhang nicht lesbarOCR/PDF-FehlerNein-Anhang-Metadaten speichern, Inhalt als nicht indexierbar markieren
LLM-TimeoutResponse > 60s1xSofortAufgabe überspringen, Email in manuelle Queue
LLM-Ungültiges JSONJSON-Parse-Fehler1x mit angepasstem PromptSofortAufgabe überspringen, Default-Werte
Qdrant nicht erreichbarConnection Error3xExponentiell: 5s, 10s, 20sEmail als not_embedded markieren, Retry per Cron
ArangoDB nicht erreichbarConnection Error3xExponentiell: 5s, 10s, 20sEmail als not_graphed markieren, Retry per Cron
MariaDB-Transaktion fehlgeschlagenSQL Exception1xSofortRollback, Email bleibt auf IMAP unmarkiert, Alert
Dublette erkanntmessage_id bereits in DBNein-Email auf IMAP als gesehen markieren, nicht erneut verarbeiten
Thread-Zuordnung mehrdeutigMehrere mögliche ThreadsNein-Neuen Thread erstellen, manuell zusammenführbar
Embedding-FehlerException im Modell1xSofortEmail ohne Embedding speichern, Retry per Cron

Block 13: API- und Integrationsgrenzen

Ressourcen und Endpunkte (V1)

RessourceEndpunkteMethodenSync/Async
Emails/api/emails, /api/emails/{id}GET, GET(list)Synchron
Threads/api/threads, /api/threads/{id}GET, GET(list)Synchron
Kontaktprofile/api/contacts, /api/contacts/{id}GET, GET(list), PATCHSynchron
Kategorien/api/categories, /api/categories/{id}GET, POST, PATCH, DELETESynchron
Klassifikationen/api/emails/{id}/classificationGET, PATCH (manuelle Korrektur)Synchron
Entwürfe/api/emails/{id}/draftGET, PATCHSynchron
Freigabe/api/emails/{id}/draft/approvePOSTAsynchron (löst SMTP-Versand aus)
Verwerfen/api/emails/{id}/draft/rejectPOSTSynchron
Suche/api/searchPOST (query, filters)Synchron
Regeln/api/rules, /api/rules/{id}GET, POST, PATCH, DELETESynchron
Prompts/api/prompts, /api/prompts/{id}GET, POST, PATCHSynchron
Templates/api/templates, /api/templates/{id}GET, POST, PATCH, DELETESynchron
Queue/api/queueGET (list, filter by status)Synchron
Health/api/healthGETSynchron
Metriken/api/metricsGETSynchron
Audit/api/auditGET (list, filter by entity)Synchron
Re-Klassifizieren/api/emails/{id}/reclassifyPOSTAsynchron
Eskalieren/api/emails/{id}/escalatePOSTSynchron

Rollen und Scopes

RolleScopesDarf nicht
adminread, write, config, approve, delete-
operatorread, write, approveRegeln/Prompts/Templates ändern, API-Keys verwalten
viewerreadSchreiben, Freigeben, Konfigurieren

Idempotenzregeln: POST /approve und POST /reject sind idempotent (mehrfacher Aufruf ändert nichts nach erster Ausführung). GET-Endpunkte sind immer idempotent. Rate-Limit: 100 Requests/Minute pro API-Key.

Email-Statusmodell als API-Ressource

Jede Email hat einen maschinenlesbaren Status, der über die API abfragbar und filterbar ist:

StatusBedeutungErlaubte Übergänge
fetchedAbgerufen, Rohdaten gespeichert→ parsed, → failed
parsedMIME zerlegt, strukturiert→ classified, → failed
classifiedKategorie + Priorität zugewiesen→ indexed, → partially_indexed, → failed
indexedVollständig in allen 3 DBs→ draft_ready, → archived (wenn kein Entwurf nötig)
partially_indexedMariaDB OK, Qdrant/ArangoDB fehlend→ indexed (nach Retry), → draft_ready
draft_readyEntwurf generiert→ awaiting_review
awaiting_reviewWartet auf menschliche Freigabe→ approved, → rejected
approvedFreigegeben, Versand ausstehend→ sent, → failed
sentAntwort versendetTerminal
rejectedEntwurf verworfen→ awaiting_review (neuer Entwurf)
archivedAbgeschlossen ohne AntwortTerminal
failedKritischer Fehler→ fetched (manuelles Reprocessing)

Reprocessing-Endpunkte

EndpunktMethodeWirkungVorbedingung
/api/emails/{id}/reparsePOSTMIME-Parsing erneut ausführenStatus ≥ fetched
/api/emails/{id}/reclassifyPOSTKlassifikation + Sentiment + Priorität erneutStatus ≥ parsed
/api/emails/{id}/reindexPOSTChunking + Embedding + NER + Graph erneutStatus ≥ classified
/api/emails/{id}/redraftPOSTNeuen Antwort-Entwurf generierenStatus ≥ indexed
/api/emails/{id}/reprocessPOSTGesamte Pipeline ab fetched neu durchlaufenBeliebiger Status

Concurrency und Locking

API-Versionierung und Fehlercodes

Versionierung: In V1 laufen alle Endpunkte unter /api/ ohne Versions-Prefix. Bei Breaking Changes in V2 wird ein /api/v2/ Prefix eingeführt, wobei /api/ als Alias für die aktuellste Version dient. Non-breaking Erweiterungen (neue Felder, neue Endpunkte) werden ohne Versionswechsel ergänzt.

HTTP-CodeBedeutungWann
200ErfolgGET, PATCH
201ErstelltPOST (neue Ressource)
202Akzeptiert, asynchronPOST /approve, /reprocess, /reindex
400Ungültige AnfrageFehlende Pflichtfelder, ungültiges JSON
401Nicht authentifiziertFehlender oder ungültiger Token
403Nicht autorisiertToken-Scope reicht nicht, IP nicht erlaubt
404Nicht gefundenRessource existiert nicht
409KonfliktOptimistic Locking gescheitert, Dublette
422Semantischer FehlerStatusübergang nicht erlaubt, ungültige Referenz
429Rate-Limit überschrittenMehr als 100 Requests/Minute
500ServerfehlerUnerwarteter interner Fehler
503Service nicht verfügbarLLM, Qdrant oder ArangoDB nicht erreichbar

Block 14: Qualitätsmodell und Abnahme

Messbare Qualitätsziele

TeilbereichMetrikZielwert V1Messmethode
KlassifikationAccuracy (Hauptkategorie)≥ 90%100 manuell gelabelte Emails als Goldstandard
KlassifikationAccuracy (Unterkategorie)≥ 75%Gleicher Goldstandard
PriorisierungCritical/High korrekt erkannt≥ 95% RecallGoldstandard mit markierten Prioritäten
Antwort-EntwurfOhne substanzielle Änderung verwendbar (Diff-Anteil ≤ 30% der Zeichenlänge, keine inhaltliche Korrektur)≥ 50%Automatische Diff-Analyse: Levenshtein-Distanz / Entwurfslänge. Manuelle Stichprobe für inhaltliche Korrekturen (20 Emails/Monat)
Falsch-positive AutomatikFälschlich automatisiert0 (in V1 keine Automatik)Audit-Log-Prüfung
Falsch-negative EskalationCritical nicht eskaliert0Goldstandard-Abgleich
ParsingErfolgsquote MIME-Parsing≥ 99%Fehlerprotokoll / Gesamtzahl
Thread-RekonstruktionKorrekte Zuordnung≥ 95%Stichproben-Prüfung gegen Message-ID-Ketten
Retrieval-RelevanzPrecision@5 der Hybrid Search≥ 0.7Manuelle Bewertung der Top-5-Ergebnisse
GUI-ReaktionszeitTime to First Byte< 500msBrowser-Messung
API-StabilitätUptime≥ 99%Health-Check-Monitoring
WiederanlaufRecovery nach Ausfall< 5 MinutenSimulierter Ausfall + Messung
LöschroutineVollständige Löschung über alle 3 DBs100%Löschung ausführen + Prüfung auf Rückstände
Audit-VollständigkeitJede Aktion protokolliert100%Vergleich Audit-Log vs. erwartete Einträge pro Email

Testmengen für Abnahme

TestmengeUmfangZweck
Goldstandard-Emails100 Emails, manuell kategorisiert und priorisiertKlassifikations- und Priorisierungsgenauigkeit messen
Schwierige Randfälle20 Emails mit mehrdeutiger Kategorie, gemischtem Sentiment, langen ThreadsRobustheit der Klassifikation testen
Bösartige Eingaben10 Emails mit Prompt-Injection-Versuchen, XSS in HTML-Body, übergroßen AnhängenSicherheit testen
Lange Threads5 Threads mit 20+ Emails, tiefer VerschachtelungThread-Rekonstruktion und Kontext-Aufbau testen
Mehrsprachige Mails20 Emails (Deutsch/Englisch gemischt, inklusive Code-Switching)Multilingual-Fähigkeit testen
Fehlerhafte MIME10 Emails mit defektem MIME, fehlendem Content-Type, kaputtem EncodingParser-Robustheit testen
Anhang-Sonderfälle10 Emails mit passwortgeschütztem PDF, Bild ohne OCR-Text, 25MB-DateiAnhangverarbeitung testen

Vor der Implementierung zu erstellende Artefakte

Aus diesen 14 Blöcken ergeben sich 12 formale Artefakte, die vor der ersten Codezeile fertiggestellt sein müssen:

  1. Ziel- und Nicht-Ziel-Dokument (aus Block 1)
  2. Scope-Dokument V1 (aus Block 2)
  3. Fachliches Domänenmodell (aus Block 4)
  4. Sollprozess mit allen Zuständen und Übergängen (aus Block 5)
  5. Entscheidungs- und Eskalationsmatrix (aus Block 3 + 6)
  6. Datenmodell für MariaDB, Qdrant und ArangoDB (aus Block 4 + 7)
  7. Prompt- und LLM-Aufgabenmatrix (aus Block 9)
  8. Sicherheits- und Datenschutzkonzept (aus Block 10)
  9. API- und Rollenmodell (aus Block 13)
  10. Fehler- und Fallback-Katalog (aus Block 12)
  11. Betriebs- und Lastprofil (aus Block 11)
  12. Test- und Abnahmekatalog (aus Block 14)