Accueil / Articles

Exécuter des agents IA AWS à grande échelle : tokens, dépenses, limites et autonomie

Le comptage des tokens, le suivi des dépenses, la récupération dans les limites de contexte ainsi que les workflows autonomes durables pour les agents AWS, tous expliqués à l’aide de concepts connus des développeurs JavaScript full-stack.

Éditeur : REACTAPP.TOP8 min de lecture1929 mots

Sources: 🏗️ Building Production-Ready Enterprise AI Agents on AWS — Part 3: Tokenization, Monitoring, Context Limits & Autonomous Workflows

Un agent dont les capacités sont définies de manière judicieuse et qui bénéficie de mécanismes de validation et de récupération doit néanmoins surmonter son premier mois en environnement de production. Ce qui détermine son succès relève le plus souvent de facteurs peu spectaculaires : la manière dont on compte les tokens, l’observation des coûts d’exécution, ce qui se passe lorsque la fenêtre de contexte est remplie, ainsi que le fait que le cycle autonome à long terme soit conçu comme un véritable moteur de flux de travail. Si vous venez d’un environnement JavaScript full-stack sur AWS, chacun de ces éléments correspond directement à des concepts que vous connaissez déjà, et cette présentation fait appel constamment à ces analogies.

La tokenisation est la couche de sérialisation

Une application web sérialise les données avant qu’elles ne soient transmises, en utilisant JSON.stringify ou protobuf. Un modèle de langage fait de même pour le texte : avant même d’analyser quoi que ce soit, le texte est divisé en tokens, qui sont des fragments de sous-mots et non des caractères ou des mots entiers.

"Enterprise agents scale."
   → ["Enterprise", " agents", " scale", "."]   (≈4 tokens, illustrative)

Les raisons pour lesquelles un ingénieur doit se soucier de cela se réduisent à trois points.

  • Les tokens sont ce sur quoi vous êtes facturé, équivalent aux GB-secondes de Lambda. Les données d’entrée et de sortie coûtent toutes deux de l’argent, et comme les prix de Bedrock varient selon le modèle, le nombre de tokens influence directement la facture AWS.
  • Les tokens déterminent également la limite maximale de votre charge utile, à l’instar d’une limite pour le corps de la requête comme express.json({ limit: '5mb' }). Dans ce cas, cette limite correspond à la fenêtre de contexte, qui peut atteindre des centaines de milliers de tokens avec les modèles actuels et continue d’augmenter ; il est donc nécessaire de consulter la limite réelle pour votre modèle plutôt que de deviner.
  • La tokenisation n’est pas uniforme d’une langue à l’autre. Les textes non anglais nécessitent souvent plus de tokens par mot, ce qui est important pour les produits multi-régions.

Au sein de Node.js, compter les tokens avant envoi revient à mesurer la charge utile avant une requête fetch :

// Node.js: counting tokens before sending a request
// (conceptually like calculating payload size before a fetch call)
import { encoding_for_model } from "tiktoken";

const enc = encoding_for_model("gpt-4o");
const tokens = enc.encode(userPrompt);
console.log(`Payload size: ${tokens.length} tokens`); // like Content-Length
enc.free();

Au Bedrock, vous pouvez omettre l’outil de tokenisation tiers. L’API CountTokens effectue le décompte du côté serveur pour les modèles Claude pris en charge, utilise la même structure de message que l’API Converse, et vous permet de vérifier à l’avance le nombre de tokens d’une requête sans avoir à payer pour son traitement :

# Python (boto3): pre-flight token count via Bedrock, no separate tokenizer library needed
response = bedrock_runtime.count_tokens(
    modelId="anthropic.claude-3-5-sonnet-20241022-v2:0",
    input={"converse": {"messages": [{"role": "user", "content": [{"text": userPrompt}]}]}}
)
print(f"Input tokens: {response['inputTokens']}")

Leçon : mesurez le nombre de tokens de la même manière que vous mesureriez la taille du chargement HTTP, avant l’envoi et non après que vous ayez été facturé ou rejeté.

Surveiller la consommation de tokens comme CloudWatch pour les factures des LLM

