localaiforum
Anmelden
Guide › Arbeiten mit Modellen

RAG: dem Model Ihre Daten geben

Das Wissen eines LLM frierte bei seinem Trainings-Cutoff ein; Ihre Dokumente ändern sich wöchentlich. Retrieval-Augmented Generation (RAG) taut es auf: Zur Abfragezeit die relevanten Scheiben Ihrer Daten holen, in den Prompt einfügen und das Model aus Belegen mit Zitaten antworten lassen. Das Model macht Reasoning; der Index macht Gedächtnis.

Die Pipeline, ein durchgerechnetes Beispiel

Nehmen Sie ein 12.000-Token-Wartungshandbuch und führen Sie es von Ende zu Ende durch:

  1. Chunken. Zuerst an Überschriften splitten (Abschnitte überleben intakt), dann jeden Abschnitt über ~400 Tokens neu splitten, mit ~60 Tokens Überlappung (10–15%). Sinnvolle Chunk-Größen liegen bei 200–800 Tokens. Ergebnis: grob 35 Chunks.
  2. Embedden. Jeder Chunk wird ein Vektor — bge-m3 stößt 1.024 Floats pro Chunk aus. Auf der CPU dauert das für das ganze Handbuch Sekunden.
  3. Indexieren. Vektoren + Text + Metadaten (Quelldatei, Überschriftenpfad) in einem Vektorspeicher ablegen.
  4. Abrufen. Die Frage embedden, die Top k = 5 Chunks nach Cosinus-Ähnlichkeit holen (4–10 ist der vernünftige Bereich).
  5. Generieren. Den Prompt zusammenbauen: Anweisungen, die 5 Chunks mit ID-Tags, die Frage.

Chunken an semantischen Grenzen schlägt feste Fenster. Eine Tabelle, die von ihrer Kopfzeile getrennt wurde, oder eine nummerierte Prozedur, die bei Schritt 4 abgeschnitten wurde, ist unabrufbarer Müll, egal wie gut das Embedding-Modell ist.

Zwei Extras, die sich sofort bezahlt machen: den Überschriftenpfad (manual › §4 › Bolts) als Metadaten speichern, damit Sie präzise filtern und zitieren können, und die Abfrage exakt so embedden, wie der Nutzer sie tippte — „Bereinigungs“-Vorverarbeitung macht Retrieval meist schlechter, nicht besser.

Embeddings: die multilinguale Anforderung

Das Embedding-Modell entscheidet, was „ähnlich“ heißt. Für koreanische und gemischt koreanisch/englische Korpora ist die Wahl eng — rein englische Embedder scheitern still bei koreanischen Abfragen und liefern plausible, aber falsche Chunks:

Model Dimensionen Notizen
bge-m3 1024 multilingual, starkes Koreanisch — die sichere lokale Standardwahl
nomic-embed-text-v1.5 768 solides Englisch, langer Kontext
all-MiniLM-L6-v2 384 schnell, englisch-zentriert, schwach auf Koreanisch

Embedding-Modelle sind winzig (0,1–0,6B Parameter); ein CPU-Kern kaut Tausende von Chunks durch — CPU-Inferenz. Betten Sie den Korpus einmal ein, Abfragen zur Fragetime. Halten Sie das Embedding-Modell pro Index eingefroren: Der Modellwechsel mitten im Index erzeugt Vektoren aus verschiedenen Räumen, und Ähnlichkeits-Scores werden zu Rauschen.

Vektorspeicher

Speicher Wann
sqlite-vec Einzelner Nutzer, bis ~1M Vektoren, null Ops — es ist eine Datei
ChromaDB lokales Prototyping mit Metadatenfiltern
Qdrant Produktion: Filterung, hybride Suche, Skalierung

Alle drei laufen lokal. Starten Sie mit sqlite-vec; wechseln Sie, wenn Sie wirklich an seine Wand stoßen, nicht vorher.

Den Prompt zusammenbauen

Answer only from the excerpts below. Cite every claim as [n].
If the excerpts do not contain the answer, reply "not in the docs".

[1] (manual §4.2) Torque the M8 bolt to 12 Nm after lubrication...
[2] (manual §7.1) Do not re-use stretch bolts...

Question: what torque spec applies to the M8 bolt?

Zitate lassen Nutzer verifizieren, statt zu vertrauen. Der Ausgang „nicht in den Docs“ zählt: Ohne ihn erfindet das Model eine Antwort, statt am Format zu scheitern.

Hybride Suche und Reranking

