Avant que le modèle ne tourne
L'utilisateur fournit un prompt et un alias comme cheap, fast ou smart. Le serveur de production vérifie l'authentification, l'appartenance à l'espace et le droit avant d'accepter la tâche. Les ID de modèle et les secrets fournisseur restent derrière cette frontière — l'alias convivial est le seul vocabulaire de modèle dont le client ait jamais besoin, car la correspondance vers un vrai modèle de fournisseur relève de la configuration, pas du contrat.
Un enregistrement de tâche durable donne une identité à la requête avant que l'exécution en arrière-plan ne commence. Cette identité relie la soumission, le worker, les enregistrements d'usage et le résultat. Elle donne aussi à l'utilisateur un moyen de récupérer le travail après avoir navigué ailleurs.
L'ordre compte : le travail coûteux ne démarre qu'après le passage des contrôles bon marché. Vérifier l'authentification, l'appartenance et le droit avant toute mise en file empêche les requêtes non authentifiées ou non payées d'atteindre jamais un fournisseur — et rend l'échec explicable pour l'utilisateur. Le guide du module IA documente où vivent ces contrôles ; l'article sur les frontières d'espace de travail explique pourquoi l'appartenance est dérivée côté serveur plutôt que crue sur parole du client.
Décidez de quelles clés et de quelles limites il s'agit
Une fonctionnalité IA est une décision de dépense. supastack laisse les espaces apporter leurs propres clés fournisseur — stockées chiffrées, jamais exposées aux clients — ou tourner sur les clés de la plateforme, et applique des budgets par espace contre un catalogue de prix de modèles. Quelle que soit votre implémentation, les questions sont les mêmes : qui paie, et où la limite est-elle appliquée ?
L'application des limites appartient au workflow serveur, pas à une estimation côté navigateur. Un budget vérifié après la génération ne fait qu'enregistrer le dépassement ; vérifié avant le dispatch, il le prévient. La configuration des clés fournisseur couvre le côté paramétrage.
Rendez l'exécution explicite
Trigger.dev exécute le workflow ai.generate. Le routeur sensible aux capacités choisit un modèle selon la politique configurée et les exigences de la requête. Traitez cette politique comme une entrée opérationnelle : un alias indisponible ne doit pas apparaître comme un choix fonctionnel dans l'interface.
Une panne réseau pendant la soumission peut laisser le client incertain sur la mise en file du travail. Le chemin de production utilise une clé d'idempotence limitée à la tâche et une soumission sauvegardée pour que la reprise réutilise la requête originale. Envoyer une nouvelle tâche après chaque timeout risquerait travail et coût en double.
La durabilité est aussi ce qui garde l'interface simple : l'écran lit le statut de la tâche et l'affiche plutôt que d'orchestrer des retries. Quand la génération s'étale sur des appels de modèle, des étapes d'outils ou des planifications, le contrat de workflow explicite — enqueue, status, cancel — est ce qui garde « en cours » honnête.
Nommez les modes d'échec
Entre la requête et le résultat, il existe un ensemble précis et fini de choses qui tournent mal. Concevez pour chacune en la nommant plutôt que pour « les erreurs » dans l'abstrait — chaque tâche doit finir dans un état explicable : en file, en cours, en échec avec une raison, ou terminée avec un résultat. La reprise de tâches est la référence du kit pour le côté reprise.
L'exigence d'interface en dessous, c'est qu'aucun état ne peut mentir. Un spinner qui survit au travail, ou un message de succès pour une tâche qui n'a jamais tourné, c'est un ticket de support et un litige de facturation qui attendent d'arriver.
- Soumission en timeout — reprenez via la soumission sauvegardée et la clé d'idempotence bornée à la tâche au lieu de remettre en file.
- Fournisseur en échec en cours de tâche — marquez la tâche en échec avec une raison que l'interface peut afficher.
- Budget épuisé — rejetez avant le dispatch, pas après la dépense.
- Utilisateur parti naviguer ailleurs — l'enregistrement durable et l'URL de reprise restaurent statut et résultat.
Suivez ce qui s'est passé
La génération produit plus que du texte. L'application enregistre l'usage et un résultat de tâche, et l'interface lit le statut via l'API authentifiée. L'enregistrement d'usage est ce qui rend le budget applicable — il est écrit avant que le résultat ne soit renvoyé, pas estimé après.
L'e-mail de fin est une étape séparée avec des enregistrements de livraison séparés. Une réponse de modèle réussie n'établit pas qu'un e-mail a été livré. Garder ces résultats distincts rend les échecs plus faciles à expliquer et à réessayer sans relancer le modèle inutilement.
Le résultat a aussi besoin d'un domicile où l'utilisateur peut revenir : une page de tâche, une liste d'historique, une URL de reprise livrée dans cet e-mail de fin. Une génération qui n'existe que dans une notification transitoire est un travail qu'on vous demandera de produire deux fois.
Vérifiez chaque frontière
Utilisez des adaptateurs fake déterministes pour tester d'abord les décisions de l'application : accès refusé, alias désactivés, soumissions en double, reprise de résultat et erreurs génériques. Ces tests doivent tourner sans identifiants fournisseur.
Utilisez ensuite le processus de smoke fournisseur explicitement opt-in pour les vraies intégrations. Il exige la configuration sandbox documentée et une approbation pour faire des appels externes. La distinction garde le développement ordinaire rapide tout en rendant les preuves de production spécifiques et traçables.
Gardez cette séparation stable à mesure que le produit change : une couverture déterministe près de chaque décision de frontière, pour qu'un changement de fournisseur, de politique de routage ou un nouvel alias fasse échouer un test plutôt qu'un client.
Questions fréquentes sur les fonctionnalités IA en SaaS
Quelques questions reviennent dans chaque conversation sur l'IA derrière un paywall.
- Où l'autorisation des fonctionnalités IA doit-elle avoir lieu ? — Avant toute mise en file : authentifier, résoudre l'espace, vérifier le droit, puis créer la tâche. Les contrôles exécutés après la génération ne font que documenter l'abus.
- Ai-je besoin du bring-your-own-key ? — Si vos clients ont leurs propres relations avec les fournisseurs, oui : cela décide qui paie et qui possède les limites de débit. Stockez les clés chiffrées et gardez-les hors des clients — le guide de configuration IA couvre le modèle.
- Comment empêcher les retries de facturer en double ? — Bornez la clé d'idempotence à la tâche et réutilisez la soumission sauvegardée pendant la reprise, pour qu'un timeout ne puisse pas créer un second passage facturable.
- Quelles données d'usage dois-je enregistrer ? — Par tâche : modèle, unités consommées, coût contre le catalogue de prix, et l'espace — assez pour appliquer les budgets et répondre aux questions de dépense sans relancer les jobs.
- Quand la génération a-t-elle sa place dans un job en arrière-plan ? — Chaque fois qu'elle peut survivre à une requête. La latence des modèles, les retries et le travail multi-étapes plaident pour une exécution durable ; seuls les appels instantanés et bon marché restent en ligne.