📚 · Eigenes Wissen für LLMs

RAG: Retrieval Augmented Generation

Lokale LLMs kennen nur was in ihren Trainingsdaten steckt. RAG gibt ihnen Zugriff auf deine eigenen Dokumente – präzise, aktuell und ohne Halluzinationen aus dem Gedächtnis.

VektordatenbankChromaChunkingEmbeddingsOllama

Wie RAG funktioniert – das Prinzip in drei Schritten

RAG löst ein fundamentales Problem: LLMs wissen viel, aber nicht das was in deinen spezifischen Dokumenten, Notizen oder internen Daten steht. RAG fügt eine Retrieval-Schicht davor.

Schritt 1 – Indexierung: Dokumente werden in Chunks zerlegt, jeder Chunk wird als Embedding (Vektor) in einer Vektordatenbank gespeichert.

Schritt 2 – Retrieval: Bei einer Anfrage wird die Frage ebenfalls als Embedding berechnet. Die Vektordatenbank findet die semantisch ähnlichsten Chunks.

Schritt 3 – Generierung: Die gefundenen Chunks werden als Kontext zusammen mit der Frage an das Sprachmodell geschickt. Das Modell antwortet auf Basis dieser echten Dokumente.

Ergebnis: Das Modell sagt nicht mehr was es aus dem Training kennt, sondern was in deinen Dokumenten steht – mit deutlich weniger Halluzinationen.

RAG-Stack lokal aufbauen: Tools und Konfiguration

Ein vollständiges lokales RAG-System braucht drei Komponenten:

  • Embedding-Modell: Wandelt Text in Vektoren um. Für lokale Setups: nomic-embed-text via Ollama oder all-MiniLM-L6-v2 via sentence-transformers.
  • Vektordatenbank: Speichert und durchsucht Vektoren. Chroma (einfach, lokal), Qdrant (skalierbar), pgvector (wenn schon PostgreSQL läuft).
  • LLM für Generierung: Beliebiges lokales Modell via Ollama.
# Minimales RAG mit Ollama + Chroma (Python) from chromadb import Client import ollama chroma = Client() collection = chroma.get_or_create_collection("meine_docs") # Dokument indexieren embed = ollama.embeddings(model="nomic-embed-text", prompt=text) collection.add(embeddings=[embed["embedding"]], documents=[text], ids=["doc1"]) # Frage beantworten q_embed = ollama.embeddings(model="nomic-embed-text", prompt=frage) results = collection.query(query_embeddings=[q_embed["embedding"]], n_results=3) kontext = "\n".join(results["documents"][0]) antwort = ollama.generate(model="mistral", prompt=f"{kontext}\n\nFrage: {frage}")

Chunking-Strategien: Das unterschätzte Detail

Die Qualität eines RAG-Systems steht und fällt mit dem Chunking – wie Dokumente in Teile zerlegt werden. Zu große Chunks: irrelevante Informationen verwässern den Kontext. Zu kleine Chunks: fehlender Kontext, unverständliche Fragmente.

  • Fixed-Size Chunking: Einfachste Methode – alle N Zeichen. Schnell, aber zerreißt oft Sätze. Mit Overlap (Überlappung) zwischen Chunks verbessern.
  • Sentence/Paragraph Chunking: An natürlichen Grenzen trennen. Besser für lesbare Kontexte.
  • Semantic Chunking: Chunks nach semantischer Ähnlichkeit bilden. Aufwändiger, aber beste Qualität.

Meine Empfehlung für den Start: Paragraph-Chunking mit 200–500 Token pro Chunk und 20% Overlap. In n8n gibt es dafür fertige Nodes im AI-Bereich.

Häufige Fragen zu RAG

Fine-Tuning bringt statisches Wissen ins Modell – teuer und muss bei neuen Daten wiederholt werden. RAG ist dynamisch: neue Dokumente einfach indexieren, das Modell selbst bleibt unverändert. Für eigene, sich ändernde Wissensdaten ist RAG fast immer die bessere Wahl.

Chroma für lokale Experimente – kein Server nötig, Python-Library, einfache API. Für Produktivsysteme: Qdrant (Docker, skalierbar, gute Performance) oder pgvector wenn schon PostgreSQL im Stack ist.

Mit Chroma oder Qdrant auf einem normalen Server problemlos hunderttausende Chunks. Die Suchgeschwindigkeit bleibt unter einer Sekunde. Für Millionen von Dokumenten braucht man verteilte Setups – für die meisten privaten Anwendungen aber weit überdimensioniert.

Ja – n8n hat AI-Nodes für Embedding, Vektorspeicher und RAG-Pipelines ohne Code. Für einfache Setups ist das der schnellste Weg. Für mehr Kontrolle über Chunking und Retrieval-Logik kommt man um etwas Python nicht herum.