Lernpfad
Deine RAG-Pipeline liefert eine Antwort auf die Frage eines Nutzers. Sie wirkt plausibel, liest sich gut und klingt selbstbewusst. Doch im Vergleich mit den tatsächlich abgerufenen Dokumenten fallen dir Dinge auf: ein Datum, das im Kontext nirgends vorkommt, oder eine Empfehlung, die der Quelle widerspricht.
Solche Probleme in großem Maßstab zu erkennen, ist knifflig. Genau deshalb wurden Metriken wie BLEU und ROUGE für maschinelle Übersetzung und Zusammenfassungen entwickelt. Aber sie sagen dir nicht, ob die Antwort des Modells wirklich im abgerufenen Kontext verankert ist oder ob sie der Quelle widerspricht.
Menschliche Bewertung erkennt diese Feinheiten, ist aber bei großen Volumina zu teuer (denk an 10.000 Anfragen oder mehr). Es gibt also eine Lücke: Automatisierte Metriken sind schnell, aber oberflächlich; manuelle Reviews sind gründlich, aber teuer und langsam.
Ein LLM als Judge liegt dazwischen. Du nimmst ein fähiges Modell, gibst ihm einen von dir definierten Bewertungsrahmen und bittest es, die Ergebnisse deines Systems so zu beurteilen, wie es ein menschlicher Prüfer tun würde. Es ist keine perfekte Lösung (auf die Schwachstellen komme ich noch), aber sie bietet dir eine praktikable Möglichkeit, Qualität in einem Umfang zu überwachen, den weder klassische Metriken noch manuelle Annotation allein leisten können.
In diesem Tutorial zeige ich dir Schritt für Schritt, wie du einen LLM-Judge zur Bewertung eines RAG-Systems baust – mit lauffähigem Code, damit du alles auf deiner eigenen Maschine reproduzieren kannst.
Was bedeutet LLM as a Judge?
Die Grundidee von LLM-as-a-judge ist, ein Sprachmodell Outputs anhand von Kriterien bewerten zu lassen, die du im Prompt definierst. Du nutzt also ein LLM, um zu prüfen, ob die Inhalte, die ein anderes Modell erzeugt hat, gut sind oder nicht.
Der Grund, warum das überhaupt funktioniert (ich war anfangs selbst skeptisch), ist: Evaluieren ist grundsätzlich einfacher als Generieren. Wenn ein Modell eine Antwort von Grund auf erzeugt, jongliert es gleichzeitig viele Anforderungen:
- Genauigkeit
- Tonalität
- Befolgen der Anweisungen
- Im Kontext bleiben
- Nicht zu viel behaupten, wenn Informationen unsicher sind
Gibst du demselben Modell aber eine fertige Antwort und bittest es, gezielte Eigenschaften zu prüfen, wird die Aufgabe viel fokussierter – es muss bewerten, nicht erstellen. Und Modelle arbeiten auf dieser enger gefassten Aufgabe oft konstanter.
LLM-as-a-judge-Ansätze im Vergleich
In der Praxis landen Teams je nach Zielsetzung meist bei einem dieser Ansätze:
- Direkte Bewertung lässt den Judge einen einzelnen Output auf einer Skala (1 bis 5, 1 bis 10 – je nach Rubrik) einstufen. Du bekommst eine Zahl und – wenn du darum bittest – eine schriftliche Begründung. Das ist der häufigste Startpunkt, hat aber ein Kalibrierungsproblem, zu dem ich noch komme.
- Paarweiser Vergleich stellt zwei Kandidatenantworten nebeneinander und bittet den Judge, die bessere zu wählen. So umgehst du das Kalibrierungsproblem komplett, weil der Judge nur relativ entscheiden muss statt eine absolute Zahl zu vergeben. Teams nutzen das oft, um Prompt-Varianten oder Modellversionen gegeneinander zu testen.
- Referenzbasierte Bewertung gibt dem Judge sowohl den Modelloutput als auch eine Goldstandard-Antwort und fragt, wie gut der Output dazu passt. Das funktioniert am besten für faktische Q&A und strukturierte Outputs, bei denen du bereits gelabelte Ground-Truth-Daten hast.
- Binäre Klassifikation reduziert das Urteil auf Bestehen/Nicht-Bestehen bei einer konkreten Eigenschaft. Ist die Antwort dem Kontext treu? Enthält sie personenbezogene Daten? Ist sie positiv? Diese binären Checks laufen schneller, sind pro Bewertung günstiger und liefern tendenziell konsistentere Ergebnisse als numerische Ansätze.

