+170 XP

Coût, latence et fiabilité : passer les agents en production

# Coût, latence et fiabilité : passer les agents en production

Votre agent de support a répondu parfaitement à la question de démo. Puis vous l'avez activé pour de vrais clients, et vendredi il avait tourné 4 000 fois, coûté 600 $, et laissé douze utilisateurs devant un spinner pendant quatre-vingt-dix secondes avant de tomber en timeout.

Une démo qui marche une fois est un tour de passe-passe. Un produit, c'est quelque chose qui marche encore au centième run, dans le budget, et sans se figer. Cette leçon couvre les leviers concrets pour y arriver.

Les trois choses qui cassent en production

Quand vous faites passer un agent de « ça marche sur mon portable » à « ça encaisse du trafic réel », trois problèmes apparaissent :

  • Coût : chaque étape d'un agent envoie du texte à un modèle, et vous payez à l'unité de texte. Un agent bavard brûle du cash vite.
  • Latence : le temps d'attente de l'utilisateur. Les agents qui « réfléchissent » sur de nombreuses étapes sont lents.
  • Fiabilité : est-ce que ça se termine, ou est-ce que ça se fige, boucle indéfiniment, ou plante sur une réponse d'outil défectueuse ?

Quelques définitions rapides avant d'aller plus loin :

  • Agent : un programme qui utilise un grand modèle de langage pour décider quoi faire ensuite, souvent en appelant des tools (une recherche, une requête en base, un envoi d'email) dans une boucle jusqu'à ce que la tâche soit terminée.
  • Token : l'unité de facturation des modèles. Environ 3 à 4 caractères, soit à peu près 0,75 mot. « Reset my password » fait environ 4 tokens.

Levier 1 : timeouts et retries

Les outils échouent. Une base de données est lente, une API renvoie une erreur, un appel réseau se bloque. Sans protection, votre agent attend indéfiniment ou meurt au premier accroc.

Deux règles règlent l'essentiel :

Timeout : fixez une attente maximale pour chaque appel externe. Si un tool ne répond pas en, disons, 10 secondes, arrêtez d'attendre et passez à la suite.

Retry : si un appel échoue, réessayez un petit nombre de fois, en attendant un peu plus longtemps entre les tentatives (c'est l'*exponential backoff* : attendre 1 s, puis 2 s, puis 4 s). La plupart des échecs sont temporaires et se résolvent à la deuxième tentative.

python
import time

def call_tool_with_retry(tool_fn, args, retries=3, timeout=10):
    for attempt in range(retries):
        try:
            return tool_fn(args, timeout=timeout)
        except (TimeoutError, ConnectionError):
            if attempt == retries - 1:
                return {"error": "tool unavailable, continue without it"}
            time.sleep(2 ** attempt)  # 1s, 2s, 4s

Regardez la dernière ligne : au lieu de planter, elle transmet au modèle un message clair. Un bon agent sait souvent s'en remettre (« Je n'ai pas pu joindre le système de commandes, j'ai donc demandé son numéro de commande à l'utilisateur »).

Pour un panorama solide et indépendant des fournisseurs sur les patterns de retry, voir les recommandations SRE de Google sur la gestion de la surcharge et des retries.

Levier 2 : plafonner la boucle

Un agent tourne en boucle : réfléchir, appeler un tool, lire le résultat, réfléchir à nouveau. Le danger, c'est la boucle qui ne se termine jamais. Le modèle continue de décider « il me faut encore une recherche » et vous continuez de payer.

Plafonnez toujours le nombre d'itérations. Si l'agent n'a pas terminé en, disons, 8 étapes, arrêtez et renvoyez soit la meilleure réponse obtenue, soit un transfert vers un humain.

python
MAX_STEPS = 8

