- Python 59.1%
- HTML 34.6%
- Shell 5.5%
- Dockerfile 0.8%
Rewrite README to match current state: NVIDIA NIM as default backend, local ports as primary URLs, Traefik only with production profile, accurate architecture and setup instructions. Remove hardcoded mail counts. Change seeder idempotency check to use len(MAILS). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|---|---|---|
| frontend | ||
| litellm | ||
| n8n | ||
| seeder | ||
| traefik | ||
| workflows | ||
| .env.example | ||
| CLAUDE.md | ||
| docker-compose.yml | ||
| README.md | ||
Mail-Triage-Demo
KI-gestützte Klassifizierung eingehender Geschäftsmails — Demo für KI ohne Umweg.
Der Demonstrator zeigt, wie ein LLM eingehende E-Mails automatisch kategorisiert, priorisiert und an die richtige Abteilung weiterleitet. Hochprio-Mails lösen automatisch einen Alert aus.
Was die Demo zeigt
- Posteingang simulieren — Realistische deutsche Geschäftsmails (Rechnungen, Kundenanfragen, Bewerbungen, Reklamationen, Newsletter, Spam) liegen unverarbeitet vor.
- KI-Klassifizierung starten — Ein Klick auf den Button triggert den n8n-Workflow. Das LLM analysiert jede Mail und gibt Kategorie, Priorität und Abteilung zurück.
- Ergebnis live verfolgen — Die Weboberfläche aktualisiert sich alle 3 Sekunden. Hochprio-Mails werden rot hervorgehoben.
- Automatischer Alert — Für jede als „hoch" priorisierte Mail sendet n8n
automatisch eine Alert-Mail an
alerts@demo.local(sichtbar in Mailpit). - Korrektur — Falsch klassifizierte Mails können per Dropdown direkt im Interface korrigiert werden (Human-in-the-Loop). Die Klassifikationsgenauigkeit in der KPI-Bar sinkt bei jeder Korrektur.
Voraussetzungen
- Docker & Docker Compose (v2)
- Zugang zu einem LLM-Backend (NVIDIA NIM, Vertex AI oder lokales Ollama)
Setup
1. Umgebungsvariablen konfigurieren
cp .env.example .env
Pflichtfelder in .env anpassen:
| Variable | Beschreibung |
|---|---|
POSTGRES_USER/PASSWORD/DB |
Datenbank-Zugangsdaten (Standard: demo) |
LLM_BACKEND |
openai (NVIDIA NIM), vertex_ai oder ollama |
LLM_MODEL |
z. B. meta/llama-3.1-8b-instruct, claude-sonnet-4-6, llama3.1 |
LITELLM_API_BASE |
API-Endpunkt (z. B. https://integrate.api.nvidia.com/v1) |
LITELLM_API_KEY |
API-Key für das gewählte Backend |
CUSTOMER_SLUG |
URL-Präfix, z. B. muster-gmbh |
DEMO_DOMAIN |
Basis-Domain, z. B. demo.ki-ohne-umweg.de |
Backend-Konfigurationen
NVIDIA NIM (Standard in .env.example):
LLM_BACKEND=openai
LLM_MODEL=meta/llama-3.1-8b-instruct
LITELLM_API_BASE=https://integrate.api.nvidia.com/v1
LITELLM_API_KEY=nvapi-...
Vertex AI (GCP):
LLM_BACKEND=vertex_ai
LLM_MODEL=claude-sonnet-4-6
VERTEXAI_PROJECT=<gcp-projekt-id>
VERTEXAI_LOCATION=europe-west3
GOOGLE_APPLICATION_CREDENTIALS=/run/secrets/gcp-sa-key
Bei Vertex AI muss der GCP Service Account Key als Volume eingebunden werden —
siehe docker-compose.yml unter dem litellm-Service:
volumes:
- ./secrets/gcp-sa-key.json:/run/secrets/gcp-sa-key:ro
Ollama (lokal, kein API-Key nötig):
LLM_BACKEND=ollama
LLM_MODEL=llama3.1
LITELLM_API_BASE=http://host.docker.internal:11434
Demo starten
docker compose up --build
Der Stack startet in dieser Reihenfolge:
- Postgres — Datenbank
- Mailpit — SMTP-Catcher für Alerts
- Seeder — erstellt Tabellen, generiert Mock-Mails, schickt sie an Mailpit
- LiteLLM — LLM-Proxy (routet alle Anfragen an das konfigurierte Backend)
- n8n — importiert den Workflow automatisch
- n8n-Activator — aktiviert den Workflow nach n8n-Start
- Frontend — Weboberfläche
Traefik startet nur mit dem production-Profil:
docker compose --profile production up --build
Erster Start dauert 2–3 Minuten (Images laden, n8n-Init).
URLs (lokaler Betrieb)
| Dienst | URL |
|---|---|
| Demo-Oberfläche | http://localhost:8000 |
| n8n Workflow-Editor | http://localhost:5678 |
| Mailpit (Posteingang) | http://localhost:8025 |
Mit Traefik (production-Profil):
| Dienst | URL |
|---|---|
| Demo-Oberfläche | https://<CUSTOMER_SLUG>.<DEMO_DOMAIN> |
| n8n Workflow-Editor | https://n8n.<CUSTOMER_SLUG>.<DEMO_DOMAIN> |
| Mailpit | https://mailpit.<CUSTOMER_SLUG>.<DEMO_DOMAIN> |
Demo durchführen
Schritt 1 — Ausgangslage zeigen
Öffne http://localhost:8000. Du siehst alle unverarbeiteten Mails ohne Klassifizierung. KPI-Bar zeigt: 0 verarbeitet, 0 Hochprio-Alerts.
Schritt 2 — KI starten
Klick auf „KI-Klassifizierung starten". Der Button wechselt zu einem Ladeindikator. Die Mails werden jetzt eine nach der anderen vom LLM analysiert — sichtbar daran, dass die Kategorien und Prioritäten im Interface erscheinen.
Schritt 3 — Ergebnis besprechen
Nach Abschluss sind alle Mails klassifiziert:
- Kategorie und Abteilung sind automatisch vergeben
- Hochprio-Mails (Mahnungen, Produktionsstillstand, DSGVO) werden rot hervorgehoben
- KPI-Bar zeigt Verarbeitungsstand, Hochprio-Anzahl und Klassifikationsgenauigkeit
Schritt 4 — Alert-Mails zeigen
Öffne Mailpit (http://localhost:8025). Für jede Hochprio-Mail liegt eine Alert-Mail
an alerts@demo.local vor.
Schritt 5 — Korrektur zeigen (optional)
Wähle eine falsch klassifizierte Mail aus. Ändere die Kategorie per Dropdown. Die Klassifikationsgenauigkeit in der KPI-Bar sinkt entsprechend — zeigt den Human-in-the-Loop-Feedback-Mechanismus.
Demo zurücksetzen
docker compose down -v && docker compose up --build
-v löscht alle Volumes (Datenbank, n8n-Daten) — der Seeder legt beim nächsten
Start frische Testdaten an.
Nur Klassifizierungen zurücksetzen (ohne Stack-Neustart):
docker compose exec postgres psql -U demo -d demo -c \
"UPDATE mail_classifications SET category=NULL, priority=NULL, routed_to=NULL, processed_at=NULL, corrected_category=NULL, corrected_by=NULL; DELETE FROM demo_events;"
Danach im Frontend erneut auf „KI-Klassifizierung starten" klicken.
Architektur
Browser
│
▼
Frontend (FastAPI :8000)
│ POST /api/classify
▼
n8n Webhook (:5678)
│
├─ GET /internal/unprocessed ──▶ Postgres
│
└─ für jede Mail:
│
├─ POST litellm:4000/v1/chat/completions ──▶ NVIDIA / Vertex AI / Ollama
│
├─ POST /internal/process ──▶ Postgres (UPDATE + demo_event)
│
└─ wenn hoch:
├─ POST mailpit:8025/api/v1/send (Alert-Mail)
└─ POST /internal/alert-event ──▶ Postgres (demo_event)
Workflow-Übersicht (n8n)
| Node | Funktion |
|---|---|
| Klassifizierung starten | Webhook-Trigger (POST /webhook/classify) |
| Unverarbeitete Mails laden | Holt alle Mails ohne processed_at |
| Mails aufteilen | Array → einzelne Items |
| Mail fuer Mail | Loop über alle Mails (batchSize 1) |
| Anfrage aufbauen | Baut LLM-Request mit System-Prompt |
| KI-Klassifizierung | Ruft LiteLLM auf, erhält JSON-Antwort |
| Antwort auswerten | Parsed category, priority, routed_to (mit Logging) |
| Klassifizierung speichern | Schreibt Ergebnis in DB via Frontend |
| Hochprio? | IF priority == "hoch" |
| Alert aufbauen | Baut Mailpit-API-Body |
| Alert senden | Sendet Alert-Mail an Mailpit |
| Alert-Event speichern | Schreibt hochprio_alert_gesendet in demo_events |
Kategorien und Routing
| Kategorie | Abteilung | Priorität |
|---|---|---|
| Rechnung | Buchhaltung | hoch bei Mahnungen/Fristen |
| Kundenanfrage | Vertrieb/Support | hoch bei dringenden Anfragen |
| Bewerbung | HR | mittel |
| Reklamation | Beschwerdemanagement | hoch bei aggressivem Ton |
| Newsletter | Sonstiges | niedrig |
| Spam | Sonstiges | niedrig |
| Sonstiges | Sonstiges | je nach Inhalt |