Aller au contenu principal

Votre premier appel API en production (attentif aux coûts)

Intermédiaire
What you'll learn
  • Nommer les quatre disciplines qui séparent un appel de production d'une commande jouet : secrets, streaming, coût et gestion d'erreurs
  • Écrire un appel streamé résilient qui réessaie les échecs transitoires (429/5xx) avec backoff — et ne réessaie jamais un 400
  • Garder l'ID du modèle en configuration pour que changer de modèle soit un changement d'une ligne, pas un rechercher-remplacer
  • Surveiller le coût en tokens sur chaque appel et le plafonner délibérément

Un appel API jouet tient en une ligne. Un appel de production, lui, gère les erreurs, diffuse la sortie en streaming, surveille les coûts et protège les secrets. Construisons cela, étape par étape.

Étape 1 — Secrets et modèle depuis la configuration

export ANTHROPIC_API_KEY="sk-ant-..." # never in source control

Gardez l'ID du modèle dans la configuration, pas éparpillé en valeurs littérales, pour que la migration soit triviale (pourquoi). Choisissez-le délibérément — Choisir un modèle.

Étape 2 — Un appel résilient et en streaming

import os, time, random, anthropic
client = anthropic.Anthropic()
MODEL = os.environ.get("CLAUDE_MODEL", "claude-sonnet-5")

def ask_stream(prompt, system=None, max_tokens=1024):
for attempt in range(5):
try:
with client.messages.stream(
model=MODEL, max_tokens=max_tokens,
system=system or anthropic.NOT_GIVEN,
messages=[{"role": "user", "content": prompt}],
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
final = stream.get_final_message()
print()
usage = final.usage
print(f"\n[tokens in/out: {usage.input_tokens}/{usage.output_tokens}]")
return final
except (anthropic.RateLimitError, anthropic.APIStatusError):
if attempt == 4: raise
time.sleep(min(2 ** attempt + random.random(), 30))

Testez-le à froid avant de le câbler à quoi que ce soit — un petit appel prouve que le stream, la ligne de tokens et votre clé fonctionnent tous :

Premier smoke test (REPL Python)

ask_stream("Say hello in one sentence.", max_tokens=64)

Étape 3 — Surveiller les coûts

  • Journalisez l'utilisation des tokens (ci-dessus) pour voir ce que coûte chaque appel.
  • Calibrez max_tokens et le modèle ; limitez l'entrée avec des prompts ciblés.
  • Pour des préfixes stables répétés, ajoutez le cache de prompts.
  • Voir Tokens et tarification et Coût et latence.

Étape 4 — Gérer les scénarios défavorables

  • Réessayez les erreurs transitoires (429/5xx) avec un backoff (ci-dessus) ; ne réessayez pas les 400.
  • Gérez les refus avec élégance.
  • Fixez un timeout et un budget de coût/itérations pour tout ce qui est agentique.

Vérifier

Forcez chaque chemin et regardez ce qui se passe — un appel de production mérite son nom en échouant bien, pas seulement en réussissant :

Guided walkthrough1 of 4
  1. Le texte s'imprime progressivement à mesure qu'il est généré, pas en un bloc bloquant à la fin. C'est le gain de latence que les utilisateurs ressentent.

Vérifiez-vous

0/3
  1. Pourquoi garder l'ID du modèle en configuration au lieu de disperser la chaîne littérale dans votre code ?
  2. La boucle de retry attrape certains échecs et re-lève les autres. Quelles erreurs devrait-elle réessayer ?
  3. Quel est le moyen le moins cher de voir ce que coûte réellement chaque appel ?
Key takeaways
  • Un appel de production, ce sont quatre disciplines superposées à la commande d'une ligne : secrets gardés hors des sources, sortie streamée, coût surveillé, erreurs gérées
  • Réessayez les échecs transitoires (429/5xx) avec backoff exponentiel plus jitter — et ne réessayez jamais un 400, qui est un bug de requête que vous devez corriger
  • Gardez l'ID du modèle en configuration pour que changer de modèle soit une ligne, pas un rechercher-remplacer à travers la codebase
  • Journalisez l'utilisation des tokens à chaque appel : c'est votre compteur de coût par requête et cela ne coûte rien à ajouter
  • Le streaming améliore la latence perçue ; les timeouts et un budget de coût/itérations empêchent les boucles agentiques de s'emballer

Suite