Accueil / Articles

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.

Éditeur : REACTAPP.TOP8 min de lecture1747 mots

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.