RAG bout en bout avec Chroma, FastAPI et Llama 3.2
Un assistant RAG opérationnel du début à la fin : segmentation des PDF, réclassement via un cross-encoder, Chroma, Llama 3.2 sur Ollama, FastAPI, Docker, pytest et GitHub Actions pour les tests en continu.
Sources: I Built a Production-Style RAG Knowledge Assistant with Python, ChromaDB, FastAPI, and Llama 3.2
RAG de type production : ingestion vers le CI
Un assistant à la connaissance basé sur des sources citées — ingestion de PDF, recherche sémantique, réclassement, génération locale avec Llama, FastAPI, Docker et GitHub Actions — conçu comme un système d’apprentissage plutôt que comme un simple notebook.
Après une première expérience avec MCP, le prochain défi était la génération améliorée par la récupération d’informations, avec évaluation et emballage, et non encore une simple fonction d’« upload de PDF dans Colab ».
Objectifs
Indexer les documents dans un stockage vectoriel persistant ; récupérer, réclasser et étayer les réponses avec des citations ; fournir du contenu via HTTP ; évaluer la qualité à l’aide d’outils simples comme pytest ; containeriser le tout et l’intégrer au CI afin que les dérives soient immédiatement détectées.
Architecture
Esquisse de l’indexation :
Documents
↓
Chunking
↓
Embeddings
↓
Vector Database
↓
Semantic Retrieval
↓
Reranking
↓
LLM
↓
Grounded Answer + Sources
Parcours de chargement des documents :
PDF Documents
↓
Document Loading
↓
Text Chunking
↓
Embeddings
↓
ChromaDB
Parcours de réponse aux questions :
User Question
↓
Semantic Retrieval
↓
Cross-Encoder Reranking
↓
Prompt Construction
↓
Llama 3.2
↓
Grounded Answer
↓
Source Citations
1. Ingestion
Chargez des PDF dans des documents de type LangChain, en conservant les métadonnées des pages pour des citations ultérieures. Des chargeurs défectueux entraînent par la suite des erreurs de citation silencieuses.
2. Fragmentation
Chunk size: 1000 characters
Chunk overlap: 200 characters
L’overlap permet aux phrases situées à la frontière entre deux fragments de ne pas disparaître lors de la récupération des données. Traitez les tailles comme des paramètres configurables, et non comme des valeurs magiques cachées dans une cellule de notebook.
3. Encodages
sentence-transformers/all-MiniLM-L6-v2
Un petit modèle sentence-transformer suffit pour faire fonctionner la démonstration sur un ordinateur portable, tout en restant suffisamment performant pour les documents techniques en anglais.
4. Persistance de Chroma
Document
↓
Chunks
↓
Embedding Vectors
↓
ChromaDB
Les fragments deviennent des vecteurs sur le disque, de sorte que les redémarrages n’obligent pas à un re-encodage complet. Versionnez le nom de la collection lorsque la stratégie de fragmentation change.
5. Récupération sémantique
documents = vector_store.similarity_search(
query=query,
k=top_k
)
Prenez les k voisins les plus pertinents comme première étape avant d’utiliser les ressources du cross-encoder.
6. Réclassement par le cross-encoder
cross-encoder/ms-marco-MiniLM-L-6-v2
User Question
↓
Vector Search
↓
Candidate Documents
↓
CrossEncoder
↓
Reranked Documents
Le rappel du bi-encodeur combiné à la précision de l’encodeur croisé constitue le modèle en deux étapes standard pour les systèmes RAG sensibles à la qualité.
7. Ancrage du LLM
La construction des prompts insère les extraits classés en tant que sources numérotées :
[Source 1]
Retrieved document content...
[Source 2]
Retrieved document content...[Source 3]
Retrieved document content...
Indiquez au modèle de ne répondre qu’à partir de ces blocs et d’en citer les sources. Refusez la réponse lorsque le contexte est vide.
8. Llama local via Ollama
La génération s’effectue directement sur l’appareil afin de préserver la confidentialité et réduire les coûts. Fixez l’identifiant correspondant dans la configuration et vérifiez le processus Ollama avant d’accepter les requêtes.
9. Interface FastAPI
GET /health
POST /query
Vérifiez l’état du système pour les tests ; effectuez la requête via le chemin RAG. Gardez le service léger — utilisez le même pipeline que celui utilisé par la ligne de commande.
Rappel complet du flux de requête :
Question
↓
Semantic Retrieval
↓
Retrieved Chunks
↓
CrossEncoder Reranking
↓
Grounded Prompt
↓
Llama 3.2
↓
Answer + Citations
10. Évaluation
Questions evaluated: 5
Questions passed: 5
Keyword Match Rate: 100.00%
Hit Rate@K
Recall@K
MRR
Answer Relevance
Faithfulness
Citation Correctness
Les vérifications des mots-clés ainsi que les métriques de récupération (taux de succès, rappel, MRR, pertinence de la réponse) permettent de détecter les dégradations silencieuses lorsque les embeddings ou les prompts changent.
11. pytest
API health endpoint
Document chunking
Document retrieval
3 passed
Vérifiez l’état de la couverture des tests, le découpage en blocs et les tests de base de récupération afin que l’CI échoue rapidement.
12. Leçon sur Docker
Les surprises liées à la taille des images sont fréquentes lorsque des modèles se glissent dans les couches :
1.36 GB
1.36 GB
2.56 KB
Ignorez correctement les caches et les virtualenvs :
.venv/
__pycache__/
*.pyc
.pytest_cache/
.git/
.github/
.env
chroma_db/
data/sample/*.pdf
*.log
Préférez monter les caches des modèles en temps de exécution afin que les reconstitutions restent légères.
13. GitHub Actions
Push / Pull Request
↓
GitHub Actions
↓
Checkout Repository
↓
Set Up Python
↓
Install Dependencies
↓
Run pytest
Les requêtes push et pull request doivent exécuter des vérifications de syntaxe, des tests unitaires, ainsi éventuellement un job d’évaluation simplifié avec des fixtures.
Stack, difficulté, prochaines étapes
Document Processing
↓
Chunking
↓
Embeddings
↓
Vector Storage
↓
Retrieval
↓
Reranking
↓
Prompt Construction
↓
LLM Generation
↓
Citation Handling
↓
Evaluation
↓
API
↓
Testing
↓
Deployment
Les défis principaux ne concernaient pas tant l’utilisation d’un LLM que plutôt les limites entre les blocs de données, la latence de réordonnancement, le formatage des citations et l’encombrement des couches Docker. Prochaines améliorations : recherche hybride, un ensemble d’évaluation plus important avec des étiquettes, authentification avant FastAPI, ainsi que des outils d’observation de la latence de récupération.
Un approche de type production signifie que l’évaluation et le packaging s’accompagnent des idées présentées dans les notebooks — ce qui ne remplace pas pour autant une équipe dédiée à la plateforme.
Suivez la taille et le degré d’overlap des blocs dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille et le degré d’overlap des blocs dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille et le degré d’overlap des blocs dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille et le degré d’overlap des blocs dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille et le degré d’overlap des blocs dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.
Suivez la taille des blocs et le degré d’overlap dans la configuration afin que les expériences restent comparables entre les branches.