Message threads Claude : l'agent n'envoie plus que le nouveau

Anthropic garde la conversation côté serveur, 5 minutes. Comment l'activer sans casser un agent en production.

Schéma d'une conversation Claude où seuls les nouveaux messages circulent entre l'agent et l'API

Anthropic a ouvert le 2 novembre 2026 les message threads en bêta publique sur l'API Messages. Le principe tient en une ligne : au lieu de renvoyer toute la conversation à chaque tour, votre agent n'envoie que ce qui est nouveau, et Claude retrouve le reste en mémoire serveur. Ça concerne tous ceux qui font tourner des agents longs (codage, navigation, documents lourds) sur l'API Claude, directement ou via AWS, Google Cloud et Microsoft Foundry.

Précision d'honnêteté : la fonction a deux jours. Je n'ai pas encore de semaines de prod derrière moi, et je n'ai pas mesuré moi-même le gain de latence. Ce tuto s'appuie sur la documentation officielle, l'annonce d'Anthropic et les premiers retours publics, et il insiste sur ce qui casse, parce que c'est là que se jouent vos soirées.

Message threads Claude : ce que ça change vraiment dans la requête

Sans thread, chaque tour d'un agent rembourse le même trajet. Votre code renvoie le prompt système, les outils, tout l'historique et les résultats d'outils, et l'API revalide et retokenise l'ensemble. Sur une session de 600 000 tokens, vous envoyez des centaines de kilooctets pour dire « et maintenant, lis ce fichier ».

Avec un thread, la première requête ouvre le fil et les suivantes ne portent que le delta. Anthropic donne deux chiffres : environ 35 % de baisse du temps médian au premier token pour les requêtes de 500 000 à 1 million de tokens, et une requête médiane qui passe d'environ 800 Ko à 1,8 Ko dans les longues conversations (annonce officielle). Les threads sont déjà activés par défaut pour la plupart des utilisateurs de Claude Code.

Deux limites de lecture à garder en tête. Le gain porte sur les très longs contextes : sur une conversation de 5 000 tokens, il sera marginal. Et la consommation de tokens ne baisse pas, puisque Claude relit toujours la conversation entière à chaque tour. Les tarifs standard et les limites de débit s'appliquent tels quels. Si votre problème est la facture et pas la latence, regardez plutôt notre tuto sur le programmatic tool calling.

Activer un thread en 3 étapes

Il faut un en-tête bêta message-threads-2026-08-12 sur chaque requête, plus un champ thread dans le corps. Tous les modèles Claude récents sont listés comme compatibles, de Haiku 5.5 à Fable 5.1 en passant par Sonnet 5.5 et Opus 5.5.

  1. Créer. Première requête classique, avec system, tools et la conversation complète, plus "thread": {"type": "create"}. L'API stocke la conversation, réponse de Claude comprise, sous l'id de la réponse.
  2. Continuer. Requête suivante : seulement les messages nouveaux, plus "thread": {"type": "continue", "previous_message_id": ""}. Vous omettez system et tools : le thread garde ceux de la création.
  3. Chaîner. À chaque tour, vous reprenez l'id de la dernière réponse.

Le SDK propose un helper, client.beta.messages.thread(...), qui pose l'en-tête, gère la création et la continuation et garde la conversation complète en mémoire. Il rejoue automatiquement une fois en cas d'erreur de thread. Pratique, mais il ne conserve l'historique que tant que l'objet existe en mémoire : c'est le piège que je détaille plus bas.

Le code : un agent avec thread et filet de sécurité

Je préfère montrer l'HTTP brut, pour qu'on voie ce qui circule. L'idée : l'historique complet vit dans votre code, le thread n'est qu'une optimisation par-dessus.

import os, httpx

URL = 'https://api.anthropic.com/v1/messages'
HEADERS = {
    'x-api-key': os.environ['ANTHROPIC_API_KEY'],
    'anthropic-version': '2023-06-01',
    'anthropic-beta': 'message-threads-2026-08-12',
}
MODEL = 'claude-sonnet-5-5'

class Agent:
    def __init__(self, system, tools):
        self.system, self.tools = system, tools
        self.history = []      # source de vérité, à persister chez vous
        self.last_id = None

    def _post(self, body):
        return httpx.post(URL, headers=HEADERS, json=body, timeout=120)

    def send(self, new_messages):
        self.history += new_messages
        r = None
        if self.last_id:
            r = self._post({
                'model': MODEL, 'max_tokens': 2048,
                'messages': new_messages,
                'thread': {'type': 'continue',
                           'previous_message_id': self.last_id},
            })
            if r.status_code != 200:
                r = None       # 404 thread_not_found, etc. : on rejoue
        if r is None:
            r = self._post({
                'model': MODEL, 'max_tokens': 2048,
                'system': self.system, 'tools': self.tools,
                'messages': self.history,
                'thread': {'type': 'create'},
            })
        r.raise_for_status()
        msg = r.json()
        self.last_id = msg['id']
        self.history.append({'role': 'assistant',
                             'content': msg['content']})
        return msg

Trois remarques sur ce code. Un échec de continuation n'est jamais fatal : on renvoie tout l'historique dans un nouveau create. L'historique est ajouté avant l'appel, sinon le replay perd le dernier message. Et les paramètres model, tool_choice et thinking doivent rester identiques d'un tour à l'autre, sinon l'API répond par une erreur de type thread_fingerprint_mismatch.

Ce code est un squelette, pas du copier-coller de prod : il ne gère pas le streaming, les nouvelles tentatives sur 429 ni la boucle d'outils complète. Pour câbler les outils, reprenez le schéma de notre tuto sur 3 agents avec les crédits API de Claude Max.

Pourquoi le thread expire après 5 minutes, et ce que ça casse

