Aller au contenu principal
OFFRE — Site 5 pages 700€En profiter →
Logo ConsilioWEB - Agence web à Ussel, Corrèze
CONSILIOWEB
Intelligence Artificielle

Construire un RAG 2026 : guide pas-à-pas pour vos docs

17 min de lecture
3 243 mots
Construire un RAG 2026 : guide pas-à-pas pour vos docs
Sommaire

Vous avez 200 contrats, fiches produit, procédures internes ou rapports techniques. Votre équipe passe des heures à chercher la bonne information dans le mauvais fichier. Un assistant RAG résout ce problème de manière chirurgicale — à condition de le construire correctement. RAG construire documents 2026 est un sujet sur lequel les équipes se plantent régulièrement, non pas par manque d'outils, mais par mauvais choix d'architecture dans les premières heures du projet.

Ce guide couvre la totalité du chemin : de l'ingestion de vos fichiers PDF ou Markdown jusqu'au déploiement en production d'un assistant exploitable par vos collaborateurs, avec des coûts mensuels inférieurs à 50 €. La stack retenue — Node.js, Qdrant, Voyage AI et Claude — n'est pas arbitraire : chaque choix répond à un compromis précis entre performance, coût et simplicité opérationnelle.

Chez ConsilioWEB, nous accompagnons des PME et des directions techniques sur ce type de projet depuis que les premiers modèles d'embedding performants sont devenus accessibles. Le retour terrain est sans équivoque : les échecs viennent presque toujours du chunking et de l'absence d'évaluation, jamais de la génération elle-même. Cet article vous donne les outils pour éviter ces écueils. Si vous souhaitez déléguer tout ou partie de la mise en œuvre, [contactez notre équipe via le formulaire de devis](/contact).

---

Architecture RAG en 2026 : les choix qui comptent

RAG signifie *Retrieval-Augmented Generation*. L'idée est simple : plutôt que de fine-tuner un modèle sur vos données (cher, lent, difficile à maintenir), vous stockez vos documents sous forme de vecteurs dans une base dédiée, puis vous récupérez les passages les plus pertinents à chaque question avant de les injecter dans le prompt du LLM.

En 2026, l'architecture standard comporte cinq couches :

  1. Ingestion : parsing des fichiers source (PDF, DOCX, Markdown, HTML), nettoyage, chunking.
  2. Embedding : transformation de chaque chunk en vecteur numérique dense (384 à 1536 dimensions selon le modèle).
  3. Vector store : indexation et recherche approximative du plus proche voisin (ANN).
  4. Reranking : re-notation des N premiers résultats par un modèle cross-encoder plus précis.
  5. Génération : appel au LLM avec les passages retenus + question de l'utilisateur.

Ce qui a changé par rapport à 2023-2024 :

  • Les modèles d'embedding spécialisés (Voyage AI, Cohere) surpassent `text-embedding-ada-002` sur les benchmarks MTEB de 8 à 12 points NDCG@10.
  • Le reranking est devenu quasi-obligatoire dès que la base dépasse 500 chunks.
  • Les vector databases self-hosted (Qdrant, Weaviate) ont atteint la maturité production avec des clients Rust et Go stables.
  • Claude 3.5 Sonnet et Claude 3 Opus gèrent des fenêtres de contexte de 200 000 tokens, ce qui permet d'injecter davantage de passages sans troncature.

Gotcha n°1 : beaucoup d'équipes choisissent leur LLM en premier et construisent le reste autour. C'est une erreur. La qualité d'un RAG dépend à 70 % du retrieval, pas de la génération. Optimisez l'embedding et le reranking avant de toucher au prompt.

---

Choix de la stack : Qdrant vs Pinecone vs Weaviate

Trois options dominent le marché en 2026 :

| Critère | Qdrant | Pinecone | Weaviate | |---|---|---|---| | Self-hosted | Oui (Docker) | Non (SaaS uniquement) | Oui | | Latence p95 (1M vecteurs) | ~8 ms | ~15 ms | ~12 ms | | Filtrage payload | Natif, indexé | Limité (plan standard) | Via GraphQL | | Coût 1M vecteurs/mois | ~0 € (self-hosted) | ~70 $ | ~0 € (self-hosted) | | SDK Node.js | Officiel, maintenu | Officiel | Officiel | | Quantisation intégrée | Scalar + Product | Non | Non |

