La plupart des diagrammes d'architecture RAG comptent trois boîtes : un utilisateur, une base de données vectorielle et un LLM. Ce schéma suffit pour expliquer l'idée en réunion. Il n'aide personne à exploiter le système, car les décisions qui déterminent la qualité et la sécurité des réponses n'y figurent pas : comment les documents sont découpés, quel modèle d'embedding est utilisé, qui peut voir quel chunk, comment les résultats sont classés et comment savoir si les réponses sont bonnes.
Ce guide dessine le tableau complet d'une application de génération augmentée par récupération sous la forme de deux chemins autour de modèles et de stockages partagés, puis explique quoi étiqueter et quelles erreurs reviennent le plus souvent.
Deux chemins, pas un seul
Le terme vient de Lewis et al. (2020), qui ont combiné un modèle de langage avec un index vectoriel dense de Wikipédia, interrogé par un récupérateur au moment de la génération. La plupart des applications RAG en production gardent l'idée sans entraîner les composants ensemble : récupérer les passages pertinents, les placer dans le prompt et demander au modèle de répondre à partir d'eux.
Toute application RAG a donc deux chemins :
- L'ingestion tourne en continu en arrière-plan. Elle transforme les documents en chunks, en vecteurs et en métadonnées.
- La requête s'exécute une fois par question. Elle transforme une question en réponse avec sources.
Les deux se rejoignent sur les éléments partagés : le modèle d'embedding, qui doit être dans la même version sur les deux chemins, l'index vectoriel et le stockage de métadonnées. Un diagramme qui ne montre que le chemin de requête cache la moitié du système et la plupart des bugs.
Le chemin d'ingestion
- Sources et détection des changements. Des connecteurs, des webhooks ou un crawler repèrent les documents nouveaux, modifiés et supprimés, et placent des tâches dans une file. Les suppressions et les changements de permissions sont aussi des tâches.
- Parsing. Extrayez le texte en conservant la structure : titres, listes, tableaux, et des métadonnées comme le titre, l'URL, le propriétaire, la dernière mise à jour et la liste de contrôle d'accès.
- Chunking. Découpez d'abord selon la structure du document, puis selon la taille. La taille des chunks et le chevauchement sont des paramètres à régler sur vos propres questions, pas des valeurs universelles. Gardez le chemin des titres dans chaque chunk pour qu'un paragraphe reste compréhensible seul.
- Embedding. Appelez un seul modèle d'embedding et figez sa version. Stockez le nom et la version du modèle avec chaque vecteur. Les vecteurs issus de modèles différents ne sont pas comparables : changer de modèle implique de recalculer les embeddings de tout le corpus.
- Indexation. Faites un upsert de chaque chunk avec son vecteur, l'identifiant du document, le numéro du chunk, sa version et ses étiquettes d'accès. Si vous prévoyez une recherche hybride, gardez un index par mots-clés à côté de l'index vectoriel.
- Rafraîchissement et suppression. Rendez les upserts idempotents, supprimez les chunks des documents retirés et suivez la fraîcheur : le temps qu'il faut à un changement dans la source pour atteindre l'index.
Le chemin de requête
- Identifier l'utilisateur. Résolvez les groupes de l'utilisateur avant le début de la récupération.
- Reformuler la question (facultatif). Une question de suivi comme « et pour les prestataires ? » doit devenir, à l'aide de la conversation, une requête autonome.
- Récupérer. La recherche vectorielle trouve les passages de sens proche ; la recherche par mots-clés trouve les termes exacts comme les codes d'erreur et les noms de produits. La recherche hybride exécute les deux et fusionne les listes, souvent avec la reciprocal rank fusion, qui attribue à chaque document un score de 1/(k + rang) additionné sur les listes. L'article original sur la RRF fixait k à 60.
- Filtrer par permission dans la requête. Passez les groupes de l'utilisateur comme filtre sur les étiquettes d'accès, pour que les chunks qu'il n'a pas le droit de voir n'atteignent jamais le prompt. Vérifiez comment votre stockage applique les filtres. La documentation de pgvector indique qu'avec les index approximatifs, le filtre s'applique après le parcours de l'index : avec la valeur
ef_searchpar défaut de HNSW, 40, un filtre qui correspond à 10 % des lignes renvoie environ 4 lignes en moyenne. Les parcours itératifs, les index partiels ou le partitionnement corrigent ce problème. - Reclasser. Récupérez largement, par exemple 50 candidats, et laissez un modèle de reranking les noter par rapport à la question. Gardez les meilleurs, par exemple 8.
- Construire le prompt. Les instructions, les chunks retenus avec leurs identifiants et leurs titres, et la question, dans un budget de tokens. Demandez des citations par identifiant de chunk.
- Générer et citer. Appelez le LLM, diffusez la réponse en streaming et transformez les identifiants de chunks en liens que l'utilisateur peut vérifier.
Autour des deux chemins
- Traitez le texte récupéré comme une entrée non fiable. Un document peut contenir des instructions destinées au modèle. L'OWASP classe cela comme injection de prompt indirecte. Limitez les outils et les données accessibles au modèle aux droits de l'utilisateur lui-même.
- Tracez chaque requête. Journalisez la requête reformulée, les identifiants de chunks récupérés et reclassés avec leurs scores, la version du prompt, les versions des modèles et la latence de chaque étape.
- Évaluez sur un jeu de questions fixe. Exécutez-le à chaque changement de chunking, de modèles, de récupération ou de prompt. L'article RAGAS retient trois dimensions utiles : la fidélité au contexte récupéré, la pertinence de la réponse et la pertinence du contexte. Vérifiez aussi que la source attendue apparaît dans les premiers résultats.
- Mettez en cache avec prudence. Mettre en cache les embeddings des requêtes est généralement sans risque. Mettre en cache les réponses ne l'est que par ensemble de permissions.
Le diagramme
Contenu du diagramme
- Ingestion path · continuous
- Source documents
- Ingestion jobs
- Ingestion worker
- Embedding model (pinned)
- Vector index
- Metadata + ACLs
- LLM
- Query path · per request
- User
- RAG API
- Reranker
- change events
- jobs
- embed chunks
- upsert chunks + ACL tags
- document metadata
- question · answer + sources
- embed question
- hybrid search + ACL filter
- user's groups
- top 50
- prompt with top 8
Comment le lire :
- À gauche, l'ingestion. Les changements dans les sources deviennent des tâches dans une file. Le worker d'ingestion parse et découpe chaque document, appelle le modèle d'embedding, fait un upsert des chunks et des vecteurs avec leurs étiquettes d'accès dans l'index vectoriel, et écrit les métadonnées des documents dans Postgres.
- Au centre, les modèles et stockages partagés. Le même modèle d'embedding, à version figée, sert les deux chemins. Le LLM se trouve là aussi, appelé uniquement par le chemin de requête.
- À droite, la requête. L'API RAG récupère les groupes de l'utilisateur, calcule l'embedding de la question, lance la recherche hybride avec le filtre de permissions, envoie 50 candidats au reranker et appelle le LLM avec les 8 meilleurs chunks.
- En bas à gauche. Un exemple de budget de latence par étape, pour qu'une réponse lente puisse être rattachée à l'étape qui a dépassé son budget.
Ce qu'il faut étiqueter
- Les versions des modèles sur chaque nœud de modèle, y compris le modèle d'embedding.
- Les paramètres de chunking sur le worker d'ingestion ou dans une note.
- L'endroit où les permissions s'appliquent, sur le lien de récupération, pas dans une note de bas de page.
- Le nombre de résultats qui circulent entre les étapes : 50 récupérés, 8 dans le prompt.
- Les objectifs de fraîcheur et de latence : en combien de temps un changement de la source devient interrogeable, et le budget de chaque étape de requête.
Les erreurs courantes
- Une seule boîte appelée « IA ». La récupération, le reranking et la génération échouent de façons différentes et méritent des boîtes séparées.
- Pas de chemin d'ingestion. Les réponses périmées ou manquantes commencent souvent là.
- Pas de permissions. Si l'index contient des documents destinés à des publics différents, un diagramme sans étiquettes d'accès décrit une fuite de données.
- Pas d'évaluation. Sans jeu de questions, chaque modification du prompt ou de la taille des chunks est un pari.
- Des versions d'embedding mélangées. Recalculer les embeddings de la moitié du corpus avec un nouveau modèle casse la recherche sans bruit.
Quand le RAG n'est pas la réponse
- La réponse se trouve dans des données structurées. Interrogez la base de données ou une API plutôt que de calculer les embeddings des lignes d'une table.
- La tâche nécessite un document entier. Résumer un contrat fonctionne mieux avec le contrat complet dans le prompt, s'il y tient.
- Le corpus est minuscule. Quelques pages peuvent aller directement dans le prompt.
- Vous avez besoin d'un comportement différent, pas de plus de connaissances. C'est un problème de prompt ou de fine-tuning.
Pour une ingestion orientée événements avec des files, consultez le guide du diagramme d'architecture orientée événements.
Le construire dans Archboard
- Connectez-vous avec Google ou GitHub et créez un diagramme.
- Ajoutez deux nœuds Cadre du pack Base : « Ingestion path » à gauche et « Query path » à droite.
- Dans le cadre d'ingestion, ajoutez un Magasin d'objets du pack Données pour les documents sources, une File d'attente du pack Données pour les tâches d'ingestion et un Conteneur du pack Modèle C4 pour le worker d'ingestion.
- Au centre, ajoutez un Modèle du pack ML pour le modèle d'embedding, un Index vectoriel du pack ML, un Postgres du pack Données pour les métadonnées et les permissions, et un second Modèle pour le LLM.
- Dans le cadre de requête, ajoutez une Personne du pack Modèle C4 pour l'utilisateur, un Conteneur pour l'API RAG et un Modèle du pack ML pour le reranker.
- Étiquetez chaque lien avec ce qui y circule, y compris « top 50 » et « top 8 », et placez le budget de latence dans un bloc Markdown du pack Base.
L'exemple utilise 13 nœuds de diagramme et reste dans les limites de l'offre Free. Si vous travaillez avec un agent IA, il peut dessiner pour vous une première version via MCP à partir d'une description des deux chemins ; consultez comment créer des diagrammes d'architecture avec des agents IA. Pour la méthode générale, voyez comment dessiner un diagramme d'architecture logicielle.
FAQ
Ai-je besoin d'une base de données vectorielle dédiée pour le RAG ? Non. Une extension vectorielle dans une base que vous exploitez déjà, comme pgvector dans PostgreSQL, ou un moteur de recherche avec prise en charge des vecteurs suffit pour beaucoup d'applications. Choisissez selon la taille du corpus, vos besoins de filtrage et ce que votre équipe sait bien exploiter.
Quelle taille de chunk utiliser ? Il n'y a pas de valeur universelle. Découpez selon les titres et les paragraphes, puis comparez quelques tailles et chevauchements sur votre propre jeu de questions.
Où faut-il contrôler les permissions ? À l'ingestion, en copiant la liste d'accès de chaque document dans ses chunks, et à la récupération, en filtrant sur cette liste. Ne comptez jamais sur le prompt pour cacher un contenu.
Comment évaluer une application RAG ? Gardez un jeu fixe de vraies questions avec leurs sources attendues. Mesurez si la récupération trouve ces sources, et si les réponses sont fidèles au contexte récupéré et pertinentes pour la question.
Le LLM devrait-il appeler des outils plutôt que d'utiliser le RAG ? Pour des données en direct ou structurées, oui : un outil qui interroge le système de référence vaut mieux qu'un index de copies. Beaucoup d'applications utilisent les deux.