AnleitungFortgeschritten

Temperatur und RAG-Sampling: Die Kreativität des LLM steuern

15. März 2026
15 Min. Lesezeit
Ailog-Team

Umfassender Leitfaden zu Sampling-Parametern für RAG-Systeme: Temperatur, top-p, top-k, frequency penalty. Optimieren Sie das Gleichgewicht zwischen Kreativität und Treue.

TL;DR

Die paramètres de sampling (Temperatur, top-p, top-k) steuern das Niveau an Kreativität und Determinismus der Antworten eines LLM. In RAG sind diese Parameter kritisch: zu viel Kreativität = Halluzinationen, zu viel Determinismus = robotische Antworten. Dieser Leitfaden zeigt, wie Sie diese Parameter nach Ihrem Anwendungsfall kalibrieren.

Die Sampling-Parameter verstehen

Was ist Sampling?

Wenn ein LLM Text generiert, sagt es eine Wahrscheinlichkeitsverteilung über alle möglichen tokens für das nächste Wort voraus. Das sampling bestimmt, wie aus diesen Kandidaten ausgewählt wird.

DEVELOPERpython
# Vereinfachtes Beispiel einer Wahrscheinlichkeitsverteilung next_token_probs = { "rapidement": 0.35, "vite": 0.25, "promptement": 0.15, "immédiatement": 0.12, "instantanément": 0.08, "...": 0.05 } # Ohne Sampling (greedy): immer "rapidement" # Mit Sampling: kann "vite", "promptement", etc. wählen

Überblick über die Parameter

ParameterBereichWirkungTypische RAG-Verwendung
Temperature0.0 - 2.0Steuert die "Wärme" der Verteilung0.1 - 0.5
Top-p0.0 - 1.0Nucleus Sampling0.9 - 1.0
Top-k1 - 100+Begrenzt die Kandidaten40 - 80
Frequency penalty-2.0 - 2.0Bestraft Wiederholungen0.0 - 0.5
Presence penalty-2.0 - 2.0Fördert Vielfalt0.0 - 0.3

Die Temperatur im Detail

Mathematische Funktionsweise

Die Temperatur verändert die Softmax-Wahrscheinlichkeitsverteilung:

DEVELOPERpython
import numpy as np def apply_temperature(logits: np.array, temperature: float) -> np.array: """ Wendet die Temperatur auf die Logits an. - temperature < 1 : schärfere Verteilung (deterministisch) - temperature = 1 : ursprüngliche Verteilung - temperature > 1 : flachere Verteilung (zufälliger) """ if temperature == 0: # Greedy: gibt einen One-Hot-Vektor für das Maximum zurück 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) # Beispiel 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] - fast deterministisch print("Temp 1.0:", apply_temperature(logits, 1.0)) # [0.42, 0.26, 0.15, 0.09, 0.07] - ursprüngliche Verteilung print("Temp 2.0:", apply_temperature(logits, 2.0)) # [0.29, 0.23, 0.19, 0.16, 0.14] - gleichmäßigere Verteilung

Visuelle Darstellung

Niedrige Temperatur (0.1)      Hohe Temperatur (1.5)
│                              │
│ ████████████                 │ ██████
│ ██                           │ █████
│ █                            │ ████
│                              │ ███
│                              │ ██
└────────────────              └────────────────
  Token 1 domine                 Distribution plate

Empfehlungen nach RAG-Anwendungsfall

AnwendungsfallTemperaturBegründung
Faktischer Kundensupport0.1 - 0.2Maximale Präzision, keine Kreativität
Automatisierte FAQ0.2 - 0.3Leichte Variationen akzeptabel
E-Commerce-Assistent0.3 - 0.5Etwas Persönlichkeit
Unterstütztes Schreiben0.5 - 0.7Kontrollierte Kreativität
Brainstorming0.7 - 1.0Vielfältige Ideen willkommen

Top-p (Nucleus Sampling)

Wie es funktioniert

Top-p wählt die Tokens aus, deren kumulierte Wahrscheinlichkeiten p erreichen:

DEVELOPERpython
def top_p_sampling(probs: dict, p: float) -> list: """ Gibt die Tokens zurück, deren kumulierte Wahrscheinlichkeit p erreicht. """ # Nach absteigender Wahrscheinlichkeit sortieren 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 # Beispiel 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)] # Kumuliert: 0.90 - die anderen werden ausgeschlossen

Top-p vs. Temperatur

KriteriumTemperaturTop-p
KontrolleGlobal über die gesamte VerteilungSchneidet unwahrscheinliche Tokens ab
RisikoKann sehr unwahrscheinliche Tokens auswählenGarantiert plausible Tokens
Verwendung"Konfidenz" einstellenAusreißer vermeiden

