Lokales RAG mit ChromaDB und Ollama: Tutorial Python
Lokales RAG mit ChromaDB, Ollama und Python besteht aus drei ineinandergreifenden Bausteinen: einem Vektorspeicher, der Daten dauerhaft auf dem Datenträger speichert (ChromaDB), einem Embedding-Modell, das Ihre Chunks in Vektoren umwandelt (nomic-embed-text über Ollama), und einem Chat-LLM, das seine Antworten auf die gefundenen Textpassagen stützt. Kein API-Schlüssel, keine Datenlecks. Dieser Leitfaden führt Sie in 22 Minuten von einer unbearbeiteten PDF-Datei zu einem Chatbot, der seine Quellen zitiert.
#Warum dieser Stack für lokales RAG
Viele RAG-Tutorials beginnen mit LangChain oder LlamaIndex. Diese Frameworks sind leistungsfähig, verbergen aber, was unter der Haube passiert. Hier schreiben wir die Pipeline von Hand mit nur drei Abhängigkeiten. Sie werden jeden Schritt verstehen und wissen, was Sie später optimieren können.
- ChromaDB
- Open-Source-Vektorspeicher in reinem Python mit integriertem persistentem Modus (SQLite + HNSW-Index). Es muss kein Server gestartet werden.
- Ollama
- Stellt sowohl das Embedding-Modell (nomic-embed-text) als auch das Chat-LLM (Qwen 3.5, Granite 4.2, Gemma 4) bereit. Ein einziger HTTP-Endpunkt unter localhost:11434.
- Natives Python
- Ein paar Funktionen, kein Framework. Sie können LangChain später bei Bedarf anbinden, aber für den Einstieg ist das nicht nötig.
#Voraussetzungen
Dieser Guide führt Sie zum Modell. Das Kit führt Sie zum Copiloten, der in Ihrem Editor Code schreibt.
- Lebenslanger Online-Zugang
- PDF + Dateien
- Erstattung binnen 30 Tagen
- Python 3.10+
- ChromaDB erfordert mindestens 3.10. Prüfen Sie die Version mit python --version.
- Ollama installiert und gestartet
- Der Daemon lauscht standardmäßig auf http://localhost:11434. Wenn Sie bei null anfangen, folgen Sie zunächst dem Leitfaden zur Installation von Ollama.
- 8 GB RAM
- Mit 16 GB läuft es komfortabel. Das 9B-Chat-Modell in Q4 benötigt etwa 6 GB, das Embedding-Modell etwa 300 MB.
- Eine GPU ist nicht erforderlich
- Inferenz auf der CPU funktioniert, nur langsamer. Beim Einlesen eines großen Korpus beschleunigt eine GPU mit mindestens 6 GB die Berechnung der Embeddings erheblich.
#1. ChromaDB installieren und Ollama vorbereiten
Wir erstellen eine saubere virtuelle Umgebung, installieren die drei benötigten Bibliotheken und laden die Modelle in Ollama herunter.
Drei Pakete: chromadb für den Vector Store, ollama für den offiziellen Python-Client, pypdf zum Lesen von PDF-Dateien. Das ist alles.
nomic-embed-text ist ein mehrsprachiges Embedding-Modell mit 137 Millionen Parametern, das Vektoren mit 768 Dimensionen erzeugt. Leichtgewichtig, schnell, gut auf Französisch. Qwen 3.5 9B (6,6 GB, 256k Kontext, mehrsprachig, Apache 2.0) übernimmt den abschließenden Chat: Es ist 2026 die Standardwahl für 8 GB. Sie können es durch granite4.2:8b (ressourcensparender) oder gemma4:12b ersetzen, ohne etwas am Code zu ändern.
#2. Das Embedding-Modell konfigurieren
Ein Embedding ist ein Vektor, der den Sinn eines Textes darstellt. Zwei textliche Inhalte, die semantisch nahe beieinander liegen, haben ähnliche Vektoren. Dies ist der Motor des RAG: Man sucht die Chunks, deren Embedding dem der Frage am ähnlichsten ist.
Sie sollten die Ausgabe „Dimension du vecteur : 768“ sehen. Wenn es mit model not found fehlschlägt, wurde ollama pull nomic-embed-text nicht ausgeführt.
#3. Einlesen von PDF-Dateien auf Französisch
Die Ingestion erledigt drei Aufgaben: Sie liest die Seiten eines PDF-Dokuments, teilt den Text in Chunks angemessener Größe auf und speichert jeden Chunk mit seinem Embedding in ChromaDB im persistenten Modus.
Der Chunker teilt den Text in Blöcke von 800 Zeichen mit einer Überlappung von 100 Zeichen auf. Das ist ein Ausgangspunkt: weder zu klein (zu wenig Kontext) noch zu groß (das Signal wird verwässert). Bei sehr dichten juristischen Inhalten reduzieren Sie die Blockgröße auf 500 Zeichen. Bei technischen Handbüchern mit großzügigem Layout erhöhen Sie sie auf 1200 Zeichen.
Starten Sie die Ingestion für einen Ordner ./pdfs/, der Ihre Dokumente enthält:
#4. Top-k-Suche in ChromaDB
Sobald die Chunks indexiert sind, besteht die Suche darin, ein Embedding der Frage zu erzeugen und anschließend bei Chroma die k nächstgelegenen Vektoren anhand der Kosinusdistanz abzufragen. Das geschieht sofort, selbst bei 100.000 Chunks.
k=4 ist ein guter Standardwert. Ist der Wert zu klein, entgeht Ihnen relevanter Kontext; ist er zu groß, überfrachten Sie das LLM mit irrelevanten Informationen und überschreiten das Kontextfenster. Für sehr präzise Fragen reicht k=2 aus. Für übergreifende Fragen erhöhen Sie den Wert auf 6.
#5. Chat-Schleife mit Quellenangaben
Jetzt setzen wir alles zusammen: Wir suchen die relevanten Chunks, erstellen einen Prompt mit dem Kontext, senden ihn über Ollama an Qwen 3.5 und bitten das Modell, seine Quellen zu zitieren.
Drei Details sind entscheidend. Erstens, temperature=0.2: Gewünscht ist eine faktentreue Antwort, keine kreative. Zweitens, num_ctx=8192: Das standardmäßige Kontextfenster von Ollama (2048) ist zu kurz, sobald man 4 Chunks mit jeweils 800 Zeichen einfügt. Drittens, der Systemprompt zwingt das Modell, „ich weiß es nicht“ zu sagen, statt zu halluzinieren – das ist der wichtigste Schutz gegen Halluzinationen beim RAG.
#6. Konkreter Fall: juristischer Chatbot für Verträge
Stellen wir uns ein Büro vor, das 200 Dienstleistungsverträge im PDF-Format abfragen möchte. Mit dem oben genannten Stack steht in weniger als einer Stunde ein Assistent bereit, der Fragen wie diese beantwortet:
- Typische Frage
- „Welche Verträge enthalten eine Klausel für ein nachvertragliches Wettbewerbsverbot von mehr als 12 Monaten?“
- Was passiert
- Das Embedding der Frage findet die Chunks, die semantisch ähnliche Schlüsselwörter enthalten (Wettbewerbsverbot, nach Beendigung, Dauer). Qwen 3.5 liest diese 4 Passagen und antwortet mit den Namen der betreffenden Dateien.
- Datenschutzgarantie
- Keine Daten verlassen den Rechner. Keine API-Schlüssel. Keine Telemetrie. Das unterscheidet einen lokalen RAG von einem OpenAI-Wrapper.
#Fehlerbehebung
- ChromaDB langsam bei der Ingestion
- Der Engpass ist fast immer die Embedding-Anfrage an Ollama. Prüfen Sie mit ollama ps, ob nomic-embed-text auf der GPU läuft. Auf der CPU können Sie mit ~50 Chunks pro Sekunde rechnen, auf der GPU mit ~500.
- « model not found »
- Ollama findet nomic-embed-text nicht. Führen Sie ollama pull nomic-embed-text erneut aus und prüfen Sie das Ergebnis mit ollama list.
- Antworten, die Quellen erfinden
- Ein 9B-Modell halluziniert noch gelegentlich. Wechseln Sie zu mistral-small (24B, ~14 GB, sehr gut auf Französisch) oder qwen3.8:27b, wenn Sie genügend VRAM haben. Oder schalten Sie nach ChromaDB einen Reranker (Cross-Encoder), um falsch positive Treffer herauszufiltern.
- Schlechte Embeddings für Französisch
- nomic-embed-text ist mehrsprachig, aber für rein französische Inhalte nicht optimal. Testen Sie für juristische oder medizinische Inhalte Solon-embeddings-large-0.1 oder bge-m3 (über sentence-transformers außerhalb von Ollama laden).
- ChromaDB wächst ohne Grenzen
- Jede erneute Indexierung fügt Duplikate hinzu. Bevor Sie eine PDF-Datei erneut einlesen, führen Sie collection.delete(where={"source": name}) aus, um die alten Chunks zu löschen.
#Weiterführende Informationen
Sie verfügen über ein funktionierendes RAG-System. Hier sind die naheliegenden nächsten Aufgaben, um es weiterzuentwickeln:
- Embedding-Modelle für Französisch vergleichen
- Unser Leitfaden „Die besten Embedding-Modelle FR“ vergleicht BGE, E5, Solon und nomic anhand französischsprachiger Inhalte.
- Chunking verbessern
- „Chunking-Strategien“ erläutert semantisches Chunking sowie die Aufteilung nach Markdown-Überschriften oder Absätzen – damit lässt sich oft der größte Zugewinn an Genauigkeit erzielen.
- Einen Reranker hinzufügen
- „Einen Reranker zur eigenen Pipeline hinzufügen“: +15 % Relevanz, indem ein Cross-Encoder nach Chroma eingesetzt wird. Der nächste logische Schritt.
- Hybride Suche
- „Hybride Suche mit BM25 und Vektoren“ kombiniert lexikalische und semantische Suche und ist unverzichtbar, sobald viel Fachjargon oder viele Eigennamen vorkommen.
Haben Sie Feedback, einen Fehler entdeckt oder möchten Sie etwas präzisieren? Geben Sie uns Bescheid – so wird der Guide für alle besser.