La section précédente portait sur une seule requête. La vue globale indique ce que chaque agent a consommé, par locataire et par jour, et vous souhaitez le savoir avant que les services financiers ne s’en aperçoivent. Personne n’activerait une API Express sur AWS sans tableaux de bord et alertes, et la surveillance des tokens mérite le même traitement.

Les indicateurs clés pour un agent :

  • Tokens de prompt par requête, comme la taille du chargement entrant.
  • Tokens de finition par requête, comme la taille de la réponse.
  • Tokens cumulatifs au cours d’une session, ce qui correspond à l’empreinte mémoire de la session.
  • Cost par agent, utilisateur ou locataire, c’est-à-dire la même mesure que celle utilisée pour l’utilisation de la base de données par locataire dans les SaaS multi-locataires.
  • Latence des appels aux agents à 95e et 99e percentile, maintenue dans les limites SLO habituelles. Précisez explicitement ces SLO et recourez à une solution en mémoire cache ou au mode meilleur effort lorsque celles-ci sont menacées.
  • Taux d’utilisation en tokens par minute, comparable à la limitation de fréquence basée sur les requêtes par seconde.
  • Étapes concrètes sur AWS :

    • Envoyez des métriques CloudWatch personnalisées pour les tokens de prompt, les tokens de complétion et le coût en dollars (prompt_tokens, completion_tokens, cost_usd), étiquetées avec le nom de l’agent et du locataire.
    • Activez le cache des prompts. Bedrock peut réutiliser des préfixes longs et stables tels que les prompts système, les définitions d’outils et les exemples de few-shot à un coût considérablement réduit et avec une latence plus faible. Placez d’abord le contenu immuable, sinon vous paierez le prix plein pour des tokens identiques à chaque appel.
    • Créez des alertes CloudWatch qui notifient via SNS lorsque les dépenses quotidiennes dépassent un seuil, tout comme les alertes de facturation d’AWS.
    • Enregistrez chaque appel de l’agent dans S3, soit via Kinesis Firehose, soit par écriture directe, afin de conserver un historique d’audit. Les exigences SOC 2 et les acheteurs d’entreprise l’exigeront.
    • Une estimation approximative fonctionne de la même manière que pour Lambda : ajoutez des tokens de démarrage et de fin, multipliez par le prix du modèle, puis ajoutez les coûts de récupération et d’infrastructure par session.

    Si vous ne pouvez pas indiquer combien a coûté l’Agent X mardi dernier, par client, vous êtes prêt pour une démonstration mais pas pour le environnement de production, et il y a une grande différence entre les deux.

    Erreurs liées à la limite de contexte : disjoncteur électrique et pagination

    Chaque fenêtre de contexte a une limite maximale. Les conversations longues, les résultats générés par les outils volumineux ainsi que les blocs de données récupérés trop importants peuvent tous dépasser cette limite. Il s’agit de l’équivalent du 413 Payload Too Large dans le monde des agents, seulement pire, car cela peut survenir au cœur d’une tâche à plusieurs étapes.

    Les stratégies de récupération proviennent directement du domaine de l’ingénierie backend :

    1. Résumé et compression. Compresser périodiquement les anciennes interactions, à l’instar de la rotation des journaux.
    2. Fenêtre glissante ou troncature. Éliminer les interactions les plus anciennes, comme on le ferait en parcourant les résultats d’une recherche volumineuse sans les charger tous.
    3. Décharge vers le système de récupération. Conserver les informations en dehors du prompt et les récupérer sur demande, dans l’esprit du chargement différé.
    4. Décomposition en sous-agents. Diviser une tâche massive en appels plus petits utilisant des contextes renouvelés, comme transformer un travail batch monolithique en une file de tâches plus petites.
  • Dégradation élégante. Si l’excédent ne peut pas être récupéré au milieu d’une tâche, échouer avec un point de contrôle structuré permettant la reprise, et jamais par une hallucination silencieuse.
  • Voici le schéma de capture et de compression en code, similaire à la gestion d’un délai d’attente de base de données :

    # Conceptual: catching a context-limit error, like catching a DB timeout
    try:
        result = agent.run(task, conversation_history)
    except AgentError as err:
        if err.code == "context_length_exceeded":
            # Keep the system prompt intact — compact the *conversation*, never the identity.
            # Summarizing everything (including system instructions) is how agents quietly
            # "forget" their role mid-task, the same way you'd never let a cache-eviction
            # policy drop your app's config alongside its session data.
            compacted = summarize(conversation_history, preserve="system_prompt")
            result = agent.run(task, compacted)
        else:
            raise  # don't swallow unrelated errors
    

    Les erreurs liées aux limites de contexte sont normales et non exceptionnelles. Traitez-les comme des limitations de fréquence et des délais d’attente : tentatives répétées avec retards progressifs, points de contrôle stockés dans DynamoDB et fonctionnement en cas de dégradation. Un bloc catch vide qui absorbe l’erreur est toujours inacceptable.

    Flux de travail autonomes en tant que machines à états

    Un agent autonome ne répond pas une seule fois : il planifie, agit, observe et itère jusqu’à atteindre un objectif. Toute personne ayant conçu une machine XState, une saga Redux ou un flux AWS Step Functions pour un processus de paiement en plusieurs étapes connaît déjà cette structure. Il s’agit du cycle classique de type ReAct — planifier, agir, observer et évaluer — avec des sorties pour la finalisation ou l’escalade vers un humain, et il doit être conçu comme un moteur de flux de travail fiable.

    • Étapes idempotentes. Relancer une étape ne doit pas facturer le client deux fois ni envoyer un e-mail dupliqué.
  • Conditions d’arrêt explicites. Limitez les itérations, le coût et le temps, ou évitez de créer une boucle infinie while(true) qui consommerait des ressources illimitées.
  • Escalade humaine. Tout comme dans les transactions compensatoires, en cas de faible niveau de confiance ou de risques élevés, l’opération doit être transmise à un humain plutôt que d’être exécutée automatiquement.
  • État persistant. Enregistrez un point de contrôle à chaque étape dans DynamoDB ou Step Functions afin que, en cas de panne pendant l’exécution du flux de travail, celui-ci puisse reprendre sans perte de transaction. Ajoutez une durée de vie limitée (TTL) dans DynamoDB aux éléments de session pour que les conversations obsolètes expirent, suivant la même logique que l’expiration des clés de session Redis.
  • Modèles de secours. Si le modèle principal, par exemple Claude sur Bedrock, rencontre un temps d’attente excessif ou une limitation de charge, un mécanisme de protection doit basculer vers un modèle secondaire comme Amazon Nova sans afficher d’erreur à l’utilisateur. C’est la même logique qu’un client HTTP qui bascule vers une région de secours.
  • Gouvernance des modèles. Gérer le remplacement d’un modèle comme n’importe quel déploiement en production : le tester progressivement sur une partie du trafic, obtenir l’approbation nécessaire et prévoir un moyen de revenir en arrière. « Nous avons simplement changé de modèle » ne doit pas constituer un changement non approuvé.
  • Mécanisme d’arrêt d’urgence. Disposer d’un moyen, manuel ou déclenché par un seuil, pour arrêter simultanément l’ensemble des agents, à l’instar d’un mécanisme de désactivation basé sur des flags fonctionnels en cas de déploiement dérapant.
  • Un point de contrôle n’est rien d’autre qu’un enregistrement de tâche reprise possible dans DynamoDB, que Step Functions lit lors du redémarrage pour continuer à partir de la dernière étape réussie :

    {
      "pk": "session#8f2c1a",
      "sk": "checkpoint#2026-08-23T10:15:00Z",
      "step": "plan",
      "hop_count": 2,
      "cost_so_far_usd": 0.014,
      "state": { "goal": "resolve billing dispute", "last_action": "lookup_charge" },
      "ttl": 1788084900
    }
    

    Ne construisez pas l’autonomie en utilisant une boucle while entourant une appel à un LLM. Créez plutôt une machine d’état fiable, observable et capable de reprendre son exécution, car c’est bien ce qu’elle est réellement. Step Functions répond parfaitement à ces besoins si vous souhaitez une solution prête à l’emploi.

    Il existe encore un niveau supplémentaire au-dessus de tout cela : les évaluations. Les règles de contrôle, la qualité des données récupérées ainsi que leur pertinence nécessitent tous des tests de régression, tout comme le code d’application. Un ensemble d’évaluations reproduit un ensemble fixe d’entrées auprès de l’agent et évalue les sorties par rapport au comportement attendu, afin qu’un simple ajustement d’instruction ou un changement de modèle ne détériore pas silencieusement le fonctionnement en production. Ragas évalue des critères spécifiques à la récupération des données tels que la fidélité et la pertinence contextuelle, tandis que Promptfoo et Braintrust couvrent des tests plus larges concernant les instructions et les sorties. Intégrez votre solution choisie dans le processus CI de la même manière que pytest, afin qu’une évaluation échouée bloque le déploiement et que personne n’ait besoin d’examiner manuellement les résultats par la suite.

    Checklist de prêt à la production

    • Chaque agent dispose d’une responsabilité testable ainsi que de permissions IAM à portée restreinte.
    • Les transferts de données intègrent un contexte structuré via un système durable (SQS ou EventBridge) et sont protégés contre les boucles.
    • Les contrôles d’entrée et de sortie sont distincts, composables et versionnés séparément.
    • La qualité des données récupérées fait l’objet de mesures de précision et de rappel propres, sans être assimilée à l’idée que « l’IA a tort ».
    • Tout élément à haut risque passe par des vérifications contre les hallucinations : vérification factuelle, évaluation de la confiance ou contrôle humain.
    • L’utilisation des tokens est mesurée avant l’envoi de l’appel, et non seulement après facturation.
    • Les tableaux de bord CloudWatch détaillent les coûts par locataire et par agent, avec des alertes de budget via SNS.
    • Un plan de récupération défini existe pour les erreurs liées aux limites de contexte : compression, troncature ou transfert vers un autre système.
  • Les boucles autonomes disposent de plafonds stricts en termes d’itérations, de temps écoulé et de ressources utilisées.
  • Les actions irréversibles telles que les remboursements, les e-mails et les suppressions nécessitent une étape d’approbation humaine.
  • Les décisions prises par les agents sont entièrement enregistrées dans S3 ou CloudWatch afin de garantir la conformité.
  • Des évaluations automatisées sont effectuées dans le cadre de CI avant toute mise en production de nouvelles instructions ou de nouveaux modèles, une étape que l’on n’omettrait jamais pour du code d’application.
  • L’environnement de pré-production a été testé en conditions chaotiques avec des temps d’attente simulés du modèle, des résultats de récupération corrompus et des boucles de transfert, de sorte que les procédures de récupération ont été éprouvées avant que la production ne s’y fonde.
  • En résumé

    Chaque concept d’agent a son équivalent dans le monde full-stack que vous connaissez. Les agents sont des microservices dotés de capacités de jugement, et les transferts de responsabilités s’effectuent via un routage fiable, traçable et limité en nombre d’étapes. Les mécanismes de contrôle constituent des couches intermédiaires, la récupération des données repose sur une couche de requêtes plus intelligente, et les hallucinations sont détectées grâce à des méthodes d’ancrage et de vérification, et non en demandant poliment. Les tokens servent à la fois à déterminer la taille des données transmises et à représenter l’unité de paiement. La surveillance des dépenses correspond au CloudWatch pour l’utilisation des modèles. Une fenêtre de contexte complète représente une défaillance prévisible qui nécessite un plan de récupération, tandis que l’autonomie correspond à une machine d’état fiable, bien différente d’une simple boucle while.

    Les agents d’entreprise échouent rarement en production à cause d’un modèle insuffisamment intelligent. Ils échouent plutôt parce que les équipes négligent les principes fondamentaux des systèmes distribués qu’elles n’auraient jamais ignorés pour une API ordinaire : validation, observabilité, tentatives de réessai, idempotence, gestion des erreurs et dégradation contrôlée. Si vous avez déjà déployé une application JavaScript résiliente sur AWS, vous possédez déjà ces intuitions. Il ne reste plus qu’à les appliquer à une dépendance inconnue et imprévisible qui répond par des phrases.