Empfohlene Kombination für RAG

DEVELOPERpython
# Empfohlene Konfiguration für einen Support-Chatbot rag_config = { "temperature": 0.3, # Wenig Kreativität "top_p": 0.95, # Behält 95 % der Wahrscheinlichkeitsmasse "top_k": 50, # Maximal 50 Kandidaten } # Die niedrige Temperatur macht die Verteilung spitzer # Top-p eliminiert Tokens mit < 5% restlicher kumulativer Masse # Top-k setzt eine harte Grenze für die Anzahl der Kandidaten

Top-k sampling

Prinzip

Top-k behält nur die k wahrscheinlichsten Tokens:

DEVELOPERpython
def top_k_sampling(probs: dict, k: int) -> dict: """ Behält die k wahrscheinlichsten Tokens. """ sorted_tokens = sorted(probs.items(), key=lambda x: x[1], reverse=True) top_k_tokens = dict(sorted_tokens[:k]) # Renormalisieren total = sum(top_k_tokens.values()) return {t: p/total for t, p in top_k_tokens.items()} # Beispiel 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 und E werden ausgeschlossen, die anderen renormalisiert

Wann Top-k verwenden

  • k klein (10-20): Sehr konservative Antworten
  • k mittel (40-60): Gutes Gleichgewicht (empfohlen für RAG)
  • k groß (100+): Fast keine Filterung

Frequency- und Presence-Penalty

Frequency Penalty

Bestraft Tokens proportional zu ihrer Häufigkeit im generierten Text:

DEVELOPERpython
def apply_frequency_penalty( logits: dict, generated_tokens: list, penalty: float ) -> dict: """ Reduziert die Wahrscheinlichkeit häufig verwendeter Tokens. """ 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

Verwendung in RAG: Vermeidet repetitive Antworten wie "wie bereits erwähnt..."

Presence Penalty

Bestraft jeden bereits aufgetretenen Token, unabhängig von der Häufigkeit:

DEVELOPERpython
def apply_presence_penalty( logits: dict, generated_tokens: set, penalty: float ) -> dict: """ Reduziert die Wahrscheinlichkeit bereits verwendeter Tokens. """ 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

Verwendung in RAG: Fördert den Einsatz von Synonymen und lexikalische Vielfalt.

Optimale Konfiguration nach Modell

OpenAI GPT-4

DEVELOPERpython
from openai import OpenAI client = OpenAI() # Empfohlene RAG-Konfiguration 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 unterstützt temperature, top_p und top_k (aber kein frequency/presence penalty) 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}"} ] )

Open-Source-Modelle (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") # RAG-Konfiguration generation_config = { "temperature": 0.3, "top_p": 0.95, "top_k": 50, "repetition_penalty": 1.1, # Entspricht frequency_penalty "do_sample": True, "max_new_tokens": 500 } outputs = model.generate( input_ids, **generation_config )

Fortgeschrittene Strategien

1. Adaptives Sampling

Die Parameter dynamisch je nach Kontext anpassen:

DEVELOPERpython
class AdaptiveSampler: def __init__(self): self.base_temperature = 0.3 def get_config(self, query_type: str, context_quality: float) -> dict: """ Passt die Parameter je nach Kontext an. - query_type: "factual", "creative", "mixed" - context_quality: 0-1, Relevanzscore des Kontexts """ if query_type == "factual": # Fragen zu Fakten: sehr deterministisch temp = 0.1 elif query_type == "creative": # Kreative Fragen: mehr Freiheit temp = 0.7 else: temp = self.base_temperature # Wenn der Kontext schlecht ist, konservativer sein if context_quality < 0.5: temp *= 0.5 # Temperatur reduzieren return { "temperature": temp, "top_p": 0.95 if context_quality > 0.7 else 0.85, "frequency_penalty": 0.2 } # Verwendung sampler = AdaptiveSampler() config = sampler.get_config( query_type="factual", context_quality=0.85 )

2. Variable Temperatur pro Abschnitt

Je nach Teil der Antwort unterschiedliche Temperaturen verwenden:

DEVELOPERpython
async def generate_structured_response(query: str, context: str): """ Generiert eine Antwort mit unterschiedlichen Parametern pro Abschnitt. """ # Abschnitt 1: Faktenantwort (niedrige Temperatur) factual_part = await llm.generate( prompt=f"Antworte sachlich: {query}\nContext: {context}", temperature=0.1, max_tokens=200 ) # Abschnitt 2: Erklärung (mittlere Temperatur) explanation = await llm.generate( prompt=f"Erkläre warum: {factual_part}", temperature=0.4, max_tokens=150 ) # Abschnitt 3: Vorschlag (höhere Temperatur) suggestion = await llm.generate( prompt=f"Schlage Alternativen oder Ergänzungen vor", temperature=0.6, max_tokens=100 ) return { "answer": factual_part, "explanation": explanation, "suggestions": suggestion }

3. A/B-Testing der Parameter

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)

