Sorties structurées
Obtenez des résultats JSON validés à partir de workflows d'agents
Les « structured outputs » (sorties structurées) contraignent les réponses de Claude à suivre un schéma spécifique, garantissant une sortie valide et analysable pour le traitement en aval. Les sorties structurées offrent deux fonctionnalités complémentaires :
- Sorties JSON (
output_config.format) : obtenez la réponse de Claude dans un format JSON spécifique, par exemple pour extraire des données d'images ou de texte, générer des rapports structurés ou formater des réponses d'API. Cette page traite des sorties JSON. - « Strict tool use » (utilisation d'outils stricte) (
strict: true) : garantissez la validation du schéma sur les noms et les entrées des outils. Consultez Utilisation d'outils stricte.
Vous pouvez utiliser ces fonctionnalités indépendamment ou ensemble dans la même requête.
Pourquoi utiliser les sorties structurées
Sans sorties structurées, Claude peut générer des réponses JSON mal formées ou des entrées d'outils invalides qui cassent vos applications. Même avec un prompting soigné, vous pouvez rencontrer :
- Des erreurs d'analyse dues à une syntaxe JSON invalide
- Des champs obligatoires manquants
- Des types de données incohérents
- Des violations de schéma nécessitant une gestion des erreurs et des nouvelles tentatives
Les sorties structurées garantissent des réponses conformes au schéma grâce au décodage contraint :
- Toujours valides : plus d'erreurs
JSON.parse() - Sûreté de typage : types de champs et champs obligatoires garantis
- Fiables : aucune nouvelle tentative nécessaire pour les violations de schéma
Fonctionnement
Définissez votre schéma
Décrivez la structure souhaitée sous forme de schéma JSON ou de type dans votre langage. Le schéma suit JSON Schema, avec certaines limitations.
Envoyez-le dans output_config.format
La requête transporte le schéma dans
output_config.formatavectype: "json_schema". Les helpers du SDK le définissent pour vous.Lisez la réponse
Claude renvoie un JSON valide correspondant à votre schéma dans le bloc de contenu texte de la réponse. Les helpers du SDK l'analysent dans votre type.
Utilisation
from pydantic import BaseModel
class ContactInfo(BaseModel):
name: str
email: str
plan_interest: str
demo_requested: bool
client = Anthropic()
response = client.messages.parse(
model="claude-opus-5-5",
max_tokens=1024,
messages=[
{
"role": "user",
"content": (
"Extract the key information from this email: "
"John Smith (john@example.com) is interested in our Enterprise plan "
"and wants to schedule a demo for next Tuesday at 2pm."
),
}
],
output_format=ContactInfo,
)
print(response.parsed_output)Passez un modèle Pydantic à client.messages.parse(), la méthode recommandée, en tant que output_format. Le SDK transforme le schéma du modèle, l'envoie en tant que output_config.format, valide la réponse et renvoie le modèle analysé dans parsed_output.
L'exemple ci-dessus produit :
name='John Smith' email='john@example.com' plan_interest='Enterprise' demo_requested=TrueFonctionnement de la transformation par le SDK
La plupart des helpers du SDK transforment les schémas qui utilisent des fonctionnalités non prises en charge. Les étapes de transformation :
- Suppression des contraintes non prises en charge (par exemple,
minimum,maximum,minLength,maxLength) - Mise à jour des descriptions en ajoutant chaque contrainte non prise en charge à la description du champ (par exemple,
{minimum: 100}) - Ajout de
additionalProperties: falseà tous les objets - Filtrage des formats de chaîne pour ne conserver que la liste prise en charge
- Validation des réponses par rapport à votre schéma d'origine et à toutes ses contraintes, si le helper valide les réponses
Claude reçoit un schéma simplifié, mais un helper qui valide les réponses applique toujours chaque contrainte dans votre code.
Exemple : un champ avec minimum: 100 devient un simple entier dans le schéma envoyé, et le SDK ajoute {minimum: 100} à la description du champ. Un helper qui valide les réponses vérifie toujours la réponse par rapport à minimum: 100.
Utiliser un schéma JSON brut
Pour utiliser un schéma JSON provenant d'un fichier, d'une spécification OpenAPI ou d'un code qui le construit à l'exécution, passez-le dans output_config.format.
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-opus-5-5",
max_tokens=1024,
messages=[
{
"role": "user",
"content": (
"Extract the key information from this email: "
"John Smith (john@example.com) is interested in our Enterprise plan "
"and wants to schedule a demo for next Tuesday at 2pm."
),
}
],
output_config={
"format": {
"type": "json_schema",
"schema": {
"type": "object",
"properties": {
"name": {"type": "string"},
"email": {"type": "string"},
"plan_interest": {"type": "string"},
"demo_requested": {"type": "boolean"},
},
"required": ["name", "email", "plan_interest", "demo_requested"],
"additionalProperties": False,
},
}
},
)
text = next(block.text for block in response.content if block.type == "text")
contact = json.loads(text)
print(contact)L'exemple ci-dessus produit :
{'name': 'John Smith', 'email': 'john@example.com', 'plan_interest': 'Enterprise', 'demo_requested': True}Pour déplacer les contraintes non prises en charge par l'API dans les descriptions des champs, faites passer le schéma par transform_schema() du package anthropic avant de l'envoyer, et modifiez le résultat si nécessaire. transform_schema() accepte également un modèle Pydantic. Contrairement à client.messages.parse(), elle renvoie le schéma transformé au lieu de l'envoyer.
Cas d'utilisation courants
Extrayez des données structurées à partir de texte non structuré :
from pydantic import BaseModel
class Invoice(BaseModel):
invoice_number: str
date: str
total_amount: float
line_items: list[dict]
customer_name: str
client = anthropic.Anthropic()
invoice_text = "Invoice #12345, Date: 2024-01-15, Total: $500.00"
response = client.messages.parse(
model="claude-opus-5-5",
max_tokens=4096,
output_format=Invoice,
messages=[
{"role": "user", "content": f"Extract invoice data from: {invoice_text}"}
],
)
print(response.parsed_output)Classez du contenu avec des catégories structurées :
from pydantic import BaseModel
client = Anthropic()
class Classification(BaseModel):
category: str
confidence: float
tags: list[str]
sentiment: str
feedback_text = "Great product, but the delivery was slow."
response = client.messages.parse(
model="claude-opus-5-5",
max_tokens=1024,
output_format=Classification,
messages=[{"role": "user", "content": f"Classify this feedback: {feedback_text}"}],
)
print(response.parsed_output)Générez des réponses prêtes pour une API :
from pydantic import BaseModel
client = Anthropic()
class APIResponse(BaseModel):
status: str
data: dict
errors: list[dict] | None
metadata: dict
response = client.messages.parse(
model="claude-opus-5-5",
max_tokens=1024,
output_format=APIResponse,
messages=[{"role": "user", "content": "Process this request: ..."}],
)
print(response.parsed_output)Utilisation d'outils stricte
Pour imposer la conformité à JSON Schema sur les entrées d'outils avec un échantillonnage contraint par grammaire, consultez Utilisation d'outils stricte.
Utiliser les deux fonctionnalités ensemble
Les sorties JSON et l'utilisation d'outils stricte résolvent des problèmes différents et fonctionnent ensemble :
- Les sorties JSON contrôlent le format de réponse de Claude (ce que Claude dit)
- L'utilisation d'outils stricte valide les paramètres des outils (comment Claude appelle vos fonctions)
Combinées, elles permettent à Claude d'appeler des outils avec des paramètres garantis valides ET de renvoyer des réponses JSON structurées. Cela est utile pour les workflows agentiques où vous avez besoin à la fois d'appels d'outils fiables et de sorties finales structurées.
response = client.messages.create(
model="claude-opus-5-5",
max_tokens=1024,
messages=[
{
"role": "user",
"content": "Help me plan a trip to Paris departing May 15, 2026",
}
],
# Sorties JSON : format de réponse structuré
output_config={
"format": {
"type": "json_schema",
"schema": {
"type": "object",
"properties": {
"summary": {"type": "string"},
"next_steps": {"type": "array", "items": {"type": "string"}},
},
"required": ["summary", "next_steps"],
"additionalProperties": False,
},
}
},
# Utilisation d'outils stricte : paramètres d'outils garantis
tools=[
{
"name": "search_flights",
"strict": True,
"input_schema": {
"type": "object",
"properties": {
"destination": {"type": "string"},
"date": {"type": "string", "format": "date"},
},
"required": ["destination", "date"],
"additionalProperties": False,
},
}
],
)
print(response)Considérations importantes
Compilation et mise en cache des grammaires
Les sorties structurées utilisent un échantillonnage contraint avec des artefacts de grammaire compilés. Cela introduit certaines caractéristiques de performance à connaître :
- Latence de la première requête : la première fois que vous utilisez un schéma spécifique, il y a une latence supplémentaire pendant la compilation de la grammaire
- Mise en cache automatique : les grammaires compilées sont mises en cache pendant 24 heures à compter de la dernière utilisation, ce qui rend les requêtes suivantes beaucoup plus rapides
- Invalidation du cache : le cache est invalidé si vous modifiez :
- La structure du schéma JSON
- L'ensemble des outils de votre requête (lorsque vous utilisez à la fois les sorties structurées et l'utilisation d'outils)
- La modification des seuls champs
nameoudescriptionn'invalide pas le cache
Modification du prompt et coûts en tokens
Lorsque vous utilisez les sorties structurées, Claude reçoit automatiquement une invite système supplémentaire expliquant le format de sortie attendu. Cela signifie que :
- Votre nombre de tokens d'entrée est légèrement plus élevé
- Le prompt injecté vous coûte des tokens comme toute autre invite système
- La modification du paramètre
output_config.formatinvalidera tout cache de prompts pour ce fil de conversation
Limitations de JSON Schema
Les sorties structurées prennent en charge le JSON Schema standard avec certaines limitations. Les sorties JSON et l'utilisation d'outils stricte partagent ces limitations.
- Tous les types de base : object, array, string, integer, number, boolean, null
enum(chaînes, nombres, booléens ou nulls uniquement - pas de types complexes). Pour une mise en garde concernant la casse, consultez Sorties invalides.constanyOfetallOf(avec limitations -allOfavec$refnon pris en charge)$ref,$defetdefinitions($refexterne non pris en charge)- Propriété
defaultpour tous les types pris en charge requiredetadditionalProperties(doit être défini àfalsepour les objets)- Formats de chaînes :
date-time,time,date,duration,email,hostname,uri,ipv4,ipv6,uuid minItemspour les tableaux (seules les valeurs 0 et 1 sont prises en charge)
- Schémas récursifs
- Types complexes dans les enums
$refexterne (par exemple,'$ref': 'http://...')- Contraintes numériques (telles que
minimum,maximum,multipleOf) - Contraintes de chaînes (
minLength,maxLength) - Contraintes de tableaux au-delà de
minItemsde 0 ou 1 additionalPropertiesdéfini à autre chose quefalse
Si vous utilisez une fonctionnalité non prise en charge, vous recevrez une erreur 400 avec des détails.
Fonctionnalités regex prises en charge :
- Correspondance complète (
^...$) et correspondance partielle - Quantificateurs :
*,+,?, cas simples de{n,m} - Classes de caractères :
[],.,\d,\w,\s - Groupes :
(...)
NON pris en charge :
- Références arrière vers des groupes (par exemple,
\1,\2) - Assertions lookahead/lookbehind (par exemple,
(?=...),(?!...)) - Limites de mots :
\b,\B - Quantificateurs
{n,m}complexes avec de grandes plages
Les motifs regex simples fonctionnent bien. Les motifs complexes peuvent entraîner des erreurs 400.
Ordre des propriétés
Lorsque vous utilisez les sorties structurées, les propriétés des objets conservent l'ordre défini dans votre schéma, avec une mise en garde importante : les propriétés obligatoires apparaissent en premier, suivies des propriétés optionnelles.
Par exemple, avec ce schéma :
{
"type": "object",
"properties": {
"notes": { "type": "string" },
"name": { "type": "string" },
"email": { "type": "string" },
"age": { "type": "integer" }
},
"required": ["name", "email"],
"additionalProperties": false
}La sortie ordonnera les propriétés comme suit :
name(obligatoire, dans l'ordre du schéma)email(obligatoire, dans l'ordre du schéma)notes(optionnelle, dans l'ordre du schéma)age(optionnelle, dans l'ordre du schéma)
Cela signifie que la sortie pourrait ressembler à ceci :
{
"name": "John Smith",
"email": "john@example.com",
"notes": "Interested in enterprise plan",
"age": 35
}Si l'ordre des propriétés dans la sortie est important pour votre application, marquez toutes les propriétés comme obligatoires, ou tenez compte de ce réordonnancement dans votre logique d'analyse.
Sorties invalides
Bien que les sorties structurées garantissent la conformité au schéma dans la plupart des cas, il existe des scénarios où la sortie peut ne pas correspondre à votre schéma :
Refus (stop_reason: "refusal")
Claude conserve ses propriétés de sécurité et d'utilité même lorsqu'il utilise les sorties structurées. Si Claude refuse une requête pour des raisons de sécurité :
- La réponse a
stop_reason: "refusal" - Vous recevrez un code de statut 200
- Les tokens générés vous seront facturés
- La sortie peut ne pas correspondre à votre schéma car le message de refus est prioritaire sur les contraintes du schéma
Une propriété qui demande la réflexion du modèle ou un raisonnement étape par étape peut entraîner un refus reasoning_extraction. Demandez plutôt une courte explication. Consultez Conserver le raisonnement dans les blocs de réflexion.
Limite de tokens atteinte (stop_reason: "max_tokens")
Si la réponse est tronquée parce que la limite max_tokens a été atteinte :
- La réponse a
stop_reason: "max_tokens" - La sortie peut être incomplète et ne pas correspondre à votre schéma
- Réessayez avec une valeur
max_tokensplus élevée pour obtenir la sortie structurée complète
Casse des valeurs enum
Les sorties structurées ne garantissent pas la casse des valeurs enum et const de type chaîne : Claude peut renvoyer une valeur qui ne diffère de votre schéma que par la casse, généralement sur la première lettre d'un mot suivant une espace. Par exemple, avec ce schéma :
{
"type": "string",
"enum": ["Conversation Topic 1", "Conversation Topic 2", "Conversation topic 3"]
}La sortie peut contenir "Conversation Topic 3" (« T » majuscule) même si cette valeur exacte ne figure pas dans l'enum. La réponse se termine normalement, sans erreur ni stop_reason particulier. Cela s'applique aussi bien aux sorties JSON qu'à l'utilisation d'outils stricte. Comparez les valeurs enum sans tenir compte de la casse, et évitez les valeurs enum qui ne diffèrent que par la casse.
Limites de complexité des schémas
Les sorties structurées fonctionnent en compilant vos schémas JSON en une grammaire qui contraint la sortie de Claude. Les schémas plus complexes produisent des grammaires plus volumineuses qui prennent plus de temps à compiler. Pour se protéger contre des temps de compilation excessifs, l'API impose plusieurs limites de complexité.
Limites explicites
Les limites suivantes s'appliquent à toutes les requêtes avec output_config.format ou strict: true :
| Limite | Valeur | Description |
|---|---|---|
| Outils stricts par requête | 20 | Nombre maximal d'outils avec strict: true. Les outils non stricts ne comptent pas dans cette limite. |
| Paramètres optionnels | 24 | Total des paramètres optionnels sur l'ensemble des schémas d'outils stricts et des schémas de sortie JSON. Chaque paramètre non listé dans required compte dans cette limite. |
| Paramètres avec types union | 16 | Total des paramètres qui utilisent anyOf ou des tableaux de types (par exemple, "type": ["string", "null"]) sur l'ensemble des schémas stricts. Ceux-ci sont particulièrement coûteux car ils créent un coût de compilation exponentiel. |
Limites internes supplémentaires
Au-delà des limites explicites du tableau précédent, il existe des limites internes supplémentaires sur la taille de la grammaire compilée. Ces limites existent parce que la complexité d'un schéma ne se réduit pas à une seule dimension : des fonctionnalités comme les paramètres optionnels, les types union, les objets imbriqués et le nombre d'outils interagissent entre elles de manières qui peuvent rendre la grammaire compilée disproportionnément volumineuse.
Lorsque ces limites sont dépassées, vous recevrez une erreur 400 avec le message « Schema is too complex for compilation. » Ces erreurs signifient que la complexité combinée de vos schémas dépasse ce qui peut être compilé efficacement, même si chaque limite individuelle du tableau précédent est respectée. En dernier recours, l'API impose également un délai d'expiration de compilation de 180 secondes. Les schémas qui passent toutes les vérifications explicites mais produisent des grammaires compilées très volumineuses peuvent atteindre ce délai.
Conseils pour réduire la complexité des schémas
Si vous atteignez les limites de complexité, essayez ces stratégies dans l'ordre :
-
Ne marquez comme stricts que les outils critiques. Si vous avez de nombreux outils, réservez ce mode aux outils pour lesquels les violations de schéma causent de réels problèmes, et fiez-vous à l'adhérence naturelle de Claude pour les outils plus simples.
-
Réduisez les paramètres optionnels. Rendez les paramètres
requiredlorsque c'est possible. Chaque paramètre optionnel double approximativement une partie de l'espace d'états de la grammaire. Si un paramètre a toujours une valeur par défaut raisonnable, envisagez de le rendre obligatoire et de demander à Claude de fournir explicitement cette valeur par défaut. -
Simplifiez les structures imbriquées. Les objets profondément imbriqués avec des champs optionnels aggravent la complexité. Aplatissez les structures lorsque c'est possible.
-
Répartissez sur plusieurs requêtes. Si vous avez de nombreux outils stricts, envisagez de les répartir sur des requêtes ou des sous-agents distincts.
Pour les problèmes persistants avec des schémas valides, contactez le support avec la définition de votre schéma.
Migration depuis la bêta
Le paramètre output_format a été déplacé vers output_config.format, et les en-têtes bêta ne sont plus nécessaires. Le paramètre output_format est déprécié et sera supprimé à l'avenir. Pour l'utiliser malgré tout, ajoutez l'en-tête bêta structured-outputs-2025-11-13. Sans celui-ci, l'API renvoie une erreur 400.
Le SDK Python (v1.0 et versions ultérieures) n'accepte pas output_format={...} sur client.beta.messages.create() ou count_tokens() et lève une TypeError. Utilisez plutôt output_config. Consultez Utiliser un schéma JSON brut pour la forme mise à jour de l'API.
Conservation des données
Les prompts et les réponses sont traités avec ZDR lors de l'utilisation des sorties structurées. Cependant, le schéma JSON lui-même est temporairement mis en cache jusqu'à 24 heures après la dernière utilisation à des fins d'optimisation. Aucune donnée de prompt ou de réponse n'est conservée au-delà de la réponse de l'API.
Les sorties structurées sont éligibles HIPAA, mais les PHI ne doivent pas être incluses dans les définitions de schémas JSON. L'API compile les schémas JSON en grammaires qui sont mises en cache séparément du contenu des messages, et ces schémas mis en cache ne bénéficient pas des mêmes protections PHI que les prompts et les réponses. N'incluez pas de PHI dans les noms de propriétés de schéma, les valeurs enum, les valeurs const ou les expressions régulières pattern. Les PHI ne doivent apparaître que dans le contenu des messages (prompts et réponses), où elles sont protégées par les garanties HIPAA.
Pour l'éligibilité ZDR et HIPAA de toutes les fonctionnalités, consultez API et conservation des données.
Compatibilité des fonctionnalités
Fonctionne avec :
- Traitement par lots : traitez des sorties structurées à grande échelle avec une remise de 50 %
- Comptage de tokens : comptez les tokens sans compilation
- Streaming : diffusez les sorties structurées en streaming comme des réponses normales
- Utilisation combinée : utilisez les sorties JSON (
output_config.format) et l'utilisation d'outils stricte (strict: true) ensemble dans la même requête
Incompatible avec :
- Citations : les citations nécessitent d'entrelacer des blocs de citation avec du texte, ce qui entre en conflit avec les contraintes strictes de schéma JSON. Renvoie une erreur 400 si les citations sont activées avec
output_config.format. - Préremplissage de message : incompatible avec les sorties JSON
Étapes suivantes
Demandez à Claude de citer ses sources lorsqu'il répond à des questions sur les documents fournis.
Imposez la conformité à JSON Schema sur les entrées d'outils de Claude avec un échantillonnage contraint par grammaire.
Connectez Claude à des outils et API externes. Découvrez où les outils s'exécutent et comment fonctionne la boucle agentique.
Découvrez la structure tarifaire d'Anthropic pour les modèles et les fonctionnalités.
Compatibility
- Supported models
- Fable 5 and 5.1
- Mythos 5, 5.1, and Preview
- Opus 4.5, 4.6, 4.7, 4.8, 5, and 5.5
- Sonnet 4.5, 4.6, 5, and 5.5
- Haiku 4.5 and 5.5
- Supported platforms
- Claude API
- Claude Platform on AWS
- Amazon Bedrock1
- Google Cloud
- Microsoft Foundry
- Sur Amazon Bedrock, les sorties structurées sont disponibles sur l'intégration héritée Amazon Bedrock (Opus 4.6 et versions antérieures) pour Claude Opus 4.6, Claude Sonnet 4.6, Claude Sonnet 4.5, Claude Opus 4.5 et Claude Haiku 4.5, et non sur Claude in Amazon Bedrock. ↩
Was this page helpful?