GuideIntermédiaire

Température et Sampling RAG : Contrôler la créativité du LLM

15 mars 2026
15 min de lecture
Équipe Ailog

Guide complet sur les paramètres de sampling pour systèmes RAG : température, top-p, top-k, frequency penalty. Optimisez la balance entre créativité et fidélité.

TL;DR

Les paramètres de sampling (température, top-p, top-k) contrôlent le niveau de créativité et de déterminisme des réponses LLM. En RAG, ces paramètres sont critiques : trop de créativité = hallucinations, trop de déterminisme = réponses robotiques. Ce guide vous apprend à calibrer ces paramètres selon votre cas d'usage.

Comprendre les paramètres de sampling

Qu'est-ce que le sampling ?

Quand un LLM génère du texte, il prédit une distribution de probabilités sur tous les tokens possibles pour le prochain mot. Le sampling détermine comment choisir parmi ces candidats.

DEVELOPERpython
# Exemple simplifié de distribution de probabilités next_token_probs = { "rapidement": 0.35, "vite": 0.25, "promptement": 0.15, "immédiatement": 0.12, "instantanément": 0.08, "...": 0.05 } # Sans sampling (greedy) : toujours "rapidement" # Avec sampling : peut choisir "vite", "promptement", etc.

Vue d'ensemble des paramètres

ParamètrePlageEffetUsage RAG typique
Temperature0.0 - 2.0Contrôle la "chaleur" de la distribution0.1 - 0.5
Top-p0.0 - 1.0Nucleus sampling0.9 - 1.0
Top-k1 - 100+Limite les candidats40 - 80
Frequency penalty-2.0 - 2.0Pénalise les répétitions0.0 - 0.5
Presence penalty-2.0 - 2.0Encourage la diversité0.0 - 0.3

La température en détail

Fonctionnement mathématique

La température modifie la distribution softmax des probabilités :

DEVELOPERpython
import numpy as np def apply_temperature(logits: np.array, temperature: float) -> np.array: """ Applique la température aux logits. - temperature < 1 : distribution plus piquée (déterministe) - temperature = 1 : distribution originale - temperature > 1 : distribution plus plate (aléatoire) """ if temperature == 0: # Greedy: retourne un vecteur one-hot sur le max result = np.zeros_like(logits) result[np.argmax(logits)] = 1.0 return result scaled_logits = logits / temperature exp_logits = np.exp(scaled_logits - np.max(scaled_logits)) return exp_logits / np.sum(exp_logits) # Exemple logits = np.array([2.0, 1.5, 1.0, 0.5, 0.2]) print("Temp 0.1:", apply_temperature(logits, 0.1)) # [0.99, 0.01, 0.00, 0.00, 0.00] - presque déterministe print("Temp 1.0:", apply_temperature(logits, 1.0)) # [0.42, 0.26, 0.15, 0.09, 0.07] - distribution originale print("Temp 2.0:", apply_temperature(logits, 2.0)) # [0.29, 0.23, 0.19, 0.16, 0.14] - plus uniforme

Impact visuel

Température basse (0.1)        Température haute (1.5)
│                              │
│ ████████████                 │ ██████
│ ██                           │ █████
│ █                            │ ████
│                              │ ███
│                              │ ██
└────────────────              └────────────────
  Token 1 domine                 Distribution plate

Recommandations par cas d'usage RAG

Cas d'usageTempératureJustification
Support client factuel0.1 - 0.2Précision maximale, pas de créativité
FAQ automatisée0.2 - 0.3Variations légères acceptables
Assistant e-commerce0.3 - 0.5Un peu de personnalité
Rédaction assistée0.5 - 0.7Créativité contrôlée
Brainstorming0.7 - 1.0Idées variées bienvenues

Top-p (Nucleus Sampling)

Comment ça marche

Top-p sélectionne les tokens dont les probabilités cumulées atteignent p :