Qdrant remporte ce comparatif pour un projet à budget raisonnable. La quantisation scalaire intégrée permet de réduire la RAM de 4x sans perte de qualité mesurable sur des corpus < 1M vecteurs. Le client TypeScript est bien typé et la documentation est maintenue activement.

Pinecone reste pertinent si vous refusez toute gestion d'infrastructure. Mais à 70 $ par million de vecteurs, la facture devient inconfortable rapidement, et l'absence de self-hosting crée une dépendance forte.

Weaviate est une bonne alternative si vous avez besoin de requêtes hybrides complexes (BM25 + vecteur) dès le départ. Sa courbe d'apprentissage est plus raide.

Pour un corpus de 200 documents (soit environ 15 000 à 30 000 chunks selon le découpage), Qdrant sur un VPS à 12 €/mois suffit amplement.

---

Ingestion et chunking : la phase qui fait ou casse votre RAG

C'est ici que la majorité des projets échouent. Un mauvais chunking produit des chunks qui coupent les phrases au milieu d'un argument, qui mélangent deux sujets distincts, ou qui sont si courts qu'ils perdent tout contexte. Le retrieval renvoie alors des fragments inutilisables.

Parsing des sources

Pour des PDFs, évitez PyMuPDF en Python si votre stack est Node.js. Utilisez plutôt `pdf-parse` pour les PDFs non-scannés, ou une combinaison `pdf2pic` + OCR (Tesseract via `node-tesseract-ocr`) pour les scannés. Pour DOCX, `mammoth` produit du HTML propre facilement nettoyable.

```typescript import pdfParse from 'pdf-parse'; import fs from 'fs';

async function extractText(filePath: string): Promise<string> { const buffer = fs.readFileSync(filePath); const data = await pdfParse(buffer); return data.text .replace(/\n{3,}/g, '\n\n') // compresse les sauts de ligne excessifs .replace(/\s{2,}/g, ' ') // supprime les espaces multiples .trim(); } ```

Stratégie de chunking

Trois approches existent, par ordre de sophistication :

Chunking fixe par tokens : découpez tous les 512 tokens avec un overlap de 64 tokens. Simple, mais aveugle à la structure du document. Acceptable pour des documents homogènes (FAQ, fiches produit).

Chunking récursif par séparateurs : séparez d'abord par `\n\n`, puis `\n`, puis `.`, puis ` `. C'est la méthode de LangChain `RecursiveCharacterTextSplitter`. Fonctionne bien pour la prose.

Chunking sémantique : calculez la similarité cosinus entre phrases consécutives et coupez quand la similarité chute sous un seuil (souvent 0.75). Meilleur résultat, mais 3x plus lent à l'ingestion.

Pour 200 documents, le chunking sémantique est recommendé. Le surcoût de temps (quelques minutes) n'est supporté qu'une fois à l'ingestion.

```typescript // Chunking sémantique simplifié function semanticChunk(sentences: string[], embeddings: number[][], threshold = 0.75): string[] { const chunks: string[] = []; let currentChunk: string[] = [sentences[0]];

for (let i = 1; i < sentences.length; i++) { const sim = cosineSimilarity(embeddings[i - 1], embeddings[i]); if (sim < threshold) { chunks.push(currentChunk.join(' ')); currentChunk = []; } currentChunk.push(sentences[i]); } if (currentChunk.length) chunks.push(currentChunk.join(' ')); return chunks; } ```

Gotcha n°2 : ajoutez toujours des métadonnées à chaque chunk (nom du fichier source, numéro de page, date de mise à jour). Elles permettent le filtrage dans Qdrant et l'attribution des sources dans la réponse finale.

---

Embeddings : pourquoi Voyage AI plutôt qu'OpenAI

Le modèle `text-embedding-3-large` d'OpenAI est correct. Mais `voyage-3` de Voyage AI le surpasse systématiquement sur le benchmark MTEB, notamment sur les tâches de retrieval en corpus spécialisés (juridique, médical, technique). L'écart moyen est de 4 à 9 points NDCG@10 selon les domaines.

