Spaces:
Sleeping
Sleeping
File size: 5,301 Bytes
7e2d97f | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | # 🚀 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).
|