← Retour au blog Dev IA

Intégrer Claude API en production : ce que j'aurais aimé savoir avant

2 juil. 20267 min

J’ai intégré Claude API dans plusieurs projets en production — un SaaS de specs IA, un ERP artisan avec traitement vocal, un moteur de devis automatisé. Voici ce que je n’avais pas anticipé, et ce que je fais différemment maintenant.

Ne pas traiter l’API comme infaillible

Première erreur classique : écrire du code qui suppose que l’API répond toujours correctement. En production, les timeouts existent, les rate limits existent, les erreurs 529 existent.

Mon wrapper de base :

async function callClaude(params: MessageCreateParams, retries = 3): Promise<Message> {
  for (let attempt = 0; attempt < retries; attempt++) {
    try {
      return await anthropic.messages.create(params);
    } catch (err) {
      if (attempt === retries - 1) throw err;
      if (isRetryable(err)) {
        await sleep(exponentialBackoff(attempt));
        continue;
      }
      throw err;
    }
  }
  throw new Error('unreachable');
}

function isRetryable(err: unknown): boolean {
  // 529 = overloaded, 529 = rate limit
  return err instanceof APIError && [429, 529].includes(err.status);
}

Sans retry avec backoff exponentiel, un pic de charge Anthropic peut faire tomber votre feature.

Le streaming change l’UX, pas seulement la perf

Le streaming n’est pas qu’une optimisation de performance — c’est un choix UX. Un utilisateur qui voit le texte apparaître progressivement tolère 8 secondes. Le même utilisateur qui attend un spinner pendant 8 secondes abandonne à 3.

Pour Next.js, j’utilise les Server-Sent Events natifs :

// app/api/generate/route.ts
export async function POST(req: Request) {
  const stream = anthropic.messages.stream({
    model: 'claude-sonnet-4-6',
    max_tokens: 1024,
    messages: [{ role: 'user', content: await req.text() }],
  });

  return new Response(stream.toReadableStream(), {
    headers: { 'Content-Type': 'text/event-stream' },
  });
}

Modéliser les coûts avant de scaler

Le coût d’un LLM en prod n’est pas linéaire avec le nombre d’utilisateurs — il dépend de la longueur du contexte, du modèle, et du pattern d’utilisation.

Ce que je mesure sur chaque appel :

const usage = response.usage;
const cost = (usage.input_tokens * 3 + usage.output_tokens * 15) / 1_000_000; // Sonnet pricing

Sur un agent qui traite 100 documents par jour avec 4 000 tokens de contexte moyen, la différence entre Sonnet et Haiku est de ~€150/mois. Ça vaut la peine de réfléchir à la granularité du modèle par tâche.

Séparer les appels par complexité de tâche

Pattern que j’utilise maintenant sur tous mes projets : routing par complexité.

const model = task.complexity === 'high'
  ? 'claude-sonnet-4-6'
  : 'claude-haiku-4-5-20251001';

Extraction d’entités, classification, résumés courts → Haiku. Raisonnement complexe, génération de specs, analyse critique → Sonnet. Ça réduit les coûts de 60-70% sans dégradation visible pour l’utilisateur.

Gérer le contexte long sans exploser le budget

Sur l’ERP artisan, les conversations peuvent atteindre 20+ échanges. Envoyer tout l’historique à chaque appel multiplie les coûts par 10 rapidement.

Ma stratégie : fenêtre glissante + résumé de contexte.

function buildContext(messages: Message[], maxTokens = 8000): Message[] {
  const recent = messages.slice(-6); // 3 derniers échanges toujours présents
  const olderTokens = estimateTokens(messages.slice(0, -6));
  
  if (olderTokens > maxTokens) {
    const summary = await summarizeHistory(messages.slice(0, -6));
    return [{ role: 'user', content: `[Résumé conversation: ${summary}]` }, ...recent];
  }
  return messages;
}

Ce que je fais systématiquement maintenant

  • Logging de chaque appel : prompt, modèle, tokens, latence, coût estimé
  • Timeout explicite : 30s max, pas de requête qui pend indéfiniment
  • Validation du format de sortie avant de le passer au code aval
  • Alertes coût : notification si le spend dépasse un seuil journalier
  • Tests sur les edge cases : input vide, très long, en mauvaise langue

L’intégration d’une API LLM en production ressemble finalement à n’importe quelle intégration d’API externe — avec une couche de non-déterminisme en plus qui demande plus de tests et de monitoring.

SC

Stéphanie Caumont

Product Owner IA · En savoir plus