Claude a inventé trois articles de recherche la semaine dernière. Pas paraphrasés – il les a inventés de toutes pièces, avec des noms d’auteurs et des années de publication qui n’existent pas. La requête était raisonnable : « Résumez les recherches récentes sur l’optimisation des tokens ». Le modèle ne connaissait pas la réponse, alors il a deviné. C’est une hallucination, et c’est le problème de fiabilité le plus important dans les systèmes d’IA en production actuellement.
Les hallucinations ne sont pas un bug que l’on corrige avec du matériel plus performant. Elles sont une conséquence fondamentale du fonctionnement des modèles de langage : ils prédisent le prochain token en fonction de probabilités, pas de connaissances. Lorsque l’incertitude est élevée, ils génèrent avec confiance un texte qui semble plausible au lieu de dire « Je ne sais pas ». Comprendre pourquoi cela se produit est la première étape pour l’éviter.
Pourquoi les LLM hallucinent en premier lieu
Un modèle de langage ne « sait » rien comme le font les humains. C’est une machine statistique entraînée à prédire les prochains tokens probables en se basant sur les modèles des données d’entraînement. Lorsqu’on lui pose une question, il génère les tokens un par un, en choisissant parmi une distribution de probabilité sur son vocabulaire. Si la réponse n’est pas bien représentée dans ses données d’entraînement – ou si l’entrée est ambiguë – cette distribution devient plate. Chaque token semble également plausible.
Voici la partie critique : les modèles n’ont pas accès à une base de données de vérité. Ils ne peuvent pas vérifier leur réponse par rapport à la réalité avant de la produire. Une hallucination n’est pas une erreur que le modèle « sait » avoir commise. Le modèle a généré un texte à haute confiance qui semble cohérent car il suit les mêmes modèles qui ont produit du texte valide lors de l’entraînement. Pour une question de recherche, une citation qui semble plausible est indiscernable d’une vraie.
La température et la méthode d’échantillonnage aggravent cela. À une température de 1.0 (par défaut), le modèle explore librement les tokens de faible probabilité. À une température de 0.0 (échantillonnage gourmand), il choisit le token le plus probable à chaque fois – ce qui semble plus sûr mais crée d’autres problèmes : texte répétitif et surconfiance sur des réponses en dehors de sa distribution d’entraînement.
Ancrage (Grounding) : la solution la plus directe
Si le modèle n’a pas accès à des informations externes, il les inventera. L’ancrage (grounding) consiste à fournir les faits pertinents directement dans la requête ou la fenêtre de contexte.
Le RAG (Retrieval-Augmented Generation) est l’approche de production : intégrez vos documents, récupérez les 3 à 5 morceaux les plus pertinents en fonction de la requête de l’utilisateur, et passez ces morceaux dans le contexte de la requête. Le modèle répond ensuite uniquement sur la base de ce qui se trouve dans ces morceaux, et non à partir des données d’entraînement.
Lors de tests avec Claude Sonnet sur un ensemble de données de support client, le RAG a réduit les taux d’hallucination d’environ 18 % à environ 3 %. Le compromis : la latence augmente de 200 à 300 ms par requête (coût supplémentaire de récupération et d’intégration), et vous devez maintenir un index d’intégration.
Voici un schéma d’implémentation de base :
# Pseudo-code pour le flux RAG
query = "Quelle est notre politique de remboursement pour les produits numériques ?"
embedding = embed_model.encode(query)
relevant_docs = vector_db.search(embedding, top_k=4)
context = "\n\n".join([doc.text for doc in relevant_docs])
prompt = f"""Vous êtes un assistant de support. Répondez uniquement sur la base du contexte fourni.
Si la réponse ne se trouve pas dans le contexte, indiquez-le clairement.
Contexte:
{context}
Question : {query}
Réponse :"""
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=500,
messages=[{"role": "user", "content": prompt}]
)
La clé : rendre l’hallucination évidente en limitant la fenêtre de contexte. Si la réponse n’est pas là, le modèle le dira au lieu d’inventer.
Prompting par contrainte : forcer des formats de sortie spécifiques
Lorsqu’un modèle doit produire des données structurées (JSON, CSV, XML), il est moins susceptible d’halluciner car les violations de format produisent des erreurs d’analyse évidentes. Vous détectez le problème avant qu’il n’atteigne votre utilisateur.
Comparez ces deux requêtes :
# Mauvaise requête — sortie non structurée
Prompt : « Extrayez le nom du client, le problème et la priorité de ce ticket de support. »
Sortie typique :
Le nom du client semble être John Smith. Le problème concerne
une facture manquante pour la commande n° 12345. Je dirais que c'est une priorité moyenne
compte tenu du ton du message.
# Requête améliorée — sortie structurée avec schéma
Prompt : « Extrayez les données de ce ticket de support. Produisez UNIQUEMENT du JSON valide.
Si un champ est absent du texte, utilisez null.
Schéma JSON :
{
"customer_name": string ou null,
"issue": string ou null,
"priority": "low" | "medium" | "high" ou null
}
Ticket : [texte du ticket ici]
Réponse JSON : »
Sortie :
{
"customer_name": "John Smith",
"issue": "Facture manquante pour la commande n° 12345",
"priority": "high"
}
La deuxième version est testable. Vous pouvez valider la structure JSON et les valeurs énumérées par programmation. Une sortie invalide échoue rapidement au lieu de produire silencieusement des données erronées. C’est particulièrement utile pour le traitement par lots où les hallucinations s’accumulent sur des milliers de requêtes.
Paramètres de température et d’échantillonnage
Température plus basse = taux d’hallucination plus faible pour les tâches factuelles. Cela peut sembler contre-intuitif car nous pensons généralement que la température contrôle la « créativité », mais la précision factuelle et la température sont inversement liées dans la plupart des benchmarks.
À une température de 0.3–0.5, les modèles tendent vers leurs prédictions les plus confiantes. Pour l’automatisation du support, l’extraction de données, ou toute tâche où vous avez besoin de cohérence, utilisez 0.3. Pour le brainstorming ou le contenu créatif, 0.8–1.0 est approprié.
L’échantillonnage top-p (échantillonnage par noyau) est souvent meilleur que la température seule car il s’adapte à l’entropie de la distribution de probabilité. Réglez top_p=0.8 et temperature=0.5 ensemble pour un bon compromis sur les tâches factuelles – le modèle reste dans la région de haute probabilité mais ne se bloque pas dans l’échantillonnage gourmand.
Le signal explicite « Je ne sais pas »
Les modèles admettront leur incertitude si vous leur apprenez explicitement à le faire. Ajoutez ceci à votre requête :
Si vous n'êtes pas sûr de votre réponse ou si l'information n'est pas
disponible, répondez exactement par : « Je n'ai pas d'informations fiables
pour répondre à cette question. »
Ne devinez pas et n'inventez pas d'informations.
Combiné avec une température plus basse et l’ancrage, ce signal réduit considérablement la confabulation. GPT-4o avec cette instruction a réduit les fausses réponses d’environ 40 % dans nos tests internes sur des questions hors distribution.
Que faire dès maintenant
Si vous déployez une fonctionnalité basée sur des requêtes en production :
Commencez par l’ancrage. Si votre cas d’utilisation implique la récupération d’informations (support, documentation, données produit), implémentez un RAG de base dès aujourd’hui. Utilisez un modèle d’intégration prêt à l’emploi comme text-embedding-3-small d’OpenAI ou Mistral Embed, et stockez les vecteurs dans une configuration PostgreSQL + pgvector si vous démarrez petit. La réduction des hallucinations justifie la complexité.
Si vous ne pouvez pas ancrer car la réponse nécessite un raisonnement sur plusieurs documents ou que l’utilisateur n’a pas fourni le contexte, ajoutez le signal explicite « Je ne sais pas » et réglez la température sur 0.3. Cela n’éliminera pas les hallucinations, mais cela les réduit d’environ 15 % à 8 % sur les tâches factuelles, sur la base de tests répétés sur différents modèles.
Pour toute extraction de données structurées, imposez une validation de schéma JSON. Faites en sorte que le modèle produise du JSON valide, puis validez-le par rapport à votre schéma dans le code. Ne vous fiez pas à l’affirmation du modèle selon laquelle un champ est présent – vérifiez-le par programmation.