Streaming granulaire des appels d'outils
Mis à jour le 30 juillet 2026
Quand on combine le streaming avec l’utilisation d’outils, Claude envoie les arguments des outils au fur et à mesure qu’il les génère. Cela permet de rendre l’interface plus réactive. Mais il y a des subtilités à comprendre sur le fonctionnement interne.
Le streaming standard avec les outils
Cette leçon traite d’un compromis précis : la fraîcheur des données contre leur validité. L’API doit choisir entre vous transmettre les fragments dès leur génération — au risque qu’ils soient inutilisables isolément — ou attendre d’avoir des morceaux valides, au prix d’un délai. Le comportement par défaut choisit la validité ; le mode granulaire choisit la fraîcheur. Tout le reste en découle.
En mode streaming, Claude envoie différents types d’événements. Pour les outils, un nouveau type apparaît : InputJsonEvent.
Chaque InputJsonEvent contient deux propriétés :
partial_json: un fragment du JSON des arguments de l’outilsnapshot: le JSON complet accumulé jusqu’à présent
for chunk in stream:
if chunk.type == "input_json":
# Traiter le fragment JSON
print(chunk.partial_json)
# Ou utiliser le snapshot complet
current_args = chunk.snapshot
La validation JSON côté API
Par défaut, l’API Anthropic ne transmet pas chaque fragment immédiatement. Elle met en tampon les morceaux et les valide avant de les envoyer.
Concrètement, l’API attend qu’une paire clé-valeur de premier niveau soit complète avant de l’envoyer. Prenons cette structure :
{
"abstract": "Cet article presente une nouvelle...",
"meta": {
"word_count": 847,
"review": "Cet article introduit QuanNet..."
}
}
L’API va :
- Attendre que toute la valeur de
abstractsoit générée - Valider cette paire clé-valeur contre le schéma
- Envoyer d’un coup tous les fragments bufferisés pour
abstract - Répéter le processus pour
meta
C’est pourquoi on observe des pauses suivies de rafales de texte, même en mode streaming. Si vous avez déjà constaté ce comportement en vous demandant si votre code était en cause : non. C’est le tampon de validation de l’API, et aucune optimisation côté client ne le fera disparaître — seul le mode granulaire le désactive. Les fragments sont retenus jusqu’à ce qu’une paire clé-valeur complète et valide soit prête.
Le mode granulaire (fine-grained)
Si vous avez besoin d’un streaming plus rapide et plus fin — par exemple pour afficher une progression en temps réel — vous pouvez activer le mode granulaire.
Ce mode fait une chose principale : il désactive la validation JSON côté API. Conséquences :
- Les fragments arrivent dès que Claude les génère
- Plus de délai de mise en tampon entre les clés de premier niveau
- Comportement de streaming plus traditionnel
- Attention : la validation JSON est désactivée, votre code doit gérer les JSON invalides
Pour l’activer :
run_conversation(
messages,
tools=[save_article_schema],
fine_grained=True
)
Avec ce mode, une valeur comme word_count peut arriver bien plus tôt dans le flux, sans attendre que tout l’objet meta soit complet.
Gérer les JSON invalides
En mode granulaire, Claude peut générer du JSON invalide (par exemple "word_count": undefined au lieu d’un nombre). Votre application doit gérer ces cas :
try:
parsed_args = json.loads(chunk.snapshot)
except json.JSONDecodeError:
# Gérer le JSON invalide
print("JSON invalide recu, on continue...")
Sans le mode granulaire, la validation de l’API détecterait cette erreur et pourrait encapsuler les valeurs problématiques dans des chaînes de caractères — ce qui ne correspondrait peut-être pas à votre schéma.
Quand utiliser le mode granulaire ?
Activez-le quand :
- Vous devez montrer la progression en temps réel de la génération des arguments
- Vous voulez commencer à traiter des résultats partiels le plus tôt possible
- Les délais de mise en tampon dégradent l’expérience utilisateur
- Vous êtes prêt à implémenter une gestion robuste des erreurs JSON
Pour la plupart des applications, le comportement par défaut avec validation est parfaitement adapté — et il faut résister à la tentation d’activer le mode granulaire « au cas où ». La validation que vous désactivez devra être réécrite chez vous, en plus complexe : un JSON tronqué à mi-fragment n’est pas parsable, et votre code devra accumuler, tenter, échouer et retenter. Ce coût ne se justifie que si la réactivité perçue est réellement un enjeu produit. Le mode granulaire est réservé aux cas où la réactivité est critique.