def run_agent(user_input):
    messages = [{"role": "user", "content": user_input}]
    for step in range(MAX_STEPS):
        response = model.respond(messages, tools=TOOLS)
        if response.is_final:
            return response.text
        result = call_tool_with_retry(response.tool, response.args)
        messages.append({"role": "tool", "content": result})
    return "I couldn't resolve this fully. Escalating to a human agent."

La ligne for step in range(MAX_STEPS) constitue à elle seule le filet de sécurité. Tous les grands frameworks d'agents (l'OpenAI Agents SDK, le Claude Agent SDK, l'ADK de Google) ont un réglage intégré pour ça, généralement appelé max turns ou max iterations. Réglez-le délibérément. La valeur par défaut est souvent plus élevée que ce que vous voulez.

Levier 3 : maîtriser le coût en tokens

Vous payez deux choses : ce que vous envoyez au modèle (input tokens) et ce qu'il écrit en retour (output tokens). L'output coûte généralement plusieurs fois plus cher par token que l'input.

Trois façons concrètes de réduire la facture :

Élaguez le contexte. Les agents accumulent de l'historique : chaque résultat d'outil, chaque message passé. À l'étape 6, vous pourriez renvoyer 20 000 tokens de transcription à chaque appel. Résumez les étapes anciennes ou supprimez les résultats d'outils dont vous n'avez plus besoin.

Mettez en cache ce qui est stable. Votre system prompt et vos définitions d'outils sont identiques à chaque appel. La plupart des fournisseurs proposent le *prompt caching*, qui facture une fraction du prix pour un input répété. L'activer se résume souvent à une ligne de configuration et peut réduire le coût d'input de 50 à 90 %.

Demandez moins d'output. « Répondez en moins de 3 phrases » ou renvoyer des données structurées plutôt que de la prose réduit directement le côté coûteux, l'output.

Levier 4 : utiliser un modèle plus petit pour les étapes de routine

C'est le plus gros levier, et celui que la plupart des équipes manquent. Vous n'avez pas besoin de votre modèle le plus puissant et le plus cher à chaque étape.

L'essentiel du travail d'un agent est de la routine : classer une question, extraire un numéro de commande, décider quel tool appeler. Un petit modèle rapide et bon marché s'en sort très bien. Gardez le grand modèle pour l'étape réellement difficile, comme rédiger la réponse finale et nuancée.

C'est ce qu'on appelle le model routing : un modèle bon marché fait le tri, et n'escalade vers le modèle coûteux qu'en cas de besoin.

python
def handle(query):
    # le modèle bon marché classifie
    category = small_model.classify(query, ["simple_faq", "complex_issue"])

    if category == "simple_faq":
        return small_model.answer(query)      # chemin bon marché
    else:
        return large_model.run_agent(query)   # chemin coûteux, seulement si nécessaire

Si 70 % de vos questions de support portent sur des réinitialisations de mot de passe et des statuts de livraison, les router vers un petit modèle signifie que vous ne payez le prix fort que sur les 30 % restants.

Vérification des acquis

1. Selon la leçon, qu'est-ce qui distingue un agent prêt pour la production d'une démo « tour de passe-passe » ?

2. Pourquoi un agent « bavard » a-t-il tendance à brûler du cash rapidement en production ?

3. Quel est l'intérêt de l'exponential backoff lorsqu'on réessaie un appel d'outil ayant échoué ?

CHOIX MULTIPLES

4. Sélectionnez TOUTES les réponses correctes sur les trois problèmes qui apparaissent typiquement lors du passage d'un agent en production.

Sélectionnez toutes les réponses correctes.

CHOIX MULTIPLES

5. Sélectionnez TOUTES les réponses correctes sur les timeouts et les retries comme leviers de fiabilité.

Sélectionnez toutes les réponses correctes.

Avant / après : le coût par résolution d'un agent de support

Voici un exemple aux ordres de grandeur réalistes. Un agent de support traite 10 000 tickets par mois. La métrique qui compte est le coût par résolution : dépense totale divisée par le nombre de tickets résolus sans intervention humaine.

