Ilyes Bouzayen
11 juil. 2026

RAG en 2026 : Construire un Chatbot qui Connaît Vos Données

16 min de lecture

RAG en 2026 : Construire un Chatbot qui Connaît Vos Données

Un LLM seul ne connaît pas vos données internes. Le RAG (Retrieval-Augmented Generation) résout ce problème en injectant le contexte pertinent avant chaque réponse.

Le principe en 3 étapes

1. Indexer   → Transformer vos documents en embeddings
2. Rechercher → Trouver les chunks pertinents pour la question
3. Générer   → Le LLM répond AVEC le contexte trouvé

Stack technique recommandée

Composant Outil Pourquoi
Embeddings OpenAI text-embedding-3-small Rapide, bon marché
Vector Store Qdrant ou pgvector Open-source, performant
Orchestrateur LangChain.js ou Vercel AI SDK Abstraction propre
LLM Claude Sonnet 4 ou GPT-4o Qualité/ratio coût

Implémentation complète

1. Indexation des documents

import { OpenAIEmbeddings } from '@langchain/openai';
import { QdrantVectorStore } from '@langchain/community/vectorstores/qdrant';
import { RecursiveCharacterTextSplitter } from 'langchain/text_splitter';

// Découper les documents en chunks
const splitter = new RecursiveCharacterTextSplitter({
  chunkSize: 500,
  chunkOverlap: 50,
  separators: ['\n\n', '\n', '. ', ' ']
});

const docs = await splitter.createDocuments(rawTexts);

// Générer les embeddings et stocker
const vectorStore = await QdrantVectorStore.fromDocuments(
  docs,
  new OpenAIEmbeddings({ model: 'text-embedding-3-small' }),
  {
    url: 'http://localhost:6333',
    collectionName: 'knowledge-base'
  }
);

console.log(`Indexé ${docs.length} chunks`);

2. Recherche sémantique

async function retrieveContext(question: string, topK = 5) {
  const results = await vectorStore.similaritySearchWithScore(
    question,
    topK
  );

  // Filtrer les résultats trop peu pertinents
  const relevant = results
    .filter(([_, score]) => score > 0.3)
    .map(([doc, score]) => ({
      content: doc.pageContent,
      source: doc.metadata.source,
      relevance: Math.round(score * 100)
    }));

  return relevant;
}

3. Génération avec contexte

import { generateText } from 'ai';
import { openai } from '@ai-sdk/openai';

async function ragQuery(question: string) {
  const context = await retrieveContext(question);

  const systemPrompt = `Tu es un assistant expert.
Réponds en te basant UNIQUEMENT sur le contexte fourni.
Si l'information n'est pas dans le contexte, dis-le.`;

  const contextBlock = context
    .map((c, i) => `[Source ${i + 1}] (pertinence: ${c.relevance}%)\n${c.content}`)
    .join('\n\n');

  const { text } = await generateText({
    model: openai('gpt-4o'),
    system: systemPrompt,
    prompt: `Contexte:\n${contextBlock}\n\nQuestion: ${question}`,
  });

  return { answer: text, sources: context };
}

Éviter les erreurs courantes

  1. Chunks trop gros → le contexte perd sa précision
  2. Chunks trop petits → le contexte perd sa signification
  3. Pas de reranking → les résultats les moins pertinents passent
  4. Pas de hybrid search → manque les mots-clés exacts
  5. Pas de cache → coûts d'embedding qui explosent

Métriques à surveiller

  • Latence p95 : < 2s pour un bon UX
  • Taux de citation : % de réponses avec sources
  • Hallucination rate : % de réponses inventées
  • Coût par query : objectif < $0.01

Conclusion

RAG n'est pas un luxe. C'est la façon dont les entreprises rendent l'IA utile avec leurs propres données.