Grounding : ancrer les réponses dans des faits
Mis à jour le 28 juillet 2026
Grounding : ancrer les réponses dans des faits
Le grounding consiste à contraindre le modèle à fonder ses réponses uniquement sur des données que vous lui fournissez, plutôt que sur ses connaissances internes. C’est la première ligne de défense contre les hallucinations et une exigence non négociable dès qu’une application sort du prototype. Un assistant de support qui invente une clause de contrat ne commet pas une erreur amusante : il engage votre entreprise auprès du client qui l’a lue.
Pourquoi le grounding est indispensable
Les LLM produisent du texte statistiquement probable, ce qui ne coïncide pas nécessairement avec du texte factuellement correct. Sans grounding, un modèle peut fabriquer des citations, des statistiques ou des références techniques parfaitement plausibles : un numéro de version qui n’a jamais existé, un délai de rétractation crédible mais faux, un nom de paramètre inventé de toutes pièces. Rien dans la formulation ne trahit l’invention, et c’est précisément ce qui rend le phénomène dangereux en production. Plus la réponse est bien écrite, moins l’utilisateur pense à la vérifier, et plus le risque juridique et réputationnel augmente.
Technique 1 : contexte explicite
La méthode la plus simple est aussi la plus robuste : vous injectez le texte source dans le prompt et vous interdisez au modèle d’en sortir. Trois éléments doivent impérativement figurer dans les instructions — la restriction au document fourni, la formule de repli exacte à employer quand l’information est absente, et l’obligation de citer le passage utilisé. Éprouvez le résultat sur un cas frontière : une demande de remboursement à 45 jours doit produire la règle du remboursement partiel à 50 %, et non la réponse arrangeante que le client espère.
from openai import OpenAI
client = OpenAI()
document = """
Politique de remboursement Acme Corp (v3.2, janvier 2026) :
- Remboursement intégral dans les 30 jours suivant l'achat
- Remboursement partiel (50%) entre 30 et 60 jours
- Aucun remboursement après 60 jours
- Les produits personnalisés ne sont pas remboursables
- Le remboursement est effectué sous 5 jours ouvrés
"""
system = """Tu es un assistant de support client Acme Corp.
RÈGLES STRICTES :
- Réponds UNIQUEMENT à partir du document fourni ci-dessous
- Si la réponse n'est pas dans le document, dis "Je n'ai pas
cette information dans notre politique actuelle"
- Ne fais JAMAIS de supposition au-delà du document
- Cite le passage pertinent entre guillemets
DOCUMENT DE RÉFÉRENCE :
""" + document
response = client.responses.create(
model="gpt-5.6-terra",
instructions=system,
input="Je voudrais me faire rembourser un article acheté il y a 45 jours.",
temperature=0.1
)
Technique 2 : citations obligatoires
Le cran au-dessus consiste à exiger une référence pour chaque affirmation produite. L’effet est double. La réponse devient vérifiable par l’utilisateur, qui peut remonter au passage d’origine au lieu de vous faire confiance sur parole. Et le modèle s’autocensure sur les affirmations qu’il ne parvient à rattacher à aucune source, puisque la consigne lui demande explicitement de les omettre plutôt que de les livrer sans référence. Numéroter les documents dans le contexte, comme le fait la fonction ci-dessous, rend en outre les citations exploitables par votre interface : « [Document 2] » peut devenir un lien cliquable vers le bon fichier.
system_with_citations = """Tu es un assistant de recherche.
Pour chaque affirmation dans ta réponse, ajoute une référence
au passage source entre crochets, par exemple : [Source: paragraphe 3].
Si tu ne peux pas citer un passage source, n'inclus pas l'affirmation.
Format de réponse :
1. Réponse avec citations inline
2. Section "Sources utilisées" avec les extraits exacts"""
def reponse_grounded(question: str, documents: list[str]) -> str:
"""Génère une réponse ancrée avec citations."""
context = "\n\n---\n\n".join(
f"[Document {i+1}]\n{doc}"
for i, doc in enumerate(documents)
)
response = client.responses.create(
model="gpt-5.6-terra",
instructions=system_with_citations + f"\n\nDOCUMENTS :\n{context}",
input=question,
temperature=0.1
)
return response.output_text
Technique 3 : vérification post-génération
Les deux premières techniques réduisent le risque sans jamais l’annuler. Pour les cas critiques, ajoutez une seconde passe : un appel dédié qui décompose la réponse en affirmations élémentaires et confronte chacune aux sources. Le principe est celui de la revue de code — l’auteur relit mal son propre travail, un regard neuf le relit bien mieux — et il fonctionne ici pour la même raison, puisque le vérificateur n’a pas produit le texte qu’il examine. La température à 0.0 n’est pas un détail : un vérificateur doit être aussi reproductible que possible, sans quoi vous ne sauriez pas si un verdict qui change vient de la réponse ou de l’humeur du modèle.
def verifier_grounding(reponse: str, sources: str) -> dict:
"""Vérifie si une réponse est bien ancrée dans les sources."""
verification_prompt = f"""Analyse si cette réponse est fidèle aux sources.
RÉPONSE À VÉRIFIER :
{reponse}
SOURCES :
{sources}
Pour chaque affirmation de la réponse, indique :
- L'affirmation
- Si elle est supportée par les sources (OUI/NON)
- Le passage source correspondant (ou "Aucun")
Termine par un score de grounding : X affirmations supportées / Y total."""
response = client.responses.create(
model="gpt-5.6-terra",
input=verification_prompt,
temperature=0.0
)
return {"verification": response.output_text}
Technique 4 : prompt défensif anti-hallucination
Certaines formulations réduisent nettement les hallucinations, et elles ne sont pas interchangeables : chacune répond à un symptôme distinct. La formulation explicite se contente d’autoriser l’aveu d’ignorance, ce qui suffit souvent. La pénalisante hiérarchise les erreurs entre elles, utile face à un modèle qui préfère spontanément répondre n’importe quoi plutôt que rien. La structurelle fait remonter l’incertitude dans la sortie elle-même, précieuse quand votre interface doit distinguer visuellement ce qui est certain de ce qui est déduit. La contrainte, enfin, délimite la source par des balises, ce qui fonctionne particulièrement bien lorsque le contexte injecté est volumineux et que la frontière entre document et consigne risque de se brouiller.
defensive_prompts = {
"explicite": "Si tu ne connais pas la réponse, dis 'Je ne sais pas'.",
"penalisant": "Il est INTERDIT d'inventer des informations. "
"Une réponse 'je ne sais pas' est toujours préférable "
"à une information incorrecte.",
"structurel": "Pour chaque point de ta réponse, indique ton niveau "
"de confiance : [CERTAIN] basé sur le document, "
"[PROBABLE] déduit du contexte, [INCERTAIN] non vérifié.",
"contrainte": "Réponds en utilisant EXCLUSIVEMENT les informations "
"entre les balises <source> et </source>. "
"Toute information extérieure est interdite."
}
Bien employées, ces formulations réduisent les hallucinations de 60 à 80 %. Encore faut-il le constater chez vous plutôt que de vous en remettre à une moyenne : le taux de grounding se calcule en rejouant la vérification sur un lot de réponses et en agrégeant les scores obtenus.
def taux_grounding(reponses: list[dict]) -> float:
"""Calcule le taux de grounding sur un ensemble de réponses.
Chaque réponse est un dict avec 'reponse' et 'sources'.
"""
scores = []
for item in reponses:
verif = verifier_grounding(item["reponse"], item["sources"])
# Extraire le score (à adapter au format de sortie)
scores.append(verif)
return scores
Combinaison avec les outils de l’API
L’API OpenAI propose deux outils natifs qui vous dispensent de construire vous-même la couche de récupération. File Search cherche dans les documents que vous avez uploadés et injecte automatiquement les extraits pertinents dans le contexte. Web Search ancre les réponses dans des résultats web récents, ce qui dépanne quand le sujet évolue plus vite que votre base documentaire. Dans les deux cas, les instructions de restriction restent indispensables : l’outil se charge d’apporter la matière, c’est votre prompt et lui seul qui interdit au modèle de s’en écarter.
response = client.responses.create(
model="gpt-5.6-terra",
instructions="Réponds en te basant uniquement sur les documents fournis.",
input="Quelles sont les conditions de garantie ?",
tools=[{"type": "file_search"}]
)
Mettez maintenant la chaîne complète à l’épreuve sur un document interne de votre entreprise — FAQ, CGV, documentation technique, peu importe pourvu qu’il soit réel. Construisez l’assistant groundé par contexte explicite, interrogez-le avec dix questions dont trois portent volontairement sur des points absents du document, et vérifiez qu’il refuse ces trois-là au lieu de broder. Ajoutez ensuite la vérification post-génération et mesurez votre taux de grounding effectif : c’est ce chiffre, et non la confiance que vous placez dans votre prompt, qui décide si l’assistant peut aller en production.
Points clés à retenir
- Le grounding est indispensable pour toute application professionnelle
- Injectez le contexte source directement dans le prompt et forcez les citations
- Vérifiez le grounding après génération pour les cas critiques
- Les formulations défensives réduisent les hallucinations de 60 à 80 %
- Utilisez temperature=0.0-0.1 pour maximiser la fidélité aux sources