Alpha Digital
Brancher un générateur IA dans son SaaS sans casser l'expérience
Études & retours de prod 15 min de lecture

Brancher un générateur IA dans son SaaS sans casser l'expérience

Une feature IA générative dans un SaaS B2B est un standard. La câbler en synchrone, c'est la facture cachée. Le pattern à câbler avant la première ligne de prompt.

Brancher une IA générative dans un SaaS B2B, c'est devenu un standard de marché. En 2026, 29% du Fortune 500 et environ 19% du Global 2000 sont déjà clients payants d'une grande startup IA (a16z, 2026). Notion et Salesforce ont arrêté de facturer l'IA en option : elle est devenue table d'entrée pour rester dans le marché. Ajouter un assistant IA à votre produit ne vous différencie plus. Mal le câbler vous coûte.

Le piège est tentant : un appel API depuis un contrôleur, on attend la réponse, on affiche. Ça tient en démo. En production, ça casse au premier utilisateur qui demande un livrable un peu long, ou au premier pic de trafic. La latence d'une génération IA n'est pas compatible avec le temps d'attente d'une requête HTTP classique.

Ce que vous allez obtenir

✅ Pourquoi un appel IA synchrone casse votre produit dès qu'il sort du happy path
✅ Les 4 décisions d'infrastructure à prendre avant la première ligne de prompt
✅ Le pattern qu'on a câblé pour l'assistant IA de Redof, avec ce qu'on en retiendrait six mois plus tard
✅ Une checklist copiable pour cadrer votre prochaine feature IA générative

Temps de lecture estimé : 13 min

Pourquoi l'appel IA synchrone tue votre produit

Le premier réflexe d'un développeur pressé : prendre la clé OpenAI ou Anthropic, faire un appel HTTP dans le contrôleur, renvoyer la réponse au navigateur. Trois jours de travail. Bingo, c'est en ligne.

Puis le téléphone sonne. Un utilisateur a essayé de générer un document complet. Il a vu une roue tourner pendant 80 secondes, puis une erreur 524. Un autre a actualisé sa page par réflexe et a déclenché deux appels facturés. Un troisième est en réunion et a perdu son brouillon.

Le problème n'est pas le modèle. Le problème est que vous avez câblé une opération longue dans un canal pensé pour des opérations courtes.

Traduction simple