Grafik der Autorin/des Autors. Vier Ansätze für LLM as a Judge.
Für einen direkten Überblick über Stärken, Einsatzfelder und Grenzen, habe ich alle vier Ansätze in der folgenden Tabelle gegenübergestellt:
|
Ansatz |
Wann einsetzen |
Stärken |
Darauf achten |
|
Direkte Bewertung |
Allgemeines Qualitätsmonitoring, kontinuierliches Tracking |
Einfach über die Zeit zu trendieren, funktioniert mit Einzel-Outputs |
Judges variieren in der Kalibrierung ihrer Scores |
|
Paarweiser Vergleich |
A/B-Tests von Modellen, Vergleich von Prompt-Varianten |
Zuverlässigere Rangfolgen als absolute Scores |
Verdoppelt die API-Calls, liefert kein absolutes Qualitätssignal |
|
Referenzbasiert |
Faktisches Q&A, strukturierte Outputs |
Klare Ground Truth macht die Bewertung geradlinig |
Benötigt gelabelte Daten, bestraft valide alternative Formulierungen |
|
Binäre Klassifikation |
Safety-Checks, Halluzinationserkennung, Compliance |
Geringe Ambiguität, Alarme leicht zu automatisieren |
Verliert Nuancen bei Grenzfällen |
Für einen breiteren Blick über den Judge-Ansatz hinaus erklärt LLM Benchmarks Explained das Gesamtbild.
Wie funktioniert ein LLM-Judge?
Unter der Haube ist es ein einfacher API-Call: Du packst die zu bewertenden Inhalte (Modellantwort, ursprüngliche Nutzerfrage und den genutzten Kontext) zusammen und umrahmst sie mit einem Prompt, der dem Judge-Modell sagt, worauf es achten soll und in welchem Format das Ergebnis zurückkommen soll.
Der Judge verarbeitet das und liefert eine strukturierte Antwort, meist einen Score plus eine schriftliche Begründung. Die Qualität deiner Bewertung hängt fast vollständig davon ab, wie gut du die Rubrik formulierst. Das kann ich nicht stark genug betonen.
Ein einfacher Prompt wie „Bewerte diese Antwort von 1 bis 5“ liefert dir völlig verstreute Werte, weil kein gemeinsames Verständnis existiert, was eine 3 gegenüber einer 4 bedeutet. Daher musst du konkret beschreiben, wie jedes Score-Niveau aussieht, idealerweise mit Beispielen.
LLM as a Judge implementieren
Jetzt kommt der praktische Teil: Wir bauen eine komplette Evaluations-Pipeline von Grund auf – ein Retrieval Augmented Generation (RAG)-System, das Fragen aus einer kleinen Wissensbasis beantwortet, einen Satz Testanfragen, die verschiedene Fehlertypen auslösen, und einen LLM-Judge, der die Outputs auf Faktentreue und Antwortrelevanz bewertet.
Umgebung einrichten
Du brauchst Python 3.9+ und einen OpenAI-API-Schlüssel, den du in der OpenAI-Konsole bekommst. Installiere die Abhängigkeiten:
pip install openai chromadb langchain langchain-openai langchain-community deepeval
Setze deinen API-Schlüssel:
import os
os.environ["OPENAI_API_KEY"] = "your-key-here"
Wir nutzen OpenAI sowohl für den RAG-Generator als auch für den LLM-Judge, allerdings unterschiedliche Modelle (GPT-4o-mini für die Generierung, GPT-4o für das Judging). Für Embeddings reicht text-embedding-3-small für den Rahmen dieses Tutorials. In der Produktion solltest du mehrere Embedding-Modelle auf deinen Domänendaten benchmarken, bevor du dich festlegst.
Wenn du vor dem Evaluationscode noch mehr RAG-Hintergrund möchtest, führt unser Kurs Retrieval Augmented Generation (RAG) mit LangChain durch die Grundlagen.
Daten und Vektorspeicher vorbereiten
Wir brauchen eine kleine Wissensbasis, aus der das RAG-System abrufen kann. Ich nutze ein paar Textabschnitte zu den Rückgaberichtlinien eines fiktiven Unternehmens. Der Inhalt ist hier nicht der Fokus, aber ein abgegrenzter Dokumentensatz macht sichtbar, wann das Modell über den bereitgestellten Kontext hinausgeht – genau diese Fälle soll der Judge finden.
from langchain_openai import OpenAIEmbeddings
from langchain_chroma import Chroma
from langchain.schema import Document
# Sample knowledge base
documents = [
Document(
page_content="All customers are eligible for a full refund within 30 days of purchase. "
"The item must be in its original packaging and unused condition. Refunds are "
"processed to the original payment method within 5-7 business days.",
metadata={"source": "return_policy.pdf", "section": "refund_eligibility"}
),
Document(
page_content="Exchanges can be requested within 45 days of purchase for items of "
"equal or lesser value. Size exchanges on clothing are free of charge. "
"For items of greater value, the customer pays the difference.",
metadata={"source": "return_policy.pdf", "section": "exchanges"}
),
Document(
page_content="Electronics have a 15-day return window due to rapid depreciation. "
"Opened software and digital downloads are non-refundable. Defective electronics "
"can be returned within 90 days with proof of defect from an authorized service center.",
metadata={"source": "return_policy.pdf", "section": "electronics"}
),
Document(
page_content="Shipping costs for returns are covered by the company for defective items. "
"For non-defective returns, the customer is responsible for return shipping. "
"Free return shipping labels are available for loyalty program members regardless of reason.",
metadata={"source": "return_policy.pdf", "section": "shipping"}
),
Document(
page_content="Gift purchases can be returned with the gift receipt for store credit only. "
"Without a gift receipt, returns are processed at the lowest sale price in the last 90 days. "
"Gift cards and prepaid cards are non-refundable and cannot be exchanged.",
metadata={"source": "return_policy.pdf", "section": "gifts"}
),
]
# Create vector store
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
vectorstore = Chroma.from_documents(documents, embeddings, persist_directory="./chroma_db")
print(f"Indexed {len(documents)} documents")
Fünf Dokumente zu Rückgaberichtlinien sind zwar nicht viel, reichen aber, um die Retrieval-Probleme zu zeigen, die uns interessieren: unvollständiger Kontext, irrelevante Chunks und Halluzinationsgelegenheiten, wenn das Modell den Druck spürt, eine vollständige Antwort zu liefern, obwohl der Kontext das nicht hergibt.
Eine einfache RAG-Pipeline bauen
Die RAG-Pipeline ruft relevante Chunks ab und generiert eine Antwort. Nichts Außergewöhnliches – das klassische Retrieve-then-Generate-Muster.
from openai import OpenAI
client = OpenAI()
def rag_query(question: str, top_k: int = 2) -> dict:
"""Run a RAG query: retrieve context, generate answer."""
# Retrieve
results = vectorstore.similarity_search(question, k=top_k)
context = "\n\n".join([doc.page_content for doc in results])
# Generate
system_prompt = """You are a helpful customer support assistant. Answer the
customer's question based ONLY on the provided context. If the context doesn't
contain enough information to answer fully, say so."""
user_prompt = f"""
Context: {context}
Question: {question}
Answer:
"""
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_prompt}
],
temperature=0.3
)
answer = response.choices[0].message.content
return {
"question": question,
"context": context,
"answer": answer,
"sources": [doc.metadata for doc in results]
}
Ich habe GPT-4o-mini als Generator gewählt, weil es günstig und schnell ist – der Fokus liegt hier auf der Evaluation. Die Temperatur liegt bei 0,3, um Zufälligkeit zu reduzieren, ohne sie komplett auszuschalten.
Der System-Prompt weist das Modell ausdrücklich an, nur den bereitgestellten Kontext zu nutzen – Standardpraxis bei RAG, auch wenn Modelle öfter als erwartet darüber hinausschießen. Genau das soll der Judge markieren.
Testen wir es:
result = rag_query("Can I return opened software?")
print(f"Question: {result['question']}")
print(f"Answer: {result['answer']}")
print(f"Sources: {result['sources']}")
Ein Evaluationsdatenset erzeugen
Du brauchst Testfälle, die verschiedene Teile der Pipeline ansprechen. In der Produktion sammelst du sie aus echten Nutzeranfragen. Für dieses Tutorial stelle ich einen Mix zusammen, der bewusst Fragen enthält, an denen RAG-Systeme häufig stolpern.
eval_questions = [
# Straightforward questions (should be easy)
"What is the refund window for regular purchases?",
"Are exchanges free for clothing size changes?",
# Questions requiring synthesis across chunks
"What are my options if I received a defective laptop 60 days ago?",
# Edge cases likely to cause hallucination
"Can I get a refund for a digital download I purchased yesterday?",
"What happens if I return a gift without the gift receipt?",
# Questions where context might be incomplete
"Do you offer refunds for international orders?",
"Can I return an item I bought on sale?",
# Adversarial or tricky questions
"If I'm a loyalty member, do I get free return shipping even for electronics?",
]
# Generate RAG responses for all questions
eval_results = []
for q in eval_questions:
result = rag_query(q)
eval_results.append(result)
print(f"Q: {q}")
print(f"A: {result['answer'][:150]}...")
print()
Der Mix ist wichtig. Einige Fragen haben klare, direkte Antworten in den Dokumenten, andere erfordern das Kombinieren mehrerer Chunks (die Laptop-Defektfrage braucht sowohl die allgemeine 30-Tage-Rückgabe als auch die 90-Tage-Regel für defekte Elektronik mit Nachweis).
Und ein paar, wie die Frage zu internationalen Bestellungen, betreffen Themen, die die Wissensbasis schlicht nicht abdeckt. Genau dort treten Halluzinationen am häufigsten auf, weil das Modell „hilfsbereit“ sein will und Lücken mit plausibel klingenden, aber unbelegten Informationen füllt.
Mehr zum Aufbau und Testen von RAG-Systemen findest du in unserer Auswahl der Top 30 RAG Interview Questions and Answers.
Den LLM-Judge einrichten
Jetzt wird’s interessant. Wir bauen zwei getrennte Judges:
- Faithfulness-Judge: Bleibt die Antwort innerhalb der Grenzen des abgerufenen Kontexts?
- Relevanz-Judge: Adressiert die Antwort wirklich die gestellte Frage?
def judge_faithfulness(question: str, context: str, answer: str) -> dict:
"""Judge whether the answer is faithful to the retrieved context."""
eval_prompt = f"""
You are an impartial judge evaluating whether an AI assistant's
answer is faithful to the provided context.
Faithfulness means every claim in the answer can be traced back to
information in the context. The answer should not contain information
that isn't supported by or inferable from the context.
Score on a scale of 1 to 5:
1 - The answer contains multiple claims not supported by the context
2 - The answer contains at least one significant unsupported claim
3 - The answer is mostly faithful but includes minor unsupported details
4 - The answer is faithful with only trivial extrapolations
5 - Every claim in the answer is directly supported by the context
Context: {context}
Question: {question}
Answer to evaluate: {answer}
Respond in this exact JSON format: {{"score": <int 1-5>, "reason": "<one paragraph explanation>"}}
"""
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": eval_prompt}],
temperature=0.0,
response_format={"type": "json_object"}
)
import json
return json.loads(response.choices[0].message.content)
def judge_relevance(question: str, answer: str) -> dict:
"""Judge whether the answer is relevant to the question."""
eval_prompt = f"""
You are an impartial judge evaluating whether an AI assistant's answer
is relevant to the user's question.
Relevance means the answer directly addresses what the user asked.
A relevant answer may acknowledge limitations in available information,
but it should not go off-topic or provide unrelated information.
Score on a scale of 1 to 5:
1 - The answer does not address the question at all
2 - The answer partially addresses the question but misses the main point
3 - The answer addresses the question but includes significant irrelevant content
4 - The answer addresses the question well with minor tangents
5 - The answer directly and completely addresses the question
Question: {question}
Answer to evaluate: {answer}
Respond in this exact JSON format: {{"score": <int 1-5>, "reason": "<one paragraph explanation>"}}
"""
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": eval_prompt}],
temperature=0.0,
response_format={"type": "json_object"}
)
import json
return json.loads(response.choices[0].message.content)
Ein paar Designentscheidungen dazu: Die temperature steht auf 0.0 für maximale Konsistenz über Läufe hinweg. Wir nutzen response_format={"type": "json_object"}, damit die Ausgabe stets parsebar ist.
Die Rubrik beschreibt jedes Score-Niveau konkret statt vager Labels wie „gut“ oder „schlecht“. Ohne diese Spezifik würde der Judge erfahrungsgemäß fast alles mit 3 oder 4 bewerten – wenig hilfreich.
Beachte: GPT-4o bewertet, obwohl GPT-4o-mini generiert. Ein stärkeres Judge-Modell ist gängig, weil es die Rubrik verlässlich befolgen muss.
Wenn du dasselbe Modell für beide Rollen nutzt, riskierst du zudem eine dokumentierte Selbstpräferenz, bei der das Modell seine eigenen Outputs wohlwollender bewertet.
Den Evaluations-Loop ausführen
Zeit, alles laufen zu lassen und Ergebnisse zu sammeln.
import json
evaluation_report = []
for result in eval_results:
# Run both judges
faithfulness = judge_faithfulness(
result["question"], result["context"], result["answer"]
)
relevance = judge_relevance(
result["question"], result["answer"]
)
evaluation_report.append({
"question": result["question"],
"answer": result["answer"][:200],
"faithfulness_score": faithfulness["score"],
"faithfulness_reason": faithfulness["reason"],
"relevance_score": relevance["score"],
"relevance_reason": relevance["reason"],
})
print(f"Q: {result['question']}")
print(f" Faithfulness: {faithfulness['score']}/5 | Relevance: {relevance['score']}/5")
print(f" Faith reason: {faithfulness['reason'][:100]}...")
print()
# Summary statistics
faith_scores = [r["faithfulness_score"] for r in evaluation_report]
rel_scores = [r["relevance_score"] for r in evaluation_report]
print(f"Average faithfulness: {sum(faith_scores)/len(faith_scores):.2f}")
print(f"Average relevance: {sum(rel_scores)/len(rel_scores):.2f}")
print(f"Questions with faithfulness < 3: {sum(1 for s in faith_scores if s < 3)}")
Jede Frage löst zwei API-Calls an GPT-4o aus, einen pro Judge. Bei acht Testfragen sind das 16 Bewertungen – gut handhabbar. In der Produktion mit tausenden täglichen Anfragen würdest du batchen, asynchron laufen lassen und wahrscheinlich nur eine Stichprobe bewerten statt alles.
Ergebnisse analysieren und iterieren
Die Zahlen geben den Überblick, aber die Begründungen zeigen dir, was du konkret verbessern musst.
# Find problematic responses
print("=== LOW FAITHFULNESS (score < 4) ===")
for r in evaluation_report:
if r["faithfulness_score"] < 4:
print(f"\nQ: {r['question']}")
print(f"Score: {r['faithfulness_score']}")
print(f"Reason: {r['faithfulness_reason']}")
print(f"Answer preview: {r['answer'][:150]}...")
print("\n=== LOW RELEVANCE (score < 4) ===")
for r in evaluation_report:
if r["relevance_score"] < 4:
print(f"\nQ: {r['question']}")
print(f"Score: {r['relevance_score']}")
print(f"Reason: {r['relevance_reason']}")
Die Fragen zu internationalen Bestellungen und reduzierter Ware werden fast sicher bei der Faktentreue schlecht abschneiden, weil die Wissensbasis diese Themen nicht abdeckt und das Modell wohl improvisiert hat.
Auch die defekte-Laptop-Frage ist interessant, denn sie verlangt, Informationen aus der allgemeinen Rückgaberichtlinie (30 Tage) mit der Defektklausel für Elektronik (90 Tage mit Nachweis) zu verknüpfen – je nach Retrieval hat das Modell eventuell nicht das volle Bild.
Was du mit den Ergebnissen machst, hängt von deinen Erkenntnissen ab. Niedrige Faktentreue in bestimmten Kategorien weist meist auf zwei Ursachen hin: Entweder zieht der Retriever die falschen Chunks (Retrieval-Problem) oder der Generator geht über den Kontext hinaus (Generierungsproblem).
Wenn du den abgerufenen Kontext neben die Antwort legst, erkennst du, welches Problem vorliegt. Niedrige Relevanz hingegen deutet oft auf Feinschliff am System-Prompt hin – oder der abgerufene Kontext ist so weit am Thema vorbei, dass das Modell nichts Sinnvolles hat, womit es arbeiten kann.
Für den operativen Betrieb von Evaluationsläufen als Teil deiner Deployment-Pipeline deckt der Kurs LLMOps Concepts die nötige Infrastruktur und Workflows ab.
Strukturierte Evaluation mit DeepEval
Eigene Judge-Funktionen zu schreiben, funktioniert – für den Produktionseinsatz willst du aber meist ein Framework, das den Boilerplate-Teil übernimmt. DeepEval ist eine der reiferen Optionen und bringt erprobte Metriken für die gängigsten Bewertungskriterien mit.
from deepeval import evaluate
from deepeval.test_case import LLMTestCase
from deepeval.metrics import FaithfulnessMetric, AnswerRelevancyMetric
# Configure metrics
faithfulness_metric = FaithfulnessMetric(
threshold=0.7,
model="gpt-4o",
include_reason=True
)
relevance_metric = AnswerRelevancyMetric(
threshold=0.7,
model="gpt-4o",
include_reason=True
)
# Create test cases from our RAG results
test_cases = []
for result in eval_results:
test_case = LLMTestCase(
input=result["question"],
actual_output=result["answer"],
retrieval_context=[result["context"]]
)
test_cases.append(test_case)
# Run evaluation
evaluate(
test_cases=test_cases,
metrics=[faithfulness_metric, relevance_metric]
)
Was dir DeepEval abnimmt, was allein lästig wäre:
- Retry-Logik, wenn der Judge fehlerhaftes JSON zurückgibt (passiert öfter als gedacht)
- Ergebnis-Caching, damit ein erneuter Lauf nicht doppelt kostet
- Pytest-Integration, um LLM-Evaluationen direkt in deine CI/CD-Pipeline zu hängen.
Jede Metrik erzeugt zudem eine Selbsterklärung – jeder Score kommt mit einer schriftlichen Begründung, die du prüfen kannst, wenn etwas komisch wirkt.
Für einen tieferen Einblick in den vollen Funktionsumfang sieh dir Evaluate LLMs Effectively Using DeepEval an.
Best Practices für LLM as a Judge
Einen LLM-Judge dazu zu bringen, Zahlen auszugeben, ist leicht. Dafür zu sorgen, dass diese Zahlen deinem Team wirklich nützen, erfordert mehr Sorgfalt, als die meisten erwarten.
Evaluations-Frameworks und Metriken
Neben DeepEval gibt es inzwischen mehrere Frameworks – und das Feld wächst. Hier ist ein praxisnaher Vergleich, wo jedes am besten passt:
|
Framework |
Stärken |
LLM-Judge-Unterstützung |
RAG-spezifische Metriken |
Integration |
|
DeepEval |
Vollständige Evaluationssuite, CI/CD-Integration |
Ja, mit selbsterklärenden Scores |
Faktentreue, kontextuelle Präzision/Recall, Relevanz |
pytest, LangChain |
|
RAGAS |
Spezifisch für RAG-Pipeline-Evaluation |
Ja |
Faktentreue, Antwortrelevanz, Kontextpräzision, Kontext-Recall |
LangChain, LlamaIndex |
|
MLflow |
Experiment-Tracking mit Evaluation |
Ja (built-in; kombinierbar mit DeepEval/RAGAS) |
Über Integrationen von Drittanbietern |
MLflow-Ökosystem |
|
Evidently |
Produktions-Monitoring und Drift-Erkennung |
Ja, mit kontinuierlichem Tracking |
Über Custom Evaluators |
Monitoring-Dashboards |
|
LangSmith |
LangChain-natives Tracing und Evaluation |
Ja |
Über Custom Evaluators |
LangChain |
Für RAG-Systeme decken vier Metriken in der Praxis das Meiste ab.
- Faktentreue (Faithfulness) zeigt, ob die generierte Antwort im abgerufenen Kontext verankert bleibt. Kommt ein Score von 0,6 zurück, heißt das grob, dass etwa 40% der Aussagen in der Antwort nicht aus den Dokumenten belegbar sind. Das ist dein zentraler Halluzinationsdetektor und aus meiner Sicht die wichtigste Metrik im laufenden Betrieb.
- Antwortrelevanz erfasst, ob die Antwort die Frage wirklich adressiert – ein völlig eigenes Thema. Eine Antwort kann vollkommen kontexttreu sein und trotzdem an der Frage vorbeigehen.
- Kontextpräzision betrachtet die Retrieval-Seite: Werden relevante Dokumente oben gerankt? Wenn das Dokument mit der Antwort auf Platz 5 von 5 landet, funktioniert Retrieval zwar, aber das Ranking ist schwach – und das mindert die Generierungsqualität, weil Modelle dem zuerst erscheinenden Kontext mehr Gewicht geben.
- Kontext-Recall geht in die andere Richtung und prüft, wie viel der für die Antwort nötigen Information tatsächlich abgerufen wurde. Niedriger Recall ist ein Infrastrukturproblem im Retrieval – das kann kein Prompt-Engineering auf der Generierungsseite kompensieren.
Du willst sie gemeinsam laufen lassen, weil unterschiedliche Score-Kombinationen auf verschiedene Ursachen hinweisen.
- Hohe Faktentreue bei niedriger Relevanz bedeutet: Das Modell spiegelt den Kontext korrekt, aber der Kontext war nicht relevant für die Frage.
- Niedrige Faktentreue bei hoher Relevanz bedeutet: Das Modell hat die Frage verstanden, ist aber über den Kontext hinausgegangen, um zu antworten.
Jede Kombination zeigt dir, wo du ansetzen musst.
Für praktische Übungen zum Evaluations-Tracking in MLflow erklärt Evaluating LLMs with MLflow die Integration.
Best Practices für den Produktionseinsatz
Der Betrieb in Produktion erfordert mehr Überlegung als ein Notebook-Run. In der Praxis tauchen bei Skalierung fünf Themen auf, die du vorab adressieren solltest.
- Mit bekannten Biases planen. LLM-Judges bewerten längere Antworten systematisch höher (Verbosity Bias) und bevorzugen beim paarweisen Vergleich leicht die zuerst gezeigte Antwort (Positionsbias). Gegen Positionsbias hilft, jeden Vergleich in beiden Reihenfolgen laufen zu lassen und nur konsistente Urteile zu zählen. Gegen Verbosity kannst du in der Rubrik explizit Kürze als erwünscht festhalten – das mindert den Effekt, eliminiert ihn aber nicht.
- Vor dem Vertrauen kalibrieren. Stelle 50–100 Beispiele zusammen, die menschliche Reviewer in deiner Domäne bereits bewertet haben, lass sie durch den Judge laufen und prüfe die Übereinstimmung. Unter 75% Agreement ist ein Signal, dass die Rubrik präziser werden muss. Wiederhole die Kalibrierung regelmäßig, weil sich Judge-Modell und Anwendung weiterentwickeln – was vor sechs Monaten gut aussah, kann durch geänderte Prompts, Daten oder Modelle driften.
- Konsistenz getrennt von Genauigkeit prüfen. Lass dieselben Inputs zweimal durch den Judge und vergleiche die Outputs. Wenn ein Ergebnis einmal „3“ und das nächste Mal „5“ bekommt, lässt die Rubrik zu viel Interpretationsspielraum. In solchen Fällen liefern binäre Pass/Fail-Checks oft konsistentere Ergebnisse als 5-Punkt-Skalen – nutze binär für Produktions-Monitoring und behalte feingranulare Skalen für Offline-Analysen.
- Kosten im Blick behalten. Evaluationsprompts sind deutlich länger als Generierungsprompts, weil Frage, kompletter Kontext, Antwort und Rubrik hineingehören. Bei hohem Volumen ist es gängig, detaillierte LLM-Evaluationen auf eine zufällige 10%-Stichprobe zu fahren und auf den restlichen 90% einfachere Checks (Länge, Format, Schlüsselwörter) anzuwenden.
- Menschen eingebunden halten. Selbst wenn der Judge stabil läuft, richte einen regelmäßigen Review-Prozess ein, bei dem jemand wöchentlich eine Stichprobe der Bewertungen prüft. Achte besonders auf Fälle mit perfektem Score (5/5) – genau dort wäre ein übersehenes Problem am gefährlichsten, weil es falsches Vertrauen schafft.
Mehr zum Operationalisieren von LLM-Workflows end-to-end deckt der Lernpfad Associate AI Engineer for Data Scientists ab.
Fazit
LLM-as-a-judge schließt eine Lücke, die weder klassische automatisierte Metriken noch menschliche Reviews allein bei großem Volumen abdecken. Automatisierte Metriken verfehlen oft das, was für LLM-Anwendungen zählt; menschliche Bewertung erkennt es, kann aber die Produktionsmenge nicht stemmen.
Ein LLM-Judge dazwischen ermöglicht dir, die Outputqualität kontinuierlich und mit der nötigen Nuance zu überwachen, die simple Metriken nicht liefern.
In diesem Tutorial haben wir eine komplette Pipeline gebaut: ein RAG-System mit kleiner Wissensbasis, Testfragen für verschiedene Fehlermodi, Custom-Judges für Faktentreue und Relevanz sowie einen Framework-Ansatz mit DeepEval – näher an dem, was du in Produktion laufen lässt.
Wenn es eine wichtigste Erkenntnis gibt, dann diese: Die Rubrik ist alles. Investiere Zeit in spezifische, konkrete Bewertungskriterien mit klaren Beispielen pro Score-Niveau. Eine gut gemachte Rubrik mit einem mittelmäßigen Modell schlägt eine vage Rubrik mit dem stärksten Modell – jedes Mal.
Wenn du von hier aus weiter bauen willst:
- Building a RAG System with LangChain and FastAPI bringt die RAG-Pipeline vom Notebook in einen Produktivservice.
- Developing LLM Applications with LangChain deckt den breiteren Entwicklungs-Workflow ab – inklusive Chains, Agenten und Memory.
- Introduction to LLMs in Python lohnt sich zur Auffrischung der Grundlagen, bevor du tiefer einsteigst.
- 12 LLM Projects For All Levels liefert weitere Projektideen zum Üben.
- What is Retrieval Augmented Generation (RAG)? beleuchtet die konzeptionellen Grundlagen von RAG ausführlicher.
LLM as a Judge: FAQs
Was genau ist LLM-as-a-judge?
Kurz gesagt: Du promptest ein leistungsfähiges Modell wie GPT-4 oder Claude, damit es nach deiner Rubrik in Klartext das Ergebnis eines anderen Modells bewertet oder klassifiziert. Es ersetzt keine menschlichen Reviews, aber bei tausenden Antworten pro Tag ist es die einzige praktikable Methode, Qualität im Blick zu behalten, ohne ein Heer an Annotatorinnen und Annotatoren einzustellen.
Was kann ein LLM-Judge bewerten?
Im Grunde alles, was du als Kriterium in Worte fassen kannst. Faktentreue zu den Quelldokumenten, Tonalität, Safety, ob die Antwort die Frage wirklich beantwortet, und Halluzinationserkennung sind gute Beispiele. Manche Teams nutzen auch paarweise Vergleiche, bei denen der Judge zwischen zwei Kandidatenantworten wählt. Die Flexibilität ist der große Vorteil.
Wie genau sind LLM-Judges im Vergleich zu Menschen?
Etwa 80% Übereinstimmung mit menschlichen Evaluatorinnen und Evaluatoren taucht in der Forschung immer wieder auf – ungefähr so hoch stimmen auch zwei Menschen miteinander überein. LLM-Judges haben aber Biases. Sie bevorzugen tendenziell längere, detailreichere Antworten, selbst wenn eine kürzere besser wäre. Darauf musst du in der Rubrik reagieren.
Welche Frameworks unterstützen LLM-as-a-judge?
DeepEval ist beliebt, weil es sich mit pytest integrieren lässt und Evaluierungen wie Unit-Tests behandelt – das passt natürlich in CI/CD-Workflows. RAGAS ist speziell für RAG-Pipelines gebaut. MLflow hat kürzlich Integrationen mit beiden hinzugefügt, sodass du Metriken aus mehreren Frameworks in einem Tracking-System zusammenführen kannst. LangSmith und Evidently runden die wichtigsten Optionen ab.
Josep ist Data Scientist und Projektmanager beim katalanischen Fremdenverkehrsamt und nutzt Daten, um die Erfahrungen von Touristen in Katalonien zu verbessern. Sein Fachwissen umfasst das Management von Datenspeicherung und -verarbeitung, gekoppelt mit fortschrittlichen Analysen und der effektiven Kommunikation von Datenerkenntnissen.
Er ist auch ein engagierter Pädagoge, der den Big-Data-Masterstudiengang an der Universität von Navarra unterrichtet und regelmäßig aufschlussreiche Artikel über Datenwissenschaft auf Medium und KDNuggets veröffentlicht.
Er hat einen BS in technischer Physik von der Polytechnischen Universität von Katalonien und einen MS in intelligenten interaktiven Systemen von der Universität Pompeu Fabra.
Derzeit engagiert er sich leidenschaftlich dafür, datenbezogene Technologien durch die Medium-Publikation ForCode'Sake einem breiteren Publikum zugänglich zu machen.