DEVELOPERpython
def top_p_sampling(probs: dict, p: float) -> list: """ Retourne les tokens dont la probabilité cumulée atteint p. """ # Trier par probabilité décroissante sorted_tokens = sorted(probs.items(), key=lambda x: x[1], reverse=True) cumulative_prob = 0.0 selected_tokens = [] for token, prob in sorted_tokens: cumulative_prob += prob selected_tokens.append((token, prob)) if cumulative_prob >= p: break return selected_tokens # Exemple probs = { "Le": 0.40, "La": 0.25, "Un": 0.15, "Une": 0.10, "Ce": 0.05, "Cette": 0.03, "Mon": 0.02 } print(top_p_sampling(probs, 0.9)) # [("Le", 0.40), ("La", 0.25), ("Un", 0.15), ("Une", 0.10)] # Cumul: 0.90 - les autres sont exclus

Top-p vs Température

CritèreTempératureTop-p
ContrôleGlobal sur toute la distributionCoupe les tokens improbables
RisquePeut sélectionner des tokens très improbablesGarantit des tokens raisonnables
UsageAjuster la "confiance"Éviter les aberrations

Combinaison recommandée pour RAG

DEVELOPERpython
# Configuration recommandée pour un chatbot support rag_config = { "temperature": 0.3, # Peu de créativité "top_p": 0.95, # Garde 95% de la masse probabiliste "top_k": 50, # Maximum 50 candidats } # La température basse rend la distribution piquée # Top-p élimine les tokens avec < 5% de masse cumulative restante # Top-k met une limite dure sur le nombre de candidats

Top-k sampling

Principe

Top-k garde uniquement les k tokens les plus probables :

DEVELOPERpython
def top_k_sampling(probs: dict, k: int) -> dict: """ Garde les k tokens les plus probables. """ sorted_tokens = sorted(probs.items(), key=lambda x: x[1], reverse=True) top_k_tokens = dict(sorted_tokens[:k]) # Renormaliser total = sum(top_k_tokens.values()) return {t: p/total for t, p in top_k_tokens.items()} # Exemple probs = {"A": 0.3, "B": 0.25, "C": 0.2, "D": 0.15, "E": 0.1} print(top_k_sampling(probs, 3)) # {"A": 0.40, "B": 0.33, "C": 0.27} # D et E sont exclus, les autres renormalisés

Quand utiliser Top-k

  • k petit (10-20) : Réponses très conservatrices
  • k moyen (40-60) : Bon équilibre (recommandé pour RAG)
  • k grand (100+) : Presque pas de filtrage

Frequency et Presence Penalties

Frequency Penalty

Pénalise les tokens proportionnellement à leur fréquence dans le texte généré :

DEVELOPERpython
def apply_frequency_penalty( logits: dict, generated_tokens: list, penalty: float ) -> dict: """ Réduit la probabilité des tokens fréquemment utilisés. """ token_counts = {} for token in generated_tokens: token_counts[token] = token_counts.get(token, 0) + 1 adjusted_logits = {} for token, logit in logits.items(): count = token_counts.get(token, 0) adjusted_logits[token] = logit - (penalty * count) return adjusted_logits

Usage en RAG : Évite les réponses répétitives comme "comme mentionné précédemment..."

Presence Penalty

Pénalise tout token déjà apparu, indépendamment de la fréquence :

DEVELOPERpython
def apply_presence_penalty( logits: dict, generated_tokens: set, penalty: float ) -> dict: """ Réduit la probabilité des tokens déjà utilisés. """ adjusted_logits = {} for token, logit in logits.items(): if token in generated_tokens: adjusted_logits[token] = logit - penalty else: adjusted_logits[token] = logit return adjusted_logits

Usage en RAG : Encourage l'utilisation de synonymes et la variété lexicale.

Configuration optimale par modèle

OpenAI GPT-4

