Source: https://aiprimetech.io/fr/blog/reduce-llm-token-usage/ Juin 20, 2026 · 7 min · API # Réduire l’utilisation de tokens sans compromettre la qualité A Par [AI Prime Tech](https://aiprimetech.io/fr/) · Avec l’aide de l’IA Le mois dernier, j’ai examiné un agent d’assistance client qui consommait 18,000–42,000 tokens d’entrée par ticket avant même d’écrire un seul mot. Le problème réel de l’utilisateur tenait généralement en moins de 300 tokens. Le reste était du contexte ajouté « au cas où » : l’historique complet de la conversation, toutes les pages de politiques internes récupérées par recherche de mots-clés, JSON résultats d’outils copiés tels quels et un prompt système de 900 tokens qui s’était étoffé au fil de six mois. La solution n’était pas « utiliser un modèle plus petit » ni « réduire max_tokens et croiser les doigts ». Nous avons réduit l’utilisation médiane des tokens d’environ 68 % tout en maintenant la qualité des réponses grâce à un travail d’ingénierie sans éclat : élaguer le contexte, récupérer des éléments probants plus ciblés, résumer l’état, imposer des schémas de sortie et mesurer honnêtement les tokens. Cet article porte sur ce type de travail. Pas sur la chasse au prompt le plus court. Pas sur des astuces qui dégradent le modèle. Simplement sur des moyens pratiques de consommer moins de tokens sans rendre votre système moins intelligent. ## L’utilisation des tokens est un problème d’architecture La plupart des équipes considèrent le coût des tokens comme un problème de tarification des modèles. En pratique, il s’agit généralement d’un problème de routage de l’information. Un appel LLM typique en production comporte quatre catégories de tokens : - Tokens d’instruction : prompt système, prompt développeur, règles de mise en forme, contraintes de sécurité. - Tokens de contexte : historique de discussion, documents récupérés, sorties d’outils, enregistrements de base de données. - Tokens de raisonnement et de tâche : demande réelle de l’utilisateur et détails intermédiaires de la tâche. - Tokens de sortie : réponse générée, objet JSON, requête SQL, résumé ou appel d’outil. Lorsque l’utilisation des tokens devient incontrôlable, le contexte et la sortie sont généralement en cause. Le modèle ne coûte pas cher parce que l’utilisateur a posé une question difficile. Il coûte cher parce que l’application a entassé le monde entier dans le prompt, puis laissé le modèle s’étendre sans fin. Un premier exercice utile consiste à journaliser l’utilisation des tokens par section, et pas seulement la taille totale de la requête : ``` { "request_id": "ticket_81291", "model": "sonnet-4.6", "tokens": { "system": 742, "history": 3890, "retrieval": 12640, "tool_results": 2110, "user": 184, "output": 931 }, "latency_ms": 4820 } ``` Une fois cette répartition visible, la voie à suivre pour optimiser devient évidente. Inutile de débattre pour savoir si Claude Opus 4.8, Sonnet 4.6, GPT-5.5, Gemini 3, Fable 5 ou un modèle ouvert comme Qwen ou DeepSeek est le « meilleur » dans l’absolu. Il faut d’abord cesser d’envoyer 12,000 tokens de contenu récupéré sans pertinence. ## Commencez par un budget de tokens par parcours Je préfère attribuer des budgets par parcours produit plutôt que globalement. L’analyse d’un contrat juridique, un agent de programmation et un bot de FAQ ne devraient pas reposer sur les mêmes hypothèses de consommation de tokens. Exemple de budget pour un assistant d’assistance client : | Option | Budget d’entrée | Budget de sortie | Catégorie de modèle | Remarques | Classer le ticket | 600 | 50 | Modèle économique et rapide | Étiquettes, urgence, langue | Récupérer les éléments probants | 1,500 | 0 | Vectorisation/recherche | Aucune génération nécessaire | Rédiger la réponse | 4,000 | 600 | Modèle performant de gamme intermédiaire ou supérieure | Utilise les éléments probants sélectionnés | Résumer le fil de discussion | 1,000 | 250 | Modèle économique et rapide | Met à jour l’état de la mémoire | Analyse pour l’escalade | 6,000 | 900 | Modèle performant | Uniquement pour les cas complexes L’idée n’est pas que ces chiffres soient universellement justes. Ce sont des contraintes de départ volontairement modestes. Le comportement utile qui en découle est que chaque étape doit justifier les tokens qu’elle consomme. Un piège fréquent : si vous définissez uniquement max_tokens pour la sortie, votre entrée peut quand même gonfler silencieusement. Les limites de sortie empêchent les réponses longues ; elles n’empêchent pas l’accumulation excessive de contenu récupéré. ## Élaguez le contexte avant la récupération, pas après De nombreux systèmes récupèrent des documents à partir du dernier message de l’utilisateur, mais incluent tout de même l’historique complet de la conversation dans le prompt final. Les anciennes digressions, les appels d’outils ayant échoué et les hypothèses périmées restent donc dans le contexte. Maintenez plutôt un état de travail compact : ``` { "user_goal": "Get refund for duplicate annual subscription charge", "known_facts": [ "User paid twice on 2025-01-08", "Invoice IDs: inv_1042 and inv_1077", "Account email: user@example.com" ], "constraints": [ "Refund policy allows duplicate-charge refunds within 90 days", "User prefers email follow-up" ], "open_questions": [ "Whether one charge has already been reversed" ], "last_updated_turn": 12 } ``` Votre appel final inclut alors : - L’état compact. - Le dernier message de l’utilisateur. - Uniquement les extraits pertinents des politiques récupérées. - Éventuellement le dernier échange ou les deux derniers échanges si la continuité du ton est importante. N’incluez pas aveuglément tous les messages précédents. L’historique de discussion n’est pas une mémoire ; c’est une transcription. La mémoire est l’état synthétisé nécessaire pour poursuivre la tâche. En pratique, j’utilise trois couches : - Échanges récents : les 1–4 derniers échanges, selon la sensibilité de la tâche. - Résumé actualisé : faits et décisions stables. - Récupération externe : documents, enregistrements de base de données, sorties d’outils. Cette approche donne généralement de meilleurs résultats que l’accumulation de transcriptions brutes, car le modèle voit moins de bruit et moins d’instructions contradictoires. ## La récupération doit être sélective, pas décorative La génération augmentée par récupération commence souvent comme une amélioration de la qualité et finit par devenir une fuite de tokens. Le mode de défaillance est facile à repérer : top-k est réglé sur 10 ou 20, les segments contiennent 1,000 tokens chacun et le prompt final contient un amas de documents vaguement liés. Une meilleure récupération est généralement une récupération moins coûteuse. Un pipeline de récupération pratique : ``` def build_context(query, user_state): search_query = rewrite_for_search(query, user_state) candidates = vector_search( query=search_query, top_k=30, filters={"product": user_state["product"]} ) reranked = rerank_cross_encoder( query=search_query, docs=candidates, top_k=6 ) selected = [] token_budget = 1800 for doc in reranked: snippet = extract_relevant_span(doc.text, query=search_query, max_tokens=300) if token_count(selected) + token_count(snippet) <= token_budget: selected.append({ "doc_id": doc.id, "title": doc.title, "text": snippet }) return selected ``` Les détails importants : - Récupérez davantage de candidats que vous ne prévoyez d’en inclure. - Reclassez les résultats avant la génération. - Extrayez les passages pertinents au lieu de transmettre des segments entiers. - Imposez un budget de tokens pour la récupération. - Conservez les identifiants des documents pour que le modèle puisse citer les éléments probants ou y faire référence en interne. La taille des segments compte. Si vos segments sont trop petits, le modèle perd le contexte. S’ils sont trop grands, chaque correspondance entraîne du texte non pertinent. Pour les documentations produit et les pages de politiques, je commence souvent autour de 300–600 tokens par segment en conservant les titres, puis j’ajuste en fonction des cas d’échec. Que se passe-t-il réellement lorsque vous accumulez trop de contexte récupéré ? Le modèle devient souvent moins précis. Il tente de concilier des politiques connexes mais non pertinentes, reprend des réserves obsolètes ou répond à la mauvaise version de la question. Réduire les tokens peut améliorer la qualité, car cela élimine les éléments qui détournent l’attention. ## Le résumé est une compression dont il faut pouvoir rendre compte La synthèse peut économiser d’énormes quantités de contexte, mais les résumés négligés sont dangereux. Si un résumé omet une contrainte, votre agent peut faire la mauvaise chose avec assurance. Je préfère les résumés structurés au texte libre : ``` { "task": "Debug failing OAuth callback in staging", "environment": { "service": "auth-api", "branch": "release-2025-02-14", "runtime": "node 20" }, "confirmed": [ "Callback returns 302 to /login", "Provider sends code and state", "State validation passes" ], "suspected": [ "Session cookie is not persisted after callback" ], "rejected": [ "Provider credentials are invalid", "Redirect URI mismatch" ], "next_steps": [ "Inspect Set-Cookie attributes in staging response", "Compare SameSite and Secure flags with production" ] } ``` Cette approche consomme moins de tokens et est plus fiable que : L’utilisateur débogue OAuth et a essayé différentes choses… Une bonne étape de synthèse doit préserver : - L’objectif de l’utilisateur. - Les faits établis. - Les décisions déjà prises. - Les contraintes et les préférences. - Les tentatives infructueuses. - Les questions en suspens. - Les identifiants, noms de fichiers, horodatages et autres références exactes. Ne faites pas disparaître les valeurs exactes dans le résumé, sauf si elles sont vraiment sans intérêt. « L’utilisateur a un problème de facture » consomme peu de tokens, mais ne sert à rien. « Double prélèvement : inv_1042 et inv_1077 le 2025-01-08 » est le type de compression à rechercher. Pour les agents qui fonctionnent sur de longues périodes, je conserve aussi les versions des résumés. Si le modèle produit un mauvais résumé, vous devez pouvoir examiner à quel moment l’état a dérivé. ## Évitez les réponses interminables grâce aux schémas Une quantité surprenante de tokens est gaspillée dans les sorties. Le prompt demande d’être concis, mais le modèle rédige un préambule, des réserves, un récapitulatif et une proposition d’aide. Pour les sorties destinées à être traitées par une machine, utilisez des schémas. Ne demandez pas simplement « une réponse JSON » : définissez sa structure et rejetez tout ce qui ne s’y conforme pas. Exemple d’appel de classification : ``` { "type": "object", "additionalProperties": false, "required": ["category", "priority", "needs_human", "reason"], "properties": { "category": { "type": "string", "enum": ["billing", "bug", "account", "how_to", "other"] }, "priority": { "type": "string", "enum": ["low", "normal", "high", "urgent"] }, "needs_human": { "type": "boolean" }, "reason": { "type": "string", "maxLength": 160 } } } ``` Pour les réponses destinées aux utilisateurs, imposez un format avec une limite stricte : ``` Write the answer in this structure: - First sentence: direct answer, max 25 words. - Then 2-4 bullets with concrete steps. - Do not include a greeting. - Do not include "let me know if you need anything else." - Stop after the final bullet. ``` Cela fonctionne mieux que « faites court », car le modèle dispose ainsi d’une structure. Un piège courant : une valeur faible de max_tokens peut tronquer une sortie utile au milieu d’une idée. Un schéma ou un format contraint réduit la longueur de la sortie tout en préservant son exhaustivité. La troncature est un dernier recours, pas une stratégie de mise en forme. ## Utilisez les séquences d’arrêt avec précaution Les séquences d’arrêt sont utiles lorsque la génération présente une limite naturelle. Par exemple, si le modèle génère une section dans un document basé sur un modèle prédéfini, vous pouvez l’arrêter au marqueur de la section suivante. ``` { "model": "gpt-5.5", "messages": [ { "role": "user", "content": "Generate only the Risk Summary section for this review..." } ], "max_tokens": 500, "stop": ["\n## Mitigations", "\n## Appendix"] } ``` Les séquences d’arrêt sont moins utiles pour les réponses ouvertes d’un assistant, car elles peuvent couper du contenu valide. Leur comportement varie aussi selon les API et les familles de modèles, notamment lorsque des appels d’outils ou des sorties structurées sont en jeu. Considérez-les comme des garde-fous délimitant la sortie, et non comme une technique principale de compression. Usages appropriés : - Générer une section d’un modèle de document connu. - Empêcher le modèle de poursuivre avec des exemples. - S’arrêter à un délimiteur lors d’un traitement par lots. - Contraindre les anciens prompts de complétion. Usages risqués : - S’arrêter sur des signes de ponctuation courants. - S’arrêter sur des mots susceptibles d’apparaître dans des réponses ordinaires. - Utiliser des séquences d’arrêt à la place d’un schéma de sortie adapté. - Supposer un comportement identique entre Claude, GPT, Gemini et les passerelles de modèles ouverts. ## Répartissez les tâches entre des modèles moins coûteux Chaque étape ne nécessite pas votre modèle le plus puissant. Dans les systèmes en production, j’oriente souvent les sous-tâches vers des modèles plus petits ou moins coûteux : | Sous-tâche | Exigence habituelle | Choix adapté | Détection de la langue | Classification simple | Modèle petit ou peu coûteux | Catégorie du ticket | Sortie structurée d’étiquettes | Modèle petit ou intermédiaire | Reformulation de requêtes | Transformation courte | Modèle petit ou intermédiaire | Reclassement de documents | Modèle de reclassement spécialisé ou petit modèle | Approche non générative lorsque c’est possible | Réponse finale | Raisonnement et ton | Modèle plus puissant | Exception à une politique | Nuances et risques | Modèle le plus puissant C’est là que l’accès à plusieurs modèles devient utile sur le plan opérationnel. Vous pouvez choisir Sonnet 4.6 pour la plupart des tâches de rédaction agentique, GPT-5.5 pour un raisonnement délicat, Gemini 3 pour certains flux de travail multimodaux ou à contexte long, Fable 5 lorsque la fenêtre de contexte de 1M est réellement nécessaire, et des modèles ouverts comme Llama, Qwen, DeepSeek, MiniMax ou Kimi pour des tâches internes contrôlées. L’enjeu technique est le routage, pas la fidélité à une marque. La limite : les surcoûts liés à l’orchestration sont bien réels. Chaque appel supplémentaire à un modèle ajoute de la latence, des modes de défaillance, de la complexité dans la journalisation et un périmètre d’évaluation plus large. Si un classificateur peu coûteux économise 300 tokens, mais ajoute 600 ms et un mécanisme de nouvelle tentative supplémentaire, le jeu n’en vaut peut-être pas la chandelle. Une approche que j’apprécie : ``` if route == "simple_faq": model = "haiku-4.5" elif route == "standard_support": model = "sonnet-4.6" elif route == "legal_or_financial_exception": model = "opus-4.8" else: model = "sonnet-4.6" ``` Les noms exacts changeront. La règle doit rester la même : utiliser le modèle le moins coûteux qui atteint de façon fiable le niveau de qualité requis pour la tâche. ## Mesurez honnêtement les tokens en entrée et en sortie L’optimisation des tokens échoue lorsque les équipes ne regardent que le coût moyen par requête. Il vous faut des distributions, ventilées par route et par étape. Suivez au minimum : - Tokens d’entrée par section du prompt. - Tokens de sortie. - Nombre de documents récupérés et tokens associés à la récupération. - Nom et version du modèle. - Percentiles de latence. - Taux de succès du cache, si vous utilisez la mise en cache des prompts ou du contexte. - Nombre de nouvelles tentatives. - Indicateurs de qualité perceptibles par l’utilisateur. - Taux de transfert à un humain ou de correction humaine. Un tableau de bord utile affiche p50, p90 et p99. Les problèmes de consommation de tokens se trouvent souvent dans la queue de distribution. Exemple de ligne de journal : ``` { "route": "support.draft_answer", "model": "sonnet-4.6", "input_tokens": 3820, "output_tokens": 514, "retrieved_docs": 4, "retrieval_tokens": 1320, "latency_ms": 3100, "cache_hit": false, "quality": { "user_thumb": "up", "human_edited": false } } ``` Méfiez-vous des affirmations comme « nous avons réduit les tokens de 40 % ». Les nouvelles tentatives ont-elles augmenté ? Les transferts à un humain ont-ils augmenté ? Les utilisateurs ont-ils posé davantage de questions complémentaires parce que les réponses étaient devenues trop laconiques ? Le modèle moins coûteux a-t-il produit davantage de JSON invalide, nécessitant des appels de correction ? La métrique honnête n’est pas le nombre de tokens par appel. C’est le nombre de tokens par tâche accomplie avec succès. ## Un contexte long n’autorise pas la paresse Les grandes fenêtres de contexte sont réellement utiles. La capacité de contexte de 1M de Fable 5, les atouts de Gemini en matière de contexte long et les modes à contexte long des modèles de pointe permettent des flux de travail qui étaient difficiles à mettre en œuvre il y a quelques années : analyse du code à l’échelle d’un dépôt entier, examen de documents volumineux, transcriptions de plusieurs heures, dossiers de recherche denses. Mais le contexte long est une capacité, pas une architecture par défaut. Les appels à contexte long peuvent être adaptés lorsque : - La réponse dépend de nombreuses parties éloignées de l’entrée. - La récupération manquerait les relations entre documents. - La tâche est exploratoire et vous ne savez pas encore ce qui compte. - Le coût de la perte d’un détail dépasse celui d’une lecture plus étendue. Ils sont généralement source de gaspillage lorsque : - L’utilisateur pose une question factuelle précise. - Quelques extraits des sources suffisent. - Le contexte contient des informations dupliquées ou obsolètes. - Le modèle est utilisé comme filtre de base de données. Une approche courante consiste à utiliser le contexte long pour l’analyse hors ligne et à produire des artefacts compacts pour le traitement en ligne. Par exemple, analysez une fois un corpus complet de politiques, puis générez une cartographie structurée des politiques, des représentations vectorielles, des résumés et des cas de test. L’assistant ne devrait pas relire tout le corpus à chaque ticket lors de son exécution. ## Une démarche pratique d’optimisation Lorsque je reprends un système LLM qui consomme beaucoup de tokens, je procède généralement dans cet ordre : - Commencez par instrumenter Ajoutez un décompte des tokens par section. N’optimisez pas à l’aveugle. - Limitez le contexte issu de la récupération Fixez un budget strict de tokens pour la récupération. Reclassez les résultats et extrayez les passages pertinents. - Remplacez l’accumulation de transcriptions par un état Conservez les échanges récents ainsi qu’une mémoire structurée. - Contraignez les sorties Utilisez des schémas pour les sorties destinées aux machines et des formats explicites pour celles destinées aux utilisateurs. - Orientez les sous-tâches vers les modèles adaptés Confiez la classification, la reformulation et la synthèse à des modèles moins coûteux lorsque leur fiabilité le permet. - Évaluez la qualité à l’échelle de la tâche Comparez les résolutions réussies, pas seulement le coût par appel. - Surveillez les valeurs extrêmes Analysez les pics de tokens aux percentiles p95 et p99. Ils révèlent souvent une recherche défaillante ou un historique qui grossit sans contrôle. Voici un garde-fou simple que j’ai utilisé dans des services : ``` TOKEN_LIMITS = { "support.classify": {"input": 800, "output": 80}, "support.retrieve": {"input": 500, "output": 0}, "support.draft": {"input": 4500, "output": 700}, "support.summarize": {"input": 1800, "output": 300}, } def assert_token_budget(route, prompt_sections, max_output_tokens): input_tokens = { name: count_tokens(text) for name, text in prompt_sections.items() } total_input = sum(input_tokens.values()) limits = TOKEN_LIMITS[route] if total_input > limits["input"]: raise TokenBudgetError(route, total_input, input_tokens) if max_output_tokens > limits["output"]: raise TokenBudgetError(route, max_output_tokens, {"output": max_output_tokens}) ``` Mieux vaut échouer rapidement que découvrir une semaine plus tard qu’une mauvaise requête de recherche a englouti votre budget dans des PDF sans rapport. ## Conseils pratiques à retenir - La réduction des tokens doit commencer par la visibilité : journalisez les tokens d’entrée et de sortie par section du prompt, route et modèle. - La recherche d’informations est plus efficace que l’accumulation de contenu lorsqu’elle est sélective : reclassez les résultats, extrayez les passages pertinents et imposez un budget de contexte. - Les résumés doivent représenter un état structuré, et non un texte vague. Conservez les faits exacts, les identifiants, les contraintes et les tentatives infructueuses. - Les schémas de sortie limitent les digressions de manière plus sûre que le simple fait de réduire max_tokens. - Les séquences d’arrêt constituent des garde-fous utiles pour délimiter la sortie, mais elles ne remplacent pas les sorties structurées. - Orientez les sous-tâches simples vers des modèles moins coûteux uniquement si le gain justifie la latence supplémentaire et les modes de défaillance introduits. - Évaluez les économies en tokens par tâche réussie, et non en tokens par appel individuel. - Les modèles à contexte long sont puissants, mais ils ne dispensent pas d’une architecture de l’information. [Inférence](/fr/blog/tag/inference/)[Prompts](/fr/blog/tag/prompts/)[Modèles](/fr/blog/tag/models/)[API](/fr/blog/tag/api/) A [AI Prime Tech](https://aiprimetech.io/fr/) Ce blog est publié par AI Prime Tech. Les articles sont rédigés avec l’aide de l’IA ; vérifiez les détails propres à chaque version, tels que les identifiants de modèles, les prix et les limites, dans la documentation officielle avant de vous y fier. Accédez à l’API Claude à moindre coût Une seule clé API pour Claude Opus 5.5, Sonnet 5, Haiku 4.5 et Fable 5.1, ainsi que GPT-6 modèles. Paiement à l’usage, sans abonnement. [Obtenir votre clé API →](/register) AI Prime Tech est une passerelle API tierce indépendante. Claude™ et Anthropic® sont des marques d’Anthropic, PBC. Aucune affiliation ni approbation n’est sous-entendue.