Une requête HTTP, c'est une conversation rapide entre le navigateur et votre serveur, conçue pour durer quelques secondes. Un LLM qui génère un document, c'est plusieurs dizaines de secondes voire minutes, parce que les tokens sortent les uns après les autres ([benchmark latence LLM 2026](https://www.kunalganglani.com/blog/llm-api-latency-benchmarks-2026)). Tenter de faire entrer le second dans le premier, c'est comme servir un menu gastronomique au drive : un des deux va casser.

Trois contraintes techniques expliquent pourquoi ça part en vrille en production.

D'abord, les passerelles ne vous laissent pas le temps. Cloudflare coupe par défaut à 100 secondes et renvoie une erreur 524 (documentation Cloudflare). Les load balancers AWS, les proxys nginx, les CDN ont des plafonds similaires, souvent non négociables. Vous ne contrôlez pas la fin de la chaîne.

Ensuite, l'API LLM elle-même tombe ou ralentit. Le temps avant premier token est en général sous la seconde, mais la durée totale est proportionnelle au nombre de tokens produits (benchmark TTFT et débit). Un long document = plusieurs minutes d'API. Un rate limit du provider = une erreur à mi-parcours. Sans reprise, c'est la génération à refaire en entier.

Enfin, votre utilisateur ne reste pas devant l'écran. Il change d'onglet, prend un appel, ferme son ordinateur. S'il revient et trouve un état nul ou un message d'erreur, vous l'avez perdu, et vous avez quand même payé le token.

Ce que ça change pour vous

"Vous lancez votre feature IA en deux semaines. Deux mois plus tard, vous découvrez que 30% des générations échouent côté utilisateur final, que votre facture API double parce que les gens relancent, et que le support reçoit le même ticket : 'J'ai perdu ce que j'avais commencé.' C'est la facture cachée de l'appel synchrone."

La file d'attente, premier réflexe à câbler

La bonne nouvelle : le pattern technique pour absorber ce type d'opération est connu depuis vingt ans dans les architectures de traitement d'image, d'export PDF, d'envoi d'emails massifs. Une file d'attente, des travailleurs en arrière-plan, et une notification quand c'est prêt.

L'utilisateur clique sur "générer". Le serveur empile la demande dans une file et répond immédiatement, en moins d'une seconde. Un processus dédié, qu'on appelle un worker, dépile, fait l'appel IA tranquillement, écrit le résultat en base. L'interface se met à jour, soit en interrogeant le serveur toutes les quelques secondes, soit via une connexion push.

C'est l'approche qu'on a prise pour Redof, notre plateforme de gestion d'événements et d'utilisateurs (redof.fr). L'assistant IA y génère des structures de contenu, des chapitres et des questionnaires (page produit). Tout passe par une file dédiée. L'interface n'attend rien. Le worker prend le temps qu'il faut.

❌ Mauvaise approche
Appel IA direct depuis le contrôleur HTTP, l'utilisateur attend devant sa page. Vous priez pour que la passerelle, le réseau, l'API et la patience du visiteur tiennent toutes en même temps.
Vous serez réveillé par les premiers tickets dès qu'un utilisateur essaiera un cas non trivial.
✅ Bonne approche
Le clic empile un travail dans une file dédiée IA. Le serveur répond en 200 ms avec un identifiant de job. Un worker dépile, appelle l'IA, écrit en base. L'interface poll ou reçoit un événement.
Aucun acteur de la chaîne n'est sous pression, ni la passerelle, ni l'API, ni l'utilisateur.

Deux décisions à prendre avant de coder.

Premièrement, dédier la file. Ne pas envoyer les jobs IA dans la même file que vos envois d'email transactionnel ou vos webhooks Stripe. Un long traitement IA va bloquer les courts. Dans le code de Redof, la file s'appelle ai-generation et possède son propre worker, avec un timeout long et un nombre de relances limité. Les autres files restent réactives.

Deuxièmement, configurer le worker pour absorber les coups durs. Timeout assez long pour laisser l'IA finir, par exemple 360 secondes. Deux tentatives en cas d'échec transitoire, pas plus, pour ne pas re-facturer indéfiniment un prompt qui ne passera jamais. Une trace écrite à chaque étape, pour que le support puisse expliquer pourquoi un job a échoué sans rejouer la conversation.

Troisième détail qui paraît mineur et qui ne l'est pas : prévoir une bascule de mise en pause de la file. Quand le provider IA a un incident, quand votre prompt produit soudain n'importe quoi, ou quand votre facture explose en milieu de mois, vous voulez pouvoir arrêter les nouvelles générations sans toucher au reste du produit. Une variable de configuration, une commande d'admin, ou une feature flag : peu importe la forme, c'est ce qui transforme un incident IA en alerte gérable plutôt qu'en arrêt d'urgence du produit.

Découper la génération en étapes spécialisées

Une fois la file en place, la deuxième tentation est de mettre tout dans un seul job géant : vous recevez la demande, vous générez la structure, les chapitres, les illustrations, les quiz, vous répondez. Vingt minutes plus tard, l'utilisateur a son brouillon.

Ne faites pas ça. Sept fois sur dix, ce qui échoue, c'est une étape sur cinq. Vous voulez pouvoir reprendre à la cinquième, pas tout recommencer.

Le bon découpage : un job par étape autonome, qui produit un résultat persistant, et qui déclenche l'étape suivante en empilant un nouveau job dans la file. C'est le pattern que Redof applique pour la génération pédagogique. Un job pour la structure d'ensemble. Un job pour le plan de chapitre. Un job pour le développement de section. Un job pour les visuels. Un job pour le quiz. Chacun écrit son résultat avant de céder la place.

Trois bénéfices concrets, et ils se cumulent.

L'éditabilité d'abord. Si l'utilisateur veut ajuster la structure avant que les chapitres soient développés, il peut. Le job suivant n'a pas encore tourné. Dans un monolithe, vous ne savez pas où vous en êtes.

La reprise ensuite. Une API timeout sur la génération d'un chapitre n° 3 sur 12 ? Vous relancez le job du chapitre 3, pas les douze. Vous économisez du temps et des tokens.

L'observabilité enfin. Vos logs vous disent quelle étape est lente, quelle étape échoue le plus, quel prompt coûte le plus cher. Vous optimisez par étape, pas en moyenne.

Et un bénéfice qu'on n'avait pas anticipé : la flexibilité du choix de modèle. Toutes les étapes n'ont pas besoin du même niveau de qualité. La structure d'ensemble mérite un modèle haut de gamme, le développement d'un paragraphe peut tourner sur un modèle plus rapide et moins cher. Quand les étapes sont des jobs distincts, vous changez de modèle par étape sans toucher au reste. Quand tout est dans un seul appel monolithique, vous payez le tarif le plus élevé sur l'intégralité du contenu.

⚠️ Le piège du découpage trop fin

Découper en trop d'étapes courtes alourdit l'orchestration et ralentit le résultat final. La règle pragmatique : un job par bloc de contenu cohérent que l'utilisateur peut éditer indépendamment, pas un job par appel IA. Si un job ne produit rien d'utile à l'utilisateur, c'est un bout d'un autre.

Le brouillon persistant côté UI, ce qui fait la différence

Vous avez votre file, vos jobs découpés, votre worker dédié. Ça tourne. Reste la moitié du problème : l'expérience utilisateur pendant que ça tourne.

Le réflexe naïf : un spinner et un message "Génération en cours, ne fermez pas cette fenêtre". L'utilisateur ferme la fenêtre. Toujours. Soit par accident, soit parce qu'il doit faire autre chose pendant trois minutes.

Le bon réflexe : persister l'état côté serveur, et reconstruire l'interface au retour. Quand l'utilisateur revient sur la page, il retrouve sa génération exactement où elle en était. Les chapitres déjà produits sont là, le chapitre en cours est marqué "en génération", les chapitres suivants sont en attente. S'il a déjà commencé à éditer un brouillon partiel, son édition n'est pas perdue.

C'est ce que fait Redof côté assistant IA. La fenêtre peut se fermer, l'ordinateur peut s'éteindre, la connexion peut sauter. Le job continue côté serveur, l'état est en base, et l'interface se rebranche dessus au retour.

Ce que ça change pour vous

"Le taux de complétion d'une feature IA double quand vous arrêtez d'imposer à l'utilisateur de rester devant l'écran. Vous économisez aussi sur la facture API : moins de relances par impatience, moins de tickets support, moins de générations partiellement faites et jetées."

Deux briques techniques pour y arriver.

D'abord, un état riche en base : pas juste "en cours" ou "fini", mais l'avancement réel, étape par étape, avec les résultats intermédiaires déjà obtenus. Une table dédiée par type de génération, ou un champ JSON structuré sur l'objet métier.

Ensuite, une interface qui sait afficher cet état. Pas un blocage global, mais une vue qui montre ce qui est là, ce qui arrive, ce qui reste à faire. L'utilisateur peut commencer à utiliser les morceaux déjà prêts pendant que les autres se génèrent.

Question récurrente côté front : polling toutes les 3 secondes ou connexion temps réel par WebSocket ? La réponse pragmatique pour une feature IA de SaaS B2B : polling au démarrage, vous passerez au temps réel quand le volume le justifiera. Le polling toutes les 3 à 5 secondes sur un endpoint qui répond en moins de 100 ms ne coûte presque rien, et il survit aux proxys d'entreprise capricieux qui bloquent parfois les WebSockets. Vous gardez la simplicité tant que vous le pouvez. C'est le pattern qui tourne sur Redof : du polling, sans drame.

Ce qu'on a appris en câblant l'assistant IA de Redof

Six mois après la mise en production de l'assistant IA de Redof (redof.fr/fonctionnalites/ia-assistant), trois enseignements qu'on n'avait pas anticipés.

Premier enseignement : isoler le service IA en couche réutilisable a payé tout de suite. On a découpé en services dédiés par usage : une couche pour la structure de contenu, une pour la planification, une pour les quiz, une pour l'enrichissement visuel. Chacune a son contrat et ses propres tests. Quand on a ajouté un quatrième cas d'usage, on a réutilisé les mêmes briques sans toucher au cœur. Le piège du service IA monolithique aurait coûté trois fois plus à étendre.

Deuxième enseignement : la facture grimpe vite si vous ne tracez pas. Compter les tokens consommés par job, par utilisateur, par fonctionnalité. Sans ça, vous découvrirez en fin de mois qu'un cas d'usage marginal pèse 40% du coût. On a ajouté ce comptage trois mois après la mise en prod et on a immédiatement coupé deux usages qui ne valaient pas leur prix. Ce n'est pas un sujet d'observabilité avancée, c'est une condition de survie économique : a16z note que la part des grands comptes qui passent au paiement à l'usage des features IA augmente chaque trimestre (a16z enterprise 2025), ce qui veut dire que le coût variable IA devient un poste de marge à part entière.

Troisième enseignement : les prompts vieillissent. Un prompt qui fonctionne en mars échoue en septembre parce que le modèle a évolué, ou qu'un cas d'usage utilisateur a glissé. Versionner les prompts, garder des exemples de sorties attendues, et tester en continu sur un jeu de cas représentatifs. Sinon vous découvrez les régressions par les tickets support.

Quatrième enseignement, plus humain : les utilisateurs ne veulent pas un texte fini, ils veulent un point de départ qu'ils peuvent corriger. Plus l'IA produit un résultat "trop fini", plus l'utilisateur a du mal à se l'approprier et plus il a tendance à tout réécrire. Calibrer la longueur et le niveau de détail de la sortie pour qu'elle invite à l'édition, c'est aussi important que la qualité du modèle. On a passé plus de temps à raboter les prompts qu'à les enrichir.

Cinquième enseignement, sur la priorisation : les premières demandes utilisateurs après la mise en prod portaient rarement sur la qualité du contenu généré. Elles portaient sur "puis-je revenir en arrière", "puis-je modifier juste cette section sans tout regénérer", "puis-je dupliquer un brouillon". La boucle d'édition autour de l'IA pèse plus dans la perception de qualité que l'IA elle-même. Prévoir cette boucle dès le cadrage, pas en correctif post-lancement.

La règle Alpha Digital

Avant la première ligne de prompt, vous écrivez le scénario d'échec. Que se passe-t-il si l'API tombe à mi-chemin ? Si l'utilisateur ferme l'onglet ? Si la facture explose ? Si le modèle est déprécié dans six mois ? Une feature IA générative qui n'a pas de réponse à ces quatre questions est un projet à risque, pas un produit.

Conclusion, par où commencer si vous avez le même chantier

Si vous êtes en train d'ajouter un assistant IA générateur à votre SaaS, la séquence à respecter ne change pas, qu'on soit fondateur, CTO, ou responsable produit.

D'abord, retirez l'appel IA du chemin synchrone. C'est non négociable, même pour la V1, même en démo client. Une file d'attente dédiée, un worker à part, et l'interface qui répond en 200 ms.

Ensuite, découpez la génération en étapes que l'utilisateur peut comprendre, et qui produisent chacune un résultat persisté. Pas de monolithe IA.

Enfin, traitez le brouillon comme un objet de première classe : il vit côté serveur, il se reconstruit côté interface, il survit à la fermeture du navigateur.

Checklist copiable : avant la mise en prod de votre feature IA

- [ ] L'appel IA est dans un job en file d'attente, pas dans un contrôleur HTTP
- [ ] La file IA est dédiée, séparée des envois d'email et des webhooks
- [ ] Le worker a un timeout adapté à la pire génération raisonnable
- [ ] Chaque étape autonome est un job distinct, qui persiste son résultat
- [ ] Le nombre de tentatives en cas d'échec est borné (2 ou 3 max)
- [ ] L'état d'avancement est en base, pas en mémoire
- [ ] L'interface reconstruit la vue au retour de l'utilisateur
- [ ] Les tokens consommés sont comptés par job et par utilisateur
- [ ] Les prompts sont versionnés et testés sur un jeu de cas représentatifs
- [ ] Une bascule simple permet de désactiver la feature si le coût dérape

Si ce chantier vous attend et que vous voulez un cadrage technique avant de partir, on fait des audits courts sur ces patterns. Décrivez-nous votre cas d'usage IA en deux paragraphes, on vous répond avec un plan d'attaque actionnable sous 48 heures.

Partager cet article