Avantages de Voyage AI :

  • Modèles spécialisés : `voyage-3` (général), `voyage-3-lite` (2x moins cher), `voyage-finance-2`, `voyage-code-3`.
  • Tarif : ~0.00002 $/token contre ~0.00013 $/token pour `text-embedding-3-large`. Un corpus de 200 documents (≈ 2M tokens) coûte ~0.04 $ avec Voyage contre ~0.26 $ avec OpenAI.
  • Instruction prefix : vous pouvez ajouter un préfixe différent pour les chunks (ex: "Represent this document for retrieval:") et les requêtes ("Represent this query for finding relevant passages:"), ce qui améliore la précision.

```typescript import Anthropic from '@anthropic-ai/sdk';

// Voyage AI est accessible via le SDK Anthropic const client = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });

async function embedChunks(chunks: string[]): Promise<number[][]> { const response = await client.embeddings.create({ model: 'voyage-3', input: chunks, input_type: 'document', }); return response.data.map(item => item.embedding); }

async function embedQuery(query: string): Promise<number[]> { const response = await client.embeddings.create({ model: 'voyage-3', input: [query], input_type: 'query', }); return response.data[0].embedding; } ```

Gotcha n°3 : n'utilisez pas le même `input_type` pour les chunks et les requêtes. L'asymétrie document/query est volontaire et améliore le retrieval de 5 à 15% selon les benchmarks internes Voyage AI.

---

Vector database : déploiement Qdrant self-hosted

Installation avec Docker

```bash docker run -d \ --name qdrant \ -p 6333:6333 \ -p 6334:6334 \ -v $(pwd)/qdrant_storage:/qdrant/storage \ qdrant/qdrant:v1.9.0 ```

Le volume `-v` est critique : sans lui, vos vecteurs disparaissent au redémarrage du conteneur.

Création de la collection et ingestion

```typescript import { QdrantClient } from '@qdrant/js-client-rest';

const qdrant = new QdrantClient({ host: 'localhost', port: 6333 });

await qdrant.createCollection('documents', { vectors: { size: 1024, // dimension Voyage-3 distance: 'Cosine', }, optimizers_config: { default_segment_number: 2, }, quantization_config: { scalar: { type: 'int8', always_ram: true, }, }, });

// Ingestion par batch de 100 async function upsertBatch(chunks: Chunk[], embeddings: number[][]) { const points = chunks.map((chunk, i) => ({ id: chunk.id, vector: embeddings[i], payload: { text: chunk.text, source: chunk.source, page: chunk.page, updatedAt: chunk.updatedAt, }, }));

await qdrant.upsert('documents', { points, wait: true }); } ```

La quantisation `int8` (scalaire) réduit la mémoire de 4x. Sur 30 000 chunks avec des vecteurs de 1024 dimensions, cela passe de ~120 Mo à ~30 Mo de RAM pour l'index — compatible avec un VPS à 2 Go.

---

Retrieval et reranking : la qualité au prix de quelques ms

Recherche initiale (ANN)

```typescript async function retrieve(query: string, topK = 20): Promise<ScoredChunk[]> { const queryEmbedding = await embedQuery(query);

const results = await qdrant.search('documents', { vector: queryEmbedding, limit: topK, with_payload: true, score_threshold: 0.5, // filtre les résultats vraiment hors sujet });

return results.map(r => ({ text: r.payload!.text as string, source: r.payload!.source as string, score: r.score, })); } ```

