Zum Inhalt springen
Alle Insights
Tutorial11 Min. Lesezeit

Für eine Unternehmens-Wissensbasis: mit RAG und einem Testset beginnen, Fine-Tuning nur für das Format

Eine Entscheidungstabelle für RAG gegenüber Fine-Tuning und ein Zwei-Wochen-Test, der zeigt, ob Retrieval über Ihre eigenen Dokumente Ihre eigenen Fragen gut genug beantwortet.

Teams, die einen Assistenten über ihre eigenen Dokumente wollen, stellen meist dieselbe erste Frage: Sollen wir ein Modell auf unseren Dokumenten trainieren oder ein Modell an sie anbinden? Für eine Wissensbasis lautet die Standardantwort: anbinden, also genau das, was Retrieval-Augmented Generation (RAG) tut, und vor jeder weiteren Entscheidung ein Testset aus echten Fragen aufbauen. Diese Notiz erklärt beide Ansätze in einfachen Worten, gibt eine Entscheidungstabelle und geht dann einen Zwei-Wochen-Test durch, den Sie mit einem Engineer und einer Person durchführen können, die die Dokumente kennt.

RAG und Fine-Tuning in einfachen Worten

Ein Sprachmodell weiß, was in seinen Trainingsdaten stand. Es kennt weder Ihre Rückgaberichtlinie noch die Preisliste vom letzten Monat noch das interne Verfahren zur Freigabe eines Lieferanten.

RAG löst das zum Zeitpunkt der Frage. Stellt jemand eine Frage, durchsucht das System Ihre Dokumente, nimmt die Handvoll Passagen, die am relevantesten erscheinen, und gibt sie dem Modell mit einer Anweisung: Antworte anhand dieser Passagen und nenne, welche du verwendet hast. Die Dokumente bleiben, wo sie sind. Ändern Sie eine Richtlinie, indizieren Sie sie neu, und die nächste Antwort spiegelt die Änderung wider. Die Technik wurde in einem Forschungspaper von 2020 beschrieben, das einen Textgenerator mit einem durchsuchbaren Dokumentindex kombinierte; die Grundidee hat sich seitdem nicht geändert.

Fine-Tuning setzt das Training eines Modells mit Beispielen aus Eingaben und gewünschten Ausgaben fort. Es verändert die Gewohnheiten des Modells: Tonfall, Struktur, Vokabular, den Umgang mit einer eng umrissenen Aufgabe. Um sich ändernde Fakten beizubringen, taugt es wenig. Jede Änderung an der Quelle erfordert einen neuen Trainingslauf, das Modell kann nicht angeben, woher eine Antwort stammt, und alles, was es gelernt hat, steht jedem zur Verfügung, der es nutzen kann.

Die meisten Unternehmen arbeiten bereits so. Der Bericht von Menlo Ventures zu generativer KI in Unternehmen vom Dezember 2025 ergab, dass Prompt-Design der häufigste Weg ist, wie Unternehmen Modelle anpassen, RAG der zweithäufigste; Fine-Tuning und Reinforcement Learning waren weiterhin Nischenthemen und wurden vor allem von Frontier-Teams genutzt.

Was es kostet. Der Zwei-Wochen-Test unten kostet die Zeit eines Engineers und einige Tage einer Fachexpertin oder eines Fachexperten, dazu Modellnutzung, die im Umfang eines Testsets gering ist. In Produktion folgen die Betriebskosten einer Formel: Fragen pro Monat × Tokens pro Frage × Preis pro Token. Zur Illustration: 10.000 Fragen im Monat, die jeweils fünf Passagen von etwa 400 Tokens plus 500 Tokens Anweisungen und Frage senden und eine Antwort von 300 Tokens erhalten, ergeben 10.000 × 2.800 = 28 Millionen Tokens. Bei einem illustrativen Mischpreis von 5 $ pro Million Tokens sind das 140 $ im Monat. Verwenden Sie die aktuellen Preise Ihres Anbieters; es geht um die Formel. Wenn Sie das System gebaut statt getestet haben möchten: Unsere veröffentlichte Spanne für einen internen RAG-Copilot liegt bei 8k–18k $ über 4–8 Wochen, und die Preisseite zeigt die zugrunde liegende Preisliste.

Die Entscheidungstabelle

