plateforme RAG open-source : transformer vos docs en base de données
Un PDF de 50 pages est une boîte noire pour un LLM sans une plateforme RAG open-source. Envoyer l’intégralité d’un corpus dans un prompt est impossible à cause de la limite de la fenêtre de contexte.
Le RAG (Retrieval-Augmented Generation) résout ce problème en extrayant uniquement les segments pertinents avant l’inférence. Avec des modèles comme Llama 3 ou Mistral, l’enjeu est de structurer la donnée pour réduire la latence de recherche sous la barre des 200ms.
Après ce guide, vous saurez mettre en place un pipeline d’ingestion, gérer un moteur de recherche vectoriel et interroger vos documents via une API Ruby.
🛠️ Prérequis
Installation des dépendances système et environnement de développement :
- Docker 24.0+ pour l’instance ChromaDB
- Python 3.12 pour les scripts de parsing de PDF
- Ruby 3.3+ avec la gem langchainrb
- Ollama (version 0.1.30+) pour l’exécution locale des embeddings
📚 Comprendre plateforme RAG open-source
Le fonctionnement d’une plateforme RAG open-source repose sur quatre piliers : l’ingestion, le chunking, l’embedding et le retrieval.
Le chunking consiste à découper le texte en morceaux (chunks) de taille fixe ou variable. Un chunk trop petit perd le contexte ; un chunk trop grand dilue la précision de la recherche vectorielle. L’embedding transforme ces morceaux en vecteurs numériques dans un espace à N dimensions. La recherche vectorielle utilise la similarité cosinus pour trouver les vectels les plus proches de la requête utilisateur.
Flux de données : [Document] -> [Parsing] -> [Chunking] -> [Embedding Model] -> [Vector Store] Requête Utilisateur -> [Embedding] -> [Similarity Search] -> [Context + Prompt] -> [LLM] -> [Réponse]
Contrairement à une recherche SQL classique utilisant des index B-Tree, nous utilisons ici des index HNSW (Hierarchical Navigable Small World) pour naviguer dans l’espace vectoriel.
💎 Le code — plateforme RAG open-source
📖 Explication
Dans le premier snippet, l’utilisation de Langchain::Embeddings::Ollama est cruciale. Pourquoi ? Parce qu’elle permet de garder vos données en local, respectant la confidentialité. Si vous utilisez OpenAI, vos données sortent de votre infrastructure.
Le second snippet montre un algorithme de chunking rudimentaire. Attention, ne l’utilisez pas tel quel en production. Le découpage par mot est dangereux car il ignore la sémantique. La doc de LangChain recommande le RecursiveCharacterTextSplitter qui tente de couper aux paragraphes, puis aux phrases, puis aux mots. L’utilisation d’un overlap (recouvrement) est indispensable pour maintenir le contexte entre deux segments.
Piège classique : ne pas configurer le index_name de manière unique. Si vous mélangez deux documents différents dans le même index, la précision du retrieval s’effondre.
🔄 Second exemple
Tutoriel pas-à-pas
La mise en place d’une plateforme RAG open-source nécessite une orchestration rigoureuse. Ne commencez pas par le code, commencez par l’infrastructure.
1. Déploiement de l’infrastructure vectorielle
Lancez ChromaDB avec Docker. Cette base de données stockera vos vecteurs. Sans elle, votre plateforme RAG open-source n’a pas de mémoire à long terme.
docker run -d -p 8000:8000 chromadb/chroma
Vérifiez la disponibilité avec un simple curl sur l’endpoint /api/v1/heartbeat.
2. Préparation de l’ingestion de données
Le parsing est l’étape la plus critique. Un PDF mal extrait produit des chunks incohérents. Utilisez une bibliothèque comme PyPDF2 en Python 3.12 pour extraire le texte brut. Si vous avez des tableaux, le parsing standard échouera. Dans ce cas, prévoyez une étape de conversion en Markdown.
3. Configuration de l’Embedding local
Pour rester dans une démarche de plateforme RAG open-source, évitez les API payantes. Installez Ollama. Téléchargez le modèle ‘nomic-embed-text’ qui est optimisé pour les tâches de retrieval. Ce modèle produit des vecteurs de 768 dimensions, ce qui est un excellent compromalle entre performance et précision.
4. Implémentation du pipeline Ruby
Utilisez la gem langchainrb. Elle permet d’abstraire la complexité des appels API vers ChromaDB. Votre script doit : charger le texte, le découper via la méthode de chunking définie plus haut, générer les embeddings via Ollama, et envoyer le tout à ChromaDB.
5. Test de la boucle de requête
Une fois l’indexation terminée, testez la récupération. Envoyez une question. Le système doit retourner les chunks les plus proches. Si la réponse est hors sujet, ajustez le paramètre ‘overlap’ de votre chunking.
▶️ Exemple d’utilisation
Exécution du script d’indexation sur un document de test :
engine = RagEngine.new
document_content = File.read('manual_v1.txt')
engine.add_document(document_content, { source: 'manual_v1.txt', version: '1.0' })
# Test de recherche
query = "Comment réinitialiser le mot de passe ?"
results = engine.query(query)
puts results.first.content
Sortie attendue :
[Found 3 relevant chunks]
"Pour réinitialiser le mot de passe, cliquez sur l'onglet Paramètres puis sur Sécurité..."
🚀 Cas d’usage avancés
1. Analyse de logs système : Indexez vos fichiers de logs Linux. Vous pouvez poser des questions comme « Quand est apparu le premier error 500 ? » en utilisant le RAG pour scanner des gigaoctets de logs.
2. Documentation technique interne : Intégrez vos fichiers Markdown de documentation. La plateforme RAG open-source devient un assistant pour vos nouveaux développeurs.
3. Audit de conformité : Chargez vos fichiers PDF de régulation. Le système peut vérifier si une nouvelle procédure respecte les règles extraites du texte source.
🐛 Erreurs courantes
⚠️ Dimension mismatch
Erreur quand le modèle d’embedding change mais que l’index Chroma n’est pas réinitialisé.
engine.add_document(text)
rm -rf ./chroma_data && engine.add_document(text)
⚠️ Context Fragmentation
Le texte est coupé au milieu d’un mot important à cause d’un chunking sans overlap.
chunks = text.split(' ', 100)
chunks = chunk_text(text, chunk_size: 500, overlap: 50)
⚠️ Memory Overflow
Tentative d’envoyer un fichier de 100Mo d’un coup dans l’API d’embedding.
engine.add_document(huge_file_content)
huge_file_content.each_line { |line| engine.add_document(line) }
⚠️
Le modèle est trop lourd pour la RAM disponible, l’API ne répond plus.
model: 'llama3:70b'
model: 'mistral:7b'
✅ Bonnes pratiques
Pour maintenir une plateforme RAG open-source performante, suivez ces règles :
- Utilisez des métadonnées : Ne stockez pas que le texte. Stockez la date, l’auteur et l’URL source. Cela permet de filtrer la recherche par date (Metadata Filtering).
- Privilégiez le format Markdown : Le Markdown préserve la structure (titres, listes) que les modèles d’embedding utilisent pour comprendre la hiérarchie.
- Surveillez la latence : Le temps de génération d’embedding augmente de façon linéaire avec la taille des chunks.
- Implémentez un mécanisme de ré-indexation : Un document modifié doit être supprimé de l’index avant d’être ré-injecté pour éviter les doublons.
- Testez avec des ‘Golden Sets’ : Créez un jeu de questions/réponses dont vous connaissez la réponse pour mesurer la dégradation de votre système après chaque mise à jour.
- Le RAG évite de dépasser la fenêtre de contexte des LLM.
- ChromaDB est l'outil standard pour stocker les vecteurs en local.
- Le chunking avec overlap est indispensable pour la continuité sémantique.
- Ollama permet de faire tourner les embeddings sans dépendre du cloud.
- Le parsing de PDF est le maillon faible du pipeline.
- L'utilisation de Markdown améliore la précision du retrieval.
- La dimension des vecteurs doit être cohérente entre l'embedding et la DB.
- Le filtrage par métadonnées réduit drastiquement le bruit lors de la recherche.
❓ Questions fréquentes
Puis-je utiliser cette plateforme pour des données confidentielles ?
Oui, si vous utilisez Ollama et ChromaDB en local, aucune donnée ne quitte votre machine ou votre serveur privé.
Quelle est la limite de taille de mes documents ?
La limite n’est pas la taille du fichier, mais votre RAM et la capacité de votre disque à stocker l’index vectoriel.
Pourquoi mon moteur de recherche ne trouve pas de résultats ?
Vérifiez la similarité cosinus. Si vos chunks sont trop petits ou si le modèle d’embedding est différent de celui utilisé à l’indexation, la recherche échouera.
Est-ce que Ruby est adapté pour l'IA ?
Ruby n’est pas fait pour l’inférence (calcul tensoriel), mais il est excellent pour l’orchestration et l’API de votre plateforme RAG open-source via des gems comme langchainrb.
📚 Sur le même blog
🔗 Le même sujet sur nos autres blogs
📝 Conclusion
La mise en place d’une plateforme RAG open-source transforme des données inertes en une base de connaissances dynamique. La réussite dépend moins du modèle de langage choisi que de la qualité de votre pipeline d’ingestion et de votre stratégie de chunking. Pour approfondir l’usage des embeddings, consultez la documentation Ruby officielle. Le coût de l’infrastructure de stockage vectoriel reste le principal goulot d’étranglement à grande échelle.