Reine Vektorsuche verpasst exakte Strings — Fehlercodes, Funktionsnamen, Teilenummern —, die Stichwortsuche nagelt. Hybrid = BM25 + Vektoren, verschmolzen mit Reciprocal Rank Fusion; es ist nahezu gratis und zuverlässig besser als jedes allein.

Für Qualität fügen Sie einen Reranker hinzu: 20–50 Kandidaten abrufen, mit einem Cross-Encoder (die bge-reranker-Familie — dieselbe multilinguale Geschichte wie bge-m3) auf die Top 5 reranken. Der Reranker liest Chunk und Abfrage zusammen, was ein Ein-Vektor-Embedder nicht kann. Billiges Rezept, das die meisten Bedürfnisse abdeckt: hybrid 25 abrufen, auf 5 reranken.

Diagnose: Retrieval-Fehler oder Generierungs-Fehler?

Bevor Sie irgendetwas tunen, beantworten Sie eine Frage: Wurde der richtige Chunk abgerufen?

  1. Drucken Sie die Top-k-Chunks einer scheiternden Abfrage, mit Scores.
  2. Ist der antworttragende Chunk nicht in der Liste, ist es ein Retrieval-Problem — Chunken oder Embeddings reparieren oder k erhöhen.
  3. Ist er in der Liste, aber die Antwort ist falsch, ist es ein Generierungs-Problem — größeres Model, besserer Prompt, reranken, um Distraktoren herauszudrängen.

Dieser eine Test spart Stunden damit, die falsche Hälfte der Pipeline zu tunen.

Fehlermodi

Symptom Ursache Fix
Richtige Docs abgerufen, falsche Antwort Distraktoren im Top-k reranken; k verkleinern
Antwort existiert in den Docs, taucht aber nie auf Top-k-Aushungerung oder schlechte Grenzen k erhöhen; nach Überschriften chunken
Selbstsichere, aber veraltete Antworten Index älter als die Docs bei Änderung neu indexieren
Koreanische Abfragen verpassen englische Docs einsprachige Embeddings bge-m3
Zitate zeigen auf den falschen Chunk Chunk verlor seine Quell-Metadaten Quelle + Überschrift pro Chunk speichern

Messen, nicht viben

Halten Sie ein Golden Set aus 20–50 echten Fragen mit bekannten Antworten. Bewerten Sie zwei Zahlen getrennt: Retrieval-Trefferrate (ist der richtige Chunk im Top-k?) und Antwortkorrektheit. Verfolgen Sie sie nach jeder Änderung an Chunk-Größe, Embedder oder k. RAG-Arbeit ohne Golden Set ist Astrologie.

Wann stattdessen fine-tunen

Fine-Tuning ändert Verhalten — Format, Stil, Terminologie. Es ist ein schlechter Weg, Fakten hinzuzufügen: Das Model kann nicht zitieren, worauf es getunt wurde, und frische Dokumente bedeuten einen frischen Trainingslauf. Faustregel: Fakten → RAG, Verhalten → LoRA, beides erst, wenn Sie Prompting ausgereizt haben: Fine-Tuning.

Lokale Stacks, kleinste zuerst

Open WebUI liefert Dokument-Upload und hybrides Retrieval eingebaut mit — starten Sie dort, und Sie schreiben womöglich nie Pipeline-Code. Der ehrliche Kern von RAG sind ~50 Zeilen; schreiben Sie ihn einmal, damit Sie wissen, was die Frameworks tun:

chunks = chunk_by_header(read("manual.md"), max_tokens=400, overlap=60)
index = [(embed(c), c) for c in chunks]          # einmal erledigt

def answer(question):
    hits = topk_by_cosine(embed(question), index, k=5)
    ctx = "\n\n".join("[{}] {}".format(i, c) for i, (v, c) in enumerate(hits))
    prompt = TEMPLATE.replace("{ctx}", ctx).replace("{q}", question)
    return chat(prompt)                           # ein kleines lokales Model genügt

Greifen Sie zu LlamaIndex oder LangChain, wenn Sie Berechtigungen, geplante Aktualisierung oder Evaluations-Rahmen brauchen — nicht für die Schleife oben. Für koreanische Dokumente speziell sind mehrsprachige Embeddings (bge-m3) nicht optional, und überschriftenbasiertes Chunken sollte die koreanische Dokumentstruktur (장/절-Überschriften) genauso respektieren wie ##-Überschriften in Markdown.

Verwandt: Fine-Tuning · Prompting · Strukturierte Ausgabe · CPU-Inferenz