Skip to main content
📝 Outils d'IA

J'ai construit une appli IA premium avec Gemini Embeddings et le RAG

Créez une app IA premium avec Gemini embeddings et RAG. Gère les PDF avec diagrammes, contenu multimodal et compréhension réelle des documents.

30 min

Temps de lecture

5,938

Mots

Mar 21, 2026

Publié

Engr Mejba Ahmed

Écrit par

Engr Mejba Ahmed

Partager l'article

J'ai construit une appli IA premium avec Gemini Embeddings et le RAG

J'ai construit une appli IA premium avec Gemini Embeddings et le RAG

Le PDF contenait des diagrammes. Pas des descriptions textuelles de diagrammes — de vrais flowcharts, des visuels d'architecture, des captures d'écran annotées. Tous les modèles d'embedding que j'avais testés avant les auraient complètement ignorés, en indexant uniquement le texte environnant et en laissant l'information visuelle sur le carreau. Alors quand j'ai uploadé ce même PDF dans un index Pinecone en utilisant le modèle Gemini Embedding 2 de Google et posé une question sur un diagramme spécifique enfoui trois pages plus loin, je m'attendais aux hallucinations habituelles.

Au lieu de ça, il a extrait le contexte exact du diagramme. Il a référencé les flèches. Il a compris le flux.

Je me suis adossé à ma chaise et j'ai fixé mon terminal pendant dix bonnes secondes. C'est à ce moment-là que j'ai su que ce projet allait être différent de toutes les applis RAG que j'avais livrées avant. Pas un peu mieux. Fondamentalement différent — parce que le modèle d'embedding comprenait enfin plus que de simples mots.

Ce qui a suivi, c'est un processus en cinq étapes pour construire une application IA premium, responsive mobile, avec un chat dynamique, une récupération de connaissances dotée de mémoire, et une ingestion de contenu multi-format. Le genre d'appli que tu peux remettre à un client et facturer pour de vrai. Je vais te guider à travers chaque étape, y compris les moments où ça a cassé et les décisions que je prendrais différemment la prochaine fois.

Mais d'abord, tu dois comprendre pourquoi Gemini Embedding 2 change la donne sur ce qui est possible avec le RAG — et pourquoi construire ce type d'appli était franchement douloureux avant mars 2026.

Pourquoi Gemini Embedding 2 réécrit les règles du RAG

Le RAG — Retrieval Augmented Generation — est le pattern de référence pour donner de la mémoire aux applis IA. Le concept est simple : au lieu de fourrer une base de connaissances entière dans un prompt (cher, lent et limité par les fenêtres de contexte), tu découpes les documents en morceaux, tu convertis ces morceaux en vecteurs numériques, tu les stockes dans une base de données vectorielle, et tu ne récupères que les parties pertinentes quand un utilisateur pose une question. L'IA reçoit précisément le contexte dont elle a besoin sans tout traiter.

Le problème a toujours été l'étape d'embedding. Avant Gemini Embedding 2, les modèles d'embedding étaient uniquement textuels. text-embedding-3-large d'OpenAI, les modèles de Cohere, même le text-embedding-004 de Google — ils traitaient tous les mots et ignoraient tout le reste. Si ta base de connaissances contenait des images, des diagrammes d'architecture, des walkthroughs vidéo ou des enregistrements audio, tu avais deux options : tout transcrire manuellement en texte (en perdant les nuances et le contexte visuel), ou accepter que ton système RAG soit aveugle à la moitié de tes données.

Gemini Embedding 2 est passé en preview publique le 10 mars 2026, et il a éliminé ce compromis entièrement. Construit nativement sur l'architecture Gemini, il projette le texte, les images, la vidéo, l'audio et les PDF dans un espace vectoriel unique de 3 072 dimensions. Un seul modèle. Un seul espace d'embedding. Tout recherchable ensemble.

Les benchmarks confirment. Sur MTEB English, il obtient un score de 68,32 — en tête avec 5,09 points d'avance sur le concurrent suivant. Mais les benchmarks ne construisent pas des applis. Ce qui compte, c'est ce qui se passe quand tu lui fournis un manuel produit de 40 pages avec des captures d'écran, que tu le connectes à Pinecone, et que tu poses la question d'un utilisateur. C'est là que le vrai test commence.

Voici à quoi ressemble un pipeline RAG multimodal comparé à l'ancienne approche texte uniquement :

Capacité Embeddings texte uniquement Gemini Embedding 2
Documents texte Oui Oui
PDF avec images/diagrammes Texte uniquement — images ignorées Compréhension multimodale complète
Contenu vidéo Nécessite d'abord une extraction de transcription Embedding vidéo natif
Fichiers audio Nécessite un prétraitement speech-to-text Embedding audio direct
Recherche cross-modale Impossible Une requête texte retrouve les images, l'audio et la vidéo pertinents
Dimensions d'embedding Variable (1 536 - 3 072) 3 072 (espace unifié)
Langues supportées Dépend du modèle 100+ langues nativement

