Pourquoi les Edge Functions pour l'IA
Trois raisons pour lesquelles les Edge Functions sont le bon choix pour les appels API IA :
**1. Sécurité** : Votre clé API OpenAI/Anthropic vit comme un secret côté serveur, jamais exposé au client. Quiconque accède à votre code frontend ne peut pas extraire la clé. C'est une exigence absolue — une clé OpenAI exposée peut générer des factures de plusieurs milliers d'euros en quelques heures.
**2. Accès à la base de données** : Les Edge Functions s'exécutent dans l'infrastructure de Supabase et ont un accès direct et faible latence à votre base de données PostgreSQL. Vous pouvez récupérer le contexte utilisateur, stocker les résultats et logger l'utilisation dans la même fonction qui appelle l'IA.
**3. Support du streaming** : Les Edge Functions supportent le streaming de réponses (Response streaming), ce qui vous permet d'envoyer la sortie IA au client mot par mot — améliorant considérablement la performance perçue pour les longues réponses IA.
Fonction proxy OpenAI basique
La plus simple des Edge Functions : recevoir un prompt, appeler OpenAI, retourner la réponse.
La fonction importe le client OpenAI via npm, lit la clé API depuis les variables d'environnement Deno, reçoit le prompt en JSON, appelle `chat.completions.create` avec le modèle gpt-4o et un max_tokens de 500, puis retourne le résultat en JSON.
Déployez avec `supabase functions deploy openai-proxy`. Définissez les secrets avec `supabase secrets set OPENAI_API_KEY=sk-...`.
Pour les apps multilingues destinées au marché français, ajoutez un paramètre `language` à votre fonction et injectez la langue dans le system prompt. Vous pouvez également détecter automatiquement la langue de l'input utilisateur avec un appel préliminaire à GPT-4o mini (très peu coûteux) et adapter la réponse en conséquence.
Ajout de l'authentification et de la limitation de débit
Chaque Edge Function IA devrait vérifier que l'utilisateur est authentifié et contrôler ses limites d'utilisation.
Le pattern standard : 1. Extraire le token JWT du header Authorization 2. Créer un client Supabase avec la service role key 3. Appeler `auth.getUser(token)` pour valider l'authentification 4. Requêter la table `ai_usage_log` pour compter les appels des dernière heure 5. Retourner une erreur 429 si la limite est atteinte 6. Sinon, procéder à l'appel OpenAI et logger la nouvelle utilisation
Adaptez les limites selon votre modèle de tarification : plan gratuit = 10 requêtes/heure, plan pro = 100 requêtes/heure, plan enterprise = illimité. Cette granularité permet de construire un modèle de monétisation des fonctionnalités IA directement dans votre backend.
Streaming des réponses vers WeWeb
Le streaming envoie progressivement la sortie IA au client — les utilisateurs voient le texte apparaître mot par mot au lieu d'attendre la réponse complète.
Dans l'Edge Function, créez la complétion avec `stream: true`, puis wrappez le flux async dans un `ReadableStream` qui encode chaque chunk de texte et le transmet au client via une réponse de type `text/event-stream`.
Dans WeWeb, utilisez une action JavaScript personnalisée pour fetch l'URL du stream et mettre à jour une variable de page caractère par caractère au fur et à mesure de l'arrivée des chunks.
Le streaming améliore considérablement la perception de performance pour les générations de texte longues (rapports, analyses, articles). Pour les fonctionnalités où la réponse est courte (extraction de données, classification), le non-streaming est plus simple à implémenter et les performances perçues sont équivalentes.
Construire un pipeline RAG (Retrieval Augmented Generation)
Le RAG améliore les réponses IA en injectant des connaissances pertinentes dans le prompt au moment de la requête. Architecture :
**1. Ingestion des connaissances** (exécuté une fois) : Pour chaque document de votre base de connaissances, appelez l'API d'embeddings d'OpenAI pour obtenir un vecteur de 1536 dimensions. Stockez les vecteurs dans Supabase en utilisant l'extension pgvector.
**2. Au moment de la requête** : Quand un utilisateur pose une question, calculez l'embedding de la question (même API d'embedding), puis lancez une recherche par similarité dans Supabase : sélectionnez les documents les plus proches sémantiquement en utilisant l'opérateur de distance cosinus `<=>`, limitez aux 3 meilleurs résultats.
**3. Prompt augmenté** : Injectez les 3 documents correspondants dans le system prompt : "Réponds en utilisant uniquement le contexte suivant : [docs]. Si la réponse n'est pas dans le contexte, dis que tu ne sais pas."
Résultat : l'IA répond uniquement à partir de votre documentation, sans hallucination. Particulièrement utile pour les chatbots support en français où la précision terminologique est importante.