case history
Case #05 · AI Automation

Triage inbox automatico: quando regex fallisce e Claude vince

Tre versioni di pattern matching per classificare le email da gestire. V1, V2, V3: tutti falliti. La svolta: sostituire le regex con una chiamata LLM. Zero falsi positivi.

ObiettivoTriage inbox automatico
StackPython, Gmail API, Claude
Iterazioni4 versioni
Accuratezza finale100%

Il problema

Un'inbox con decine di email al giorno. Alcune richiedono risposta — clienti, collaboratori, richieste attive. Molte no — newsletter, notifiche automatiche, thread già chiusi.

L'obiettivo: identificare automaticamente le email che richiedono risposta e preparare una bozza, senza leggere tutto manualmente. Il sistema deve essere preciso: un falso positivo (bozza su email che non la richiedeva) è fastidioso; un falso negativo (email importante ignorata) è un problema reale.

Quattro versioni, una lezione

V1
Keyword matching su oggetto

Lista di parole chiave (richiesta, preventivo, urgente, aiuto...) applicata all'oggetto dell'email.

Fallito — troppi falsi positivi su newsletter con oggetti sensazionalistici, troppe email legittime senza keyword evidenti.
V2
Regex su oggetto + mittente

Pattern regex più sofisticati, whitelist mittenti noti, blacklist domini newsletter.

Fallito — il problema è contestuale. "Grazie" in chiusura di un thread può essere la fine di una conversazione o una nuova richiesta. Regex non capisce il contesto.
V3
Scoring multi-fattore

Punteggio basato su mittente (noto/sconosciuto), presenza di domande (?), lunghezza email, ora di invio.

Fallito — troppi parametri da calibrare, risultato instabile, manutenzione infinita per ogni nuovo tipo di email.
V4
Analisi contestuale con LLM

Elaborazione dell'intero thread (non solo l'ultimo messaggio) tramite chiamata a Claude. Il modello riceve il thread completo e risponde con una classificazione strutturata.

✓ Funziona — 8 draft legittimi identificati, zero falsi positivi su un batch di 49 email.

Implementazione V4

Il sistema raggruppato per thread (non per singola email) è la chiave. Un'email non si legge da sola: va letta nel contesto di cosa è stato detto prima.

import subprocess
import json

def classify_thread(thread_messages: list[dict]) -> dict:
    """Classifica un thread email con Claude."""

    # Costruisce contesto leggibile
    context = "\n\n---\n\n".join([
        f"Da: {m['from']}\nOggetto: {m['subject']}\n\n{m['body']}"
        for m in thread_messages
    ])

    prompt = f"""Analizza questo thread email e rispondi in JSON:
{{
  "requires_response": true/false,
  "reason": "spiegazione breve",
  "priority": "high/medium/low",
  "suggested_action": "cosa fare"
}}

Thread:
{context}"""

    result = subprocess.run(
        ["claude", "-p", prompt],
        capture_output=True, text=True, timeout=30
    )

    return json.loads(result.stdout)

Risultati

49
email processate
8
draft generati
0
falsi positivi

Perché il contesto batte le regex

Il problema del triage email non è sintattico, è semantico. Due email con oggetto identico ("Re: Progetto X") possono richiedere risposta o no, dipende dal contenuto e da cosa è già stato detto nel thread.

Le regex operano su pattern di testo. Un LLM opera su significato. Per problemi di classificazione contestuale, il secondo strumento è strutturalmente più adatto del primo — anche considerando il costo aggiuntivo per chiamata API.

La lezione non è "usa sempre l'AI". È: prima di costruire un sistema di regole complesso per un problema di comprensione del linguaggio, valuta se una singola chiamata LLM non risolva il problema con meno codice e più accuratezza. Spesso sì.

Costo

~$0.002 per thread analizzato con Claude Haiku. Su 50 email al giorno: ~$0.10/giorno, ~$3/mese. Accettabile per eliminare 20-30 minuti di triage manuale quotidiano.

Claude API Gmail API Python automation NLP email triage