Récupérez toujours plus de résultats que nécessaire pour le prompt final (ici 20, alors que vous n'en injecterez que 5). Le reranker sélectionnera les meilleurs.

Reranking avec Cohere

Le reranker est un cross-encoder : il compare la question et chaque passage en parallèle, avec plus de contexte qu'un simple calcul de similarité cosinus. Cohere `rerank-v3.5` est le standard en 2026.

```typescript import { CohereClient } from 'cohere-ai';

const cohere = new CohereClient({ token: process.env.COHERE_API_KEY });

async function rerank(query: string, chunks: ScoredChunk[], topN = 5): Promise<ScoredChunk[]> { const response = await cohere.rerank({ model: 'rerank-v3.5', query, documents: chunks.map(c => c.text), topN, returnDocuments: false, });

return response.results.map(r => ({ ...chunks[r.index], rerankScore: r.relevanceScore, })); } ```

Coût du reranking : ~0.001 $ pour 20 passages rerankés. Négligeable. Le gain de précision est en revanche très mesurable : sur nos tests internes, le taux de réponses pertinentes passe de 71 % (retrieval seul) à 89 % (retrieval + reranking) sur un corpus de notices techniques.

Gotcha n°4 : ne rerankez que les passages dont le score ANN dépasse 0.5. Injecter des passages hors sujet dans le reranker ne les améliore pas, mais gaspille des appels API.

---

Génération avec Claude : prompts qui exploitent le contexte

Claude 3.5 Sonnet est le choix privilégié en 2026 pour la génération RAG : il respecte scrupuleusement les instructions de "répondre uniquement sur la base du contexte fourni" et cite bien ses sources lorsque vous le lui demandez. GPT-4o a tendance à halluciner des informations hors-contexte même avec des instructions contraires.

```typescript import Anthropic from '@anthropic-ai/sdk';

const anthropic = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });

function buildSystemPrompt(chunks: ScoredChunk[]): string { const context = chunks .map((c, i) => `[Source ${i + 1} — ${c.source}]\n${c.text}`) .join('\n\n---\n\n');

return `Tu es un assistant expert. Tu réponds UNIQUEMENT sur la base des sources ci-dessous. Si la réponse n'est pas dans les sources, tu indiques clairement que tu ne disposes pas de l'information. Tu cites la source entre crochets (ex : [Source 2]) après chaque information clé.

SOURCES : ${context}`; }

async function generate(query: string, chunks: ScoredChunk[]): Promise<string> { const response = await anthropic.messages.create({ model: 'claude-sonnet-4-5', max_tokens: 1024, system: buildSystemPrompt(chunks), messages: [{ role: 'user', content: query }], });

return response.content[0].type === 'text' ? response.content[0].text : ''; } ```

Trois règles de prompt qui font la différence :

  1. Instruction négative explicite : "Si la réponse n'est pas dans les sources" — cette formulation réduit les hallucinations mieux que "réponds uniquement sur la base de".
  2. Attribution des sources : demandez la citation inline, pas seulement une liste en fin de réponse. Ça force le modèle à ancrer chaque affirmation.
  3. Contrôle du ton : ajoutez une ligne de style adapté à votre usage ("Réponds de manière concise en 3-5 phrases" pour un assistant interne, "Fournis une analyse détaillée" pour un outil de recherche juridique).

---

Évaluation : datasets, métriques, itération continue

Un RAG sans évaluation est une boîte noire. Vous ne saurez pas si votre nouveau modèle d'embedding est meilleur, si votre chunking amélioré aide réellement, ou si votre reranker dégrade certains cas.

Construire un dataset d'évaluation

Pour 200 documents, générez 50 à 100 paires (question, réponse attendue). Deux méthodes :

  • Manuellement : demandez à des utilisateurs métier de formuler 50 questions réelles qu'ils se poseraient.
  • Synthétiquement : utilisez Claude pour générer des questions à partir de chunks sélectionnés aléatoirement. Validez ensuite manuellement une sélection (30% suffit pour détecter les erreurs systématiques).

Métriques à suivre

| Métrique | Ce qu'elle mesure | Objectif cible | |---|---|---| | Recall@5 | Les bons chunks sont-ils dans les 5 premiers ? | > 0.85 | | MRR (Mean Reciprocal Rank) | Position du premier bon chunk | > 0.75 | | Faithfulness | La réponse est-elle fidèle aux sources ? | > 0.90 | | Answer Relevance | La réponse répond-elle à la question ? | > 0.85 | | Latence p95 | Temps total end-to-end | < 3 000 ms |

Pour Faithfulness et Answer Relevance, vous avez deux options : le framework Ragas (Python, mais appelable depuis Node.js via une API) ou un juge LLM maison (Claude évalue sa propre sortie sur ces deux dimensions — fonctionne bien si le prompt du juge est bien structuré).

```typescript // Juge LLM simplifié pour la faithfulness async function evaluateFaithfulness( query: string, context: string, answer: string ): Promise<number> { const judgment = await anthropic.messages.create({ model: 'claude-sonnet-4-5', max_tokens: 100, system: `Tu évalues si une réponse est fidèle aux sources fournies. Réponds UNIQUEMENT avec un score entre 0.0 et 1.0, sans aucun texte.`, messages: [{ role: 'user', content: `Question: ${query}\nSources: ${context}\nRéponse: ${answer}\nScore:` }], });

const text = judgment.content[0].type === 'text' ? judgment.content[0].text : '0'; return parseFloat(text.trim()) || 0; } ```

Gotcha n°5 : ne mesurez jamais la qualité d'un RAG en demandant à des utilisateurs "est-ce que c'est bien ?". Construisez un pipeline d'évaluation automatique dès le premier sprint. C'est ce qui permet d'itérer vite et de justifier les arbitrages techniques.

---

Mise en production : monitoring, coût, latence

Architecture de production

Pour un usage PME (< 50 utilisateurs simultanés), cette stack suffit :

  • VPS 4 vCPU / 8 Go RAM (Scaleway, OVH, Hetzner) : ~20-25 €/mois
  • Qdrant en Docker avec volume persistant
  • Node.js API (Express ou Fastify) derrière un reverse proxy Nginx
  • Redis pour le cache des embeddings de requêtes fréquentes (économie ~40% sur les appels Voyage AI)

Estimatif de coût mensuel (200 documents, 500 requêtes/jour)

| Poste | Coût estimé | |---|---| | VPS (Hetzner CX31) | 11 €/mois | | Voyage AI embeddings (ingestion one-shot) | ~0.05 € | | Voyage AI embeddings (requêtes) | ~0.50 €/mois | | Cohere reranking | ~1.50 €/mois | | Claude 3.5 Sonnet (génération) | ~15 €/mois | | Total | ~28 €/mois |

Ce chiffre inclut la réserve pour les pics. En dessous de 100 requêtes/jour, comptez 12-15 €/mois.

Monitoring

Instrumentez dès le départ avec ces trois métriques en production :

  1. Latence par étape : séparez embedding / ANN search / reranking / génération. Si la latence globale augmente, vous saurez immédiatement quelle étape est en cause.
  2. Score de reranking moyen : un score moyen qui chute indique soit une dérive des questions utilisateurs, soit un problème dans vos données.
  3. Taux de réponses "non disponible" : si le modèle répond trop souvent qu'il n'a pas l'information, vos chunks ne couvrent pas les questions posées — signal pour enrichir le corpus.

```typescript // Middleware de logging structuré interface RAGTrace { queryId: string; query: string; embeddingMs: number; retrievalMs: number; rerankingMs: number; generationMs: number; topRerankScore: number; answeredFromContext: boolean; } ```

Mise à jour du corpus

Lorsqu'un document change, vous n'avez pas besoin de réindexer tout le corpus. Grâce aux métadonnées de source dans Qdrant, vous pouvez supprimer les anciens chunks et insérer les nouveaux :

```typescript await qdrant.delete('documents', { filter: { must: [{ key: 'source', match: { value: 'procedures/achat-v1.pdf' } }], }, }); // puis réingestion uniquement du fichier modifié ```

Ce guide sur RAG construire documents 2026 vous a donné une vue complète, de l'architecture à la mise en production. Pour aller encore plus loin côté performance web et coût d'infrastructure, consultez notre article sur [la performance web et son impact direct sur les ventes](/posts/vitesse-chargement-site-web-impact-ventes). Sur les questions de conformité RGPD liées au traitement de documents internes, notre guide [RGPD et cookies en 2026](/posts/rgpd-cookies-conformite-site-web-2026) complète utilement cette lecture. Si vous réfléchissez à l'intégration d'une IA dans votre CMS existant, notre article sur le [CMS agentique](/posts/cms-agentique-ia-contenu-entreprise) explore une approche complémentaire. Et pour contextualiser la place de ces outils dans votre stratégie globale, lisez notre analyse sur [l'IA et les agences web](/posts/ia-remplacer-agence-web-2026).

---

Questions fréquentes sur RAG construire documents 2026

Combien de documents faut-il minimum pour qu'un RAG soit pertinent ? Dix documents bien structurés suffisent pour tester l'architecture. En dessous, une simple recherche full-text (Elasticsearch, Typesense) est souvent plus rapide à déployer et presque aussi efficace. Le RAG prend tout son sens à partir de 50 à 100 documents hétérogènes.

Faut-il obligatoirement du Python pour construire un RAG ? Non. Node.js/TypeScript couvre l'intégralité du pipeline décrit ici. Les SDK de Qdrant, Voyage AI, Cohere et Anthropic sont tous disponibles et activement maintenus en JavaScript/TypeScript. Python reste utile si vous voulez utiliser Ragas ou LlamaIndex pour l'évaluation.

Comment gérer les documents confidentiels dans un RAG ? Deux approches : soit vous déployez tout en self-hosted (aucun document ne sort de votre infrastructure), soit vous utilisez des services cloud en vous assurant de signer un DPA avec chaque fournisseur. Voyage AI et Anthropic proposent tous deux des accords de traitement des données conformes au RGPD.

Le reranking est-il obligatoire pour 200 documents ? Pas strictement obligatoire, mais fortement recommandé. Sur un petit corpus, le gain est moins spectaculaire qu'à grande échelle. Cependant, le coût est quasi nul (~0.001 $ par requête) et le gain de précision vaut largement l'ajout de 200 ms de latence.

Peut-on utiliser un LLM local (Ollama, LM Studio) pour la génération ? Oui, et c'est une option intéressante pour les données ultra-confidentielles. Llama 3.2 ou Mistral Small via Ollama fonctionnent bien pour la génération RAG sur des corpus simples. La qualité de suivi d'instructions est toutefois inférieure à Claude, ce qui nécessite des prompts plus défensifs.

---

Conclusion : du POC à l'assistant en production

Construire un RAG sur vos documents internes n'est plus réservé aux équipes data engineering de grandes entreprises. Avec la stack Node.js + Qdrant + Voyage AI + Claude présentée ici, une PME peut aller d'un répertoire de 200 fichiers PDF à un assistant pleinement opérationnel en deux à trois semaines de développement, pour moins de 30 € par mois en infrastructure.

Les points qui font la différence entre un POC qui impressionne en démo et un outil qui sert vraiment en production : le chunking sémantique, l'asymétrie query/document dans les embeddings, le reranking systématique, et surtout l'évaluation continue avec un dataset métier. Sans ces quatre piliers, votre RAG répondra correctement 70 % du temps — ce qui est suffisant pour convaincre en démonstration, mais pas pour remplacer une vraie recherche documentaire.

Chez ConsilioWEB, nous avons déployé ce type d'architecture pour des clients en Corrèze et en Nouvelle-Aquitaine : un cabinet de conseil qui a transformé ses 300 rapports en assistant RFP, une PME industrielle dont les techniciens interrogent désormais les notices en langage naturel. Dans les deux cas, le retour sur investissement s'est mesuré en semaines, pas en mois.

Si vous souhaitez démarrer ce projet sans repartir de zéro — architecture, choix de stack, déploiement, formation de votre équipe — notre équipe peut intervenir à chaque étape. [Décrivez votre besoin via notre formulaire de devis](/contact) et nous reviendrons vers vous sous 48 heures avec une estimation concrète.

---

Pour aller plus loin

  • [Documentation officielle Qdrant](https://qdrant.tech/documentation/) — référence complète du moteur vectoriel, configuration avancée et API REST/gRPC.
  • [Voyage AI — API Embeddings](https://docs.voyageai.com/docs/embeddings) — modèles disponibles, tarification, benchmarks MTEB.
  • [Anthropic Claude API](https://docs.anthropic.com/fr/docs/welcome) — documentation Messages API, gestion du contexte, bonnes pratiques RAG.
  • [Ragas — RAG Evaluation Framework](https://docs.ragas.io/) — framework open-source pour évaluer faithfulness, answer relevance et context recall.
  • [MTEB Leaderboard](https://huggingface.co/spaces/mteb/leaderboard) — classement comparatif des modèles d'embedding par tâche et domaine.
Partager

Un projet en tête ?

Discutons de votre projet web et transformons vos idées en réalité.

DEVIS GRATUIT

Articles similaires