De combien de mémoire votre agent a-t-il réellement besoin ?

La mémoire d'un agent n'est pas une ressource fixe. Une publication de recherche IBM vérifiée sur Hugging Face examine les modèles de Markov cachés adaptatifs pour répondre à la question de savoir de quelle quantité de mémoire un agent a réellement besoin. Les résultats aident les développeurs à éviter le surprovisionnement du contexte et à construire des systèmes plus efficaces.

Lecture audio non disponible dans ce navigateur
De combien de mémoire votre agent a-t-il réellement besoin ?

Tags

Résumé rapide

La mémoire d'un agent n'est pas une ressource fixe. Une publication de recherche IBM vérifiée sur Hugging Face examine les modèles de Markov cachés adaptatifs pour répondre à la question de savoir de quelle quantité de mémoire un agent a réellement besoin. Les résultats aident les développeurs à éviter le surprovisionnement du contexte et à construire des systèmes plus efficaces.

Un an après que les agents utilisant des outils sont devenus la norme pour construire sur de grands modèles de langage, une question reste encore tranchée par habitude plutôt que par mesure : quelle quantité de mémoire l'agent doit-il conserver ? De nombreuses équipes partent d'une décision unique — « donner toute la conversation » ou « tout stocker dans un index vectoriel » — et ne découvrent le coût qu'une fois que la fenêtre de contexte commence à dicter le comportement de l'agent. La mémoire n'est pas une ressource qu'on ajoute tard dans le projet ; c'est un budget que l'on alloue dès la première requête. La question pratique n'est pas de savoir si votre agent a de la mémoire, mais de savoir quelle quantité de chaque type il lui faut, et comment vous pourriez le savoir.

La pyramide de la mémoire : pourquoi la capacité n'est pas uniforme

Le mot « mémoire » recouvre une pyramide de systèmes de rétention distincts. Tout en bas se trouve le transcript brut : chaque message de l'utilisateur, chaque appel d'outil et chaque réponse du modèle depuis le démarrage de l'agent. Au-dessus se trouve l'état de la tâche — le petit ensemble de variables, de plans intermédiaires et de résultats d'outils qui définissent ce que fait actuellement l'agent. Plus haut encore se trouvent les faits à long terme : préférences de l'utilisateur, conventions du dépôt, particularités des API apprises lors des sessions précédentes. Enfin, il y a la fenêtre de contexte du modèle lui-même, qui n'est pas de la mémoire du tout, mais l'espace de travail éphémère où tout le reste est en concurrence pour l'espace.

Ces couches se comportent différemment sous charge. Le transcript croît linéairement à chaque étape et contient souvent des doublons — chaque nouvelle tentative d'un appel d'outil renvoie le message d'erreur précédent. L'état de la tâche croît avec la complexité de l'objectif courant, mais diminue lorsque l'objectif est atteint. Les faits à long terme croissent lentement et, une fois écrits, tendent à rester pertinents. Confondre ces couches est la cause la plus courante de sur-allocation mémoire. Une équipe qui voit un contexte gonflé suppose généralement qu'il lui faut un stockage externe plus grand, alors qu'en réalité elle doit cesser de rejouer d'anciens résultats d'outils.

La seule façon honnête de savoir quelle couche consomme le budget de votre agent est d'instrumenter l'agent avant de l'optimiser. C'est la discipline que cet article détaille : un harnais de mesure minimal, sans dépendances lourdes, qui vous indique où va réellement votre budget mémoire.

Quatre charges dans le même budget

Chaque jeton dans la fenêtre de contexte de votre agent appartient à l'une de quatre charges. Comprendre la répartition fait la différence entre deviner et construire.

La charge conversationnelle est l'échange récent entre l'utilisateur et l'agent. Elle semble essentielle, mais la plupart de son contenu ne l'est pas. Une fois la demande de l'utilisateur comprise, le libellé exact des questions de clarification précédentes a rarement besoin d'être rejoué mot pour mot.

