Système de recherche documentaire intelligent avec RAG (Retrieval-Augmented Generation) hybride
RAG Insights est une application full-stack de recherche documentaire avancée qui combine :
- Recherche vectorielle dense (embeddings sémantiques)
- Recherche sparse (BM25)
- Fusion hybride (RRF - Reciprocal Rank Fusion)
- Reranking avec cross-encoder
- Génération de réponses via LLM avec citations précises
Le système ingère des documents PDF et DOCX, les découpe intelligemment en chunks, les indexe dans Qdrant, puis permet d'effectuer des recherches sémantiques précises et de générer des réponses synthétiques citant les sources.
Recherche sémantique classique
Génération de réponse via LLM avec citations
Backend (Python + FastAPI)
- FastAPI : API REST haute performance
- Qdrant : Base de données vectorielle pour la recherche sémantique
- FastEmbed : Génération d'embeddings (
BAAI/bge-small-en-v1.5) - BM25Okapi : Recherche lexicale (sparse retrieval)
- CrossEncoder : Reranking avec
BAAI/bge-reranker-base - PyPDF + docx2txt : Extraction de texte
- OpenAI API : Génération de réponses (compatible avec tout endpoint OpenAI)
Frontend (React + TypeScript)
- React 19 + Vite : Interface utilisateur moderne
- TailwindCSS : Styling
- Radix UI : Composants accessibles
- React Markdown : Rendu des réponses formatées
Infrastructure
- Qdrant : Serveur de vecteurs
- PostgreSQL : Base de données
- Temporal : Orchestration de workflows (optionnel)
- Docker Compose : Déploiement simplifié
- Python 3.10+
- Node.js 18+
- Docker et Docker Compose
git clone https://github.com/iamhmh/rag-insights.git
cd rag-insightscd infrastructure
docker-compose up -d
cd ..Vérifiez que les services sont actifs :
- Qdrant : http://localhost:6333/dashboard
- PostgreSQL :
localhost:5432 - Temporal UI : http://localhost:8080
cd backend
python -m venv .venv
source .venv/bin/activate # Sur Windows: .venv\Scripts\activate
pip install fastapi uvicorn qdrant-client fastembed pypdf docx2txt rank-bm25 sentence-transformers python-multipart httpx python-dotenvCréer un fichier .env dans backend/ :
LLM_API_BASE=https://api.openai.com/v1
LLM_API_KEY=sk-proj-VOTRE_CLE_API_OPENAI
LLM_MODEL=gpt-4o-mini
QDRANT_URL=http://localhost:6333
QDRANT_COLLECTION=docs_v1cd backend
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000L'API sera accessible sur http://localhost:8000
cd frontend
npm install
npm run devL'interface web sera accessible sur http://localhost:5173
Via l'interface web :
- Cliquez sur "Choisir un fichier" (PDF ou DOCX)
- Cliquez sur "Uploader & Indexer"
Via l'API :
curl -X POST http://localhost:8000/upload \
-F "file=@mon-document.pdf"Indexation en batch (tous les fichiers dans backend/data/raw/) :
curl -X POST http://localhost:8000/ingest/batchInterface web :
- Tapez votre requête dans la barre de recherche
- Cliquez sur "Rechercher"
- Les résultats apparaissent avec :
- Score de similarité
- Nombre de hits exacts
- Surlignage des termes trouvés
API :
curl -X POST http://localhost:8000/search \
-H "Content-Type: application/json" \
-d '{"q": "ISO-9001 audit", "top_k": 5, "debug": false}'Interface web :
- Tapez votre question
- Cliquez sur "Rédiger une réponse"
- Une réponse synthétique avec citations [1], [2], etc. est générée
API :
curl -X POST http://localhost:8000/answers \
-H "Content-Type: application/json" \
-d '{
"q": "Quelles sont les exigences pour l audit ISO-9001 ?",
"top_k": 5,
"max_tokens": 350,
"temperature": 0.1
}'Réponse :
{
"answer": "### Réponse synthétique\n\n- L'audit ISO-9001 requiert une revue documentaire complète [1]\n- Les non-conformités doivent être corrigées sous 30 jours [2]\n\n**Sources :** [1] ISO-9001.pdf | [2] Procedures-audit.pdf",
"citations": [
{"id": 1, "source": "ISO-9001.pdf", "url": "http://localhost:8000/files/ISO-9001.pdf"},
{"id": 2, "source": "Procedures-audit.pdf", "url": "http://localhost:8000/files/Procedures-audit.pdf"}
]
}| Endpoint | Méthode | Description |
|---|---|---|
/health |
GET | Vérification de l'état du serveur |
/upload |
POST | Upload et indexation d'un fichier PDF/DOCX |
/ingest/batch |
POST | Indexation de tous les fichiers du dossier data/raw/ |
/search |
POST | Recherche hybride (dense + sparse + fusion RRF) |
/answers |
POST | Génération de réponse synthétique avec LLM |
/metrics |
GET | Métriques de performance (latence, requêtes) |
/files/{filename} |
GET | Accès aux fichiers sources originaux |
- Recherche Dense : Utilise des embeddings (
BAAI/bge-small-en-v1.5) pour capturer la similarité sémantique - Recherche Sparse : BM25 pour les matchs lexicaux exacts
- Fusion RRF : Combine les deux approches en fusionnant les rangs
- Reranking : CrossEncoder pour affiner le classement final
- Découpage sémantique : Split sur les phrases (
.,!,?) - Overlap : 150 caractères de chevauchement entre chunks
- Taille optimale : Max 900 caractères par chunk
- Préserve la continuité du contexte
- Prompt engineering : Instructions strictes pour éviter les hallucinations
- Citations automatiques : Chaque fait est sourcé avec [n]
- Déduplication : Suppression des phrases répétées
- Limitation : Max 3 sources, 5 puces
- Fallback : Réponse extractive si l'API LLM échoue
curl http://localhost:8000/metricsRetourne :
- Compteur de requêtes par endpoint
- Latence moyenne et p95
- Historique des dernières requêtes
- Barre de recherche : Autocomplete, highlight des termes
- Cartes de résultats : Score, hits exacts, surlignage
- Upload de documents : Drag & drop, feedback visuel
- Panneau de réponses : Markdown avec citations cliquables
highlight.ts: Surlignage des termes de recherchecountHits.ts: Comptage des occurrences exactes
# API LLM (OpenAI-compatible)
LLM_API_BASE=https://api.openai.com/v1
LLM_API_KEY=sk-proj-...
LLM_MODEL=gpt-4o-mini
# Qdrant
QDRANT_URL=http://localhost:6333
QDRANT_COLLECTION=docs_v1
# Optionnel
EMBED_MODEL=BAAI/bge-small-en-v1.5 # Modèle d'embeddings
RERANK_MODEL=BAAI/bge-reranker-base # Modèle de rerankingDans main.py, ajustez :
# Nombre de candidats à récupérer en recherche dense
topk_dense = 50
# Nombre de résultats finaux après fusion
topk_final = 6
# Nombre de chunks à envoyer au LLM
max(3, body.top_k)
# Taille des chunks
max_chars = 900
overlap = 150{
"q": "uptime 99.5% pénalités SLA",
"top_k": 5
}{
"q": "Comment réaliser un audit ISO-9001 conforme ?",
"top_k": 5,
"max_tokens": 400,
"temperature": 0.1
}{
"q": "huile ISO-46 pompe hydraulique",
"top_k": 3,
"debug": true
}rag-insights/
├── backend/
│ ├── app/
│ │ ├── main.py # API FastAPI + endpoints
│ │ └── ingest.py # Ingestion documents + chunking
│ ├── data/
│ │ ├── raw/ # Documents sources (PDF/DOCX)
│ │ └── chunks/ # (optionnel) chunks sauvegardés
│ └── .env # Configuration backend
├── frontend/
│ ├── src/
│ │ ├── App.tsx # Composant principal
│ │ ├── components/ui/ # Composants Radix UI
│ │ └── lib/ # Utilitaires (highlight, countHits)
│ └── package.json
├── infrastructure/
│ ├── docker-compose.yml # Qdrant + PostgreSQL + Temporal
│ ├── pg/ # Volume PostgreSQL
│ └── qdrant/ # Volume Qdrant
├── images/
│ ├── search.png # Capture recherche sémantique
│ └── search_llm.png # Capture recherche avec LLM
└── README.md
Backend :
# Lancer le serveur en mode dev
uvicorn app.main:app --reload
# Indexer tous les fichiers
curl -X POST http://localhost:8000/ingest/batch
# Vérifier la santé de l'API
curl http://localhost:8000/healthFrontend :
# Développement
npm run dev
# Build production
npm run build
# Preview production
npm run previewInfrastructure :
# Démarrer tous les services
docker-compose up -d
# Arrêter
docker-compose down
# Logs
docker-compose logs -f qdrant- Support de formats supplémentaires (Markdown, HTML, CSV)
- Interface d'administration (gestion des collections Qdrant)
- Authentification utilisateur
- Historique des recherches
- Export des résultats (PDF, JSON)
- Mode multi-tenancy (plusieurs collections)
- Optimisation des embeddings (quantization)
- Workflows Temporal pour indexation asynchrone
- Tests unitaires et d'intégration
- CI/CD avec GitHub Actions
MIT License - Voir LICENSE pour plus de détails.
hmh - @iamhmh

