L'automatisation dans les opérations marketing a dépassé le stade du « send email on time ». Lorsque des LLM comme Claude 3.5 Sonnet arrivent en production, la vraie question n'est pas : en combien de secondes j'ai terminé le workflow, mais comment as-tu architecturé la gestion d'erreurs. La combinaison n8n + Claude API nous a permis de générer 200+ articles sans intervention manuelle — mais ce résultat provient d'une architecture solide d'idempotence, de stratégie de retry et de suivi d'état.

Définir un workflow autonome

Un workflow autonome est un système qui se termine de bout en bout sans intervention humaine. Si tu peux « lancer et oublier », c'est autonome. En opérations marketing, cela signifie : extraire des keywords de Google Search Console, les envoyer à Claude, récupérer le contenu, commit sur GitHub, gérer le versionnage — tout avec un seul déclencheur.

n8n joue le rôle d'orchestrateur. Il est déclenché par webhook, maintient l'état entre chaque étape, et active la logique de retry en cas d'erreur. Claude API est le générateur de contenu — mais tu dois architacter la génération sans contrôle manuel. Si tu hardcode le prompt dans n8n, chaque modification c'est 15 endroits à mettre à jour. Versionne ton prompt dès le départ.

Notre setup utilise une instance n8n self-hosted gratuite. Cinq nœuds de workflow : webhook trigger, HTTP request (Claude API), data transformation, GitHub API commit, Supabase logging. Temps total : 3 minutes — 90 secondes pour que Claude génère 1500 mots, le reste en I/O.

Idempotence : même input, même output

L'idempotence garantit que relancer la même opération plusieurs fois produit le même résultat. Avec les LLM, ce n'est pas naturel — le même prompt produit différentes outputs. Mais ton système de fichiers et ta logique de commit doivent être idempotents.

Notre approche : chaque contenu est lié à un identifiant unique (i18nKey). Le format : {category}-{seq}-{YYYY-MM}. Le workflow n8n génère cette clé, la transmet à Claude et construit le chemin du fichier. Si le même keyword est déclenché une deuxième fois, on vérifie dans Supabase — s'il existe : SKIP, sinon : PROCESS.

// n8n Function node — vérification idempotence
const existingRecord = await $('Supabase').first().json.data.find(
  (r) => r.i18n_key === $json.i18nKey
);
if (existingRecord) {
  return { skip: true, reason: 'already_published' };
}
return { skip: false };

Pour les commits GitHub, on vérifie aussi le nom du fichier. Si le fichier existe : 409 Conflict, le nœud de gestion d'erreur capture cela et le log — le workflow ne s'arrête pas. Avec un batch de 50 keywords, si 3 sont déjà générés, on ne traite que les 47 restants.

Claude API : versionnage du prompt et budget token

En production, le point critique est la stabilité du prompt. Si tu le hardcode dans n8n, chaque itération demande une édition manuelle. À la place, stocke le prompt sur GitHub en fichier Markdown, récupère-le via une URL brute.

Notre setup : le fichier prompts/roibase-master-fr.md est stocké sur GitHub. Un nœud HTTP Request de n8n récupère cette URL, son contenu devient le message SYSTEM envoyé à Claude. Le message USER est rempli dynamiquement — keyword, catégorie, liste de liens internes, date du jour.

{
  "model": "claude-3-5-sonnet-20241022",
  "max_tokens": 200000,
  "system": "{{$node['Fetch_Prompt'].json.content}}",
  "messages": [
    {
      "role": "user",
      "content": "KEYWORD: {{$json.keyword}}\nCATEGORY: {{$json.category}}\n..."
    }
  ]
}

Budget token : Claude 3.5 Sonnet a une fenêtre contextuelle de 200K tokens. Notre prompt master consomme 8K tokens (directives principales + guides par catégorie), le message USER ~500 tokens, l'output de Claude en moyenne 2.5K tokens (1500 mots). Total : ~11K tokens, soit $0.04 par exécution en pricing par batch. 200 articles = $8 de coût API.

Gestion d'erreurs : retry, fallback et state logging

Avec les LLM, trois classes d'erreurs existent : temporaires (rate limit), permanentes (output malformé) et inattendues (timeout réseau). n8n ne peut pas les distinguer automatiquement — c'est toi qui conçoit la stratégie de retry.