La charge de sortie d'outils est le résultat sérialisé de chaque fonction que l'agent a appelée. C'est le gonflement caché le plus courant. Les charges utiles JSON provenant des API sont verbeuses, imbriquées et répétitives. Un seul appel d'outil qui retourne 40 enregistrements peut consommer plus de jetons que le reste de la conversation combiné, et l'agent appelle souvent le même outil deux fois avec des paramètres légèrement différents.

La charge épisodique est la mémoire de ce que l'agent a déjà tenté et du résultat obtenu. Une partie est nécessaire — on ne veut pas que l'agent répète une approche qui a échoué. Mais la plupart peut être comprimée en une seule ligne : « SSH direct tenté, échec avec erreur de permissions, passage à l'API. »

La charge contextuelle est tout le reste dont le modèle a besoin pour se comporter correctement : le prompt système, les définitions d'outils, les exemples few-shot et les instructions de formatage. Cette charge est constante. Elle ne croît pas avec la session, mais elle réduit l'espace disponible pour les trois autres.

Lorsque les praticiens demandent « de quelle quantité de mémoire mon agent a-t-il besoin ? », ils demandent généralement la somme de ces charges. La réponse utile est une ventilation, pas un total.

Ce que nous apprend ALTK-Evolve d'IBM Research

La question n'est pas simplement un souci de laboratoire. Le 18 août 2026, IBM Research a publié un article intitulé « How Much Memory Does Your Agent Actually Need? » sur le blog Hugging Face, dans le cadre de l'initiative ALTK-Evolve. Le titre seul est remarquable : un groupe de recherche industriel s'est explicitement demandé à quel point la mémoire compte, plutôt que de supposer que plus est forcément mieux.

Je ne résumerai pas ici ce billet de blog point par point, car le but de cet article est de vous donner un instrument pratique, pas un récapitulatif. Ce qui importe, tel que je le lis, c'est que les besoins en mémoire ne sont pas statiques. Un agent qui débloque de nouveaux outils ou obtient l'accès à de nouveaux dépôts modifiera le ratio entre charge de sortie d'outils et charge conversationnelle. Une configuration mémoire généreuse au moment du déploiement devient gaspilleuse après l'évolution des outils de l'agent. Le nom du projet « ALTK-Evolve » suggère exactement cette vision évolutionniste : la mémoire doit être réglée en continu, pas une fois pour toutes.

Si vous traitez le dimensionnement de la mémoire comme un problème de mesure, vous pouvez faire en sorte que n'importe quel agent — quel que soit le cadre — justifie son empreinte mémoire par des chiffres. C'est ce que le reste de cet article vous montre comment faire.

Prérequis

Avant de pouvoir mesurer la mémoire de votre agent, vous avez besoin de quatre choses :

  1. Accès au flux de requêtes de l'agent — vous devez pouvoir consigner chaque échange entre l'agent, ses outils et le modèle. En pratique, cela signifie une petite enveloppe autour de votre boucle d'agent existante, ou un crochet de journalisation si votre cadre en fournit un.
  2. Un moyen d'estimer les nombres de jetons — le SDK de votre fournisseur de LLM expose généralement les données usage dans l'objet de réponse. Sinon, utilisez une heuristique approximative : comptez les caractères et divisez par quatre pour le texte anglais, ou utilisez le tokenizer de votre fournisseur.
  3. Un environnement Python — l'outil de mesure ci-dessous n'utilise que la bibliothèque standard plus un petit paquet de validation, il fonctionne donc dans toute configuration Python 3.9+.
  4. Des charges de travail représentatives — mesurez sur des tâches réelles, pas sur des tâches synthétiques. Un audit mémoire d'un agent de questions-réponses ne ressemblera en rien à celui d'un agent de codage.

Vous n'avez pas besoin d'une base vectorielle, d'une plateforme d'observabilité dédiée, ni de changer de cadre. Vous avez besoin d'un notebook et d'un sens de ce que chaque nombre signifie.

Installation étape par étape : construire un compteur de mémoire

