veilletech.fr
20 sept. Feed du jour
#05 IA Article

Batch API : 112 jobs sur 1842 jamais revenus

Un lot qui se termine n'est pas un lot qui a réussi. Ce sont deux phrases différentes, et une seule est vérifiable.

Un développeur publie le bilan de 30 jours sur l'API Batch d'Anthropic : sur 1 842 requêtes, 112 n'ont jamais donné de résultat exploitable, sans qu'aucune erreur ne remonte. La cause est un contresens sur le statut du lot, doublé d'un appariement des résultats par position alors qu'ils reviennent dans un ordre arbitraire.

3 min de lectureintermédiairevidéo 1:20
Partager
Sommaire4 sections
  1. Ce qui se passe
  2. Pourquoi ça compte
  3. Comment s'y prendre
  4. À retenir

Ce qui se passe

Sur 30 jours, 1 842 requêtes réparties en 96 lots sont parties dans l'API Batch d'Anthropic. 112 n'ont jamais produit de résultat exploitable — non pas 112 plantages, mais 112 lignes restées à NULL en base, sans une erreur dans les journaux. Soit 6,1 % de perte silencieuse sur une chaîne réputée verte.

Le décompte exact :

result.type Nombre
succeeded 1 747 — dont 17 tronquées (stop_reason: "max_tokens")
errored 71 — 52 overloaded_error, 14 invalid_request_error, 5 api_error
expired 24, au plafond de 24 heures
canceled 0

Pourquoi ça compte

Deux faits différents portaient le même nom dans son code. batch.processing_status == "ended" signifie qu'Anthropic a cessé de travailler sur le lot — y compris sur ce qu'il a abandonné. Le sort de chaque requête vit ailleurs : dans batch.request_counts, et dans le champ result.type de chaque ligne du flux de résultats.

Le défaut le plus coûteux n'est pourtant pas là. Les résultats reviennent dans un ordre arbitraire. Les apparier par position avec la liste d'entrée, via un zip, fonctionne tant que tout réussit ; dès qu'une requête manque, la liste raccourcit et tout ce qui suit se décale d'un cran. Le rapport d'une personne part alors dans le compte d'une autre. Deux utilisateurs l'ont reçu — le défaut a été repéré en lisant un compte rendu qui félicitait quelqu'un pour un projet Kubernetes jamais mentionné pendant l'entretien. Aucune exception, aucune alerte : une sortie fausse, joliment rendue.

Dernier piège du même ordre : une réponse succeeded dont le stop_reason vaut max_tokens contient du JSON coupé en deux. Le parseur lève, le except trop large avale, la ligne reste nulle.

Comment s'y prendre

Indexer les résultats par custom_id, et traiter les quatre types sans branche par défaut :

Python
by_id = {entry.custom_id: entry for entry in
         client.messages.batches.results(batch.id)}   # jamais l'ordre

for session in pending_sessions:
    entry = by_id.get(session.id)
    if entry is None:
        mark_retry(session.id, "missing_from_results")
        continue
    match entry.result.type:
        case "succeeded":
            msg = entry.result.message
            if msg.stop_reason == "max_tokens":
                mark_retry(session.id, "truncated")
            else:
                save_report(session.id, msg.content[0].text)
        case "errored":
            mark_retry(session.id, entry.result.error.type)
        case "expired" | "canceled":
            mark_retry(session.id, entry.result.type)

Aucun chemin ne laisse disparaître une requête. Quatre règles complètent le dispositif : écrire la ligne en base avant de soumettre, vérifier stop_reason sur les succès, retomber sur l'API synchrone après deux tentatives en lot, et alerter sur l'écart entre lignes soumises et lignes résolues — le seul indicateur qui aurait attrapé les 112. Sur les 30 jours suivants, environ 2 100 requêtes sont passées sans une seule ligne non résolue.

Dernier point, sur le choix du format : la latence médiane est de 9 minutes, le p90 de 51 minutes, le p99 de 6 h 20. Batch sert au travail que personne n'attend devant son écran. Le compte rendu d'entretien, attendu juste après la session, y avait été placé à tort : il est repassé sur l'API synchrone, et seul le scoring nocturne est resté en lot. La facture, elle, est passée de 209 à 104 dollars.

Source : Anthropic Batch API: 112 of My 1,842 Jobs Never Came Back, DEV Community, 20 septembre 2026. Le billet indique que son auteur ou autrice développe la plateforme citée.