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.
💻 Code-Einblicke
Ein Blick unter die Haube — so analysiert und sortiert die KI Ihre E-Mails:
🏗️ Architektur
🤖 LLM-Handler: Prompt-Engineering & Ollama
class LLMHandler:
def __init__(self, config_path='config.yaml'):
with open(config_path, 'r', encoding='utf-8') as f:
self.config = yaml.safe_load(f)
self.ollama_config = self.config['ollama']
self.categories = self.config['categories']
self.prompt_template = self.config['prompt_template']
self.personal_context = self.config.get('personal_context', {})
def _format_categories_with_rules(self) -> str:
categories_text = []
categories_text.append("HAUPTPOSTFACH:")
categories_text.append(" Normale, persönliche oder geschäftliche Kommunikation.")
for category in self.categories:
category_name = category.get('name', 'Unbekannt').upper()
description = category.get('description', '')
detailed_rules = category.get('detailed_rules', '')
categories_text.append(f"{category_name}:")
if description:
categories_text.append(f" Beschreibung: {description}")
if detailed_rules:
rules_lines = detailed_rules.split('\n')
for rule in rules_lines:
if rule.strip():
categories_text.append(f" - {rule.strip()}")
return "\n".join(categories_text)
def categorize_email(self, subject, content, from_address, links):
prompt = self._format_prompt(subject, content, from_address, links)
response = requests.post(
f"{self.ollama_config['base_url']}/api/generate",
json={
"model": self.ollama_config['model'],
"prompt": prompt,
"temperature": self.ollama_config['temperature'],
"max_tokens": self.ollama_config['max_tokens'],
"stream": False
}
)
if response.status_code == 200:
category = response.json().get('response', '').strip().strip('"\' ')
valid_categories = [cat['name'] for cat in self.categories] + ["Hauptpostfach"]
return category if category in valid_categories else "Archiv"
📧 E-Mail-Handler: IMAP & Content-Extraktion
class EmailHandler:
def __init__(self, config_path='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 = [self.sanitize_folder_name(cat['name'])
for cat in self.config['categories']]
self.db_handler = DatabaseHandler()
def get_email_content(self, email_message):
subject = self.decode_email_header(email_message.get('subject', ''))
from_address = self.decode_email_header(email_message.get('from', ''))
text_content, html_content, links = [], [], []
if email_message.is_multipart():
for part in email_message.walk():
if part.get_content_type() == "text/plain":
payload = part.get_payload(decode=True)
if payload:
charset = part.get_content_charset() or 'utf-8'
text_content.append(payload.decode(charset, errors='replace'))
elif part.get_content_type() == "text/html":
payload = part.get_payload(decode=True)
if payload:
html = payload.decode(
part.get_content_charset() or 'utf-8', errors='replace')
parser = LinkExtractor()
parser.feed(html)
links.extend([f"{text} -> {href}"
for text, href in parser.links])
return subject or "Kein Betreff", content, from_address, links
🔄 Verarbeitungs-Pipeline mit Duplikat-Erkennung
def process_emails(self, llm_callback) -> None:
for account in self.accounts:
imap = self.connect_to_account(account)
self.ensure_folders_exist(imap)
imap.select('INBOX')
_, messages = imap.uid('search', None, 'ALL')
for email_uid in messages[0].split():
email_uid_str = email_uid.decode('utf-8')
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)
# Duplikat-Check via Content-Hash
email_hash = self.db_handler.create_email_hash(subject, from_address, content)
duplicate_info = self.db_handler.is_email_duplicate(email_hash)
if duplicate_info:
category = duplicate_info['category']
else:
category = llm_callback(subject, content[:5000], from_address, links)
self.db_handler.mark_email_processed(
account['name'], email_uid_str, subject, from_address, content, category)
if category.lower() != "hauptpostfach":
self.move_email(imap, email_uid, category)
📂 IMAP-Ordner & Robustheit
def sanitize_folder_name(self, name: str) -> str:
sanitized = re.sub(r'[^\w\s\-_]', '_', name)
if len(sanitized) > 30:
sanitized = sanitized[:27] + "..."
return sanitized.strip(' _') or "Kategorie"
def move_email(self, imap, email_uid, category):
self.safe_imap_operation(imap, f"Kopiere UID {email_uid}",
lambda: imap.uid('copy', email_uid, category))
time.sleep(0.5)
self.safe_imap_operation(imap, f"Markiere UID {email_uid} gelöscht",
lambda: imap.uid('store', email_uid, '+FLAGS', '\\Deleted'))
time.sleep(0.5)
self.safe_imap_operation(imap, f"Expunge",
lambda: imap.expunge())
return True
def safe_imap_operation(self, imap, operation_name, operation_func, max_retries=3):
for attempt in range(max_retries):
try:
return operation_func()
except (socket.error, socket.timeout, imaplib.IMAP4.abort) as e:
if attempt < max_retries - 1:
time.sleep(2 ** attempt) # 1, 2, 4 Sekunden Exponential Backoff
⚡ 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.