Réduire le coût et l’épuisement du contexte des agents IA grâce à des réponses API compactes
L’agent demande un dossier client. Votre API renvoie le client, ses 200 dernières commandes, chaque article associé, trois formats d’horodatage et un bloc _links par ressource. Résultat : 40 000 jetons dans la fenêtre de contexte, alors que l’agent voulait uniquement l’adresse e-mail.
Essayez Apidog dès aujourd’hui
Répétez cela quatre fois dans une même exécution : l’agent dépense l’essentiel de son budget à lire du JSON inutile. Il oublie l’instruction initiale, résume la tâche au lieu de la terminer, et le coût augmente tandis que la qualité diminue.
C’est un problème de conception d’API, pas de prompt. Chaque champ renvoyé entre en concurrence avec les instructions, l’historique, les outils et le plan de l’agent. Ce guide présente les principales sources de surcharge, les modèles de sélection de champs et de pagination, les optimisations possibles dans la couche d’outils et les métriques à suivre.
Apidog permet de mesurer la taille réelle des réponses et de simuler une forme optimisée avant même que l’équipe API ne l’implémente.
Où vont les jetons ?
Les API conçues pour les interfaces web transportent souvent beaucoup de données inutiles à un agent :
-
Enveloppes verbeuses :
data,meta,linksetincludedpeuvent doubler la taille d’un objet simple. - Clés répétées : une liste de 200 éléments contenant 15 champs paie 3 000 noms de clés.
- Expansion imbriquée par défaut : client, commandes et articles forment rapidement un arbre volumineux.
-
Formats redondants :
created_at,created_at_unixetcreated_at_humanreprésentent une seule valeur. - Valeurs nulles et champs vides : les champs non définis ne devraient pas être sérialisés systématiquement.
Le coût suit la taille du texte sérialisé, pas seulement le nombre d’enregistrements. Deux cents objets plats peuvent coûter moins cher qu’un seul objet profondément imbriqué.
1. Retournez des champs, pas des ressources entières
La modification la plus rentable consiste à permettre à l’appelant de demander uniquement les champs nécessaires :
GET /v1/customers/8812?fields=id,email,plan,status
{ "id": "8812", "email": "dana@example.com", "plan": "pro", "status": "active" }
Sur la plupart des API, cette approche réduit la réponse d’environ 90 % et peut être ajoutée en une après-midi. Le guide de conception d’API de Google documente le modèle des masques de champs. GraphQL résout le même problème en rendant la sélection obligatoire.
Bonnes pratiques d’implémentation
- Validez les champs demandés par rapport au schéma.
- Rejetez les noms inconnus avec une erreur explicite.
- Définissez un petit ensemble de champs par défaut.
- N’utilisez pas « tout retourner » comme comportement par défaut.
Exposez ensuite cette règle dans la description de l’outil :
{
"name": "getCustomer",
"description": "Récupère un client par ID. Toujours passer `fields` avec seulement ce dont vous avez besoin. Disponible : id, email, name, plan, status, created_at, billing_address, order_count.",
"input_schema": {
"type": "object",
"required": ["customerId", "fields"],
"properties": {
"customerId": { "type": "string" },
"fields": {
"type": "array",
"items": { "type": "string" },
"description": "Noms des champs à retourner. Gardez cette liste minimale."
}
}
}
}
Les descriptions d’outils sont l’endroit où le modèle apprend ces règles. Consultez le guide d’appel de fonction OpenAI et la documentation d’utilisation des outils Anthropic.
Rendre fields obligatoire est essentiel : un paramètre facultatif peut être ignoré, tandis qu’un paramètre obligatoire force l’agent à réfléchir à ses besoins.
2. Limitez toujours les listes
Un point de terminaison sans limite stricte est une source fréquente d’explosion :
GET /v1/orders?customer_id=8812&limit=5000
L’agent demande les « commandes récentes » et reçoit potentiellement toutes celles créées depuis 2019.
Imposez un maximum côté serveur. Si limit=5000, plafonnez la réponse à 100 et indiquez-le. Pour les agents :
- Visez 20 à 50 éléments par page pour des enregistrements classiques.
- Retournez le nombre total.
- Préférez la pagination par curseur : les offsets peuvent dériver lorsque les données changent.
- Ajoutez un indicateur explicite comme
"truncated": true.
Les modèles déduisent mal l’exhaustivité à partir de la seule longueur d’un tableau.
Donnez aussi à l’agent un moyen d’éviter la pagination :
- un point de terminaison
count; - une recherche filtrée avec une fenêtre étroite ;
- un objet récapitulatif ;
- une agrégation directement calculée côté serveur.
La réponse la moins coûteuse est celle qui ne contient pas les données détaillées. Voir le guide sur la pagination d’API REST et la conception de la pagination pour des millions d’enregistrements.
3. Optimisez dans la couche d’outils si vous ne contrôlez pas l’API
Les API tierces n’ajouteront pas forcément la sélection de champs. Placez alors une projection dans votre exécuteur, entre la réponse HTTP et le modèle :
KEEP = {
"getCustomer": ["id", "email", "plan", "status"],
"listOrders": ["id", "total", "status", "created_at"],
}
def project(tool_name, payload):
keep = KEEP.get(tool_name)
if keep is None:
return payload
if isinstance(payload, list):
return [{k: item.get(k) for k in keep if k in item} for item in payload]
return {k: payload.get(k) for k in keep if k in payload}
Trois raffinements utiles
Conservez la réponse complète
Donnez la projection au modèle, mais conservez la réponse originale dans les journaux d’exécution pour faciliter le débogage. Le traçage des appels d’outils d’agent détaille les données à enregistrer.
Indiquez ce qui a été supprimé
Ajoutez les champs omis pour permettre à l’agent de demander une réponse plus complète lorsqu’il en a besoin :
{
"id": "8812",
"email": "dana@example.com",
"_omitted": ["billing_address", "notes", "metadata"]
}
La troncature transparente est préférable à une suppression silencieuse qui ferait croire que les champs n’existent pas.
Utilisez un format compact pour les listes
Pour des données tabulaires, le CSV ou un tableau Markdown peut coûter moins de jetons que le JSON, car les noms de champs ne sont répétés qu’une seule fois :
id,total,status,created_at
ord_91,4900,paid,2026-08-21
ord_92,1200,refunded,2026-08-22
4. Résumez côté serveur pour les cas lourds
Certaines questions n’exigent aucun enregistrement détaillé :
Ce client a-t-il eu des paiements échoués ce mois-ci ?
Renvoyer 40 objets de paiement pour obtenir une réponse booléenne est inutilement coûteux. Si une question revient souvent, créez un point de terminaison qui y répond directement :
- résumé de l’état du compte ;
- récapitulatif des statuts ;
- agrégation ;
- indicateur booléen.
C’est du travail classique de conception d’API, mais c’est souvent l’optimisation la plus précieuse : vous évitez de produire une réponse volumineuse au lieu de simplement la réduire.
Conservez une forme stable pour les résumés et versionnez-les. Une invite dépend d’une structure précise ; un changement silencieux peut la casser. Consultez les articles sur les changements d’API qui cassent les agents et la meilleure stratégie de versioning d’API.
Mesurez avant et après
Ne faites pas ces changements à l’aveugle. Suivez au moins trois métriques.
Octets par réponse et par point de terminaison
Envoyez une requête réaliste à chaque outil et mesurez la charge utile. Tout ce qui dépasse quelques kilo-octets mérite une analyse.
Dans Apidog, exécutez chaque point de terminaison, lisez directement la taille de la réponse et enregistrez la requête pour pouvoir répéter la mesure après chaque modification.
Jetons par appel d’outil
Les octets ne sont qu’une approximation. Faites passer les charges utiles dans le tokenizer du fournisseur, par exemple tiktoken pour les modèles OpenAI, puis classez les points de terminaison par coût.
Le classement est souvent très déséquilibré : un ou deux points de terminaison représentent la majorité de l’utilisation du contexte.
Contexte utilisé par exécution
modifier l’API. Un serveur de simulation vous permet de mesurer le gain et de vérifier que l’agent termine toujours sa tâche avec moins de données. Le guide sur l’exécution d’agents contre des simulations plutôt que la production décrit ce flux de travail.
À quoi ressemble une bonne réponse ?
Une réponse adaptée aux agents est petite, plate et explicite sur ce qu’elle omet :
{
"customer": { "id": "8812", "email": "dana@example.com", "plan": "pro" },
"recent_orders": [
{ "id": "ord_91", "total_cents": 4900, "status": "paid" },
{ "id": "ord_92", "total_cents": 1200, "status": "refunded" }
],
"recent_orders_total": 47,
"truncated": true,
"_omitted": ["billing_address", "metadata", "order_line_items"]
}
Cette réponse fait moins de 200 jetons. Elle répond à la question courante, précise qu’il existe 47 commandes et indique quels champs peuvent être demandés ensuite.
Commencez par le point de terminaison le plus volumineux :
- mesurez sa réponse ;
- ajoutez la sélection de champs ;
- plafonnez la pagination ;
- exécutez à nouveau l’agent ;
- comparez le coût et le taux de réussite.
L’écart suffit généralement à justifier le reste du travail. Vous pouvez télécharger Apidog pour réunir mesure et simulation dans un même projet.
Trois cas d’usage
Triage du support
Un agent lit un ticket, récupère le client et décide s’il faut escalader.
- Approche naïve : objet client complet et 50 derniers tickets, soit environ 30 000 jetons avant même la lecture de la plainte.
- Approche optimisée : plan, statut, nombre de tickets ouverts et date du dernier contact, soit environ 80 jetons.
La décision s’améliore parce que les informations utiles ne sont plus noyées dans le bruit.
Opérations internes
Un agent de déploiement vérifie l’état de santé de 40 services. Les objets complets saturent la fenêtre autour du douzième service.
Un résumé d’une ligne par service — nom, état et taux d’erreur — permet de traiter les 40 services en quelques centaines de jetons et de raisonner sur l’ensemble du parc.
Saisie et rapprochement de données
Un agent rapproche des factures et des paiements. Les documents complets échouent après quelques dizaines d’enregistrements.
Retourner id, amount_cents, date et reference en CSV permet de traiter plusieurs centaines d’enregistrements en une passe : la comparaison n’a jamais nécessité plus de quatre champs.
Le motif commun est simple : l’agent avait besoin d’une surface de décision, mais l’API lui a fourni un document.
Mesurez l’historique des exécutions
Une seule exécution montre qu’une réponse était volumineuse. Elle ne révèle pas quel point de terminaison dépasse le budget ni à quelle fréquence.
Ces données doivent survivre à la session :
- pour un service déployé, utilisez votre propre télémétrie ;
- pour un agent de codage exécutant un travail assigné, Sharkly conserve l’exécution et son résultat sur la tâche d’origine.
Sans historique, un budget vous indique qu’une réponse est trop grande, mais pas quelle correction appliquer en premier. Pour comprendre pourquoi les agents échouent en production, consultez cet article.
Définissez un budget par outil
Un budget global par exécution est utile, mais un budget par outil transforme un problème vague en action concrète.
Par exemple, fixez une limite de 1 500 jetons par outil. Lorsqu’une réponse dépasse ce seuil, l’exécuteur peut :
- appliquer une projection ;
- ajouter
_omitted; - enregistrer le dépassement ;
- classer le point de terminaison selon sa fréquence d’appel.
Vous obtenez ainsi une file de travail priorisée.
Le budget protège aussi contre les longues queues de distribution. Une réponse minuscule en test peut devenir énorme pour un client réel possédant 4 000 commandes. Un plafond strict produit alors une réponse tronquée et explicite plutôt qu’une tâche échouée à 2 heures du matin.
Questions fréquentes
La troncature est-elle dangereuse si l’agent a besoin des données manquantes ?
Seulement si elle est silencieuse. Ajoutez truncated et _omitted afin que l’agent puisse demander les informations nécessaires. C’est l’absence d’indication, et non la réduction elle-même, qui provoque les mauvaises réponses.
Dois-je utiliser GraphQL pour les agents ?
GraphQL rend la sélection de champs obligatoire et résout proprement le problème. Il ajoute toutefois de la complexité, et les modèles produisent plus souvent des requêtes invalides qu’ils n’utilisent mal un simple paramètre fields. Ajouter fields aux points de terminaison REST est généralement le changement le plus simple.
Quelle taille viser pour une réponse d’outil ?
Visez moins de 1 000 jetons pour la lecture d’un enregistrement et moins de 2 000 pour une liste. Au-delà, demandez-vous si l’agent a réellement besoin des enregistrements ou plutôt d’un résumé.
La mise en cache des prompts résout-elle le problème ?
Elle réduit le coût du contexte répété, mais pas l’espace occupé dans la fenêtre. Une réponse de 40 000 jetons continue de remplir la fenêtre, même si elle est mise en cache.
Que faire des fichiers et réponses binaires ?
Ne les placez jamais directement dans le contexte. Stockez le fichier, transmettez une référence et une courte description, puis fournissez un outil séparé capable d’en extraire uniquement les informations nécessaires.
Où placer l’optimisation : dans l’API ou le wrapper ?
Dans l’API lorsque vous la contrôlez : tous les appelants en bénéficient et les octets inutiles ne traversent jamais le réseau. Utilisez le wrapper lorsque l’API appartient à un tiers. Les deux approches sont compatibles.


Top comments (0)