
2026
Pipeline de traitement d'emails - Société Pretto
Analyse automatique des emails échangés entre courtiers et banquiers pour en extraire les taux d'emprunts à jours. Les logiciels internes sont ensuite automatiquement mis à jour.
Développement d'un pipeline de traitement automatique des emails échangés entre les courtiers immobiliers et les banquiers. Objectif final : extraire automatiquement des informations métiers clés (notamment les évolutions de taux) à partir de ces emails, en utilisant un LLM comme moteur d'analyse. Le pipeline se décompose en plusieurs étapes : 1. Formatage de l'entrée LLM : nettoyage et structuration du contenu brut des emails. 2. Filtrage des images : détection et exclusion automatique des logos envoyés en pièce jointe, inutiles pour l'analyse. 3. Enrichissement : agrégation avec des données internes existantes dans l'entreprise avant l'envoi au LLM. 4. Inférence : utilisation du service de batch développé précédemment pour traiter les volumes en production.
Étude de cas détaillée
Chez Pretto, des dizaines de banques envoient chaque semaine des emails de mise à jour de leurs taux immobiliers. Traiter ces emails manuellement pour maintenir la base de taux à jour prenait des heures. J'ai automatisé ce processus avec un pipeline ETL Python en quatre étapes, en utilisant un LLM pour l'extraction structurée et le service batch interne pour absorber les volumes.
En résumé : le pipeline nettoie le contenu brut des emails, filtre les images inutiles (logos, bannières de signature), enrichit le contexte avec les taux déjà en base, puis envoie en batch au LLM pour extraire les évolutions sous forme structurée.
Quel problème résout-on exactement ?
Pretto est un courtier en crédit immobilier. Chaque partenaire bancaire envoie régulièrement des notifications de changement de taux par email : taux fixes sur 15, 20 ou 25 ans, conditions d'éligibilité, parfois des grilles tarifaires complètes.
Ces emails arrivent en volume, dans des formats hétérogènes, et contiennent rarement une structure machine-lisible. Un email type ressemble à ça :
"Suite à nos derniers arbitrages, nous vous informons d'une révision de nos taux à compter du lundi 3 juin. Pour un prêt sur 20 ans, le taux nominal passe à 3,45 % (contre 3,55 % précédemment)..."
Ces informations arrivant dans la boîte mail des courtiers, le pôle banque ne les analysait pas.
L'extraction par LLM est particulièrement adaptée ici : le contenu est libre, mais la structure de l'output est définie (quel taux, pour quelle durée, quelle date d'effet). C'est le type de tâche que les LLMs résolvent bien avec un prompt structuré et un schéma de sortie.
Architecture en quatre étapes
Le pipeline suit ce flux séquentiel :
- Formatage : nettoyage du contenu brut de l'email (HTML, encodage, métadonnées)
- Filtrage images : détection et exclusion des logos et bannières de signature
- Enrichissement : injection des taux actuels en base dans le prompt
- Inférence batch : extraction structurée via le service batch interne
Chaque étape transforme l'email en quelque chose de plus exploitable. Sans ce preprocessing, le contexte envoyé au modèle serait bruité, coûteux en tokens, et les extractions moins fiables.
Étape 1 : comment nettoyer le contenu brut d'un email ?
Les emails reçus sont des messages multipart MIME. Le contenu textuel utile est souvent enfoui dans du HTML riche : balises de style, commentaires conditionnels Outlook, zones de tracking invisibles.
Ce nettoyage était fait en SQL via des transformations DBT. L'objectif en data étant de faire le plus possible de transformations en SQL, pour éviter de faire des DAGs, plus complexes à maintenir et pour avoir un lineage de la data propre.
Étape 2 : pourquoi filtrer les images des emails avant d'appeler le LLM ?
C'est l'étape qui a eu le plus d'impact sur la qualité des inputs. Les emails de banquiers contiennent systématiquement des logos en signature, des bannières commerciales, parfois des tampons légaux. Si on les encode en base64 et les inclut dans le contexte, ils consomment des tokens pour rien et peuvent perturber l'extraction.
La stratégie de filtrage repose sur trois critères :
- Le nom du fichier d'image en pièce jointe
- Le mimetype du fichier
- Les dimensions
Un logo de signature vérifie généralement au moins deux de ces trois critères. Le plus robuste est la dimension : les logos sont petits en hauteur ou très allongés horizontalement. Un tableau de taux envoyé en image (cas rare) est plus grand et carré, il passe le filtre. Transformation également faite en dbt.
Étape 3 : comment enrichir le prompt avec les données internes ?
Avant d'envoyer l'email au LLM, on injecte dans le prompt les taux actuellement enregistrés en base pour la banque expéditrice.
Pourquoi ? Le LLM doit distinguer deux cas : une mise à jour d'un taux existant et l'annonce d'un nouveau produit inexistant en base. Sans contexte, il ne peut pas savoir ce qui était en place avant. Plus critique : certains emails expriment des variations relatives ("baisse de 10 points de base") plutôt que des valeurs absolues. Avec les taux actuels injectés, le LLM peut recalculer la valeur finale.
Le prompt était perfectionné en utilisant langfuse, dans le but d'améliorer l'extraction en sélectionnant le meilleur prompt / LLM.
Étape 4 : inférence batch et validation Pydantic
Une fois les emails préparés, l'inférence est déléguée au service batch interne. L'appel soumet un batch de jobs, poll jusqu'à complétion, et récupère les outputs. Le batch APIs des fournisseurs offre environ 50% de réduction de coût par rapport aux appels synchrones, ce qui sur des volumes hebdomadaires représente une économie concrète.
L'output du LLM est validé par Pydantic avant toute écriture en base :
from pydantic import BaseModel
from datetime import date
class RateChange(BaseModel):
duration: int
new_rate: float
effective_date: date | None
change_type: str # "update" ou "new"Si le JSON retourné est invalide (hallucination de format, champ manquant), Pydantic lève une erreur loguée sans écriture silencieuse en base. C'est un point non négociable : une donnée financière mal extraite et enregistrée silencieusement est pire qu'une absence de donnée.
Ce que ce projet m'a appris
Le filtrage des images n'est pas optionnel. Sans lui, les logos encodés en base64 font gonfler le contexte et dégradent la qualité des extractions. Ce n'est pas une optimisation de confort.
L'enrichissement contextuel change l'équation. Injecter les taux actuels en base dans le prompt réduit significativement les erreurs sur les emails exprimant des variations relatives. Le LLM sans contexte hallucine des valeurs absolues quand l'email dit "baisse de 10bp".
Le traitement différé en batch est la bonne approche pour ce cas. L'extraction de taux n'est pas urgente au sens temps-réel. Accumuler les emails sur la journée et les traiter le soir en batch, c'est moins cher, plus simple à exploiter, et le résultat est disponible le lendemain matin.
Le même pattern s'applique à d'autres contextes : extraction d'informations depuis des emails fournisseurs, traitement de commandes reçues par email, classification de tickets entrants. Le preprocessing email est toujours le même, seuls le prompt et le schéma Pydantic changent selon le métier.
Si vous traitez des volumes d'emails en entreprise et cherchez à en extraire des données structurées, parlons-en.
Témoignage client
“A la suite de son stage nous avons continué à travailler avec Pierre en freelance alors qu'il continuait ses études en parallèle. Il est travailleur, efficace, précis et fiable. Merci encore Pierre pour tout le super boulot et à très vite :)”