C'est la ligne de recherche cross-modale qui change tout. Une requête texte comme « montre-moi le flux d'authentification » peut désormais retrouver un diagramme, un timestamp vidéo ou un snippet de code — selon ce qui est le plus pertinent — à partir d'un seul index unifié. Pas de pipelines séparés. Pas besoin de combiner des résultats provenant de différents modèles d'embedding.

La stack technique sur laquelle je me suis arrêté pour ce projet raconte comment ces pièces s'assemblent. Et l'ordre compte — chaque choix d'outil contraignait le suivant d'une manière que je n'ai pleinement appréciée qu'une fois plongé dans l'implémentation.

Le framework en cinq étapes : de l'écran vide au SaaS déployé

J'ai adapté un framework de Jack Roberts qui découpe le développement d'applis IA en cinq phases distinctes. Pas parce que j'adore les frameworks — j'en ai vu trop qui ajoutent du process sans ajouter de valeur — mais parce que celui-ci colle proprement aux décisions réelles auxquelles tu seras confronté. Chaque étape produit un livrable qui alimente la suivante.

Voici la stack avant de commencer à construire :

Composant Outil Pourquoi celui-là
Design UI & Prototypage Lovable Génère du React + Tailwind production-ready à partir de langage naturel, livré avec intégration Supabase
Intégration de code & Débogage Anti-Gravity IDE + Claude Code IDE agent-first avec l'accès terminal de Claude Code pour le câblage API
Base de données vectorielle Pinecone Support natif des vecteurs à 3 072 dimensions, scaling serverless, filtrage par métadonnées
Modèle d'embedding Gemini Embedding 2 Embeddings multimodaux pour texte, images, vidéo, audio et documents
Automatisation & Scheduling Railway Cron jobs pour l'ingestion automatisée de connaissances, tarification à l'usage à partir de 5 $/mois
Données utilisateur & Auth Supabase Auth basée sur Postgres, abonnements temps réel, sécurité au niveau des lignes
Tests Test UI (anciennement LambdaTest) + Kane AI Tests automatisés cross-browser avec simulation de flux utilisateur pilotée par IA
Déploiement Vercel Déploiements connectés à Git, edge functions, domaines personnalisés

Maintenant, laisse-moi te raconter chaque étape telle qu'elle s'est réellement passée — pas la version propre, la vraie.

Étape 1 : Fondations et architecture — Construire l'UI avec Lovable

J'ai commencé par Lovable parce que je voulais prioriser la qualité du design dès le départ. La plupart des tutos d'applis IA produisent des applis qui ont l'air d'avoir été construites par un développeur backend à 2h du matin — fonctionnelles mais visuellement douloureuses. Pour un produit SaaS destiné aux clients, l'UI doit donner une sensation premium dès la première interaction.

Lovable génère des applications full-stack à partir de prompts en langage naturel. Tu décris ce que tu veux, et il produit des composants React avec Tailwind CSS, câblés à un backend Supabase. Le tier gratuit te donne 5 messages par jour (30 mensuels max), c'est serré mais utilisable pour un build initial. Le plan Starter à 25 $/mois pour 100 crédits, c'est là que se retrouvent la plupart des builders sérieux.

Mon prompt initial était spécifique — pas « construis-moi une appli de chat » mais une description détaillée du layout du tableau de bord, incluant un écran de connexion avec des transitions animées, une interface de chat principale pour interroger la base de connaissances, et une section de notes en style Kanban pour sauvegarder et organiser les insights. J'ai spécifié le support des modes clair et sombre, des effets de confetti au premier login, et des contrastes de couleurs spécifiques pour l'accessibilité.

La première génération m'a donné environ 80 % de ce que je voulais. L'interface de chat était propre. Le tableau Kanban fonctionnait. Le flux de connexion avait des transitions fluides. Mais l'espacement était décalé sur mobile, le mode sombre avait des problèmes de contraste sur deux composants, et l'animation de confetti se déclenchait à chaque chargement de page au lieu du premier login uniquement.

Voici ce que j'ai appris sur le prompting efficace avec Lovable : traite chaque raffinement comme une instruction ciblée, pas comme une demande de refonte. Au lieu de « corrige le layout mobile », j'ai dit « réduis le padding du conteneur de messages de chat de 24px à 16px sur les écrans en dessous de 640px, et empile les colonnes Kanban verticalement sur mobile avec un gap de 12px ». Des prompts spécifiques produisent des corrections spécifiques. Des prompts vagues produisent de nouveaux problèmes.

Après quatre rounds d'itération — chacun ciblant un seul problème — j'avais une UI que je montrerais vraiment à un client. L'export vers GitHub s'est fait en un clic. À ce stade, la couche visuelle était terminée et je n'avais pas touché un éditeur de code.

