Introduction
Quand on demarre un produit IA conversationnel, la tentation est simple : brancher un modele, afficher une zone de chat, streamer la reponse et appeler ca un assistant. Pour une demo, ca marche. Pour un SaaS, ca casse vite.
Le probleme n'est pas seulement de faire parler le modele. Le vrai probleme est de transformer une conversation floue en donnees structurees, de rendre ces donnees visibles, de permettre a l'utilisateur de corriger, de persister les effets sans doublons, puis de produire un artefact final fiable. Dans le cas de VitamCV, cet artefact est un CV exportable, adapte a une offre, mais les questions d'architecture sont les memes pour beaucoup de SaaS IA.
Cet article ne cherche donc pas a dire “regardez mon SaaS”. Il part dans l'autre sens : si on veut construire un produit de chat conversationnel serieux avec Next.js, React et AI SDK, quelles difficultes apparaissent, et comment peut-on structurer le systeme pour ne pas se retrouver avec un simple wrapper de ChatGPT ?
Etude de cas reelle
VitamCV sert ici de terrain d'observation : un SaaS IA avec chat, generation de CV, scoring, validation humaine et exports DOCX/PDF. Pas une maquette, pas une demo jetable : un produit qui doit survivre aux vrais usages.
Tester le scanner gratuit VitamCVLe changement de modèle mental
Un chat IA devient un produit quand la conversation déclenche des états, des validations, des calculs et des sorties contrôlées.
- Le texte utilisateur est une entree non structuree.
- Les tools deviennent la frontiere entre langage et action.
- L'UI doit rendre visibles les effets du modele.
- Le systeme doit rester recuperable si le stream s'interrompt.
Le point de départ : un chat ne suffit pas
Un CV est un bon cas d'etude parce qu'il force plusieurs contraintes a cohabiter. Il faut extraire des donnees d'un document ou d'une conversation, detecter les informations faibles, poser des questions utiles, reformuler sans inventer, comparer le profil a une offre, puis produire un fichier final.
Si tout reste dans une bulle de chat, l'utilisateur ne sait pas ce qui est retenu, ce qui a ete modifie, ni ce qui sera utilise pour generer le document. L'experience devient impressionnante mais opaque. Le frontend doit donc jouer un role beaucoup plus important : il doit transformer le flux conversationnel en surface de controle.
C'est souvent la premiere claque quand on passe du prototype au produit : le modele peut etre bon, mais l'utilisateur ne fait pas confiance a une boite noire. Il veut voir ce qui change, comprendre pourquoi, et garder la main avant qu'un document parte dans la nature.
- Rapide a construire
- Impressionnant en demo
- Peu de design system
- Etat implicite
- Sortie difficile a auditer
- Peu de controle utilisateur
- •POC
- •Support simple
- •Brainstorming
- Progression visible
- Donnees persistantes
- Actions verifiables
- Architecture plus stricte
- Gestion des erreurs plus delicate
- Front plus exigeant
- •CV
- •Legal tech
- •Finance
- •Outils internes IA
Chat IA de démonstration | SaaS IA conversationnel |
|---|---|
Une entrée texte, une réponse streamée, peu de mémoire produit | Conversation, état durable, tools métier et UI spécialisée |
Avantages
| Avantages
|
Inconvenients
| Inconvenients
|
Cas d'usage
| Cas d'usage
|
La stack choisie et pourquoi
Le socle technique de VitamCV combine AI SDK, assistant-ui, Next.js Route Handlers, Zustand, Supabase, Zod et shadcn/ui. Chaque brique repond a une contrainte differente.
Les responsabilités par bloc
Le choix de stack devient plus clair quand on le lit par frontières de responsabilité.
- AI SDK : streaming, tool calling, messages UI et integration provider.
- assistant-ui : primitives de chat, composer, messages, ToolUI et integration AI SDK.
- Next.js : frontiere serveur pour le provider IA, les secrets, l'auth et la persistance.
- Zustand : etat client reactif pour le profil, les scores, les editions du panel et le Focus Mode.
- Supabase : source de verite durable, auth, RLS, documents et donnees utilisateur.
Sur Maxpaths, j'ai deja detaille le choix entre Redux, Context et Zustand dans l'article sur le state management React. Le cas VitamCV illustre bien pourquoi Zustand devient pertinent : l'etat ne sert pas seulement a afficher un theme ou une modale. Il synchronise un chat, un panneau editable, une preview CV, des scores, des edits en attente et des effets venant de tools IA.
Pour creuser les primitives citees dans cette architecture, les pages utiles sont la reference AI SDK streamText, le guide tools and tool calling et l'integration ToolUI d'assistant-ui.
1Conversation utilisateur2 -> assistant-ui Thread + Composer3 -> POST /api/chat (Next.js Route Handler)4 -> AI SDK streamText()5 -> tools métier typés6 -> Supabase pour la vérité durable7 -> Zustand pour la réactivité frontend8 -> panel profil + preview CV + score cardsCote React, assistant-ui sert surtout a donner une forme produit a la conversation : messages, composer, rendu ToolUI et, dans les versions recentes, logique de toolkit. Pour un article, le plus interessant n'est pas d'embarquer un vrai chat, mais de montrer le genre d'objet que l'utilisateur doit voir quand une action IA devient sensible.
Exemple visuel Assistant UI
ToolUIValidation de section
Experience professionnelle · source utilisateur conservee
Original
J'ai travaille sur des interfaces React et un assistant IA.
Proposition
Conception d'interfaces React conversationnelles connectees a des workflows IA securises et mesurables.
La difficulté front : qui possède l'état ?
Dans une app React classique, la question “qui possede l'etat ?” revient souvent. Dans une app IA conversationnelle, elle devient plus dure parce que plusieurs acteurs modifient le meme objet mental : l'utilisateur, le modele, les tools, le panneau d'edition, la base de donnees et parfois une reprise de conversation.
C'est la partie la moins spectaculaire a raconter, mais l'une des plus importantes a construire. Un mauvais decoupage d'etat donne une interface qui semble marcher, puis commence a mentir : un score qui ne correspond plus au profil, une preview en retard, un assistant qui felicite une correction qu'il n'a pas vraiment prise en compte.
Dans VitamCV, la reponse est volontairement double. Supabase reste la source durable : ce qui doit survivre au refresh, au retry, au document genere ou a la reconnexion finit cote serveur. Zustand gere la reactivite locale : ce qui doit changer instantanement dans le panel, la preview, les animations et les composants ToolUI passe par le store.
1// Modèle mental simplifié2type DurableState = {3 cvData: JsonResume;4 scores: Scores;5 targetJob: JobPosting | null;6 generatedDocuments: Document[];7};8
9type UiState = {10 focusedPanel: 'profile' | 'documents' | 'focus';11 pendingPanelEdits: PanelEdit[];12 highlightedSections: string[];13 conversationPhase: ConversationPhase;14};Ce decoupage evite deux extremes. Tout mettre dans le chat rend l'application opaque. Tout mettre directement en base rend l'experience lente et peu fluide. Le frontend a besoin d'un etat reactif pour donner un feedback immediat, mais cet etat doit rester reconcilie avec une verite durable.
Les phases conversationnelles
Un autre piege classique consiste a garder un seul system prompt pour toute la conversation. C'est confortable au debut, mais le modele se retrouve avec des objectifs contradictoires : accueillir, extraire, coacher, valider, scorer, generer. VitamCV utilise donc un system prompt dynamique par phase.
La phase est calculee depuis l'etat du profil. Elle ne sert pas a afficher une etape marketing, mais a changer les instructions envoyees au modele, la temperature et les tools pertinents.
1type ConversationPhase =2 | 'onboarding'3 | 'extraction'4 | 'exploration'5 | 'validation';6
7function computePhase(profile: CvData): ConversationPhase {8 if (!profile.name && filledSections(profile) === 0) return 'onboarding';9 if (filledSections(profile) < 2) return 'extraction';10 if (filledSections(profile) < 3 || skills(profile).length < 3) {11 return 'exploration';12 }13 return 'validation';14}- Ton humain
- Peu de contraintes
- Deux chemins clairs
- Ne doit pas déclencher trop tôt des tools
- •Premier message
- •Upload CV ou départ de zéro
- Temperature 0
- Tool calls immédiats
- Panel qui se remplit
- Peu de place pour le coaching
- •Parsing CV
- •Import de sections existantes
- Questions ciblées
- Méthode STAR
- Anti-imposter
- Risque de trop questionner si le flow est mal dosé
- •Achievements
- •Métriques
- •Skills implicites
- Temperature 0
- Fidélité
- Contrôle utilisateur
- Peut devenir long sans ToolUI clair
- •Work highlights
- •Projects
- •Summary
Onboarding | Extraction | Exploration | Validation |
|---|---|---|---|
Créer la confiance et choisir le chemin d’entrée | Sauvegarder vite les données disponibles | Chercher la valeur cachée et les preuves concrètes | Comparer original, proposition et version validée |
Avantages
| Avantages
| Avantages
| Avantages
|
Inconvenients
| Inconvenients
| Inconvenients
| Inconvenients
|
Cas d'usage
| Cas d'usage
| Cas d'usage
| Cas d'usage
|
Le detail important est l'escalade sans retour arriere. Une fois que l'utilisateur atteint une phase avancee, la conversation ne regresse pas simplement parce qu'il supprime une section dans le panel. Sinon, le modele peut redevenir incoherent : il recommence a poser des questions d'onboarding alors que l'utilisateur est deja dans une validation fine.
La synchronisation chat ↔ panel
Le pattern le plus important cote frontend est la synchronisation bidirectionnelle. Quand le modele appelle updateProfile, le panel doit se mettre a jour. Quand l'utilisateur corrige le panel, le modele doit le savoir au prochain tour.
1// Chat -> Panel2LLM appelle updateProfile({ section: 'work', data, source })3 -> résultat tool streamé4 -> ToolResultSync détecte le résultat5 -> useCvStore.setProfileWithSource(data, 'ai')6 -> panel + preview CV se mettent à jour7
8// Panel -> Chat9Utilisateur édite un champ10 -> store marque l'edit comme pending11 -> prochain POST /api/chat12 -> body() injecte panelEdits13 -> le LLM voit les corrections utilisateurCe n'est pas seulement un detail d'implementation. C'est ce qui permet au produit de ne pas mentir a l'utilisateur. Si le panel montre une chose et le modele raisonne sur une autre, la confiance disparait. Dans un CV, cette incoherence peut produire une phrase fausse dans un document final.
ToolUI : rendre les actions visibles
Le tool calling est souvent presente comme un sujet backend : le modele appelle une fonction. Dans une application conversationnelle, c'est aussi un sujet UI. Certains tools ne doivent pas seulement modifier un etat, ils doivent afficher une interaction.
C'est la partie ou les ToolUI assistant-ui deviennent utiles. Un appel tool peut se transformer en carte dans le chat : validation d'une section, score anime, analyse d'offre, comparaison avant/apres. L'IA ne reste pas une voix invisible ; elle produit des objets manipulables.
1const tools = {2 updateProfile, // effet durable : modifie le profil3 validateSection, // humain dans la boucle : original vs proposé4 analyzeJobPosting, // extrait les exigences d'une offre5 computeScore, // calcule un score explicable6 generateDocument, // produit DOCX ou PDF7};Pour la validation, VitamCV distingue les sections simples des sections narratives. Un nom, une langue ou un certificat peut etre confirme en texte. Une experience professionnelle ou un projet demande une vraie comparaison : texte original, version proposee, source, bouton accepter, modifier ou reformuler.
Le principe de fidélité
Chaque donnée importante doit pouvoir revenir à quelque chose que l'utilisateur a dit ou confirmé.
original: ce que l'utilisateur a donne ou ce que le CV contient.proposed: la reformulation professionnelle proposee.source: la trace vers l'information confirmee.updateProfile: appele apres validation, pas comme reflexe automatique sur tout texte genere.
Focus Mode : transformer, ne pas naviguer
Un SaaS IA conversationnel a besoin d'un moment ou l'utilisateur voit le resultat prendre forme. Pour VitamCV, ce moment est le Focus Mode : le panneau de droite s'agrandit en preview CV, pendant que le chat reste visible.
Ce moment compte presque autant que la qualite du texte genere. Quand le CV se remplit a cote de la conversation, l'utilisateur n'a plus l'impression de discuter avec une IA abstraite : il voit son parcours devenir un objet concret.
La decision UX importante est : transformer, ne pas naviguer. Une page separee de preview couperait le lien entre conversation et resultat. Une modale masquerait le chat. Un thumbnail serait trop petit pour creer la confiance. Le panneau qui grandit garde la meme geographie mentale : je parle a gauche, je vois mon CV se construire a droite.
1Normal mode2┌───────────────────────┬──────────────┐3│ Chat conversationnel │ Panel 420px │4│ │ Profil/Docs │5└───────────────────────┴──────────────┘6
7Focus Mode8┌──────────────┬────────────────────────┐9│ Chat ~35% │ Preview CV ~65% │10│ toujours │ scores + sections │11│ utilisable │ mises à jour en live │12└──────────────┴────────────────────────┘Ce pattern est tres frontend : transitions, reflow, scroll preservation, responsive, reduced motion, sections vides qui doivent paraitre intentionnelles. Une preview partiellement remplie ne doit pas sembler cassee. Elle doit dire : “voici ce qu'on a deja, voici ce qui manque”.
Scoring : ne pas laisser le LLM inventer le chiffre
Le scoring est un autre endroit ou une app IA peut devenir dangereuse. Demander au modele “donne un score a ce CV” produit souvent un chiffre plausible, mais difficile a expliquer. Dans VitamCV, le score est separe en plusieurs dimensions : match avec l'offre, coherence du CV, authenticite du texte et score global.
Le LLM peut aider a extraire ou normaliser des mots-cles. Mais le score final doit etre calcule par le systeme : overlap de mots-cles, presence de preuves, coherence temporelle, detection de keyword stuffing. C'est une decision produit autant qu'une decision technique.
1// Modèle de scoring simplifié2const vitamScore =3 matchScore * 0.5 +4 coherenceScore * 0.25 +5 authenticityScore * 0.25;6
7// Le LLM aide à normaliser.8// Le système calcule le score final.Pourquoi c'est important
Un score généré par le LLM peut sembler crédible. Un score calculé peut être expliqué, testé et amélioré.
- Le candidat comprend ce qui manque vraiment.
- Le produit evite de promettre une verite magique.
- Les tests peuvent couvrir les fonctions de scoring.
- Le frontend peut afficher les deltas et les causes du score.
Streams interrompus, retry et effets idempotents
Une difficulte moins visible apparait quand le produit devient reel : que se passe-t-il si le stream s'interrompt apres qu'un tool a deja modifie le profil ? Si l'utilisateur clique retry, faut-il rejouer le tool ? Si un document a ete genere ou un credit deduit, comment eviter le double effet ?
La reponse n'est pas purement frontend, mais le frontend en depend. Il doit pouvoir afficher un etat honnete : reponse interrompue, receipts de tools deja completes, bouton retry sur le bon turn, historique inerte, nouvelle conversation qui preserve le profil et les documents.
1Turn utilisateur2 -> assistant envelope durable3 -> tool call enregistré avec input hash4 -> effet métier appliqué une seule fois5 -> receipt durable6 -> retry réutilise le résultat7 -> pas de double mutationC'est le genre de sujet qui n'apparait jamais dans une demo de chat, mais qui decide si le SaaS peut encaisser les vrais usages : reseau instable, refresh, onglet ferme, generation longue, erreur provider, retry impatient.
Leçons frontend et IA
La lecon principale est que le frontend d'un SaaS IA ne se limite pas au rendu d'une conversation. Il porte une partie de la confiance. Il doit montrer les effets, separer ce qui est propose de ce qui est valide, permettre la correction, et rendre les erreurs recuperables.
En pratique, le “wow effect” ne vient pas seulement du modele. Il vient du moment ou l'interface rend le travail du modele lisible : une section qui s'illumine, une proposition que l'on peut refuser, un score qui bouge pour une raison explicable, un retry qui ne duplique pas les effets.
Les arbitrages qui ont le plus compté
Ce sont rarement les choix les plus visibles qui font tenir l'expérience.
- Phaser le prompt plutot que demander au modele de tout faire avec une seule instruction globale.
- Utiliser les tools comme contrats metier, pas comme simples helpers.
- Garder le chat et la preview dans le meme espace visuel.
- Synchroniser panel et conversation dans les deux sens.
- Calculer les scores critiques au lieu de les faire inventer.
- Penser retry, interruption et idempotence des le debut.
Checklist pour un SaaS IA conversationnel
Frontiere d action
Identifier quelles actions le modele a vraiment le droit de faire.
Contrats tools
Donner a chaque tool un schema d'input strict et une responsabilite unique.
Source de verite
Decider ce qui vit dans le store client et ce qui vit en base.
Actions visibles
Rendre les tool calls importants visibles dans l'interface.
Validation humaine
Prevoir une phase de validation humaine pour les contenus sensibles.
Traçabilite
Garder une trace de source pour les donnees reformulees.
Scores calcules
Eviter les scores inventes par le LLM quand un calcul est possible.
Retries propres
Gerer les streams interrompus et les retries sans rejouer les effets.
Etats partiels
Concevoir les etats partiels : profil vide, profil incomplet, erreur, reprise.
Documentation
Ajouter des liens documentaires clairs pour les technos structurantes.
Conclusion
Construire un SaaS IA conversationnel avec Next.js, React et AI SDK ne consiste pas a ajouter un chat sur une app existante. C'est concevoir un systeme ou le langage, l'etat, l'UI et les effets metier doivent rester coherents.
VitamCV sert ici de cas concret parce que le domaine force la rigueur : un CV contient des donnees personnelles, des formulations sensibles, des preuves a respecter, un scoring a expliquer et un document final a produire. Mais les patterns sont reutilisables ailleurs : assistants metier, outils internes, onboarding intelligent, audit documentaire, workflows RH ou legal tech.
Pour voir le principe cote utilisateur, le plus simple est de passer par le scanner gratuit VitamCV. C'est volontairement le point d'entree le moins frictionnel : on part d'un CV existant, puis on observe ce que le systeme peut extraire, scorer et expliquer.
Le bon critere n'est donc pas “est-ce que le modele repond bien ?”. C'est plutot : est-ce que le produit sait quoi faire de cette reponse, comment la montrer, comment la verifier, et comment recuperer quand le monde reel interrompt le joli stream de la demo ?