DEVELOPERpython
from openai import OpenAI client = OpenAI() # Configuration RAG recommandée response = client.chat.completions.create( model="gpt-4", messages=[ {"role": "system", "content": system_prompt}, {"role": "user", "content": f"Context: {context}\n\nQuestion: {query}"} ], temperature=0.3, top_p=0.95, frequency_penalty=0.2, presence_penalty=0.1, max_tokens=500 )

Anthropic Claude

DEVELOPERpython
import anthropic client = anthropic.Anthropic() # Claude utilise seulement temperature et top_p response = client.messages.create( model="claude-3-opus-20240229", max_tokens=500, temperature=0.3, top_p=0.95, messages=[ {"role": "user", "content": f"Context: {context}\n\nQuestion: {query}"} ] )

Modèles open-source (Llama, Mistral)

DEVELOPERpython
from transformers import AutoModelForCausalLM, AutoTokenizer model = AutoModelForCausalLM.from_pretrained("mistralai/Mistral-7B-Instruct-v0.2") tokenizer = AutoTokenizer.from_pretrained("mistralai/Mistral-7B-Instruct-v0.2") # Configuration RAG generation_config = { "temperature": 0.3, "top_p": 0.95, "top_k": 50, "repetition_penalty": 1.1, # Équivalent frequency_penalty "do_sample": True, "max_new_tokens": 500 } outputs = model.generate( input_ids, **generation_config )

Stratégies avancées

1. Sampling adaptatif

Ajuster les paramètres dynamiquement selon le contexte :

DEVELOPERpython
class AdaptiveSampler: def __init__(self): self.base_temperature = 0.3 def get_config(self, query_type: str, context_quality: float) -> dict: """ Ajuste les paramètres selon le contexte. - query_type: "factual", "creative", "mixed" - context_quality: 0-1, score de pertinence du contexte """ if query_type == "factual": # Questions factuelles : très déterministe temp = 0.1 elif query_type == "creative": # Questions créatives : plus de liberté temp = 0.7 else: temp = self.base_temperature # Si le contexte est de mauvaise qualité, être plus conservateur if context_quality < 0.5: temp *= 0.5 # Réduire la température return { "temperature": temp, "top_p": 0.95 if context_quality > 0.7 else 0.85, "frequency_penalty": 0.2 } # Utilisation sampler = AdaptiveSampler() config = sampler.get_config( query_type="factual", context_quality=0.85 )

2. Température variable par section

Utiliser différentes températures selon la partie de la réponse :

DEVELOPERpython
async def generate_structured_response(query: str, context: str): """ Génère une réponse avec des paramètres différents par section. """ # Section 1: Réponse factuelle (temp basse) factual_part = await llm.generate( prompt=f"Réponds factuellement: {query}\nContext: {context}", temperature=0.1, max_tokens=200 ) # Section 2: Explication (temp moyenne) explanation = await llm.generate( prompt=f"Explique pourquoi: {factual_part}", temperature=0.4, max_tokens=150 ) # Section 3: Suggestion (temp plus haute) suggestion = await llm.generate( prompt=f"Suggère des alternatives ou compléments", temperature=0.6, max_tokens=100 ) return { "answer": factual_part, "explanation": explanation, "suggestions": suggestion }

3. A/B Testing des paramètres

DEVELOPERpython
import random from dataclasses import dataclass @dataclass class SamplingVariant: name: str temperature: float top_p: float frequency_penalty: float class SamplingABTester: def __init__(self): self.variants = [ SamplingVariant("conservative", 0.1, 0.9, 0.0), SamplingVariant("balanced", 0.3, 0.95, 0.2), SamplingVariant("creative", 0.5, 1.0, 0.3), ] self.results = {v.name: {"count": 0, "satisfaction": []} for v in self.variants} def get_variant(self) -> SamplingVariant: return random.choice(self.variants) def record_feedback(self, variant_name: str, satisfaction: float): self.results[variant_name]["count"] += 1 self.results[variant_name]["satisfaction"].append(satisfaction) def get_best_variant(self) -> str: avg_scores = { name: sum(data["satisfaction"]) / max(len(data["satisfaction"]), 1) for name, data in self.results.items() } return max(avg_scores, key=avg_scores.get)

