Chercher dans des décennies d'e-mails : les mots-clés d'abord, le sens ensuite
La recherche IA sur les e-mails échoue sur des données sales. Comment nettoyer, threader et indexer une archive pour que mots-clés et sémantique coopèrent.

Pointer un modèle de langage sur une boîte mail et lui poser des questions ressemble à un projet de week-end. Puis il vous donne avec assurance la mauvaise date de contrat, parce qu'il a lu une copie citée d'un vieil e-mail à l'intérieur d'une réponse plus récente, ou il ne trouve pas la facture 10442 parce que le numéro n'a aucun « sens » auquel une recherche vectorielle puisse s'accrocher. Une bonne recherche sur une archive de mails ne tient pour l'essentiel pas au modèle. Elle tient aux données que vous lui donnez et à la façon dont vous récupérez. Voici comment nous l'abordons.
L'e-mail est plus désordonné qu'il n'y paraît
Une archive de mails qui s'étend sur des années, plusieurs systèmes de messagerie et quelques migrations a des problèmes qui ruinent la recherche avant toute intervention de l'IA :
- Les doublons. Le même message se trouve dans la boîte de réception, un dossier de projet et un vieil export. La recherche le renvoie trois fois ; une IA le compte comme trois sources d'accord.
- L'historique cité. Chaque réponse porte tout le fil en dessous d'elle. Indexez cela naïvement et le plus vieil e-mail d'un fil apparaît dans chaque réponse, hors contexte et avec la mauvaise date.
- Les encodages. Les vieux mails regorgent de jeux de caractères hérités, d'en-têtes encodés et de parties mal étiquetées. Décodez-les mal et les noms et le texte non anglais se transforment en charabia.
- Les pièces jointes. Le contrat, c'est le PDF, pas l'e-mail qui dit « ci-joint ». Si vous n'extrayez pas le texte des pièces jointes, vous ne pouvez pas trouver les documents les plus importants.
- Les suppressions. Un mail supprimé de la boîte pour des raisons de rétention doit disparaître aussi de chaque index.
Nettoyez avant d'indexer
Dédupliquez sur le Message-ID, avec en repli un hachage des en-têtes clés et du corps quand il manque. Stockez un document par message et gardez la liste des dossiers où il est apparu comme métadonnée.
Threadez sur References et In-Reply-To, pas sur les lignes d'objet. Les objets changent et « Re: facture » n'est pas unique. Avec un threading correct, vous pouvez montrer toute une conversation dans l'ordre et laisser l'étape de récupération rassembler un fil plutôt que des fragments isolés.
Séparez le texte nouveau du texte cité. Pour chaque message, indexez le corps complet pour la recherche par mots-clés, mais n'embarquez que la partie que l'auteur a réellement écrite. Un point de départ simple :
import re
from email import policy
from email.parser import BytesParser
QUOTE_MARKERS = [
re.compile(r"^On .+ wrote:$", re.M),
re.compile(r"^-{2,}\s*Original Message\s*-{2,}", re.M | re.I),
re.compile(r"^From: .+\nSent: .+", re.M),
]
def new_text(raw: bytes) -> str:
msg = BytesParser(policy=policy.default).parsebytes(raw)
part = msg.get_body(preferencelist=("plain", "html"))
text = part.get_content() if part else ""
cut = len(text)
for rx in QUOTE_MARKERS:
m = rx.search(text)
if m:
cut = min(cut, m.start())
lines = [l for l in text[:cut].splitlines() if not l.startswith(">")]
return "\n".join(lines).strip()
Le vrai courrier a besoin de plus de marqueurs que cela, dans chaque langue que votre entreprise écrit, mais le principe tient : le modèle doit lire ce que chaque personne a dit, une fois, avec la bonne date et le bon expéditeur.
Extrayez le texte des pièces jointes avec des outils standard (pdftotext pour les PDF, des bibliothèques d'analyse pour les formats bureautiques) et indexez-le comme partie du message, tout en gardant un lien vers le fichier d'origine.
Deux index, parce qu'ils répondent à des questions différentes
Un index plein texte répond aux questions avec des prises exactes : un expéditeur, un domaine, une plage de dates, un numéro de facture, une expression, « a un PDF ». Il est rapide, précis et explicable. Utilisez-en un avec une racinisation consciente de la langue, pour que « factures » trouve « facture », et avec des synonymes entre les langues que votre entreprise utilise, pour qu'une recherche dans une langue trouve le courrier écrit dans l'autre.
Un index vectoriel répond aux questions sur le sens : « quand le fournisseur a-t-il contesté pour la première fois le calendrier de livraison ? » Il n'y a peut-être aucun mot-clé pour cela. Un modèle d'embedding transforme chaque message nettoyé en vecteur, et la recherche trouve les messages proches de la question par le sens.
Aucun des deux ne suffit seul. Les vecteurs sont faibles sur les identifiants et les nombres ; les mots-clés sont faibles sur la paraphrase. Faites tourner les deux, et combinez :
- Extrayez d'abord les filtres de la question : personnes, domaines, dates, « avec pièce jointe ».
- Appliquez ces filtres aux deux recherches, pour que la recherche vectorielle ne s'égare jamais hors de la période ou des personnes dont parle la question.
- Fusionnez les deux listes de résultats. La fusion par rang réciproque est simple et fonctionne bien : notez chaque message par la somme de
1 / (k + rank)sur les deux listes. - Étendez les meilleurs résultats à leurs fils, pour que le modèle lise des conversations, pas des fragments.
Faites montrer son travail au modèle
Ce n'est qu'alors que le modèle de langage entre en jeu. Donnez-lui les messages récupérés, chacun avec un identifiant, une date et un expéditeur, et demandez-lui de ne répondre qu'à partir d'eux et de citer l'identifiant pour chaque affirmation. Dans l'interface, transformez chaque citation en lien qui ouvre l'e-mail d'origine.
Les citations font deux choses. L'utilisateur peut vérifier chaque affirmation en un clic, ce qui est la seule façon responsable d'utiliser un modèle sur des documents d'entreprise. Et vous voyez immédiatement quand la récupération a échoué : une réponse qui cite les mauvais messages est un problème de récupération, pas un problème de modèle, et elle vous dit où regarder.
Dites clairement aux utilisateurs qu'un modèle peut mal lire. Avec les sources à un clic, c'est un risque gérable.
Gardez les données dans le bâtiment
Chaque composant de cette conception tourne confortablement sur votre propre matériel : l'index plein texte sur des serveurs ordinaires, la base de données vectorielle à côté, et le modèle d'embedding et le modèle de langage sur des serveurs GPU que vous contrôlez. Le courrier, les questions et les réponses n'ont jamais besoin de quitter votre réseau.
Testez-le comme un système, pas comme une démo
Avant de lui faire confiance, constituez un petit jeu de questions aux réponses connues : une facture précise, le premier e-mail d'un litige connu, un message écrit dans votre seconde langue, un message supprimé le mois dernier (il ne doit pas être trouvé). Lancez-les après chaque changement du nettoyage, de l'indexation ou des prompts, et conservez les résultats. Si un changement dégrade des questions connues, vous le verrez.
Et surveillez le pipeline lui-même. Une synchronisation arrêtée en silence, un index qui n'a pas rattrapé son retard, ou un arriéré de vecteurs après un redémarrage ressemblent tous à « la recherche fonctionne » jusqu'à ce que quelqu'un ait besoin du courrier de la semaine dernière. Vérifiez toute la chaîne de bout en bout, selon un calendrier, et alertez quand une étape prend du retard.
En bref
- Dédupliquez, threadez, décodez et retirez le texte cité avant d'indexer quoi que ce soit.
- Indexez les pièces jointes ; c'est là que sont les contrats.
- Faites tourner ensemble la recherche par mots-clés et la recherche vectorielle, avec les filtres appliqués aux deux.
- Répondez uniquement à partir du courrier récupéré, avec une citation sur chaque affirmation.
- Gardez chaque composant sur du matériel que vous contrôlez, et testez avec des questions connues.
Nous construisons des archives de messagerie privées de cette façon, avec l'IA qui tourne sur vos propres GPU privés. Si vous en planifiez une, nous vous aiderons volontiers.
Related (rows[1])
Voir aussi : Archive de messagerie privée avec recherche IA locale · Documents bureautiques infogérés sur Nextcloud
Publié le 15 octobre 2026.
Toutes les notes de terrain