L'outil que nous allons construire est volontairement petit : un journal qui enregistre chaque événement lié à la mémoire dans le cycle de vie de l'agent et affiche un résumé de l'endroit où sont allés les jetons. Il ne remplace pas la mémoire existante de votre agent ; il l'observe.

Tout d'abord, créez un répertoire dédié afin que l'outil de mesure reste isolé de l'agent que vous auditez.

mkdir agent-memory-meter && cd agent-memory-meter

Ensuite, créez un environnement virtuel pour éviter que les dépendances Python n'interfèrent avec l'interpréteur système.

python -m venv .venv

Activez l'environnement. Sur macOS et Linux, utilisez la commande source.

source .venv/bin/activate

Si vous êtes sous Windows, la commande diffère légèrement ; utilisez le script d'activation dans le dossier Scripts à la place. Une fois l'environnement actif, installez une seule dépendance pour la validation des données.

pip install pydantic

Créez maintenant le script de mesure. Il définit un enregistrement MemoryEvent et un journal qui agrège les événements.

# How Much Memory Does Your Agent Actually Need?
import json
import time
from pydantic import BaseModel


class MemoryEvent(BaseModel):
    timestamp: float
    step: int
    kind: str            # "user", "tool_output", or "assistant"
    tokens_in: int       # approximate prompt tokens consumed by this event
    tokens_out: int      # approximate completion tokens produced
    payload_chars: int   # length of the raw payload in characters


class MemoryLogger:
    def __init__(self):
        self.events = []

    def record(self, step, kind, tokens_in, tokens_out, payload):
        self.events.append(MemoryEvent(
            timestamp=time.time(),
            step=step,
            kind=kind,
            tokens_in=tokens_in,
            tokens_out=tokens_out,
            payload_chars=len(payload),
        ))

    def summary(self):
        total_prompt = sum(e.tokens_in for e in self.events)
        total_completion = sum(e.tokens_out for e in self.events)
        total_chars = sum(e.payload_chars for e in self.events)
        return {
            "events": len(self.events),
            "total_prompt_tokens": total_prompt,
            "total_completion_tokens": total_completion,
            "payload_kb": round(total_chars / 1024, 2),
        }


def main():
    log = MemoryLogger()
    log.record(1, "user", 120, 0, "List all open issues assigned to me")
    log.record(2, "tool_output", 0, 0,
               '{"issues": [{"id": 12, "title": "fix login", "assignee": "ada"}]}')
    log.record(3, "assistant", 0, 240,
               "There is one open issue assigned to you: fix login.")
    print(json.dumps(log.summary(), indent=2))


if __name__ == "__main__":
    main()

Le script enregistre trois types d'événements : un message utilisateur, une sortie d'outil et une réponse de l'assistant. Dans votre véritable agent, vous appelleriez log.record à chacun de ces points, en utilisant les nombres de jetons retournés par votre fournisseur de modèle. Exécutez le script pour confirmer que l'outil fonctionne.

python memmeter.py

Vous devriez voir un résumé JSON avec les nombres d'événements, les totaux de jetons et la taille de la charge utile en kilo-octets. Les nombres seront faibles pour cet exemple jouet ; la valeur apparaît lorsque vous raccordez le journal à un véritable agent.

Exemples d'utilisation : lire les chiffres

Une fois le journal attaché à votre agent, laissez-le tourner sur un ensemble représentatif de tâches. Après quelques sessions, inspectez le résumé et posez quatre questions.

Quelle est la taille de la charge de sortie d'outils par rapport à la charge conversationnelle ? Si les sorties d'outils dominent, votre agent dépense son budget mémoire en réponses API brutes. La solution n'est pas une fenêtre de contexte plus grande ; c'est des schémas d'outils plus étroits ou une étape de résumé qui condense un résultat d'outil en ses champs pertinents avant qu'il ne réintègre la conversation. Votre mesure vous indique, en kilo-octets et en jetons, si vous résolvez le bon problème.

