# 🚀 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).