Le thread vit 5 minutes après la dernière requête. Chaque réponse stockée relance le compteur, et l'API supprime tout au plus une heure après la dernière utilisation. Le contenu (conversation, prompt système, outils) reste en mémoire, chiffré, sans écriture sur disque. Au-delà, une continuation renvoie une 404 thread_not_found, et la doc admet que le message ne dit pas pourquoi.

Les premiers retours publics (un billet sur DEV Community) listent les cas où la 404 tombe sans que vous ayez rien fait de travers :

  • un tour servi mais non stocké, par exemple un appel d'outil coupé par max_tokens ;
  • une réponse venue d'un modèle de secours (fallback) ;
  • une autre clé API ou un autre espace de travail ;
  • l'ajout de la première image dans la conversation.

Mon avis, avant même d'avoir tourné dessus longtemps : le scénario à risque n'est pas l'agent de code qui enchaîne les tours en quelques secondes. C'est l'agent qui attend un humain (validation, mail, signature) ou un outil lent. Cinq minutes de silence et le fil est mort. Si votre agent tourne dans des workers ou des fonctions serverless qui redémarrent, l'objet du helper disparaît avec le processus : l'historique doit alors vivre dans votre base, pas en mémoire.

Les autres pièges à connaître avant la prod

  • Un ID ne se continue qu'une fois. Pour éditer un message ancien ou brancher deux pistes, il faut un nouveau create. Le fil est en ajout seulement.
  • Streaming : continuez uniquement après l'événement message_stop.
  • Doublons silencieux. L'API ne compare pas vos nouveaux messages aux messages stockés : si vous renvoyez un message déjà envoyé, il apparaît deux fois.
  • Cache de prompt : le thread ne le remplace pas. Il reste à votre charge, avec au plus 4 points de rupture (cache_control) par requête ; un cinquième renvoie une erreur 400.
  • Non pris en charge : Message Batches, comptage de tokens, compaction à la demande, la plupart de l'édition de contexte, et lister ou supprimer un thread.

Données sensibles : la fonction n'est pas éligible ZDR

Point qui compte pour une PME française traitant des données clients : les message threads ne sont pas éligibles à la rétention zéro (ZDR), ni à HIPAA d'après les premiers retours. Même si le contenu est chiffré, en mémoire et supprimé sous une heure, si votre contrat ou votre analyse RGPD exige zéro conservation, laissez la fonction coupée. Notre guide sur la mémoire des agents et le RGPD donne la grille pour trancher.

Message threads ou cache de prompt : qui fait quoi

On confond vite les deux. Le cache de prompt réduit le coût des tokens déjà vus et accélère leur traitement. Le thread réduit ce que vous envoyez et ce que l'API doit revalider. Ils se complètent, mais ne se substituent pas : la doc précise que le thread ne met rien en cache pour vous. Un agent bien monté utilise les deux, avec le cache pour la facture et le thread pour la latence.

Autre confusion à éviter : les message threads n'ont rien à voir avec les « session threads » de Claude Managed Agents, qui sont un autre mécanisme.

Message threads Claude : faut-il l'activer dans votre agent ?

Ma grille, à confirmer par vos mesures :

  1. Activez si votre agent tient des sessions longues (au-delà de 200 000 tokens), dans un processus stable, avec des tours rapprochés. Codage, navigation web, analyse de gros documents : c'est le cas visé.
  2. Testez derrière un drapeau si vos sessions sont moyennes. Mesurez le temps au premier token avec et sans thread sur 50 sessions réelles. Si l'écart est sous 10 %, ce n'est pas la peine d'ajouter une dépendance à un état serveur de 5 minutes.
  3. Ne l'activez pas si vous êtes en ZDR, en traitement par lots, ou si votre agent attend régulièrement des humains.

Pour mesurer proprement, branchez vos traces sur l'un des outils de notre comparatif des plateformes d'observabilité et comparez deux cohortes. Si vous n'avez pas encore de compte, vous pouvez ouvrir l'accès API via Claude.

Le verdict : bonne idée d'ingénierie, vendue avec un chiffre flatteur mais borné. Le −35 % vaut pour 500 000 tokens et plus ; en dessous, n'attendez pas de miracle. Et la contrainte des 5 minutes fait de cette fonction un accélérateur pour les agents qui tournent d'une traite, pas une mémoire. Le jour où vous la branchez, branchez aussi le replay.

FAQ

Les message threads Claude coûtent-ils plus cher ?
Non. Les tarifs standard et les limites de débit s'appliquent tels quels, et la consommation de tokens ne change pas, puisque Claude relit la conversation entière à chaque tour. Le gain porte sur la latence et la taille des requêtes, pas sur la facture.
Que se passe-t-il quand un thread expire ?
Un thread expire 5 minutes après la dernière requête. Une continuation renvoie alors une erreur 404 thread_not_found. Il faut renvoyer la conversation complète dans une nouvelle requête de création. Le helper du SDK le fait automatiquement, mais seulement tant que son objet reste en mémoire.
Faut-il un en-tête spécial pour activer les message threads ?
Oui, l'en-tête bêta message-threads-2026-08-12 sur chaque requête, avec un champ thread de type create puis continue. Le helper client.beta.messages.thread du SDK l'ajoute pour vous.
Les message threads sont-ils compatibles avec la rétention zéro de données ?
Non, la fonction n'est pas éligible ZDR. Le contenu est chiffré, tenu en mémoire et supprimé au plus tard une heure après la dernière utilisation, mais si votre contrat exige zéro conservation, ne l'activez pas.
Les message threads fonctionnent-ils avec Message Batches ?
Non. Message Batches, le comptage de tokens, la compaction à la demande et la plupart de l'édition de contexte ne sont pas pris en charge avec un thread.
Partager
Résumé vidéoen cours…