Mais une belle UI sans cerveau derrière, c'est juste une maquette. L'étape suivante — câbler Gemini embeddings et Pinecone dans le backend — c'est là que ce projet devient intéressant. Et là que les choses ont commencé à casser.

Étape 2 : Connecter les embeddings et construire le cerveau de la connaissance

C'est l'étape qui sépare une démo d'un produit. J'ai cloné le repo généré par Lovable depuis GitHub dans Anti-Gravity IDE, l'environnement de développement agent-first de Google construit à partir du travail de l'ancienne équipe Windsurf. Anti-Gravity maintient seize agents spécialisés — des spécialistes frontend, des architectes backend, des auditeurs de sécurité — mais celui qui compte ici, c'est Claude Code, qui tourne dans le terminal intégré avec un accès complet au système de fichiers.

Pourquoi Claude Code dans Anti-Gravity plutôt que Claude Code en standalone ? Deux raisons. Premièrement, le navigateur intégré d'Anti-Gravity te permet de vérifier visuellement les changements en temps réel sans changer de fenêtre. Deuxièmement, le système de compétences d'agents signifie que Claude Code gère le câblage backend pendant que l'agent frontend d'Anti-Gravity détecte les régressions visuelles. Ils se complètent au lieu de dupliquer les efforts.

La première tâche : connecter Pinecone comme base de données vectorielle. Le tier serverless de Pinecone gère les 3 072 dimensions que Gemini Embedding 2 produit, et leur filtrage par métadonnées te permet de cadrer les requêtes par type de document ou date d'upload — crucial pour une base de connaissances qui grandit au fil du temps.

J'ai demandé à Claude Code de configurer le client Pinecone, de créer un index avec les bonnes dimensions et la métrique de similarité cosinus, et de le câbler à une route API dans l'appli Next.js. Le code qu'il a généré était fonctionnel du premier coup. Voici le coeur du flux d'embedding et d'upsert :

// lib/embeddings.ts
import { GoogleGenerativeAI } from "@google/generative-ai";
import { Pinecone } from "@pinecone-database/pinecone";

const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY!);
const pinecone = new Pinecone({ apiKey: process.env.PINECONE_API_KEY! });

// Gemini Embedding 2 model - supports text, images, video, audio, PDFs
const embeddingModel = genAI.getGenerativeModel({
  model: "gemini-embedding-exp-03-07"
});

export async function embedAndStore(
  content: string,
  metadata: Record<string, any>,
  namespace: string = "default"
) {
  const index = pinecone.index(process.env.PINECONE_INDEX!);

  // Generate embedding - 3,072 dimensions
  const result = await embeddingModel.embedContent(content);
  const embedding = result.embedding.values;

  // Upsert to Pinecone with metadata for filtering
  await index.namespace(namespace).upsert([{
    id: `doc_${Date.now()}_${Math.random().toString(36).slice(2)}`,
    values: embedding,
    metadata: {
      ...metadata,
      timestamp: new Date().toISOString(),
      contentPreview: content.slice(0, 200)
    }
  }]);
}

export async function queryKnowledge(
  query: string,
  topK: number = 5,
  filter?: Record<string, any>
) {
  const index = pinecone.index(process.env.PINECONE_INDEX!);

  const queryEmbedding = await embeddingModel.embedContent(query);

  const results = await index.namespace("default").query({
    vector: queryEmbedding.embedding.values,
    topK,
    includeMetadata: true,
    filter
  });

  return results.matches?.map(match => ({
    score: match.score,
    content: match.metadata?.contentPreview,
    source: match.metadata?.source,
    type: match.metadata?.contentType
  }));
}

La stratégie de découpage compte bien plus que la plupart des tutos ne l'admettent. J'ai découpé les documents en chunks de 512 tokens avec un chevauchement de 50 tokens. Trop petit et tu perds le contexte. Trop grand et tu gaspilles des tokens sur du contenu non pertinent lors de la récupération. Le chevauchement de 50 tokens garantit que tu ne coupes pas accidentellement une phrase critique entre deux chunks en en perdant le sens.

Pour les PDF en particulier, j'ai utilisé une approche en deux passes. Première passe : extraire le contenu textuel par page. Deuxième passe : extraire les images et les diagrammes, les embedder séparément avec des métadonnées de numéro de page, et stocker les chunks texte et visuels dans le même namespace Pinecone. C'est là que la capacité multimodale de Gemini Embedding 2 paye — les chunks visuels vivent dans le même espace vectoriel que les chunks texte, donc une seule requête peut remonter les deux.

Le premier vrai test : j'ai uploadé un manuel produit de 40 pages qui incluait des diagrammes d'architecture, des captures d'écran d'UI et des tableaux de référence API. Puis j'ai demandé à l'interface de chat : « Comment fonctionne le flux d'authentification ? » Le système a récupéré trois chunks de texte décrivant le processus OAuth et — c'est la partie qui m'a bluffé — un chunk image contenant le vrai diagramme du flux d'authentification de la page 12. La récupération multimodale a fonctionné du premier coup.

