Évals, tests et débogage
Un sous-domaine, 2,6 % des points — un coup d’œil plutôt qu’une session d’étude, selon la pondération officielle. Mais le contenu est la trousse de débogage que vous utiliserez sur tous les autres domaines : ce qu’une erreur d’API vous dit, quels échecs on retente et comment distinguer une limite de débit d’un plafond de dépense.
Chaque erreur de l’API Claude arrive en JSON avec la même anatomie : un objet error portant un type lisible par machine, un message lisible par l’humain, et un identifiant de requête à journaliser pour le support. Cette anatomie est aussi votre liste d’inspection, dans l’ordre : le statut HTTP, le type d’erreur, tout sous-type ou code d’erreur dans les détails (là où vivent enforced_spend_limit_reached et ses cousins), l’en-tête retry-after quand il est présent — et, pour le ticket de support, l’identifiant de requête. La discipline que l’examen teste se pose par-dessus : branchez sur le type — ou sur les classes d’exception typées du SDK, interceptées en commençant par la plus spécifique — jamais sur le texte du message. Les messages sont de la prose, et la prose change. Go est le seul langage à faire exception : un seul type d’erreur, sur lequel vous branchez selon le code de statut.
01Deux familles d’échec
Triez chaque code de statut dans deux paniers. Transitoire signifie que la requête était bonne et les conditions mauvaises — attendez et réessayez. Changement de requête signifie que la requête elle-même est fausse — la resoumission identique échoue identiquement, donc corrigez la cause. Toute la taxonomie en un écran :
| Statut | Type | Famille | Décision et correction |
|---|---|---|---|
| 429 | rate_limit_error | Transitoire — en général | Faites du backoff et respectez retry-after. Mais confirmez laquelle des trois conditions 429 vous avez sous la main avant de faire confiance à un retry (section suivante). |
| 500 | api_error | Transitoire | Réessayez avec backoff exponentiel ; ouvrez un ticket de support avec l’ID de requête si cela persiste. |
| 504 | timeout_error | Famille transitoire — mais réessayer n’est pas la correction | L’appel a dépassé sa fenêtre. La correction documentée est de passer au streaming ou à l’API Batches, pas de réessayer plus fort. |
| 529 | overloaded_error | Transitoire | Capacité côté Anthropic, pas votre requête. Attendez et réessayez. |
| 409 | conflict_error | Changement de requête, avec une récupération en forme de retry | Deux écritures concurrentes sont entrées en collision. Résolvez le conflit, puis resoumettez — le seul 4xx que l’on retente. |
| 400 | invalid_request_error | Changement de requête | Corrigez la requête mal formée — sauf si une limite de dépense que vous avez fixée vous-même a été atteinte, auquel cas relevez ou supprimez la limite. |
| 401–404 | authentication / billing / permission / not_found | Changement de requête | Identifiants, facturation, portée ou mauvais chemin. Corrigez ; ne réessayez pas. |
| 413 | request_too_large | Changement de requête | Charge utile au-dessus du plafond de taille — 32 Mo pour les messages et le comptage de tokens, 256 Mo pour les batches, 500 Mo pour les fichiers. Elle doit maigrir ; réessayer ne peut rien pour elle. |
La ligne qui brouille les paniers mérite son propre paragraphe, parce que l’examen sait qu’elle brouille. Faites le test des deux paniers au pied de la lettre : la resoumission identique échouerait-elle identiquement ? Pour un 409, oui — tant que le conflit tient, renvoyer la même écriture échoue encore, ce qui est un comportement de changement de requête. Ce qui rend le 409 unique parmi les 4xx, c’est la récupération : une fois la collision résolue, resoumettre la même opération logique est le chemin documenté. Changement de requête par mécanisme, récupération en forme de retry — donc « résoudre, puis resoumettre » ne compte comme retry qu’au sens large, et c’est la forme de réponse à viser.
02Ce que le SDK fait déjà pour vous
Les SDK officiels retentent eux-mêmes les échecs transitoires — erreurs de connexion, limites de débit, 5xx — avec backoff exponentiel, en respectant tout en-tête retry-after, deux fois par défaut. Votre gestionnaire d’erreurs ne se déclenche qu’après que ces tentatives sont épuisées. Deux conséquences suivent. Votre propre boucle de retry posée par-dessus double l’attente, sauf à désactiver l’un des deux côtés — max_retries sur le client est le bouton ; coupez-le quand une file de tâches externe retente déjà. Et « j’ai vu l’exception » veut dire que le SDK a déjà retenté, pas qu’il a échoué une fois.
03Trois choses qui ressemblent à une limite de débit
La famille des 429 est là où ce domaine gagne ses points, parce que trois conditions différentes portent les mêmes habits — et la mauvaise réponse les traite en une seule. Côte à côte :
| Vrai 429 de limite de débit | 429 de plafond de dépense du palier | Limite auto-fixée — un 400 | |
|---|---|---|---|
| Ce qui a déclenché | L’une des trois limites par classe de modèle : requêtes, tokens d’entrée ou de sortie par minute | Le palier d’usage a atteint son plafond de dépense | La limite d’organisation que vous avez fixée vous-même |
| Le signe révélateur | retry-after présent ; l’erreur nomme la limite déclenchée | Pas de retry-after ; enforced_spend_limit_reached dans les détails | Administratif — vérifiez les limites que vous avez fixées |
| Réessayer aide-t-il | Oui — backoff, et respectez retry-after | Non — pas avant que l’accès reprenne | Non — relevez ou supprimez la limite |
| Subtilités de comptabilité | La limite d’entrée ne compte que les tokens non mis en cache (la plupart des modèles) ; la limite de sortie compte les tokens générés, pas votre réglage max_tokens | — | — |
La troisième colonne est le piège que le tableau existe pour exposer : la limite d’organisation auto-fixée n’est pas du tout une limite de débit — elle renvoie un 400 invalid_request_error, et la correction est administrative. Une exception court dans l’autre sens : les limites de workspace de Claude Code sont vérifiées séparément et reviennent bien en 429, avec un en-tête retry-after.
Et le fait organisationnel qui tue toute une classe de mauvaises réponses : les limites de débit s’attachent à l’organisation, pas à la clé. Faire une rotation des clés pour « répartir la charge » ne sert à rien — et c’est parfois exactement la mauvaise option que l’examen vous propose.
04L’habitude des évals
Le nom du domaine promet plus que son unique sous-domaine ne livre — mais l’évaluation revient dans tout l’examen par les autres domaines — alors retenez le motif. Un changement de modèle, de prompt ou d’architecture ne se juge que par une éval construite à partir de vos vrais prompts et de vos vraies données, avec un seuil de réussite. L’objet usage de chaque réponse (tokens d’entrée, tokens de sortie, lectures et écritures de cache) est la vérité terrain pour la facturation comme pour le débogage. Et quand le comportement dérive en cours de projet, la première question est ce qui a changé dans le contexte — pas qui blâmer. Petit domaine, trousse transférable.
05Les pièges de ce domaine
- —« Tout 429 est transitoire » — le 429 de plafond de dépense n’a ni retry-after ni récupération par retry.
- —« 413, retentez simplement » — la charge utile est au-dessus du plafond ; elle doit maigrir.
- —« Une rotation des clés esquive les limites de débit » — les limites sont organisationnelles.
- —« Analyser le message d’erreur pour le classer » — branchez sur le type ou sur la classe d’exception.
- —« Retenter le 504 plus fort » — l’appel a dépassé sa fenêtre ; changez la forme de la requête, pas le rythme des retries.
- —« 409 veut dire que la requête était mal formée » — la requête était bonne ; deux écritures concurrentes sont entrées en collision. Résolvez, puis resoumettez.