Was Sie brauchen RAG Fine-Tuning
Wissen, das sich wöchentlich oder täglich ändert Änderungen erscheinen nach der nächsten Neuindizierung Jede Änderung braucht einen neuen Trainingslauf und eine neue Evaluation
Ein Quellenlink zu jeder Antwort Eingebaut: Die Antwort zitiert die verwendeten Passagen Kein verlässlicher Weg anzugeben, woher eine Antwort stammt
Verschiedene Personen dürfen verschiedene Dokumente sehen Passagen werden nach den Berechtigungen des Nutzers gefiltert, bevor das Modell sie sieht Was eintrainiert ist, ist für jeden Nutzer des Modells sichtbar
Ein festes Ausgabeformat oder der Tonfall des Hauses Mit Anweisungen und Beispielen im Prompt möglich, manchmal uneinheitlich Passt gut
Niedrige Latenz Fügt einen Suchschritt und einen längeren Prompt hinzu Kein zusätzlicher Schritt; ein kleineres getuntes Modell kann zudem schneller sein
Aktualisierungsaufwand Die geänderten Dokumente neu indizieren Beispiele vorbereiten, neu trainieren, neu evaluieren
Benötigte Daten für den Start Die Dokumente und ein Testset aus echten Fragen Beispieleingaben mit idealen, von Menschen geprüften Ausgaben, plus dasselbe Testset

Zählen Sie, welche Zeilen für Ihren Fall zählen. Bei einer Wissensbasis entscheiden meist die ersten drei: Der Inhalt ändert sich, Menschen wollen die Quelle prüfen, und nicht jeder darf alles lesen.

Fine-Tuning verdient seinen Platz in einer engeren Gruppe von Fällen: Antworten müssen immer einer strikten Struktur folgen; eine Aufgabe mit hohem Volumen, etwa das Einordnen von Tickets in Kategorien, könnte auf einem kleineren, günstigeren Modell laufen; oder der Tonfall muss einem Styleguide entsprechen, den Prompting nicht hält. Selbst dann sitzt es meist auf dem Retrieval auf, statt es zu ersetzen, als getuntes Modell, das weiterhin die abgerufenen Passagen liest.

Der Standard ist also zuerst RAG plus ein Evaluationsset. Fine-Tuning kommt später, für Format, Tonfall oder eine eng umrissene Aufgabe, und nur wenn das Testset zeigt, dass die verbleibenden Fehler von dieser Art sind.

Der Zwei-Wochen-Test

Der Test ersetzt Meinungen durch eine Zahl. Am Ende haben Sie einen Score auf Ihren eigenen Fragen und eine nach Ursachen sortierte Liste von Fehlern. Daraus ergibt sich, ob Sie bauen sollten, was zu beheben ist und ob Fine-Tuning überhaupt helfen würde.

Schritt 1: echte Fragen sammeln

Nehmen Sie Fragen, die tatsächlich gestellt wurden: Helpdesk-Tickets, interne Chat-Threads, Suchprotokolle des Intranets, die Fragen, die die verantwortliche Person für eine Richtlinie per E-Mail beantwortet. Ziel sind 150 bis 300. Nehmen Sie 10–15% Fragen auf, die Ihre Dokumente nicht beantworten können, denn korrekt abzulehnen gehört zur Aufgabe.

Warum so viele: Bei 200 Fragen und einer tatsächlichen Genauigkeit um 80% liegt die Fehlermarge bei 95% Konfidenz bei etwa ±5,5 Prozentpunkten (1,96 × √(0,8 × 0,2 / 200) ≈ 0,055). Ein kleineres Set kann zwei Versionen des Systems nicht unterscheiden.

Für jede Frage schreibt eine Person, die den Stoff kennt, die erwartete Antwort und nennt das Dokument, aus dem sie stammen sollte. Eine JSON-Zeile pro Frage:

{"id": "q041", "question": "Who approves a new supplier above the purchasing threshold?", "expected": "Procurement lead and finance, both in writing.", "doc": "supplier-onboarding", "groups": ["procurement"], "answerable": true}

Jede Antwort erhält dann eines von vier Labels:

  • correct (richtig): korrekt, vollständig und mit Zitat des richtigen Dokuments;
  • partly (teilweise): korrekt, aber unvollständig, oder korrekt mit falschem oder fehlendem Zitat;
  • wrong (falsch): behauptet etwas Falsches oder beantwortet eine Frage, die die Dokumente nicht beantworten können;
  • declined (abgelehnt): sagt, dass es nicht antworten kann.

Abgelehnt ist bewusst ein eigenes Label. Bei einer beantwortbaren Frage ist es ein Fehlschlag, aber ein günstigerer als eine falsche Antwort, und der Fachbereich entscheidet, wie viele von beiden er akzeptieren kann. Legen Sie diese Schwelle vor dem ersten Lauf fest, so wie eine Kennzahl festgelegt wird, bevor ein Modell trainiert wird.

