AccueilClients

Applications et sites

  • Application métiersIntranet, back-office...
  • Applications mobilesAndroid & iOS
  • Sites InternetSites marketings et vitrines
  • Expertises techniques

  • React
  • Expo / React Native
  • Next.js
  • Node.js
  • Directus
  • TypeScript
  • Open SourceBlogContactEstimer

    22 juin 2026

    Créer un RAG minimaliste avec Gemini et Google Drive

    4 minutes de lecture

    Créer un RAG minimaliste avec Gemini et Google Drive
    🇺🇸 This post is also available in english

    La plupart des tutoriels « construis ton RAG » vous noient sous les bases de données vectorielles, les stratégies de découpage et les comparaisons de rerankers. Tout cela peut être très simplifié avec Google Workspace qui fournit déjà les trois briques d'un RAG, et la colle tient en quelques heures.

    Ce billet déroule une petite expérience : une web app qui vous connecte avec Google, vous laisse choisir des fichiers dans votre Drive, les indexe avec Gemini, puis discute avec eux.

    RAG
    Démonstration du RAG

    C'est quoi un RAG, vraiment ?

    Retrieval-Augmented Generation, dans ce contexte c'est en fait deux étapes :

    1. Récupérer — étant donné une question, trouver les passages de vos documents les plus susceptibles de contenir la réponse.
    2. Générer — coller ces passages dans le prompt et laisser le LLM formuler la réponse.

    Habituellement, nous avons besoin de : découper les documents en chunks, les transformer en vecteurs, stocker ces vecteurs dans une base, et classer les résultats à la requête. Chacune de ces étapes a son lot d'articles qui débattent de la « bonne » manière.

    Le raccourci ici est de laisser Gemini tout faire. L'API Gemini expose un FileSearchStore — vous uploadez des fichiers, Google s'occupe du découpage, des embeddings et de la récupération. Au moment de la requête, vous passez le store comme un outil, et le modèle décide quand chercher et quoi faire des résultats.

    Trois dépendances, un seul fournisseur

    Toute la stack tient dans Google Workspace :

    • API Gemini — le LLM et le File Search Store. Une clé API.
    • OAuth Google — pour que l'utilisateur autorise l'app à lire son Drive. Un client OAuth.
    • API Google Drive — pour lister et télécharger les fichiers. Le même client OAuth.

    Pas de Pinecone, pas de LangChain, pas de modèle d'embedding à choisir. La seule « infrastructure » nécessaire est une mémoire pour savoir quels fichiers Drive ont été indexés et le nom du store.

    Pour le framework j'ai choisi TanStack Start — un framework React full-stack où la logique serveur n'est qu'une fonction typée que le client appelle directement. Pas de routes REST à écrire, pas de frontière client/serveur à concevoir. Une server function ressemble à ça :

    const chat = createServerFn({ method: 'POST' })
      .validator((d: { question: string }) => d)
      .handler(async ({ data }) => ask(data.question))
    

    Et côté client :

    await chat({ data: { question: '...' } })
    

    C'est toute la couche RPC.

    Étape 1 : chercher dans Drive

    Une fois l'utilisateur connecté en OAuth (avec le scope drive.readonly), lister les fichiers tient en un appel :

    const res = await drive.files.list({
      q: "trashed = false",
      pageSize: 50,
      fields: 'files(id, name, mimeType, modifiedTime)',
      orderBy: 'modifiedTime desc',
    })
    

    La seule subtilité, ce sont les types MIME. Les PDF et fichiers texte peuvent se télécharger tels quels (alt: 'media'), mais les Google Docs, Sheets et Slides sont virtuels — il faut les exporter d'abord :

    const GOOGLE_DOC_EXPORTS = {
      'application/vnd.google-apps.document':     { mimeType: 'application/pdf' },
      'application/vnd.google-apps.presentation': { mimeType: 'application/pdf' },
      'application/vnd.google-apps.spreadsheet':  { mimeType: 'text/csv' },
    }
    

    Un Google Doc est exporté en PDF, un Sheet en CSV. Gemini File Search gère les deux nativement.

    Étape 2 : indexer un fichier

    Voilà la partie magique. Indexer, c'est uploader + attendre :

    const ai = new GoogleGenAI({ apiKey })
    
    // Crée le store une fois, à la première utilisation
    const store = await ai.fileSearchStores.create({
      config: { displayName: 'gemini-rag' },
    })
    
    // Upload d'un d'un fichier Drive
    let op = await ai.fileSearchStores.uploadToFileSearchStore({
      file: new Blob([bytes], { type: mimeType }),
      fileSearchStoreName: store.name,
      config: { displayName: name, mimeType },
    })
    
    // L'indexation est asynchrone
    while (!op.done) {
      await new Promise(r => setTimeout(r, 2000))
      op = await ai.operations.get({ operation: op })
    }
    

    Voilà tout le pipeline d'indexation. Google découpe le fichier, calcule les embeddings et les écrit dans le store. En coulisses c'est la même mécanique qu'une base vectorielle — sauf que vous n'avez pas à l'opérer.

    Le seul état qu'on garde nous-mêmes est un petit fichier JSON qui mappe { driveId → { name, mimeType } }. Il existe pour deux raisons : éviter de réindexer des fichiers déjà uploadés, et retenir le nom du store entre les redémarrages du serveur.

    Étape 3 : discuter

    const res = await ai.models.generateContent({
      model: 'gemini-2.5-flash',
      contents: question,
      config: {
        tools: [{ fileSearch: { fileSearchStoreNames: [store.name] } }],
      },
    })
    return res.text
    

    Voilà tout le handler de chat. On donne à Gemini la question et un pointeur vers le store. Gemini décide s'il faut chercher, exécute la récupération, choisit les chunks pertinents et écrit la réponse.

    Si vous avez déjà construit un RAG à la main, c'est le moment qui ressemble à de la triche.

    Ce que ce n'est pas

    Soyons honnête, nous sommes assez éloigné d'un projet de production, cependant la logique principale du RAG est présente et fonctionnelle.

    Une solution complète aurait besoin de :

    • un stockage en base de donnée
    • une synchronisation automatique et récursive des dossiers Drive
    • une interface de tchat complète, multimodale et streamée (https://ai-sdk.dev/)

    À retenir

    Si vous construisez un RAG pour un outil interne et que vous êtes déjà dans l'écosystème Google, vous n'avez presque certainement pas besoin de monter une base vectorielle. À savoir que le free tier de l'API FileSearch permet un stockage de 1 GB.

    Si vous cherchez à discuter avec vos documents avec de l'AI, aussi dans l'écosystème Google, je vous recommande chaudement NotebookLM qui permet en plus de générer du contenu (résumé audio, vidéo, quiz, infographie...) en rapport avec vos documents.

    L'ensemble du code concernant le RAG tient sur ces 500 lignes de code et est disponible sur GitHub.

    À découvrir également