Votre premier appel API en production (attentif aux coûts)
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
- Python
- TypeScript
import os, time, random, anthropic
client = anthropic.Anthropic()
MODEL = os.environ.get("CLAUDE_MODEL", "claude-sonnet-4-6")
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))
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic();
const MODEL = process.env.CLAUDE_MODEL ?? "claude-sonnet-4-6";
export async function askStream(prompt: string, system?: string, maxTokens = 1024) {
for (let attempt = 0; attempt < 5; attempt++) {
try {
const stream = client.messages.stream({ model: MODEL, max_tokens: maxTokens, system,
messages: [{ role: "user", content: prompt }] });
for await (const e of stream)
if (e.type === "content_block_delta") process.stdout.write(e.delta.text ?? "");
const final = await stream.finalMessage();
console.error(`\n[tokens in/out: ${final.usage.input_tokens}/${final.usage.output_tokens}]`);
return final;
} catch (e: any) {
if (attempt === 4 || ![429, 500, 529].includes(e?.status)) throw e;
await new Promise(r => setTimeout(r, Math.min(2 ** attempt * 1000, 30000)));
}
}
}
Étape 3 — Surveiller les coûts
- Journalisez l'utilisation des tokens (ci-dessus) pour voir ce que coûte chaque appel.
- Calibrez
max_tokenset 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
Lancez-le : vous devriez voir une sortie en streaming, une ligne d'utilisation des tokens et un comportement gracieux si vous forcez une erreur (par ex. une mauvaise clé → un message propre, pas un plantage).