RAG mit Ollama aufbauen
Was dieser Artikel über RAG mit Ollama behandelt
- Was RAG ist und wie es funktioniert.
- Welche Komponenten ein lokales RAG-System braucht.
- Wie Dokumente in Chunks aufgeteilt werden.
- Wie Embeddings und Vektordatenbanken zusammenspielen.
- Ein praktisches Python-Beispiel mit Ollama und ChromaDB.
Einleitung: RAG mit Ollama aufbauen
Retrieval-Augmented Generation, kurz RAG, erweitert Sprachmodelle um externes Wissen. Statt sich auf das im Modell gespeicherte Wissen zu verlassen, werden passende Dokumentenabschnitte zur Laufzeit aus einer Wissensdatenbank gesucht und in den Prompt eingefügt. Dadurch antwortet das Modell präziser, aktueller und kann auf eigene Dokumente zugreifen. Ollama eignet sich ideal für RAG, weil sowohl Sprachmodelle als auch Embedding-Modelle lokal betrieben werden können.
Dieser Artikel zeigt, wie man ein einfaches RAG-System mit Ollama, einem Embedding-Modell und einer Vektordatenbank aufbaut.
Wichtige Begriffe
- RAG: Retrieval-Augmented Generation.
- Embedding: Vektor-Darstellung eines Textes.
- Vektordatenbank: Speicher für Embeddings mit Ähnlichkeitssuche.
- Chunk: Kleiner Textausschnitt aus einem Dokument.
- Retriever: Komponente, die passende Chunks findet.
- Kontext: Zusammengestellte Chunks, die an das Sprachmodell übergeben werden.
- Prompt: Anfrage inklusive Kontext und Frage.
- Kosinusähnlichkeit: Mass für die Nähe zweier Vektoren.
Architektur eines lokalen RAG-Systems
Ein typisches RAG-System besteht aus vier Teilen:
- Dokumente laden: PDF, Text, Markdown oder Webseiten einlesen.
- Chunking: Dokumente in überlappende Stücke aufteilen.
- Embeddings erzeugen: Jedes Chunk in einen Vektor umwandeln.
- Speichern und suchen: Vektoren in einer Datenbank ablegen und abfragen.
- Antwort generieren: Passende Chunks als Kontext an Ollama senden.
Dokumente laden
Python mit langchain oder einfachem Code:
from pathlib import Path
doc_path = Path("dokumente/handbuch.md")
text = doc_path.read_text(encoding="utf-8")
Für PDFs eignen sich pymupdf oder pdfplumber.
Chunking
Dokumente werden in Stücke mit fester Länge und Überlappung aufgeteilt:
def chunk_text(text, chunk_size=500, overlap=50):
chunks = []
for i in range(0, len(text), chunk_size - overlap):
chunks.append(text[i:i + chunk_size])
return chunks
chunks = chunk_text(text)
Typische Werte:
- Chunk-Grösse: 300 bis 1000 Zeichen.
- Überlappung: 10 bis 20 Prozent.
Semantisches Chunking, zum Beispiel nach Absätzen oder Überschriften, ist oft besser als reine Zeichenanzahl.
Embeddings erzeugen
import requests
import json
def embed(texts, model="nomic-embed-text"):
url = "http://localhost:11434/api/embed"
payload = {"model": model, "input": texts}
resp = requests.post(url, json=payload)
return resp.json()["embeddings"]
vectors = embed(chunks)
Vektordatenbank einrichten
ChromaDB lässt sich lokal betreiben:
pip install chromadb
import chromadb
client = chromadb.Client()
collection = client.create_collection(name="wissen")
for i, (chunk, vector) in enumerate(zip(chunks, vectors)):
collection.add(
ids=[str(i)],
embeddings=[vector],
documents=[chunk]
)
Suche
question = "Wie wird das Passwort zurückgesetzt?"
question_vector = embed([question])[0]
results = collection.query(
query_embeddings=[question_vector],
n_results=3
)
context = "\n\n".join(results["documents"][0])
Antwort generieren
import requests
url = "http://localhost:11434/api/chat"
payload = {
"model": "llama3.1",
"messages": [
{"role": "system", "content": "Beantworte die Frage ausschliesslich anhand des Kontexts."},
{"role": "user", "content": f"Kontext:\n{context}\n\nFrage: {question}"}
],
"stream": False
}
resp = requests.post(url, json=payload)
print(resp.json()["message"]["content"])
System-Prompt für RAG
Der System-Prompt sollte festlegen, dass das Modell nur aus dem Kontext antwortet:
Du beantwortest Fragen ausschliesslich anhand des bereitgestellten Kontexts.
Wenn die Antwort nicht im Kontext steht, ehrlich angeben, dass keine passende Information vorliegt.
Alternative Vektordatenbanken
| Datenbank | Besonderheit |
|---|---|
| ChromaDB | Einfach, gut für Prototypen. |
| Qdrant | Schnell, skalierbar, REST-API. |
| Weaviate | Modellunabhängig, stark für Enterprise. |
| pgvector | PostgreSQL-Erweiterung. |
| FAISS | Meta-Bibliothek, sehr schnell. |
Tipps für gutes RAG
- Dokumente sauber vorverarbeiten.
- Sinnvolle Chunk-Grössen wählen.
- Semantisches Chunking prüfen.
- Passendes Embedding-Modell nutzen.
- Anzahl der zurückgegebenen Chunks anpassen.
- Antworten auf Halluzinationen prüfen.
- Fragen und Antworten testen und iterieren.
Typische Stolpersteine
- Chunks zu gross: Viele irrelevante Informationen im Kontext.
- Chunks zu klein: Zusammenhänge gehen verloren.
- Falsches Embedding-Modell: Sprache oder Domäne passt nicht.
- Dokumente nicht bereinigt: Kopfzeilen, Fusszeilen oder HTML stören.
- Zu viele Chunks im Kontext: Modell überschreitet Kontextlänge.
- Keine Quellenangabe: Nutzer können Antworten nicht nachvollziehen.
- Halluzinationen: Modell erfindet trotz Kontext Antworten.
Erweiterungen
- Re-Ranking: Erst schnell viele Chunks finden, dann bestes sortieren.
- Hybrid Search: Kombination aus Keyword- und Vektorsuche.
- Metadaten: Filter nach Datum, Quelle oder Kategorie.
- LangChain / LlamaIndex: Frameworks, die RAG-Ketten vereinfachen.
- Open WebUI: Bietet integrierte RAG-Funktionen für Ollama.
Weiterführende Links und Infos
- BotServ.de Ollama Embeddings
- BotServ.de Ollama REST API
- BotServ.de Ollama Befehle
- BotServ.de RAG Wissensdatenbank
- BotServ.de Vektordatenbanken
FAQ: RAG mit Ollama
Brauche ich für RAG eine GPU? Empfohlen, aber nicht zwingend. Embedding und Inferenz sind auf GPU deutlich schneller.
Welches Embedding-Modell eignet sich?
nomic-embed-text ist ein guter Allrounder, mxbai-embed-large besser für Mehrsprachigkeit.
Kann ich PDFs verwenden? Ja, nach Textextraktion und Chunking.
Wie gross sollten Chunks sein? 300 bis 1000 Zeichen, abhängig vom Dokument und der Frage.
Ist Open WebUI für RAG geeignet? Ja, es bietet eine integrierte RAG-Funktion mit Dokumenten-Upload.
Quellen und weiterführende Literatur
- LangChain RAG: https://python.langchain.com/docs/use_cases/question_answering/
- LlamaIndex: https://www.llamaindex.ai/
- ChromaDB: https://www.trychroma.com/
- Ollama RAG Tutorial: https://github.com/ollama/ollama/blob/main/docs/
Zusammenfassung: RAG mit Ollama aufbauen
RAG erweitert Ollama um eigene Dokumente und aktuelles Wissen. Die Architektur umfasst Laden, Chunking, Embedding, Vektordatenbank und generative Antwort. Mit ChromaDB, Python und Ollama lässt sich ein prototypisches RAG-System schnell aufbauen. Wichtig sind saubere Dokumente, sinnvolle Chunk-Grössen, ein passendes Embedding-Modell und ein guter System-Prompt. Wer RAG iterativ testet, verbessert präzise und datenschutzfreundlich die Antwortqualität.