Notre approche : chaque nœud a des paramètres de retry activés. Le nœud HTTP Request (Claude API) a retryOnFail: true, maxRetries: 3, waitBetweenTries: 5000ms. Un rate limit (429) déclenche un backoff exponentiel. Si les 3 tentatives échouent, un nœud de gestion d'erreur prend le relais — on écrit un log failed_generation dans Supabase, le workflow s'arrête, mais le traitement des autres keywords continue.

Pour les outputs malformés (Claude génère moins de 1400 mots ou le frontmatter manque), un nœud de validation les intercepte. On parse le JSON, vérifie readingTime et title. Si la validation échoue, on renvoie un message à Claude : « regenerate with stricter length constraint » — cette fois, le paramètre max_tokens augmente. Deuxième échec ? la tâche passe en révision manuelle.

Le state logging dans Supabase suit ce schéma :

ChampTypeDescription
i18n_keytextIdentifiant unique
keywordtextRequête GSC
statusenumpending, generated, failed
retry_countintNombre de retries
error_logjsonbDétails des erreurs
created_attimestampMoment du premier run
completed_attimestampMoment de fin (null si en cours)

Cette table sert au monitoring et au debugging. Sur Grafana, les enregistrements avec retry_count > 2 remontent au dashboard — tu vois quels keywords bloquent Claude.

Expérience production : 200+ articles, 4% de failure rate

Les 50 premiers articles ont été générés sous supervision. Les 150 suivants, complètement autonomes. Résultats :

  • Taux de succès : 96% (192/200)
  • Temps moyen de completion : 3.2 minutes
  • Rate limit hit : 7 fois (tous résolus avec retry)
  • Intervention manuelle requise : 8 articles (output malformé + keyword ambigu)

Moitié des défaillances viennent de keywords trop génériques (« marketing digital »). Claude sur ce type de requête génère du contenu de remplissage pour atteindre 1500 mots — le nœud de validation le détecte mais la régénération n'aide pas. Solution : blacklist du keyword.

L'autre moitié : GitHub API retourne 409 Conflict (fichier existe mais pas d'enregistrement Supabase — race condition). Fix : écrire un statut pending dans Supabase AVANT de commit sur GitHub, puis passer à generated après succès. Le taux est tombé de 4% à 1.5%.

Profil de latence : 90 secondes Claude API, 45 secondes commit GitHub (gros fichiers Markdown), 15 secondes Supabase write, 30 secondes processing interne n8n. Goulot : Claude — mais pas besoin de paralléliser (rate limit). Traitement par batch : 10 keywords/heure, 240 keywords/jour de capacité.

Trade-offs : ce qu'on a gagné, ce qu'on a perdu

Construire un workflow autonome impose trois trade-offs majeurs :

  1. Qualité vs vitesse : La qualité de Claude dépend du tuning du prompt. Version 1 : 40% de rejet — on ajoute « 1400-1600 mots OBLIGATOIRE » et ça tombe à 4%. Mais Claude surcharge parfois avec du contenu inutile. Un éditeur humain le voit, pas l'IA.
  2. Coût vs fiabilité : Une logique de retry agressive consomme plus de tokens. Initialement, chaque retry envoyait le prompt complet (8K × 3 = 24K tokens). Maintenant on envoie juste le USER message, le SYSTEM est en cache (prompt caching — feature de Claude mai 2025). Coût divisé par 2.4.
  3. Flexibilité vs complexité : On voulait des prompts distincts par catégorie (AI plus technique, Marketing plus business-focused). Cela fait 6 fichiers à maintenir — versionnage cauchemardesque. Solution : un prompt master + bloc CATEGORY_GUIDANCE injecté dans le USER message. Complexité augmente mais flexibilité gagnée.

Futur : multi-agent et self-healing

L'architecture actuelle est single-agent — Claude travaille seul. Prochaine itération : multi-agent — un agent génère, un autre review, un troisième optimise pour le SEO. n8n supporte les sub-workflows mais le coût token triple.

Le self-healing : quand le workflow échoue, analyser la cause racine et se corriger automatiquement. Par exemple, si Claude génère des contenus courts en continu, modifier le prompt pour « augmenter la longueur de l'output », réessayer. C'est une méta-optimisation — l'LLM évoluant son propre prompt. Dangereux mais puissant.

Dans le travail de Roibase sur l'Architecture Première Partie & Mesure, on applique une approche similaire : collecter les signaux de conversion de façon autonome, détecter les anomalies, auto-corriger. En production, le principe fondateur reste : architecturer la gestion d'erreurs dès le départ, logger l'état, rendre la retry logic idempotente.