Spaces:
Sleeping
Sleeping
| # 🚀 Pistes d'amélioration — RAG Number_one | |
| Objectif du hackathon : **JUSTE** (accuracy) · **PAS CHER** (tokens) · **SOBRE** (CO₂). | |
| On avance **dans l'ordre**, une piste à la fois, en mesurant l'effet avant de passer à la suivante. | |
| > État de base actuel : 152 mémoires, 84 840 chunks, `text-embedding-3-small`, LLM `gpt-5.1`, | |
| > recherche cosinus top-3, `temperature=0.7`. Pipeline = `rag_query()` dans `app.py`. | |
| --- | |
| ## 1. ✍️ Améliorer le pré-prompt `[ À FAIRE ]` | |
| **Objectif :** de meilleures réponses (plus justes, moins d'hallucinations, format respecté) sans rien changer au code. | |
| **Où :** `prompts/rag_prompt.txt` (chargé tel quel par `build_rag_prompt()` dans `app.py`). | |
| **Comment :** | |
| - Rendre les consignes plus strictes : répondre **uniquement** à partir du contexte, dire explicitement « information insuffisante » sinon (anti-hallucination). | |
| - Soigner le format JSON exigé (`answer`, `explanation`) — un écart = parsing raté. | |
| - Ajouter éventuellement : style concis, citer les sources, raisonner étape par étape avant de répondre. | |
| - Spécialiser le ton « expert actuariat » (vocabulaire métier). | |
| **Impact attendu :** ↗️ accuracy · coût/CO₂ ≈ neutres (prompt un peu plus long). | |
| **Risque :** faible. **Effort :** très faible. → **Meilleur rapport gain/effort, on commence par là.** | |
| --- | |
| ## 2. 🎯 Réduire le `k` (top-3 → top-2 ?) `[ À FAIRE ]` | |
| **Objectif :** moins de tokens injectés dans le prompt → **moins cher + moins de CO₂**, si 2 passages suffisent à répondre. | |
| **Où :** `app.py` → `TOP_K_RESULTS = 3` (≈ ligne 60). Aussi le défaut de `/query`. | |
| **Comment :** | |
| - Tester `k=2` et comparer l'accuracy vs `k=3` sur quelques questions types. | |
| - Chaque chunk ≈ 130 tokens → passer de 3 à 2 économise ~1 chunk de contexte par requête, à chaque appel. | |
| **Impact attendu :** ↘️ coût · ↘️ CO₂ · accuracy = à surveiller (risque de perdre le bon passage). | |
| **Risque :** moyen (si le bon contexte était le 3ᵉ). **Effort :** très faible (1 ligne). | |
| **Note :** à tester APRÈS le prompt, pour mesurer proprement. | |
| --- | |
| ## 3. 🌡️ Régler la température du LLM `[ À FAIRE ]` | |
| **Objectif :** réponses plus **déterministes et factuelles** (moins de variabilité/invention). | |
| **Où :** `config.json` → `llm.temperature` (actuellement `0.7`), lu par `app.py`. | |
| **Comment :** | |
| - Pour du factuel/RAG, une température **basse** (ex. `0.0`–`0.3`) est généralement préférable. | |
| - Tester `0.2` puis `0.0`, comparer la justesse et la stabilité des réponses. | |
| **Impact attendu :** ↗️ accuracy (moins d'hallucinations) · coût/CO₂ ≈ neutres. | |
| **Risque :** faible. **Effort :** très faible (1 valeur). | |
| --- | |
| ## 4. 🔁 Cross-encoder (reranker) `[ À FAIRE ]` | |
| **Objectif :** récupérer les **bons** passages → c'est *« la qualité du retrieval qui fait le score »*. | |
| **Principe :** | |
| ``` | |
| question → recherche cosinus large (top-20) ← rappel | |
| → cross-encoder reclasse les 20 (lit question+passage ENSEMBLE) | |
| → garde les top-2/3 meilleurs → LLM ← précision | |
| ``` | |
| **Où :** `retrieve_relevant_context()` dans `app.py` (élargir le `n_results`, ajouter une étape de rerank avant de renvoyer). | |
| **Comment :** | |
| - Modèle type `BAAI/bge-reranker-v2-m3` via `sentence-transformers`, **en local sur le GPU**. | |
| - Bien plus précis que le cosinus (qui compare 2 vecteurs figés). | |
| **Impact attendu :** ↗️↗️ accuracy (souvent le plus gros levier) · coût ≈ neutre (rerank local, pas d'appel payant) · CO₂ : un peu de calcul GPU local. | |
| **Risque :** moyen (latence + dépendance). **Effort :** moyen. **⚡ Le GPU sert enfin ici.** | |
| --- | |
| ## 5. 🧭 Routing petit/gros modèle via le cross-encoder `[ À FAIRE ]` | |
| **Objectif :** envoyer les questions **simples** sur **GPT-5-mini** (petit, pas cher, sobre) et garder **GPT-5.1** pour les **difficiles** → c'est l'*« arbitrage intelligent »* explicitement récompensé par le jury. | |
| **Principe :** | |
| ``` | |
| question + passages → score de confiance (issu du cross-encoder / du retrieval) | |
| ├─ confiance haute (question simple, contexte net) → GPT-5-mini (€/CO₂ ↓↓) | |
| └─ confiance basse (ambigu, technique) → GPT-5.1 | |
| ``` | |
| **Où :** dans `rag_query()` (`app.py`), choisir dynamiquement le modèle/endpoint avant l'appel LLM. Nécessite d'ajouter la config du **mini** dans `config.json` (2ᵉ endpoint/modèle). | |
| **Comment :** | |
| - Réutiliser le **score du reranker** (piste 4) comme signal de difficulté/confiance : score élevé sur le top-1 ⇒ question bien couverte ⇒ mini suffit. | |
| - Seuil à calibrer sur des exemples. | |
| **Impact attendu :** ↘️↘️ coût · ↘️↘️ CO₂ · accuracy ≈ maintenue si le seuil est bien réglé. | |
| **Risque :** moyen-élevé (calibrer le seuil sans perdre en accuracy). **Effort :** moyen-élevé. | |
| **Dépend de :** la piste 4 (le cross-encoder fournit le signal de confiance). | |
| --- | |
| ## Ordre de travail recommandé | |
| 1 → 2 → 3 (gains rapides, faible risque) puis 4 (gros levier accuracy) puis 5 (gros levier coût/CO₂, s'appuie sur 4). | |
| ⚠️ **À chaque changement** : tester quelques questions, vérifier que le **format JSON de `/query` reste intact** (sinon score = 0), puis re-déployer (push + restart Space). | |