
Wie ein moderner RAG-Bot funktioniert
Eine gute RAG-Pipeline ist mehr als „Dokumente in eine Vektordatenbank stecken”. Der grundlegende Flow sieht so aus:| Schritt | Was passiert |
|---|---|
| Laden | Lokale Markdown-, Text- oder reStructuredText-Dateien lesen |
| Chunken | Lange Dokumente in überlappende Abschnitte splitten |
| Embedden | Mit Venice-Embeddings Chunks in Vektoren umwandeln |
| Speichern | Vektoren und Quell-Metadaten in Qdrant ablegen |
| Abrufen | Frage des Nutzers embedden und Vektorsuche ausführen |
| Re-Ranken | Mit einem Cross-Encoder die besten Kandidaten neu bewerten |
| Antworten | Besten Kontext an ein Venice-Chat-Modell schicken, mit Zitations-Anweisungen |
Abhängigkeiten installieren
Wir verwenden das OpenAI-Python-SDK, weil Venice eine OpenAI-kompatible API bereitstellt. Dazu nehmen wir Qdrants Python-Client mit FastEmbed-Support:requirements.txt mit denselben Paketen an:
Modelle auswählen
Erstelle eine Dateirag_bot.py und beginne mit Imports, Datenstrukturen, API-URL und Modellnamen:
base_url und API-Schlüssel umziehen kann.
Verfügbare Venice-Modelle kannst du so auflisten:
Venice- und Qdrant-Clients erzeugen
Erstelle einen OpenAI-kompatiblen Venice-Client für Embeddings und Chat-Completions:| Modus | Wann zu verwenden |
|---|---|
QdrantClient(":memory:") | Schnelle lokale Demos und Tests |
QdrantClient(path="./qdrant_data") | Lokal persistierter Speicher |
QdrantClient(url=..., api_key=...) | Ein remoter oder managed Qdrant-Cluster |
Dokumente laden und chunken
Für dieses Tutorial soll der Bot lokale Dateien oder Ordner einlesen. Starten wir mit.md-, .rst- und .txt-Dateien:
1000 Zeichen mit 150 Zeichen Überlappung ist ein guter Default für gemischte Markdown- und Textdokumente. Kleinere Chunks können die Präzision erhöhen. Größere Chunks bewahren mehr Kontext. Die richtige Einstellung hängt oft von der Art deiner Dokumente ab.
Dokumente mit Venice embedden
Sobald wir Chunks haben, embedden wir sie in Batches:Vektoren in Qdrant speichern
Bevor du Punkte einfügst, erstelle eine Qdrant-Collection mit der richtigen Vektorgröße. Die Vektorgröße erfährst du am einfachsten, indem du den ersten Batch embeddest undlen(embeddings[0]) nutzt.
source, chunk_index und Inhalt. So wird wiederholtes Ingesting für unveränderte Chunks idempotent.
Kandidaten-Chunks abrufen
Zur Fragezeit embeddet der Bot die Nutzerfrage und fragt Qdrant nach den besten Vektortreffern:limit ist hier die Kandidatenzahl. Sie sollte normalerweise höher sein als die Anzahl der Chunks, die du ans Modell schickst, weil der nächste Schritt sie neu rankt. Ein guter Default ist, 8 Kandidaten abzurufen und die besten 4 ans Chat-Modell zu senden.
Re-Ranking mit FastEmbed
Jetzt fügen wir den Teil hinzu, der das Retrieval deutlich schlauer wirken lässt.- Mit Vektorsuche eine größere Kandidatenmenge abrufen.
- Nur diese Kandidaten lokal neu ranken.
- Die obersten Chunks an das Sprachmodell senden.
candidate_k=8 und top_k=4. Erhöhe candidate_k, wenn die richtige Quelle oft in der Nähe ist, aber nicht in den finalen Kontext kommt.
Antworten mit Venice-Chat-Completions
Sobald der Kontext gewählt ist, formatiere ihn mit Quellnummern:Den Bot ausführen
Wenn du die Teile zu einem Skript zusammenbaust, speichere es alsrag_bot.py. Ein einfacher erster Lauf kann ein paar eingebaute Beispieldokumente verwenden, damit du die Pipeline prüfen kannst, bevor du eigene Dateien einliest:
Nützliche CLI-Optionen
Mach die wichtigsten Retrieval-Stellschrauben als CLI-Optionen verfügbar, damit du den Bot ohne Code-Änderungen tunen kannst:| Option | Default | Was sie steuert |
|---|---|---|
--candidate-k | 8 | Anzahl der Vektorsuch-Ergebnisse, die neu gerankt werden |
--top-k | 4 | Anzahl der neu gerankten Chunks, die an das Chat-Modell gehen |
--chunk-size | 1000 | Maximale Chunk-Größe vor Überlappung |
--chunk-overlap | 150 | Zwischen benachbarten Chunks wiederholte Zeichen |
--embedding-batch-size | 32 | Anzahl der Chunks pro Venice-Embedding-Request |
--qdrant-path | nicht gesetzt | Lokaler persistenter Qdrant-Speicherpfad |
--qdrant-url | nicht gesetzt | Remote-Qdrant-URL |
--skip-ingest | false | Bestehende Collection abfragen, ohne Dokumente neu zu laden |
--recreate-collection | false | Qdrant-Collection löschen und neu aufbauen |
Privacy-Hinweise
Für ein privates RAG-Setup betrachte jede Schicht einzeln:| Schicht | Privacy-Überlegung |
|---|---|
| Venice-Embeddings | Dokument-Chunks gehen zur Vektorerzeugung an Venice |
| Venice-Chat | Der abgerufene Kontext geht zur Beantwortung an Venice |
| Qdrant lokal | Vektoren und Payloads bleiben auf deinem Rechner |
| Qdrant remote | Vektoren und Payloads werden dort gespeichert, wo dein Qdrant-Server läuft |
| FastEmbed-Re-Ranker | Re-Ranking läuft lokal, sobald das Modell verfügbar ist |
Häufige Fehler, auf die du vorbereitet sein solltest
| Symptom | Was es meist bedeutet | Was tun |
|---|---|---|
Set VENICE_API_KEY before running this example. | Die Umgebungsvariable fehlt | VENICE_API_KEY vor dem Start exportieren |
Document path does not exist | Ein Pfad an --docs ist falsch | Datei-/Ordnerpfad prüfen |
| Leere Retrieval-Ergebnisse | Nichts wurde ingestet oder falsche Collection wird abgefragt | --skip-ingest entfernen oder --collection und --qdrant-path prüfen |
| Qdrant-Vektorgrößenfehler | Die Collection wurde mit einem anderen Embedding-Modell erstellt | Collection nach Modellwechsel neu erstellen |
| Erster Re-Rank ist langsam | FastEmbed lädt oder initialisiert den Cross-Encoder evtl. | Ersten Lauf abwarten, danach ist es schneller |
Wie es weitergeht
Sobald die Basis läuft, sind die wirkungsvollsten Verbesserungen meist:- Dokumentspezifische Loader für PDFs, HTML, Tickets oder interne Wiki-Seiten ergänzen.
- Reichere Metadaten speichern: Titel, Überschriften, Daten, Owner, URLs.
candidate_k,top_k, Chunk-Größe und Überlappung an echten Fragen tunen.- Bewertungsfragen anlegen, um Retrieval-Qualität vor und nach Änderungen zu messen.
- Die finale Venice-Chat-Completion streamen für ein besseres interaktives Chat-Erlebnis.