KI-gestützte E-Mail-Automatisierung: 90% weniger manuelle Sortierung
Von manueller Regelpflege zur intelligenten KI-Kategorisierung
🚀 Ihr Posteingang. Automatisiert. Heute.
💰 Warum sich KI-E-Mail-Sortierung rechnet
Ein durchschnittlicher Mitarbeiter verbringt 18–25 Minuten pro Tag mit manuellem E-Mail-Sortieren — das sind 3.300–4.600 € pro Jahr an verlorener Arbeitszeit (bei 80 € Stundensatz). Die Automatisierung via lokalem LLM amortisiert sich innerhalb weniger Wochen.
⚙️ So funktioniert's
Vier Schritte vom Posteingang zum sortierten Ordner — vollautomatisch im Hintergrund.
💻 Technische Umsetzung
Das System läuft als Python-Script auf einem lokalen Windows-Rechner mit RTX 3060 (12 GB VRAM). Ollama hostet das Sprachmodell, IMAP verbindet zum Postfach, SQLite trackt verarbeitete E-Mails.
🏗️ Architektur
🐍 Kern: Der E-Mail-Handler
class EmailHandler:
def __init__(self, config_path: str = 'config.yaml'):
with open(config_path, 'r', encoding='utf-8') as f:
self.config = yaml.safe_load(f)
self.accounts = self.config['email_accounts']
self.categories = [cat['name'] for cat in self.config['categories']]
self.db_handler = DatabaseHandler()
def process_emails(self, llm_callback) -> None:
"""Verarbeitet die E-Mails im INBOX-Ordner aller konfigurierten Konten."""
for account in self.accounts:
imap = self.connect_to_account(account)
imap.select('INBOX')
_, messages = imap.uid('search', None, 'ALL')
for email_uid in messages[0].split():
if self.db_handler.is_email_processed(account['name'], email_uid_str):
continue # Bereits verarbeitet → überspringen
_, msg_data = imap.uid('fetch', email_uid, '(RFC822)')
email_message = BytesParser().parsebytes(msg_data[0][1])
subject, content, from_address, links = self.get_email_content(email_message)
category = llm_callback(subject, content, from_address, links)
self.db_handler.mark_email_processed(account['name'], email_uid_str, subject, from_address, content, category)
self.move_email(imap, email_uid, category)
🧠 Der LLM-Handler — Prompt-Engineering
def categorize_email(self, subject, content, from_address, links):
prompt = self.prompt_template.format(
categories_with_rules=self._format_categories_with_rules(),
personal_context=self._format_personal_context(),
subject=subject, content=content[:5000],
from_address=from_address,
links="; ".join(links) if links else "keine"
)
response = requests.post(
f"{self.ollama_config['base_url']}/api/generate",
json={
"model": "gemma3:1b",
"prompt": prompt,
"temperature": 0.1,
"max_tokens": 1000,
"stream": False
}
)
category = response.json().get('response', '').strip()
return category if category in self.valid_categories else "Archiv"
📁 9 konfigurierbare Kategorien
🗄️ Datenbank-Tracking
class DatabaseHandler:
def init_database(self):
with sqlite3.connect(self.db_path) as conn:
cursor = conn.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS processed_emails (
id INTEGER PRIMARY KEY AUTOINCREMENT,
account_name TEXT NOT NULL,
email_uid TEXT NOT NULL,
email_hash TEXT NOT NULL,
subject TEXT,
from_address TEXT,
category TEXT,
processed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE(account_name, email_uid)
)
''')
def is_email_duplicate(self, email_hash: str) -> Optional[dict]:
"""Prüft, ob eine E-Mail mit gleichem Inhalt bereits verarbeitet wurde."""
cursor.execute(
'SELECT account_name, subject, from_address, category, processed_at
FROM processed_emails WHERE email_hash = ?',
(email_hash,)
)
result = cursor.fetchone()
return {'subject': result[1], 'category': result[3]} if result else None
⚙️ Konfiguration via YAML
categories:
- name: Wichtig
description: Wichtige E-Mails, die sofortige Aufmerksamkeit erfordern
- name: Projekte
description: E-Mails bezüglich laufender Projekte
- name: Newsletter
description: Newsletter und regelmäßige Updates
- name: Werbung
description: Werbemails und Angebote
detailed_rules: |
Newsletter, Angebote oder Promo-Mails von großen Tech-Firmen:
Google, Microsoft, Apple, Amazon, Meta/Facebook, LinkedIn
Seriöse Angebote von bekannten Marken und etablierten Online-Shops
- name: Rechnungen
description: Rechnungen und Zahlungsbestätigungen
# ... weitere Kategorien
email_accounts:
- name: IONOS Postfach
server: imap.ionos.de
port: 993
use_ssl: true
username: marcel@verkooyen.de
ollama:
model: gemma3:1b
temperature: 0.1
max_tokens: 1000
personal_context:
name: Marcel Verkooyen
job_title: CEO CTO
company: Verkooyen Informatics & media / Volt NRW Herzogenrath
important_contacts: cristin verkooyen (Ehefrau)
interests: Fokusgruppe KI, digitalhub aachen, IHK Aachen
⚡ In 5–7 Tagen zum MVP — nicht in 8–13 Wochen.
🚀 Gebaut mit Vibecoding — in 5–7 Tagen statt 8–13 Wochen
- 📋 2–3 Wochen Requirements Engineering
- 🏗️ 2–3 Wochen Architektur & Design
- 💻 3–4 Wochen Implementierung
- 🧪 1–2 Wochen Testing
- 🚢 1 Woche Deployment
- ⏱️ Gesamt: 8–13 Wochen
- 🗣️ 0.5 Tage Prompt-Engineering
- ⚡ 2–3 Tage iterative Generierung
- 🔧 1–2 Tage Refinement & Debugging
- ✅ 1 Tag Integration & Testing
- 🚀 0.5 Tage Deployment
- ⏱️ Gesamt: 5–7 Tage
🗣️ Der System-Prompt hinter diesem Projekt
Dieser konkrete, deutsche System-Prompt wurde für Coding-Agenten (Claude, ChatGPT, Copilot) optimiert — so entstand der gesamte Code in wenigen Iterationen:
Du bist ein Python-Experte für E-Mail-Automatisierung mit IMAP und lokaler KI. Aufgabe: Erstelle ein Python-Script, das E-Mails aus einem IMAP-Postfach liest, mit einem lokalen LLM (Ollama) kategorisiert und automatisch in entsprechende IMAP-Ordner verschiebt. Technische Anforderungen: - Python 3.10+, ausschließlich Standard-Bibliotheken wo möglich - IMAP-Verbindung über imaplib mit SSL - Kategorisierung über Ollama API (lokale Instanz, Modell: gemma3:1b) - Kategorien aus YAML-Konfigurationsdatei lesbar - SQLite-Datenbank zur Vermeidung von Doppelverarbeitung - Robustes Error-Handling mit Retry-Logik (Exponential Backoff) - Duplikat-Erkennung via Content-Hashing (MD5) - Logging mit verschiedenen Log-Leveln Kategorien: 1. Wichtig — sofortige Aufmerksamkeit 2. Projekte — laufende Kundenprojekte 3. Newsletter — abonnierte Inhalte 4. Werbung — Marketing großer Tech-Firmen 5. Spam — verdächtige/unerwünschte Mails 6. Rechnungen — Zahlungsverkehr 7. Termine — Kalender & Meetings 8. Archiv — Fallback-Kategorie 9. Volt-Herzogenrath — politische Kommunikation Prompt-Template für die Kategorisierung: "Du bist ein E-Mail-Kategorisierer. Deine Aufgabe ist es, E-Mails in eine der folgenden Kategorien einzuordnen: [KATEGORIEN]. Antworte NUR mit dem Namen der Kategorie, ohne weitere Erklärungen." Wichtig: - Normale Geschäftskommunikation bleibt im Hauptpostfach - Persönlicher Kontext (Name, Firma, wichtige Kontakte) einbeziehen - Links in E-Mails auf verdächtige Muster prüfen (Linktext ≠ Ziel-URL = Spam) - IONOS-IMAP-Limit: Ordnernamen max. 30 Zeichen Output: Mehrere .py-Dateien — modular, testbar, produktionsreif.
🎯 Strategische Erkenntnisse aus diesem Projekt
Die Entwicklung dieses Systems hat wertvolle Einsichten geliefert — nicht nur technisch, sondern vor allem strategisch. Diese Erkenntnisse sind direkt auf andere Automatisierungsprojekte übertragbar.
Bereit für die digitale Transformation?
Jedes Unternehmen hat repetitive E-Mail-Workflows. Lassen Sie uns gemeinsam herausfinden, wo KI bei Ihnen den größten Hebel hat — unverbindlich und pragmatisch.