Combien d'événements font référence au même fait ? Le journal enregistre les numéros d'étape, vous pouvez donc repérer les appels d'outils répétés avec des charges utiles presque identiques. Si la même liste de problèmes est récupérée trois fois avec des paramètres de filtre différents, la mémoire de l'agent se remplit de quasi-doublons. Envisagez de mettre en cache les résultats d'outils par arguments, afin que la mémoire ne contienne que la première réponse et la clé de cache.

La sortie de complétion est-elle volumineuse ? Les grandes réponses de l'assistant sont souvent renvoyées mot pour mot lors des étapes ultérieures de la conversation. Si les jetons de complétion dominent le résumé, votre agent se parle plus qu'il ne parle à l'utilisateur. Taillez les sorties de chaîne de pensée avant de les ajouter au transcript.

Quelle part de la fenêtre de contexte ces totaux consommeraient-ils ? Comparez les totaux mesurés à la limite de contexte du modèle que vous déployez. Si vous êtes à 10 % de la limite, vous avez de la marge et ne devriez pas encore ajouter de stockage mémoire externe. Si vous êtes à 90 %, la solution est la réduction avant l'expansion — compressez d'abord les sorties d'outils, puis envisagez seulement un stockage à long terme pour les faits qui survivent entre les sessions.

Un contrôle complémentaire utile est le ratio de compression : divisez la somme des payload_chars par le nombre total de jetons. Si le ratio est élevé — beaucoup de caractères par jeton — vos charges utiles sont verbeuses et hautement compressibles. S'il est faible, votre mémoire contient un contenu dense que la synthèse endommagerait, et vous devriez plutôt empêcher une partie de ce contenu d'entrer en mémoire du tout.

Pourquoi la réponse par défaut est généralement fausse

La réponse par défaut à « de quelle quantité de mémoire mon agent a-t-il besoin ? » est généralement formulée comme un multiple de la fenêtre de contexte : « assez pour contenir toute la session », ou « un store vectoriel avec tout ». Ces deux réponses évitent la vraie question, qui porte sur la composition de la mémoire, pas sur son volume.

Le contexte ambiant — le prompt système et les définitions d'outils — est facile à raisonner car il est constant. C'est la mémoire de session que le gaspillage se cache. Un agent qui appelle un outil de recherche, reçoit 600 lignes de JSON et raisonne ensuite sur deux lignes de ce résultat paie en réalité pour une mémoire bien plus grande que l'information qu'il utilise. L'alternative n'est pas de lui donner plus de mémoire, mais de lui donner moins de mémoire non pertinente, mesurée avec un outil comme celui ci-dessus.

C'est aussi pourquoi la perspective ALTK-Evolve compte. À mesure que l'agent évolue — nouveaux outils, nouvelles sources de données, nouvelles habitudes d'utilisation — le profil mémoire change. Une configuration réglée pour un agent à deux outils sera fausse pour un agent à dix outils. La seule pratique durable est de garder le compteur attaché, de l'exécuter périodiquement et de laisser les chiffres piloter l'allocation.

Conclusion

Le besoin en mémoire de votre agent n'est pas un nombre unique que vous pouvez consulter ou mesurer une fois. C'est une distribution entre conversation, sorties d'outils, historique épisodique et contexte constant — et cette distribution se déplace à mesure que l'agent change. La réponse pratique à « de quelle quantité de mémoire votre agent a-t-il réellement besoin ? » est : assez pour accomplir la tâche sans récupérer les mêmes données, et pas davantage. La seule façon de trouver ce point, c'est de mesurer.

Le journal léger présenté ici vous donne une base de référence en quelques minutes. Attachez-le à votre agent, collectez des données à partir de charges de travail réelles et agissez sur la ventilation : compressez les sorties d'outils, dédupliquez les événements répétés et réduisez avant d'étendre. Comme le suggère la question d'IBM Research sur le blog Hugging Face, la mémoire mérite le même traitement empirique que toute autre partie du système. Traitez-la comme un budget à mesurer, pas comme une fonctionnalité à maximiser, et votre agent fonctionnera plus vite, coûtera moins cher et raisonnera sur ce qui compte vraiment.

Sources