Erreurs courantes

1. Température trop haute pour du factuel

DEVELOPERpython
# ❌ Mauvais : température haute pour du support response = llm.generate( prompt="Quel est le délai de retour ?", temperature=1.0 # Risque d'hallucinations ! ) # ✅ Bon : température basse pour du factuel response = llm.generate( prompt="Quel est le délai de retour ?", temperature=0.2 )

2. Ignorer le context quality

DEVELOPERpython
# ❌ Mauvais : même température peu importe le contexte config = {"temperature": 0.5} # ✅ Bon : adapter selon la qualité du contexte context_score = retriever.get_relevance_score(query, documents) config = { "temperature": 0.2 if context_score < 0.6 else 0.4 }

3. Combiner de façon incohérente

DEVELOPERpython
# ❌ Incohérent : température basse + top_p très bas config = { "temperature": 0.1, "top_p": 0.5 # Double restriction inutile } # ✅ Cohérent : une restriction principale config = { "temperature": 0.2, "top_p": 0.95 # Juste pour éviter les aberrations }

Intégration avec Ailog

Ailog permet de configurer les paramètres de sampling directement dans l'interface :

DEVELOPERpython
from ailog import AilogClient client = AilogClient(api_key="your-key") # Configuration via l'interface ou l'API channel_config = { "generation": { "temperature": 0.3, "top_p": 0.95, "frequency_penalty": 0.2, "adaptive_sampling": True # Ajustement automatique } } client.update_channel_config("support-widget", channel_config)

Conclusion

Les paramètres de sampling sont des leviers puissants mais subtils. En RAG :

  1. Température basse (0.1-0.3) pour les réponses factuelles
  2. Top-p autour de 0.95 pour filtrer les aberrations
  3. Frequency penalty léger (0.1-0.3) pour éviter les répétitions
  4. Adaptation dynamique selon la qualité du contexte
  5. A/B testing pour trouver la configuration optimale

Ressources complémentaires


Besoin d'une configuration optimale sans vous casser la tête ? Essayez Ailog - paramètres pré-optimisés par cas d'usage, ajustement adaptatif inclus.

FAQ

Une température entre 0.1 et 0.3 est recommandée pour le support client. Les réponses doivent être précises et cohérentes : deux utilisateurs posant la même question doivent obtenir des réponses similaires. Évitez les valeurs supérieures à 0.5 qui introduisent trop de variabilité.
Oui, c'est même la configuration recommandée pour RAG. Une température basse (0.2-0.3) rend la distribution piquée sur les tokens probables, tandis qu'un top-p élevé (0.9-0.95) élimine seulement les tokens vraiment improbables. Cette combinaison offre précision et protection contre les aberrations.
Des répétitions excessives indiquent généralement une température trop basse combinée à l'absence de frequency penalty. Ajoutez un frequency_penalty de 0.2-0.3 pour pénaliser les tokens déjà utilisés. Vérifiez aussi que votre prompt ne contient pas de formulations qui encouragent la répétition.
Indirectement oui. Une température élevée permet au modèle de sélectionner des tokens moins probables, ce qui peut inclure des informations inventées. Pour RAG, combinez température basse avec des instructions explicites de se baser uniquement sur les documents fournis.
Commencez avec les valeurs recommandées (temperature=0.3, top_p=0.95) puis ajustez empiriquement. Mettez en place un A/B test avec 2-3 configurations et mesurez la satisfaction utilisateur. Les paramètres optimaux dépendent de votre domaine, votre corpus et les attentes de vos utilisateurs.

Tags

RAGtempératuresamplingLLMcréativitéparamètresgeneration

Articles connexes

Ailog Assistant

Ici pour vous aider

Salut ! Pose-moi des questions sur Ailog et comment intégrer votre RAG dans vos projets !