Häufige Fehler

1. Zu hohe Temperatur für Faktisches

DEVELOPERpython
# ❌ Schlecht: zu hohe Temperatur für Support response = llm.generate( prompt="Wie lange ist die Rückgabefrist?", temperature=1.0 # Risiko von Halluzinationen ! ) # ✅ Gut: niedrige Temperatur für Faktenfragen response = llm.generate( prompt="Wie lange ist die Rückgabefrist?", temperature=0.2 )

2. Kontextqualität ignorieren

DEVELOPERpython
# ❌ Schlecht: gleiche Temperatur unabhängig vom Kontext config = {"temperature": 0.5} # ✅ Gut: an die Qualität des Kontexts anpassen context_score = retriever.get_relevance_score(query, documents) config = { "temperature": 0.2 if context_score < 0.6 else 0.4 }

3. Inkonsistente Kombination

DEVELOPERpython
# ❌ Inkonsistent: niedrige Temperatur + sehr niedriges top_p config = { "temperature": 0.1, "top_p": 0.5 # unnötige doppelte Einschränkung } # ✅ Konsistent: eine hauptsächliche Einschränkung config = { "temperature": 0.2, "top_p": 0.95 # Nur um Ausreißer zu vermeiden }

Integration mit Ailog

Ailog ermöglicht die Konfiguration der Sampling-Parameter direkt in der Oberfläche:

DEVELOPERpython
from ailog import AilogClient client = AilogClient(api_key="your-key") # Konfiguration über die Oberfläche oder die API channel_config = { "generation": { "temperature": 0.3, "top_p": 0.95, "frequency_penalty": 0.2, "adaptive_sampling": True # automatische Anpassung } } client.update_channel_config("support-widget", channel_config)

Fazit

Die Sampling-Parameter sind mächtige, aber subtile Stellschrauben. In RAG:

  1. Niedrige Temperatur (0.1-0.3) für faktische Antworten
  2. Top-p um 0.95, um Ausreißer zu filtern
  3. Leichtes Frequency Penalty (0.1-0.3) zur Vermeidung von Wiederholungen
  4. Dynamische Anpassung je nach Kontextqualität
  5. A/B-Testing um die optimale Konfiguration zu finden

Ergänzende Ressourcen


Brauchen Sie eine optimale Konfiguration ohne Kopfzerbrechen? Testen Sie Ailog - vorab optimierte Parameter nach Anwendungsfall, adaptives Tuning inklusive.

FAQ

Eine Temperatur zwischen 0.1 und 0.3 wird für den Kundensupport empfohlen. Die Antworten sollten präzise und konsistent sein: zwei Nutzer, die dieselbe Frage stellen, sollten ähnliche Antworten erhalten. Vermeiden Sie Werte über 0.5, die zu viel Variabilität einführen.
Ja — das ist sogar die für RAG empfohlene Konfiguration. Eine niedrige Temperatur (0.2-0.3) macht die Verteilung spitz auf wahrscheinliche tokens, während ein hohes top-p (0.9-0.95) nur wirklich unwahrscheinliche tokens ausschließt. Diese Kombination bietet Präzision und Schutz vor Ausreißern.
Zu viele Wiederholungen deuten meist auf eine zu niedrige Temperatur in Kombination mit fehlendem frequency penalty hin. Fügen Sie ein frequency_penalty von 0.2-0.3 hinzu, um bereits genutzte tokens zu bestrafen. Prüfen Sie auch, dass Ihr Prompt keine Formulierungen enthält, die Wiederholungen fördern.
Indirekt ja. Eine hohe Temperatur erlaubt es dem Modell, weniger wahrscheinliche tokens zu wählen, was erfundene Informationen einschließen kann. Für RAG kombinieren Sie niedrige Temperatur mit klaren Anweisungen, sich ausschließlich auf die bereitgestellten Dokumente zu stützen.
Starten Sie mit den empfohlenen Werten (temperature=0.3, top_p=0.95) und passen Sie empirisch an. Führen Sie ein A/B-Test mit 2–3 Konfigurationen durch und messen Sie die Nutzerzufriedenheit. Die optimalen Parameter hängen von Ihrer Domäne, Ihrem Korpus und den Erwartungen Ihrer Nutzer ab.

Tags

RAGtempératuresamplingLLMcréativitéparamètresgeneration

Verwandte Artikel

Ailog Assistant

Ici pour vous aider

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