Comment vérifier la vraie fenêtre de contexte de votre IA
Comment vérifier la vraie fenêtre de contexte d'un LLM, comprendre le contexte externe contre interne, et éviter le problème de troncature silencieuse.
Chaque LLM a une fenêtre de contexte, la quantité maximale de texte qu’il peut traiter en une seule requête. Mais le nombre annoncé et le nombre effectif sont souvent très différents. Et si vous ne comprenez pas la différence, vous tomberez sur des défaillances silencieuses incroyablement difficiles à déboguer.
Contexte annoncé contre contexte effectif
Les fiches techniques des modèles ont l’air nettes :
| Modèle | Contexte annoncé |
|---|---|
| GPT-4o | 128K tokens |
| Claude 3.5 Sonnet | 200K tokens |
| Gemini 1.5 Pro | 1M tokens |
| Llama 3.1 70B | 128K tokens |
Mais la “fenêtre de contexte” n’est pas un seul nombre. C’est la somme de :
Contexte total = Prompt système + Historique de conversation + Définitions d'outils + Résultats d'outils + Message courant + Budget de sortie
Si votre prompt système fait 2 000 tokens, vos définitions d’outils 3 000 tokens, et que vous voulez 4 000 tokens de sortie, votre budget d’entrée effectif sur un modèle 128K est :
128 000 - 2 000 - 3 000 - 4 000 = 119 000 tokens pour la conversation + les résultats d'outils
Et ça, avant d’avoir envoyé le moindre message utilisateur.
Le problème de la troncature silencieuse
Voilà ce qui rend ça dangereux : la plupart des API n’émettent pas d’erreur quand vous dépassez la fenêtre de contexte. Elles tronquent en silence, généralement depuis le début de la conversation. Votre prompt système soigneusement conçu ? Disparu. Le contexte du projet chargé au départ ? Disparu. L’agent perd silencieusement sa mémoire et se met à produire n’importe quoi.
Vous n’aurez aucune erreur. Vous aurez des réponses assurées et fausses.
Comment vérifier la fenêtre de contexte
Le test le plus simple : envoyez des entrées de plus en plus longues et observez quand la qualité se dégrade ou quand la troncature survient.
import tiktoken
def count_tokens(text: str, model: str = "gpt-4") -> int:
encoding = tiktoken.encoding_for_model(model)
return len(encoding.encode(text))
# Tester avec votre vraie charge utile
system_prompt = open("system_prompt.txt").read()
tool_defs = open("tool_definitions.json").read()
user_message = open("task.txt").read()
total = count_tokens(system_prompt) + count_tokens(tool_defs) + count_tokens(user_message)
print(f"Total input tokens: {total}")
print(f"Remaining for output: {128000 - total}")
Mais compter les tokens ne suffit pas. Vous devez vérifier la rétention sémantique : le modèle se souvient-il vraiment de ce que vous avez mis dans le contexte ?
Le test de l’aiguille dans une botte de foin
# Placer un fait unique à une position précise dans un long contexte
needle = "The secret project codename is BLUEFIN-7."
haystack = generate_long_context(position=0.5, needle=needle) # à 50 %
response = llm.complete(
system="Answer based only on the context provided.",
context=haystack,
question="What is the secret project codename?"
)
assert "BLUEFIN-7" in response # S'en souvient-il vraiment ?
Lancez ça à différentes longueurs de contexte et à différentes positions. Vous découvrirez que :
- Le début et la fin du contexte sont bien mémorisés
- Le milieu des longs contextes se “perd”, c’est le problème du perdu-au-milieu (lost-in-the-middle)
- La rétention effective est souvent 20 à 40 % inférieure à la fenêtre annoncée
- Différents modèles se dégradent à des rythmes différents
Contexte externe : la taxe cachée
Quand vous utilisez le RAG (génération augmentée par récupération), la recherche vectorielle ou le chargement de contexte par outils, il y a un coût supplémentaire que la plupart des gens ratent :
Votre pipeline RAG :
1. L'utilisateur pose une question → 50 tokens
2. Encoder la question pour la recherche → appel d'API (pas gratuit)
3. Récupérer les 5 meilleurs chunks → 5 × 500 = 2 500 tokens
4. Injecter les chunks dans le prompt → 2 500 tokens de contexte
5. Le modèle génère une réponse → 500 tokens
Contexte total utilisé : ~3 050 tokens
Appels d'API totaux : 2 (embedding + complétion)
Chaque chunk récupéré coûte des tokens. Si votre récupération est imprécise et renvoie 10 chunks au lieu de 5, vous avez doublé votre coût en contexte pour ce tour.
Recommandations pratiques
1. Budgétez votre contexte explicitement
CONTEXT_BUDGET = {
"system_prompt": 2000,
"tool_definitions": 3000,
"conversation_history": 40000,
"retrieved_context": 10000,
"output_reserved": 4000,
"total": 128000,
}
# Restant pour l'entrée utilisateur : 69 000 tokens
2. Surveillez l’usage réel, pas les estimations
La plupart des API renvoient l’usage de tokens dans la réponse :
{
"usage": {
"prompt_tokens": 45230,
"completion_tokens": 1200,
"total_tokens": 46430
}
}
Logguez ça. Alertez quand l’usage dépasse 80 % de votre fenêtre.
3. Compressez agressivement
- Résumez les anciens tours de conversation au lieu de les garder mot pour mot
- Utilisez des formats structurés (JSON) plutôt que de la prose pour les résultats d’outils
- Dédupliquez les chunks récupérés avant de les injecter
- Tronquez le contenu des fichiers aux sections pertinentes, pas aux fichiers entiers
4. Testez avec vos vraies charges utiles
Ne faites pas confiance aux chiffres de benchmark. Testez avec vos vrais prompts système, vos vraies définitions d’outils et vos vrais schémas de conversation. La courbe de dégradation est propre à votre cas d’usage.
Quoi en faire concrètement
Si vous construisez un outil à un seul coup (un prompt, une réponse), la fenêtre de contexte annoncée est assez proche : ne sur-construisez pas.
Si vous construisez quoi que ce soit avec un état multi-tours, du RAG ou de la mémoire d’agent, lancez le test de l’aiguille dans une botte de foin ci-dessus contre vos vrais prompts, pas un benchmark synthétique. La courbe de rétention dépend du modèle et de la structure du prompt ; le seul nombre qui compte est celui que vous avez mesuré sur vos propres données.