Avant (build naïf) :

  • Chaque ticket utilise le grand modèle à toutes les étapes.
  • Historique complet de la conversation renvoyé à chaque étape. Pas de caching.
  • Pas de plafond d'itérations, donc les tickets bloqués bouclent jusqu'à 20 fois.
  • Moyenne : 15 appels modèle par ticket, ~18 000 tokens chacun.

Cela donne environ 0,42 $ par ticket, et environ 8 % des tickets bouclent jusqu'au timeout, donc ne se résolvent pas du tout. Certains utilisateurs attendent plus de 60 secondes.

Après (build de production) :

  • Un petit modèle fait le triage. 65 % des tickets (FAQ, vérifications de statut) se résolvent sur le chemin bon marché.
  • Prompt caching sur le system prompt et les outils.
  • Contexte élagué : les anciens résultats d'outils sont résumés après 3 étapes.
  • Plafond d'itérations à 8, avec escalade propre vers un humain.

Nouveaux chiffres :

| Métrique | Avant | Après |

|---|---|---|

| Coût par résolution | 0,42 $ | 0,09 $ |

| Temps d'attente médian | 22 s | 6 s |

| Tickets qui se figent | 8 % | 0 % |

Même agent, même qualité de réponses, environ 4x moins cher et beaucoup plus rapide. Rien de tout cela n'a nécessité un modèle plus intelligent. Il a fallu de la discipline sur le *quand* utiliser le modèle coûteux, et des garde-fous pour que rien ne s'emballe.

Mesurez avant d'optimiser

Ne devinez pas où partent l'argent et le temps. Activez le tracing (un log de chaque étape : quel modèle, combien de tokens, combien de temps, succès ou échec). Tous les grands SDK d'agents incluent le tracing, et des outils ouverts comme Langfuse vous donnent un dashboard indépendant du fournisseur.

Cherchez d'abord les gains évidents :

  • Quelle étape consomme le plus de tokens ? (Généralement un contexte surchargé.)
  • Quel outil est le plus lent ? (Ajoutez un timeout.)
  • Combien d'étapes prend un ticket typique ? (S'il frôle votre plafond, creusez.)

Optimisez la première ou les deux premières lignes. Ignorez le reste tant que ça ne compte pas.

Reliable Agents in Production

Watch on YouTube

Une checklist simple de mise en production

Avant de diriger du trafic réel vers un agent, vérifiez :

1. Chaque appel d'outil a un timeout et une limite de retries.

2. La boucle de l'agent a un plafond d'itérations strict avec un fallback propre.

3. Le prompt caching est activé, et le contexte est élagué.

4. Les étapes de routine utilisent un modèle plus petit.

5. Le tracing est activé pour voir coût et latence par run.

Les détails propres à chaque fournisseur (noms exacts des réglages, comment activer le caching) figurent dans les blocs d'approfondissement pour OpenAI, Claude et Gemini. Les leviers ci-dessus se transposent à tous.

Points clés

  • Plafonnez la boucle et posez des timeouts sur chaque outil. Ces deux garde-fous évitent les deux pires pannes en production : le coût qui s'emballe et les requêtes qui se figent.
  • Routez selon la difficulté. Un modèle bon marché et rapide pour le triage et les étapes de routine ; le modèle coûteux réservé au travail réellement difficile. C'est généralement votre plus gros gain de coût.
  • Suivez le coût par résolution, pas le coût par appel. Cela relie la dépense à la valeur réellement délivrée et met en évidence les tickets qui brûlent de l'argent sans aboutir.
  • Élaguez le contexte et activez le prompt caching. Les agents renvoient discrètement des historiques qui grossissent ; ces deux gestes réduisent fortement le coût d'input pour un effort minimal.
  • Activez le tracing avant d'optimiser. Mesurez quelle étape est lente ou coûteuse, corrigez la première ou les deux premières, et arrêtez-vous là.

Articles liés

Les articles récents du blog qui s'appuient sur cette leçon.