Chaque interaction avec un LLM s’accompagne d’une taxe cachée. Vous envoyez une requête, le modèle la traite, génère une réponse, et vous payez par token. Pas par mot. Pas par caractère. Par token, une unité qui ne correspond pas directement à quelque chose que vous pouvez voir à l’écran.
La plupart des personnes qui développent avec des LLM ne savent pas vraiment ce qu’est un token. Ils voient un prix par token, font le calcul, et passent à autre chose. Ensuite, leurs coûts explosent pour des raisons qu’ils ne peuvent pas expliquer. Ou ils se heurtent aux limites de la fenêtre de contexte et se demandent pourquoi leur document de 8 000 mots a été coupé en plein traitement.
La tokenisation n’est pas qu’un détail de facturation. C’est la condition limite de tout ce que vous construisez avec des modèles de langage. Comprenez-la, et vous débloquerez des gains d’efficacité qui se cumulent sur tous les systèmes que vous exécutez. Ignorez-la, et vous perdrez de l’argent, atteindrez des limites à des moments frustrants, et construirez de moins bons produits.
Ce qu’est réellement un token
Un token est la plus petite unité avec laquelle un modèle de langage travaille. Ce n’est pas un mot. Ce n’est pas un caractère. C’est quelque chose entre les deux, et les limites exactes varient en fonction du modèle que vous utilisez et du tokenizer qui encode votre texte.
Imaginez ceci : un tokenizer est une table de correspondance. Du texte brut entre d’un côté. De l’autre, une séquence d’entiers : des identifiants de token. Le modèle voit ces entiers, les traite, et génère de nouveaux entiers en retour.
Voici ce qui se passe en pratique :
- Le mot « bonjour » = 1 token
- Le mot « malheureusement » = 2 tokens (mal +heureusement)
- Le signe de ponctuation « . » = 1 token
- Un espace avant un mot = 1 token (généralement)
- La séquence « \n\n » (saut de paragraphe) = 1 token
Les mots courts et courants sont compressés en tokens uniques. Les mots plus longs ou plus rares sont divisés en plusieurs tokens. Les caractères spéciaux, les chiffres et les espaces blancs ont tous leurs propres règles d’encodage.
Différents modèles utilisent différents tokenizers. Les modèles GPT d’OpenAI (GPT-4o, GPT-4 Turbo) utilisent le tokenizer cl100k_base. Les modèles Claude d’Anthropic utilisent un tokenizer différent. Llama 3 70B en utilise encore un autre. Cela a de l’importance : la même phrase se tokenise en différentes longueurs selon le modèle qui la traite.
Pourquoi le compte de tokens n’est pas intuitif
Vous écrivez 500 mots. Vous supposez que cela représente environ 500 tokens, peut-être 700 si vous comptez la mise en forme. Ensuite, vous le faites passer par un tokenizer et obtenez 820 tokens. Ou 1 240. Ou tout autre chose.
L’inadéquation se produit parce que les tokens ne suivent pas les frontières des mots. Voici un exemple concret :
# Texte d'entrée
"L'API ChatGPT ne renvoie pas automatiquement les comptes de tokens."
# Nombre de mots : 9
# Nombre de tokens (OpenAI cl100k_base) : 13
Pourquoi 13 ? Décomposons :
- « L’API » = 1 token
- « ChatGPT » = 1 token
- » ne » = 1 token (espace + mot)
- » renvoie » = 1 token
- » pas » = 1 token
- » automatiquement » = 1 token
- » les » = 1 token
- » comptes » = 1 token
- » de » = 1 token
- » tokens » = 1 token
- « . » = 1 token
Les contractions se divisent. Les noms de marque se compressent. Les espaces comptent. Votre hypothèse intuitive sur la densité des tokens ne tient pas.
Cela a une importance pratique car :
- Vous ne pouvez pas budgétiser les coûts avec précision sans connaître votre densité de tokens réelle
- Vous ne pouvez pas concevoir des prompts efficaces si vous devinez les nombres de tokens
- Vous atteindrez les limites de contexte de manière inattendue si vous sous-estimez la quantité de contenu qui rentre
Fenêtres de contexte : les limites strictes
Chaque LLM a une fenêtre de contexte, c’est-à-dire le nombre maximum de tokens qu’il peut traiter en une seule interaction. Cela inclut votre prompt (tokens d’entrée) plus la réponse du modèle (tokens de sortie).
| Modèle | Fenêtre de contexte | Sortie Max |
|---|---|---|
| Claude 3.5 Sonnet | 200 000 tokens | 4 096 tokens |
| GPT-4o | 128 000 tokens | 4 096 tokens |
| GPT-4 Turbo | 128 000 tokens | 4 096 tokens |
| Llama 3 70B | 8 192 tokens | N/A (variable) |
| Mistral 7B | 32 768 tokens | N/A (variable) |
La fenêtre de 200 000 tokens de Claude 3.5 Sonnet est vraiment grande. Cela représente environ 150 000 mots d’entrée, un manuel technique complet ou une année d’e-mails. GPT-4o, avec 128 000 tokens, gère la plupart des tâches à l’échelle d’un document. Llama 3 70B, si vous l’exécutez localement, atteint un maximum de 8 192 tokens, soit environ 6 000 mots.
La fenêtre de contexte est un plafond strict. Si votre entrée + la sortie souhaitée dépasse la fenêtre, le modèle tronque votre entrée (perte d’informations) ou renvoie une erreur. Pas de dégradation gracieuse. Pas de tampon de dépassement. Vous atteignez la limite et votre requête échoue.
C’est pourquoi le comptage des tokens est important avant de construire. Si vous traitez des documents et que votre flux de travail ajoute des prompts système, du contexte de récupération, des exemples few-shot et le document lui-même, vous pouvez facilement dépasser la fenêtre.
Comment mesurer les tokens efficacement
Vous avez trois options : compter localement, utiliser un appel API, ou estimer.
Option 1 : Compter localement à l’aide de bibliothèques de tokenisation
Pour les modèles OpenAI, utilisez le tokenizer officiel :
import tiktoken
enc = tiktoken.encoding_for_model("gpt-4o")
text = "Votre requête va ici. Ceci est un test."
tokens = enc.encode(text)
print(f"Nombre de tokens : {len(tokens)}")
# Sortie : Nombre de tokens : 15
Pour les modèles Claude d’Anthropic, Anthropic fournit un tokenizer :
import anthropic
client = anthropic.Anthropic()
text = "Votre requête va ici. Ceci est un test."
response = client.messages.count_tokens(
model="claude-3-5-sonnet-20241022",
messages=[{"role": "user", "content": text}]
)
print(f"Nombre de tokens : {response.input_tokens}")
# Sortie : Nombre de tokens : 15
Les deux approches sont rapides et précises. Utilisez-les avant de construire quoi que ce soit à grande échelle.
Option 2 : Vérifier les tokens via la réponse de l’API
La plupart des appels API renvoient l’utilisation des tokens dans la réponse. Les modèles GPT renvoient l’utilisation comme ceci :
from openai import OpenAI
client = OpenAI()
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Bonjour, comment allez-vous ?"}]
)
print(f"Tokens d'entrée : {response.usage.prompt_tokens}")
print(f"Tokens de sortie : {response.usage.completion_tokens}")
print(f"Total : {response.usage.total_tokens}")
Claude renvoie les mêmes informations dans la réponse du message. Capturez toujours ces données lorsque vous développez ; c’est la vérité terrain pour votre utilisation réelle.
Option 3 : Estimer (quand on ne peut pas compter)
Si vous avez besoin d’une estimation approximative sans exécuter de code, la règle générale est :
- Texte anglais : 1 token ≈ 0,75 mots (donc 100 mots ≈ 133 tokens)
- Code : 1 token ≈ 0,5 mots (le code se tokenise moins efficacement)
- JSON : similaire au code (les caractères structurels ajoutent une surcharge)
Ceci est approximatif. Si la précision est importante, et elle devrait l’être en production, mesurez directement au lieu d’estimer.
Conception de prompts efficaces sous contraintes de tokens
Étant donné que les tokens sont limités et que leur nombre n’est pas intuitif, comment concevoir des prompts qui respectent le budget tout en restant efficaces ?
Technique 1 : Prioriser l’entrée sur la verbosité
Votre prompt système n’a pas besoin de tout expliquer. Donnez-lui les règles qui comptent, supprimez le reste.
Mauvaise approche (148 tokens) :
Vous êtes un analyste financier expert avec une connaissance approfondie des stratégies d'investissement, des tendances du marché et de la gestion des risques. Votre rôle est d'analyser attentivement les données financières et de fournir des informations. Vous devez toujours être approfondi, réfléchi et précis dans votre analyse. Pensez étape par étape aux données et fournissez des explications complètes pour vos conclusions.
Meilleure approche (42 tokens) :
Analysez les données financières. Fournissez des informations spécifiques avec une évaluation des risques. Soyez précis.
La deuxième version utilise 71 % de tokens en moins et contraint le modèle plus clairement. Supprimez les adjectifs. Supprimez les réassurances. Gardez les instructions.
Technique 2 : Utiliser les exemples few-shot sélectivement
Le prompting few-shot (donner des exemples) améliore la qualité de la sortie mais coûte des tokens pour chaque exemple ajouté. Utilisez-les stratégiquement :
- Ignorez le few-shot pour les tâches simples (classification, extraction directe). Le modèle connaît ces schémas.
- Ajoutez un exemple pour les tâches de complexité moyenne (logique conditionnelle, exigences de format). Un exemple ≈ 30-50 tokens selon la longueur.
- Ajoutez deux exemples uniquement pour les tâches complexes (cas limites, schémas rares, exigences de style spécifiques).
Testez : exécutez votre prompt sans exemples, mesurez la qualité de la sortie. Si la qualité est acceptable, vous avez économisé des tokens. N’ajoutez des exemples que si la sortie se dégrade visiblement.
Technique 3 : Compresser le contexte avant l’envoi
Si vous traitez de longs documents, extrayez les parties pertinentes avant de les passer au modèle. C’est là que le RAG (Retrieval-Augmented Generation) permet d’économiser de l’argent : vous récupérez uniquement les passages pertinents, pas le document entier.
import anthropic
client = anthropic.Anthropic()
# Au lieu d'envoyer un document de 50 000 tokens
full_document = "... manuel technique complet ..."
# Extrayez d'abord la section pertinente (votre propre logique, pas le LLM)
relevant_section = extract_relevant_section(full_document, query)
# Envoyez uniquement la partie pertinente
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1024,
messages=[{
"role": "user",
"content": f"Contexte : {relevant_section}\n\nQuestion : {query}"
}]
)
print(response.content[0].text)
Cela fonctionne parce que vous contrôlez ce que le modèle voit. La majeure partie du document reste sur le disque. Seuls les 500 tokens pertinents sont traités. Même réponse. Coût différent.
Technique 4 : Réutiliser les prompts système entre les lots
Si vous effectuez plusieurs appels API avec le même prompt système, c’est bien : vous serez facturé pour les tokens du prompt système à chaque fois. Mais si votre prompt système est volumineux, certains modèles proposent la « mise en cache de prompt » (Claude avec l’API Anthropic facture 10 % pour les tokens mis en cache lors des utilisations ultérieures).
Pour AlgoVesta, nous standardisons les prompts système courts et réutilisables. Au lieu d’un prompt de 300 tokens envoyé à chaque requête, nous utilisons un ensemble d’instructions de 40 tokens. Les économies sur des millions d’inférences sont substantielles.
Coûts des tokens selon les modèles : la comparaison
Les tokens sont la monnaie, mais le prix réel par token varie énormément. Voici les prix réels en mars 2025 :
| Modèle | Entrée (par 1M tokens) | Sortie (par 1M tokens) | Coût pratique pour 10K entrées |
|---|---|---|---|
| Claude 3.5 Sonnet | 3,00 $ | 15,00 $ | 0,03 $ |
| GPT-4o | 5,00 $ | 15,00 $ | 0,05 $ |
| GPT-4 Turbo | 10,00 $ | 30,00 $ | 0,10 $ |
| Llama 3 70B (auto-hébergé) | 0 $ (votre infra) | 0 $ (votre infra) | 0 $ (votre infra) |
Claude 3.5 Sonnet est le moins cher pour l’entrée. GPT-4o coûte 60 % de plus par token d’entrée. GPT-4 Turbo coûte 3 fois plus. Si vous effectuez des millions d’inférences, l’efficacité des tokens se traduit directement par des économies.
Les modèles auto-hébergés (Llama 3 70B, Mistral, etc.) déplacent le coût vers votre infrastructure. Pas de facturation par token, mais vous payez pour le calcul initial. Le point d’équilibre dépend de votre volume et de vos coûts d’infrastructure.
Pièges courants liés aux limites de tokens et comment les éviter
Piège 1 : Oublier le comptage des tokens du prompt système
Votre contexte disponible n’est pas la fenêtre complète moins votre entrée. C’est la fenêtre moins votre prompt système moins votre entrée. Un prompt système de 1 000 tokens n’est pas gratuit.
Avec GPT-4o (fenêtre de 128 000 tokens), un prompt système de 1 000 tokens + une entrée de 2 000 tokens + une sortie souhaitée de 4 000 tokens = 7 000 tokens utilisés. Il vous reste 121 000 pour le contenu réel. C’est encore beaucoup, mais si vous utilisez ces calculs négligemment sur de nombreuses couches de prompts, vous perdez rapidement de la marge.
Piège 2 : Ne pas tenir compte des tokens répétés
Si vous construisez un système où un utilisateur pose plusieurs questions d’affilée, ne supposez pas que vous pouvez faire entrer N questions dans la fenêtre de contexte. Chaque message ajoute des tokens de métadonnées. Chaque tour de conversation utilise des tokens pour le formatage et la structure.
En pratique, une conversation de 10 tours avec des messages courts peut utiliser 2 fois plus de tokens que le texte brut seul en raison de la surcharge de formatage.
Piège 3 : Tronquer les entrées longues naïvement
Si vous atteignez une limite de tokens, ne coupez pas simplement le texte à la position N en espérant ne pas avoir perdu d’informations critiques. Sélectionnez explicitement les sections dont vous avez besoin, ou utilisez le RAG pour faire remonter le contenu pertinent.
La troncature naïve provoque des hallucinations. Le modèle essaie de donner un sens à des informations partielles et fabrique le contexte manquant.
Piège 4 : Supposer que tout espace blanc est gratuit
Les lignes vides, l’indentation et les espaces supplémentaires sont tous tokenisés. Si vous formatez un prompt avec beaucoup d’espaces blancs pour la lisibilité, vous consommez des tokens sur des caractères invisibles.
Pour les prompts destinés aux utilisateurs, la lisibilité compte. Pour les prompts système internes, compressez : supprimez les sauts de ligne supplémentaires, utilisez des espaces simples, minimisez la mise en forme.
Flux de travail pratique : concevoir un système efficace en tokens
Voici l’approche étape par étape que j’utilise lorsque je crée de nouvelles fonctionnalités LLM :
Étape 1 : Mesurez votre référence. Écrivez votre prompt de manière logique. Mesurez le nombre de tokens. Notez-le.
Étape 2 : Identifiez ce qui compte réellement en tokens. Prompt système. Entrée. Exemples. Quel compartiment consomme le plus ? S’il s’agit d’exemples, supprimez-les. S’il s’agit de l’entrée, vous avez besoin d’une meilleure sélection de documents. S’il s’agit du prompt système, réduisez les instructions.
Étape 3 : Définissez un budget de tokens et respectez-le. Décidez du nombre maximum de tokens que vous pouvez vous permettre (coût) ou tolérer (latence). Incluez une marge pour les variations.
Étape 4 : Testez la qualité au budget. Exécutez votre prompt à la limite de tokens avec des entrées réelles. La qualité de la sortie se dégrade-t-elle ? Si oui, vous coupez trop. Sinon, coupez plus.
Étape 5 : Surveillez en production. Enregistrez l’utilisation réelle des tokens. Si l’utilisation réelle dépasse systématiquement votre estimation de 20 %, ajustez votre budget. Si elle est inférieure de 30 %, vous avez de la marge pour ajouter de la valeur (plus de contexte, de meilleurs exemples, des instructions plus claires).
Faites-le aujourd’hui
Choisissez un prompt ou un système que vous utilisez régulièrement. Exécutez le tokenizer officiel de votre modèle dessus. Obtenez le nombre réel. Mesurez ensuite le nombre de mots et calculez votre ratio tokens/mots. La plupart des gens seront surpris que ce ne soit pas 1:1. Comprendre cet écart, comment votre utilisation réelle diverge de votre hypothèse, est le début de l’efficacité.
Si vous créez un système multi-messages (chat, conversation, récupération), mesurez une interaction complète de bout en bout. Voyez à quoi ressemble la surcharge de formatage dans votre flux de travail spécifique. Ce nombre ne change pas : capturez-le une fois, utilisez-le pour toutes les estimations futures.