Je ne vais pas prétendre que tout s'est passé sans accroc. Le composant de scraping YouTube a nécessité trois tentatives. Ma première approche utilisait youtube-transcript-api pour récupérer les transcriptions, mais elle échouait silencieusement sur les vidéos qui n'avaient que des sous-titres auto-générés dans des langues non anglaises. La deuxième tentative a ajouté la détection de langue et une logique de fallback. La troisième a ajouté une vérification de déduplication contre les métadonnées de Pinecone pour éviter de ré-embedder des vidéos déjà dans la base de connaissances.

// lib/youtube-ingestion.ts
async function ingestYouTubeVideo(videoUrl: string) {
  const videoId = extractVideoId(videoUrl);

  // Check if already ingested
  const existing = await queryKnowledge("", 1, {
    videoId: { $eq: videoId }
  });

  if (existing && existing.length > 0) {
    console.log(`Video ${videoId} already in knowledge base, skipping.`);
    return;
  }

  const transcript = await fetchTranscript(videoId);
  const chunks = chunkText(transcript, 512, 50);

  for (const chunk of chunks) {
    await embedAndStore(chunk.text, {
      source: videoUrl,
      videoId,
      contentType: "youtube_transcript",
      chunkIndex: chunk.index
    });
  }
}

Cette vérification de déduplication — interroger les métadonnées de Pinecone avant d'embedder — m'a évité un problème qui aurait été invisible au début et catastrophique à grande échelle : des vecteurs dupliqués qui diluent la qualité de recherche. À chaque exécution de l'auto-updater, il vérifie ce qui existe déjà avant d'ajouter quoi que ce soit de nouveau. Logique simple, facile à oublier, coûteuse à corriger après coup.

À ce stade, l'appli avait une UI fonctionnelle, une base de connaissances connectée avec du RAG multimodal, et la capacité d'ingérer des PDF et du contenu YouTube. Ce qu'elle n'avait pas, c'était un moyen de rester à jour sans que je lance manuellement des scripts d'ingestion. C'est ce que l'Étape 3 résout — et c'est l'étape que la plupart des tutos zappent complètement.

Étape 3 : Le système de mise à jour automatique qui garde la base de connaissances fraîche

Une base de connaissances qui arrête de grandir le jour où tu la livres est une dette, pas une fonctionnalité. Les utilisateurs s'attendent à des informations actuelles. Si ton appli RAG renvoie encore des résultats de données que tu as uploadées il y a deux mois alors que le monde a avancé, la confiance s'érode vite.

J'ai utilisé Railway pour la couche d'automatisation. Railway supporte trois types de compute : les services persistants, les cron jobs et les fonctions serverless. C'est la capacité de cron job qui compte ici — elle te permet d'exécuter un script selon un planning, de ne payer que le temps d'exécution, et de s'arrêter proprement entre les exécutions.

La configuration : un service Node.js sur Railway qui tourne tous les jours à 3h UTC. Il vérifie une liste configurée de chaînes YouTube pour les nouvelles vidéos publiées depuis la dernière exécution, scrape les transcriptions, les découpe en chunks, et les upsert dans Pinecone. Le processus entier prend environ 90 secondes pour un volume typique de contenu quotidien, ce qui coûte des fractions de centime avec la tarification à l'usage de Railway.

// workers/daily-ingestion.ts
import { CronJob } from "cron";

async function dailyIngestion() {
  const channels = process.env.YOUTUBE_CHANNELS!.split(",");
  let newVideos = 0;

  for (const channelId of channels) {
    const recentVideos = await fetchRecentVideos(channelId, {
      publishedAfter: getLastRunTimestamp()
    });

    for (const video of recentVideos) {
      await ingestYouTubeVideo(video.url);
      newVideos++;
    }
  }

  console.log(`Ingested ${newVideos} new videos.`);
  await updateLastRunTimestamp();

  // Railway cron jobs expect the process to exit cleanly
  process.exit(0);
}

dailyIngestion();

Le plan Hobby de Railway inclut 5 $ d'usage par mois. Pour un cron job quotidien qui tourne pendant 90 secondes, tu utiliseras environ 0,50-1,00 $ par mois en compute — bien dans l'enveloppe incluse. L'intervalle le plus court que Railway supporte est de 5 minutes entre les exécutions, et les plannings tournent en UTC, donc planifie tes horaires en conséquence.

Une décision de design que je prendrais différemment : j'avais initialement stocké le timestamp « dernière exécution » dans un fichier local sur le service Railway. C'est fragile — si le service est redéployé, le fichier disparaît, et la prochaine exécution re-traite tout. J'ai déplacé le timestamp dans une table Supabase, qui persiste à travers les déploiements et me donne un log interrogeable de chaque exécution d'ingestion. Petit changement, grosse amélioration de fiabilité.