Eine Fachexpertin oder ein Fachexperte bewertet die ersten 50 Antworten von Hand. Danach kann ein zweites Modell den Rest anhand der erwarteten Antworten bewerten, sofern seine Labels bei diesen 50 mit denen der Expertin oder des Experten übereinstimmen. Beide Praktiken sind verbreitet: In der Umfrage von LangChain unter 1.340 Praktikern, die Agenten bauen, durchgeführt im November und Dezember 2025, nutzten 59,8% menschliches Review, 53,3% ein Modell als Richter und 52,4% führten Offline-Evaluationen auf Testsets durch.

Schritt 2: Passagen mit ihren Berechtigungen indizieren

Teilen Sie Dokumente entlang ihrer Überschriften in Passagen von einigen hundert Wörtern. Speichern Sie zu jeder Passage Dokument-ID, Titel, Link und Zugriffsgruppen. Berechtigungen gehören von Anfang an zur Passage; sie später hinzuzufügen bedeutet, alles neu zu indizieren.

Schritt 3: hybrides Retrieval mit Reciprocal Rank Fusion

Schlüsselwortsuche (BM25) findet exakte Begriffe wie Produktcodes, Formularnummern und Abkürzungen. Embedding-Suche findet Umschreibungen: „Freizeit“, wenn in der Richtlinie „Jahresurlaub“ steht. Jede verfehlt, was die andere findet, also nutzen Sie beide und führen die Rankings zusammen.

Reciprocal Rank Fusion (RRF) führt nach Position statt nach Score zusammen, sodass die beiden Bewertungsskalen nie kalibriert werden müssen: Jede Passage erhält aus jeder Liste 1 / (k + Rang), aufsummiert. Das Paper von 2009, das das Verfahren einführte, setzte k auf 60 und stellte fest, dass dieser Wert nahezu optimal, aber nicht kritisch ist.

import numpy as np
from rank_bm25 import BM25Okapi

def tokenize(text):
    return text.lower().split()

class HybridIndex:
    def __init__(self, chunks, embed):
        # chunks: dicts with "text", "doc", "groups" (a set); embed: list[str] -> unit vectors
        self.chunks, self.embed = chunks, embed
        self.bm25 = BM25Okapi([tokenize(c["text"]) for c in chunks])
        self.vectors = np.asarray(embed([c["text"] for c in chunks]))

    def search(self, query, user_groups, k=5, depth=50, rrf_k=60):
        allowed = [i for i, c in enumerate(self.chunks) if c["groups"] & user_groups]
        lexical = self.bm25.get_scores(tokenize(query))
        semantic = self.vectors @ np.asarray(self.embed([query]))[0]
        fused = {}
        for scores in (lexical, semantic):
            ranked = sorted(allowed, key=lambda i: scores[i], reverse=True)[:depth]
            for rank, i in enumerate(ranked, start=1):
                fused[i] = fused.get(i, 0.0) + 1.0 / (rrf_k + rank)
        top = sorted(fused, key=fused.get, reverse=True)[:k]
        return [{**self.chunks[i], "similarity": float(semantic[i])} for i in top]

embed ist eine beliebige Embedding-Funktion, gehostet oder Open Source; ein Austausch ändert ein Argument. Der Berechtigungsfilter läuft vor dem Ranking, sodass eine Passage, die der Nutzer nicht öffnen darf, das Modell nie erreicht.

Schritt 4: mit Zitaten antworten oder ablehnen

Zwei Prüfungen verhindern, dass das System etwas erfindet. Vor dem Modellaufruf: Ist die beste Passage der Frage nicht ähnlich genug, wird ohne Generierung abgelehnt. Danach: Jede Antwort muss Passagen zitieren, und jede zitierte Nummer muss existieren. Alles andere zählt als abgelehnt.

import re

PROMPT = """Answer the question using only the numbered passages below.
After each sentence, cite the passages you used, for example [2].
If the passages do not contain the answer, reply with exactly: NOT_FOUND

{passages}

Question: {question}"""

def answer(question, index, user_groups, llm, min_similarity=0.35):
    hits = index.search(question, user_groups)
    if not hits or max(h["similarity"] for h in hits) < min_similarity:
        return {"status": "declined", "text": None, "docs": []}
    passages = "\n\n".join(f"[{n}] ({h['doc']}) {h['text']}" for n, h in enumerate(hits, 1))
    text = llm(PROMPT.format(passages=passages, question=question)).strip()
    cited = {int(n) for n in re.findall(r"\[(\d+)\]", text)}
    if text == "NOT_FOUND" or not cited or not cited <= set(range(1, len(hits) + 1)):
        return {"status": "declined", "text": None, "docs": []}
    return {"status": "answered", "text": text, "docs": [hits[n - 1]["doc"] for n in sorted(cited)]}