L'automatisation en arrière-plan a aussi ouvert un workflow que je n'avais pas prévu. Parce que la base de connaissances se met à jour toute seule, je pouvais pointer le pipeline d'ingestion vers des chaînes concurrentes, des sources d'actualités du secteur ou des dépôts de documentation. La connaissance de l'appli grandissait pendant que je dormais. Pour un client qui livre ça comme un produit SaaS, cette capacité d'auto-mise à jour est un vrai différenciateur — l'expérience de leurs utilisateurs s'améliore chaque jour sans aucune intervention manuelle.

Si tu préfères que quelqu'un construise tout ce pipeline d'automatisation de zéro, je prends des missions de développement d'applis IA et de construction de systèmes RAG. Tu peux voir ce que j'ai construit sur fiverr.com/s/EgxYmWD.

Mais une appli qui fonctionne n'est pas la même chose qu'une appli prête pour les utilisateurs. L'écart entre « ça marche sur ma machine » et « ça marche sur chaque appareil, chaque navigateur, chaque taille d'écran » est exactement là où se situe l'Étape 4. Et c'est l'étape que la plupart des développeurs solo zappent — à leurs risques et périls.

Étape 4 : Le contrôle qualité qui détecte vraiment les problèmes

Avant, je livrais des projets après les avoir testés dans Chrome sur mon laptop et basta. Cette approche a assez mal tourné pour que je traite désormais le test cross-device comme non négociable. L'outil qui a rendu ça praticable, c'est Test UI (anciennement LambdaTest), en particulier leur fonctionnalité Kane AI.

Kane AI est un agent IA qui simule le comportement réel des utilisateurs sur différents appareils et navigateurs. Tu décris un flux utilisateur en langage naturel — « connecte-toi avec les identifiants de test, pose une question dans le chat, sauvegarde la réponse dans une note Kanban, passe en mode sombre, puis vérifie le layout sur iPhone 15 Pro » — et Kane l'exécute, en signalant les régressions visuelles, les interactions cassées et les problèmes de performance.

Les trois problèmes que Kane a détectés et que j'aurais livrés sans lui :

  1. Le bug de scroll du chat. Sur Safari iOS, le conteneur de chat ne scrollait pas jusqu'au dernier message après la réponse de l'IA. Le chat fonctionnait parfaitement sur Chrome desktop et même Chrome mobile. Safari gérait le comportement scrollIntoView différemment, et le message apparaissait sous le pli. Les utilisateurs auraient pensé que l'appli était cassée.

  2. L'échec de contraste en mode sombre. Deux éléments textuels dans le composant de carte Kanban avaient un ratio de contraste de 3,2:1 en mode sombre — en dessous du minimum WCAG AA de 4,5:1. Invisible pour moi sur mon écran haut de gamme. Illisible sur un téléphone Android premier prix en plein soleil.

  3. La race condition d'authentification. Sur des connexions lentes (3G simulée), l'appli affichait occasionnellement le tableau de bord avant que Supabase confirme la session d'auth, flashant l'écran de connexion pendant 200ms avant de rediriger. Pas un problème de sécurité — les données n'étaient pas accessibles — mais ça donnait une impression de truc cassé et non professionnel.

Chacun de ces problèmes aurait généré des tickets de support. Chacun était invisible dans mon environnement de développement normal. Les tests automatisés ont trouvé les trois en moins de dix minutes.

La revue de sécurité était une passe séparée. J'ai utilisé la capacité de revue de code de Claude Code pour scanner les vulnérabilités — en vérifiant spécifiquement les clés API exposées, les vecteurs d'injection SQL dans les requêtes Supabase, et la configuration CORS incorrecte sur les routes API. Claude a signalé un problème : la clé API Gemini était envoyée dans le bundle côté client parce que j'avais nommé la variable d'environnement en inversant la convention du préfixe NEXT_PUBLIC_ — je l'avais accidentellement incluse là où elle n'aurait pas dû être. Les appels API côté serveur doivent utiliser des clés qui ne touchent jamais le navigateur. Détecté avant le déploiement. Ça aurait pu être une fuite coûteuse.

Pour quiconque construit une appli en production, voici ma checklist de tests :

  1. Tests cross-browser sur Chrome, Safari, Firefox et Edge (Kane AI ou manuellement)
  2. Tests mobile sur au moins un appareil iOS et un Android à différentes tailles d'écran
  3. Simulation de réseau lent pour détecter les race conditions et les trous dans les états de chargement
  4. Audit d'accessibilité pour les ratios de contraste, la navigation au clavier et la compatibilité avec les lecteurs d'écran
  5. Scan de sécurité pour les identifiants exposés, les vecteurs d'injection et les CORS mal configurés
  6. Test de charge sur le pipeline RAG — que se passe-t-il quand 50 utilisateurs simultanés interrogent la base de connaissances ?

J'estime que la phase de tests a ajouté 3 heures au build. Ces 3 heures ont évité au moins 10 heures d'extinction d'incendies post-lancement. Le calcul n'est même pas serré.

Maintenant — l'appli fonctionne, elle est testée, elle est sécurisée. La seule chose qui sépare ce projet de vrais utilisateurs, c'est le déploiement. Et grâce au pipeline Vercel + GitHub, c'est l'étape la plus facile de tout le processus.

Étape 5 : Déploiement — Du build local au produit en ligne

Le pipeline de déploiement est presque anticlimatique après la complexité des Étapes 2-4. C'est par design — si ton processus de déploiement est stressant, quelque chose en amont ne va pas.

J'ai commité les changements finaux dans le dépôt GitHub que Lovable avait initialement créé. Puis j'ai connecté le repo à Vercel, ce qui a pris environ deux minutes : autoriser l'intégration GitHub, sélectionner le dépôt, confirmer la détection du framework (Next.js), et ajouter les variables d'environnement.

Les variables d'environnement sont la seule partie qui demande de l'attention :

GEMINI_API_KEY=your-gemini-api-key
PINECONE_API_KEY=your-pinecone-api-key
PINECONE_INDEX=your-index-name
NEXT_PUBLIC_SUPABASE_URL=your-supabase-url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-supabase-anon-key
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key

Note le pattern : les variables préfixées NEXT_PUBLIC_ peuvent être exposées côté client en toute sécurité (l'URL Supabase et la clé anon sont conçues pour être publiques). Tout le reste — clé API Gemini, clé API Pinecone, clé de rôle service Supabase — reste côté serveur uniquement. Mélanger ça est l'une des erreurs de sécurité les plus courantes dans les déploiements Next.js, et c'est exactement le problème que Claude Code a détecté pendant la revue de sécurité.

Le premier déploiement de Vercel a pris 47 secondes. Les pushs suivants sur la branche main déclenchent des redéploiements automatiques. J'ai ajouté un domaine personnalisé via le tableau de bord de Vercel — pointer le DNS, attendre le provisionnement SSL (généralement moins de 5 minutes), et l'appli est en ligne sur une URL professionnelle.

L'architecture finale ressemble à ça :

Couche Service Coût mensuel (Hobby/Starter)
Frontend + API Vercel Tier gratuit (hobby) ou 20 $/mois (pro)
Auth + Base de données Supabase Tier gratuit (jusqu'à 50K utilisateurs actifs mensuels)
Stockage vectoriel Pinecone Tier gratuit (100K vecteurs) ou 70 $/mois (Starter)
Embeddings Gemini API Tier gratuit (1 500 requêtes/jour)
Automatisation Railway 5 $/mois (Hobby, inclut 5 $ d'usage)
Total (Tiers gratuits) 5 $/mois
Total (Tiers payants) ~95 $/mois

Pour une appli SaaS que tu peux vendre à des clients pour 50-200 $/mois par siège, cette structure de coûts est extrêmement saine. Même le total en tiers payants de 95 $/mois laisse une marge significative.

Ce que j'ai raté et ce que je changerais

Je veux être honnête sur les parties de ce build qui ne se sont pas bien passées, parce que la version polie de n'importe quel tuto cache les décisions qui comptent vraiment.

La stratégie de découpage doit être ajustée par type de contenu. Mes chunks de 512 tokens avec un chevauchement de 50 tokens fonctionnaient bien pour les documents texte et les transcriptions. Pour les PDF avec du contenu technique dense, j'ai réalisé plus tard que des chunks de 768 tokens capturaient des concepts plus complets. Pour les transcriptions vidéo — qui tendent à être plus conversationnelles et moins denses en information — des chunks de 384 tokens réduisaient le bruit dans les résultats de récupération. Il n'y a pas de taille de chunk universelle. Tu dois tester avec tes données réelles.

Gemini Embedding 2 est encore en preview. L'identifiant du modèle gemini-embedding-exp-03-07 inclut « exp » pour une raison. Pendant mon build, j'ai atteint des limites de débit deux fois lors de l'ingestion en masse qui n'étaient pas documentées dans la référence API. Le contournement consistait à ajouter un backoff exponentiel avec un maximum de 5 tentatives, que Claude Code a implémenté en environ 30 secondes quand j'ai décrit le problème. Mais s'appuyer sur un modèle expérimental pour des workloads de production comporte des risques. Surveille l'annonce de disponibilité générale avant de passer à l'échelle pour des milliers d'utilisateurs.

Le tier gratuit de Lovable est trop serré pour l'itération. Cinq messages quotidiens, ça semble raisonnable jusqu'à ce que tu en sois à ta troisième passe de raffinement et que tu aies épuisé ton allocation à 10h du matin. J'ai upgradé vers Starter (25 $/mois) dès le deuxième jour. Si tu es sérieux avec ce workflow, prévois le tier payant dès le départ.

Le pipeline de scraping YouTube est fragile. YouTube n'a pas d'API officielle de transcription — les outils qui existent font du reverse-engineering d'endpoints non documentés. Google pourrait changer quelque chose demain et casser tout le pipeline d'ingestion. Pour une appli en production, je construirais un fallback qui utilise Whisper ou les capacités audio de Gemini pour transcrire directement à partir du flux audio au lieu de dépendre des données de sous-titres de YouTube.

La qualité de la récupération cross-modale varie. La récupération texte-vers-texte avec Gemini Embedding 2 est excellente. La récupération texte-vers-image est bonne mais pas parfaite — environ 80 % du temps elle remonte le bon diagramme. Les 20 % restants renvoient des images vaguement liées. Pour les cas d'usage critiques, j'ai ajouté un seuil de score de pertinence (0,75) en dessous duquel les résultats sont filtrés. Ça a amené la précision à un niveau que j'étais à l'aise de livrer.

Ce ne sont pas des dealbreakers. Ce sont le genre d'ajustements qui séparent un prototype de week-end d'un produit en production. Et les connaître avant de commencer signifie que tu peux les anticiper au lieu de les découvrir à 23h la veille d'une démo client.

Ce que cette stack rend possible

La combinaison de Gemini Embedding 2, Pinecone, et l'ingestion automatisée permet une catégorie d'applications qui n'étaient pas praticables il y a six mois. Quelques exemples concrets :

Des bases de connaissances internes d'entreprise qui comprennent vraiment ta documentation. Pas de la recherche par mots-clés — de la recherche sémantique sur le texte, les diagrammes, les vidéos de formation et les réunions enregistrées. Un ingénieur demande « comment fonctionne la logique de retry de paiement ? » et obtient le snippet de code pertinent, le diagramme d'architecture, ET le timestamp de l'explication du tech lead dans le all-hands du mois dernier.

Des assistants de recherche pour les clients qui restent à jour automatiquement. Cabinets d'avocats, agences de conseil, organisations de recherche — toute entreprise où les professionnels passent des heures à chercher dans des documents des précédents ou des données pertinentes. Le pipeline d'auto-mise à jour fait que la base de connaissances grandit quotidiennement sans curation manuelle.

Des plateformes éducatives où les étudiants peuvent interroger le matériel de cours à travers tous les formats. Uploade des vidéos de cours magistraux, des manuels PDF et des présentations. Les étudiants posent des questions en langage naturel et reçoivent des réponses sourcées depuis le format le plus pertinent — parfois un passage texte, parfois un moment spécifique dans une vidéo de cours.

Chacun de ces cas était possible avant en théorie. En pratique, la complexité d'intégration — des modèles d'embedding séparés pour le texte et les images, des pipelines de récupération séparés, des étapes de transcription manuelles — les rendait impraticables pour les petites équipes. Gemini Embedding 2 compresse cette complexité en un seul appel API. Pinecone gère le stockage et la récupération. Claude Code câble le tout plus vite que tu n'écrirais le boilerplate manuellement.

La question n'est pas de savoir si cette stack technique fonctionne. J'ai prouvé que oui. La question est ce que tu vas construire avec.

Le playbook, condensé

Pour les builders qui veulent la version condensée sans les récits de guerre :

  1. Designe l'UI dans Lovable. Sois spécifique dans tes prompts. Itère en passes ciblées sur des problèmes individuels. Exporte vers GitHub quand tu atteins 80 % de qualité.

  2. Câble le backend dans Anti-Gravity + Claude Code. Connecte Pinecone (3 072 dimensions, similarité cosinus). Intègre Gemini Embedding 2 pour le découpage et l'embedding multimodaux. Construis l'endpoint de requête avec filtrage par métadonnées et seuils de score de pertinence.

  3. Automatise l'ingestion avec Railway. Cron jobs quotidiens pour le nouveau contenu. Vérifications de déduplication contre les métadonnées Pinecone. Stocke les timestamps d'exécution dans Supabase, pas dans des fichiers locaux.

  4. Teste sur différents appareils et scanne les problèmes de sécurité. Kane AI pour les tests cross-browser et mobile. Claude Code pour la revue de sécurité. Prévois 3 heures — ça en économise 10.

  5. Déploie sur Vercel. Connecte GitHub, configure les variables d'environnement (les clés côté serveur restent côté serveur), configure le domaine personnalisé. Premier déploiement en moins d'une minute.

Temps total de build pour quelqu'un qui suit ce guide : 2-3 jours pour la première itération. Les applis suivantes utilisant le même pattern : 4-8 heures.

Si tu as construit des applis RAG avec des embeddings texte uniquement en te demandant pourquoi la qualité de récupération plafonne, Gemini Embedding 2 est l'upgrade qui brise ce plafond. Si tu as codé des UI à la main pour des applis IA au lieu d'utiliser des outils comme Lovable, tu passes des heures sur un travail qu'un prompt peut gérer en minutes. Si tu as mis à jour manuellement des bases de connaissances au lieu d'automatiser l'ingestion, ton appli est déjà en retard.

Les outils ont rattrapé la vision. Le framework en cinq étapes fonctionne. La seule variable restante, c'est ce que tu décides de construire — et si tu commences aujourd'hui ou si tu attends que quelqu'un d'autre le construise à ta place.

Questions fréquentes

Qu'est-ce que Gemini Embedding 2 et en quoi diffère-t-il des modèles d'embedding précédents ?

Gemini Embedding 2 est le premier modèle d'embedding nativement multimodal de Google DeepMind, sorti en preview publique le 10 mars 2026. Contrairement aux prédécesseurs texte uniquement, il projette le texte, les images, la vidéo, l'audio et les PDF dans un espace vectoriel unique de 3 072 dimensions. Il obtient un score de 68,32 sur MTEB English, en tête avec 5,09 points d'avance. Pour une analyse détaillée de l'architecture, consulte la section ci-dessus sur pourquoi Gemini Embedding 2 réécrit les règles du RAG.

Combien coûte la construction et l'exploitation d'une appli RAG avec cette stack ?

En utilisant les tiers gratuits de Vercel, Supabase, Pinecone et l'API Gemini, le seul coût obligatoire est Railway à 5 $/mois pour l'ingestion automatisée. Les tiers payants pour tous les services totalisent environ 95 $/mois. Pour le détail complet des coûts par service, consulte la section déploiement ci-dessus.

Quelle taille de chunk utiliser pour Gemini Embedding 2 avec Pinecone ?

Commence avec des chunks de 512 tokens et un chevauchement de 50 tokens pour le contenu général. Ajuste selon le type de contenu : 768 tokens pour les PDF techniques denses, 384 tokens pour les transcriptions conversationnelles. Il n'y a pas de taille optimale universelle — teste avec tes données réelles et mesure la précision de récupération. Consulte la section « Ce que j'ai raté » pour plus de détails sur le tuning.

Gemini Embedding 2 peut-il remplacer des pipelines d'embedding texte et image séparés ?

Oui — c'est son avantage principal. Un seul appel API embedde le texte, les images, la vidéo, l'audio et les documents dans un espace vectoriel unifié, éliminant le besoin de modèles d'embedding et de pipelines de récupération séparés. La recherche cross-modale (requête texte récupérant des images pertinentes) fonctionne à environ 80 % de précision avec un seuil de pertinence de 0,75.

Gemini Embedding 2 est-il prêt pour la production ?

En mars 2026, le modèle est en preview publique avec l'identifiant gemini-embedding-exp-03-07. Il fonctionne de manière fiable pour des applications à échelle modérée mais a des limites de débit non documentées lors de l'ingestion en masse. Ajoute un backoff exponentiel à ton pipeline et surveille l'annonce de disponibilité générale avant de passer à l'échelle pour des milliers d'utilisateurs simultanés.

Travaillons ensemble

Tu cherches à construire des systèmes IA, automatiser des workflows ou faire évoluer ton infrastructure tech ? Je serais ravi de t'aider.

Coffee cup

Vous avez apprécié cet article ?

Votre soutien m'aide à créer davantage de contenu technique approfondi, d'outils open source et de ressources gratuites pour la communauté des développeurs.

Sujets connexes

Engr Mejba Ahmed

À propos de l'auteur

Engr Mejba Ahmed

Engr. Mejba Ahmed builds AI-powered applications and secure cloud systems for businesses worldwide. With 10+ years shipping production software in Laravel, Python, and AWS, he's helped companies automate workflows, reduce infrastructure costs, and scale without security headaches. He writes about practical AI integration, cloud architecture, and developer productivity.

Discussion

Comments

0

No comments yet

Be the first to share your thoughts

Leave a Comment

Your email won't be published

6  x  7  =  ?

Continuer l'apprentissage

Articles connexes

Tout parcourir

Comments

Leave a Comment

Comments are moderated before appearing.

Learning Resources

Expand Your Knowledge

Accelerate your growth with structured courses, verified certificates, interactive flashcards, and production-ready AI agent skills.

Sample Certificate of Completion

Sample certificate — complete any course to earn yours

Engr Mejba Ahmed

Engr Mejba Ahmed

Claude Code Expert · Online

👋

Hey there!

Quick Actions

WhatsApp Instant reply

Chat on WhatsApp

+880 1723 741224 · Instant reply

Popular Questions

Engr Mejba Ahmed is connected
Engr Mejba Ahmed is typing...
Engr Mejba Ahmed avatar

✉ Want me to follow up? Drop your email

Engr Mejba Ahmed avatar

📞 Connect Directly

Choose how you'd like to reach me

WhatsApp

+880 1723 741224

Email

[email protected]

✓ Details sent! I'll get back to you shortly.

Powered by OpenAI

335+

Blog Posts

25

AI Courses

63

Projects

Services & Expertise

Pricing & Process

Learning & Resources

Connect & Support