llm ist eine beliebige Funktion, die einen Prompt entgegennimmt und Text zurückgibt, sodass sich das Modell austauschen lässt, ohne diesen Code anzufassen. Die Schwelle von 0,35 ist ein Platzhalter: Ähnlichkeitsskalen unterscheiden sich zwischen Embedding-Modellen. Legen Sie sie auf Ihrem Testset so fest, dass die nicht beantwortbaren Fragen abgelehnt werden, ohne zu viele beantwortbare zu verlieren.

Schritt 5: die Bewertungsschleife

import json
from collections import Counter

def run_eval(path, index, llm, judge):
    items = [json.loads(line) for line in open(path)]
    labels, found = Counter(), 0
    for item in items:
        groups = set(item["groups"])
        if item["answerable"]:
            hits = index.search(item["question"], groups)
            found += item["doc"] in {h["doc"] for h in hits}
        result = answer(item["question"], index, groups, llm)
        if not item["answerable"]:
            label = "correct" if result["status"] == "declined" else "wrong"
        elif result["status"] == "declined":
            label = "declined"
        else:  # judge returns "correct", "partly" or "wrong"
            label = judge(item["question"], item["expected"], result["text"])
        labels[label] += 1
    answerable = sum(1 for item in items if item["answerable"])
    print({k: round(v / len(items), 3) for k, v in labels.items()})
    print("expected document in top 5:", round(found / answerable, 3))

Die zweite Zahl ist so wichtig wie die erste. War das richtige Dokument nicht unter den ersten fünf, hatte das Modell nie eine Chance, und die Lösung liegt im Retrieval oder in den Dokumenten, nicht im Modell. Speichern Sie die Labels jedes Laufs mit Datum und der vorgenommenen Änderung, damit jede Änderung mit derselben Baseline verglichen wird.

Woche 1 und Woche 2

Woche 1: die Baseline.

  • Tage 1–2: die Fragen mit den Verantwortlichen der Dokumente sammeln und aufschreiben; die Abnahmeschwelle festlegen.
  • Tag 3: die Dokumente indizieren; zuerst nur Schlüsselwortsuche, dann hybrid ausführen und für beide die Top-5-Trefferquote festhalten.
  • Tage 4–5: erster vollständiger Lauf; die Fachperson bewertet 50 Antworten; den Richter daran prüfen; den Rest bewerten.

Das Ergebnis von Woche 1 ist ein Score und eine Liste von Fehlern, sortiert nach vier Ursachen: Das Dokument fehlt oder ist veraltet; das Retrieval hat die richtige Passage verfehlt; das Modell hatte die richtige Passage und hat trotzdem schlecht geantwortet; das System hätte ablehnen sollen und hat es nicht getan.

Woche 2: nach Größe beheben.

  • Beginnen Sie mit der größten Ursache. Fehlende oder veraltete Dokumente sind eine inhaltliche Aufgabe für ihre Verantwortlichen. Retrieval-Fehlschläge lassen sich meist durch besseres Chunking, Dokumenttitel und Überschriften in jeder Passage oder Synonyme für internen Jargon beheben. Schlechte Antworten trotz guter Passagen lassen sich durch Prompt-Änderungen und manchmal ein anderes Modell beheben.
  • Führen Sie nach jeder Änderung das vollständige Set erneut aus. Behalten Sie eine Änderung nur, wenn sich der Score um mehr als die Fehlermarge bewegt.
  • Stimmen Sie die Ablehnungsschwelle zuletzt ab, auf dem endgültigen Retrieval-Setup.

Am Ende von Woche 2 ist die Entscheidung meist klar. Liegt die Quote falscher Antworten unter der vereinbarten Schwelle, bauen Sie die Produktionsversion und behalten das Testset als Release-Gate. Betreffen die verbleibenden Fehler Format oder Tonfall, während die Fakten stimmen, ist das der Fall, in dem sich ein Test von Fine-Tuning lohnt, und das Testset existiert bereits, um zu zeigen, ob es geholfen hat. Sind die meisten Fehler fehlende Dokumente, liegt das Problem in der Wissensbasis, und keine Modellwahl wird es beheben.

In dieser Reihenfolge gehen wir beim Bau von RAG-Copilots vor: zuerst echte Fragen, dann Retrieval, dann ein Score, den jedes Release schlagen muss.

Quellen

Haben Sie einen Prozess, der zu viel kostet?

Erzählen Sie uns davon. Das erste Gespräch ist kostenlos, und wenn KI nicht die Antwort ist, sagen wir das.

Aufgabe besprechen