Chatbot mit n8n und lokalen LLMs
RAG-Chatbot mit n8n und lokalen LLMs: Ein Praxisbericht
Das Ziel: Ein intelligenter Support-Assistent
Wer kennt es nicht? Die Dokumentation ist umfangreich, aber Benutzer finden trotzdem nicht die Antworten, die sie suchen. Die Lösung: Ein KI-gestützter Chatbot, der die eigene Wissensdatenbank durchsucht und präzise Antworten liefert.
In diesem Artikel zeige ich, wie wir einen RAG-Chatbot (Retrieval-Augmented Generation) mit n8n, Qdrant und einem lokalen LLM aufgebaut haben - komplett selbst gehostet, ohne Cloud-Abhängigkeiten.
Was ist RAG?
RAG steht für "Retrieval-Augmented Generation" und kombiniert zwei Ansätze:
- Retrieval: Relevante Dokumente aus einer Wissensdatenbank finden
- Generation: Ein LLM nutzt diese Dokumente als Kontext für die Antwort
Der Vorteil: Das LLM "halluziniert" weniger, weil es konkrete Informationen aus der eigenen Dokumentation erhält.
Ablauf einer RAG-Anfrage
Benutzer-Frage: "Wie funktioniert das Docker Auto-Update?"
|
v
+---------------------------------------------+
| 1. RETRIEVAL |
| Suche in Vektordatenbank |
| -> Findet: Blog-Post über Docker Updates|
+---------------------------------------------+
|
v
+---------------------------------------------+
| 2. GENERATION |
| LLM + gefundene Dokumente |
| -> Generiert präzise Antwort |
+---------------------------------------------+
|
v
Antwort: "Das automatische Docker Update-System
überprüft täglich alle Container..."
Die Architektur
Unser System besteht aus zwei n8n Workflows:
Workflow 1: Data Ingestion
Dieser Workflow läuft täglich um 02:00 Uhr und indexiert neue Blog-Posts:
Directus CMS --> Text-Bereinigung --> Embedding --> Qdrant
(Blog) (HTML/Emojis) (768 Dim) (Vektoren)
Workflow 2: Chatbot
Dieser Workflow beantwortet Benutzeranfragen in Echtzeit:
Chat-Anfrage --> Embedding --> Vektor-Suche --> LLM --> Antwort
|
Qdrant findet
relevante Dokumente
Die Komponenten
Qdrant: Die Vektordatenbank
Qdrant speichert unsere Dokumente als hochdimensionale Vektoren. Wenn ein Benutzer eine Frage stellt, wird diese ebenfalls in einen Vektor umgewandelt und die ähnlichsten Dokumente werden gefunden.
Warum Qdrant?
- Open Source und selbst hostbar
- Schnelle Similarity-Suche
- Einfache REST-API
- Unterstützt Filtering und Payloads
LiteLLM: Das LLM-Gateway
LiteLLM fungiert als einheitliche API vor unserem lokalen Ollama-Server. So können wir verschiedene Modelle mit der gleichen OpenAI-kompatiblen API ansprechen.
Unsere Modelle:
nomic-embed-text: Für Embeddings (768 Dimensionen)llama3.1:8b: Für Chat-Generierung
n8n: Die Workflow-Engine
n8n orchestriert den gesamten Prozess. Der große Vorteil: Alles ist visuell konfigurierbar und leicht zu debuggen.
Die Herausforderungen
Challenge 1: Saubere Vektoren
Blog-Posts aus einem CMS enthalten oft HTML-Tags, Emojis und spezielle Zeichen. Diese müssen vor dem Embedding bereinigt werden.
Das Problem:
<p>Docker Update erfolgreich!</p>
Die Lösung: Eine gründliche Text-Bereinigung, die HTML-Tags entfernt, HTML-Entities dekodiert und Emojis samt ihrer unsichtbaren Variation Selectors entfernt.
Variation Selectors sind unsichtbare Unicode-Zeichen (U+FE00-U+FE0F), die nach dem Entfernen von Emojis zurückbleiben können.
Challenge 2: LLM gibt JSON aus
Bei der Integration mit dem n8n AI Agent Node stellten wir fest, dass das LLM plötzlich JSON im Tool-Call-Format ausgab statt normalen Text.
Die Ursache: Der AI Agent Node sendet automatisch Tool-Definitionen an das LLM, selbst wenn keine Tools verbunden sind. Das LLM "lernt" aus der Chat-History dieses Verhalten.
Die Lösung: Direkte HTTP-Requests an die Chat-Completion API, ohne den AI Agent Node. So haben wir volle Kontrolle über das Request-Format.
Challenge 3: Chat-History Kontamination
Die PostgreSQL Chat-Memory speicherte alte Antworten im JSON-Format. Das LLM reproduzierte dieses Format, weil es aus der History "lernte".
Die Lösung: Bereinigen der Chat-History oder kompletter Verzicht auf persistente Memory für den Chatbot.
Best Practices
1. Score-Threshold für Relevanz
Nicht jedes gefundene Dokument ist relevant. Wir filtern nach Similarity-Score und verwenden nur Dokumente mit einem Score über 0.3.
2. Kontext-Limitierung
Zu viel Kontext überfordert das LLM. Wir begrenzen auf maximal 5 Dokumente mit je 600 Zeichen.
3. Klare System-Prompts
Das System-Prompt muss explizit sein und klar vorgeben, in welchem Format die Antwort erfolgen soll.
4. Rate Limiting
Schützt vor Missbrauch: 25 Anfragen pro Stunde pro Session/IP, plus Audit-Log für Analyse.
Die Ergebnisse
| Metrik | Wert |
|---|---|
| Durchschnittliche Antwortzeit | ~3 Sekunden |
| RAG-Trefferquote | 85% der Anfragen |
| Relevanz der Antworten | Deutlich verbessert |
| Halluzinationen | Stark reduziert |
Der Chatbot beantwortet jetzt Fragen zu unseren Services präzise und verweist auf die entsprechenden Blog-Posts.
Lessons Learned
- n8n AI Agent Node mit Vorsicht verwenden: Bei lokalen LLMs kann der Tool-Calling-Mechanismus Probleme verursachen. Direkte HTTP-Requests sind oft zuverlässiger.
- Text-Bereinigung ist kritisch: Unsichtbare Unicode-Zeichen wie Variation Selectors können die Embedding-Qualität beeinträchtigen.
- Chat-History kann kontaminieren: Wenn das LLM einmal falsches Verhalten gelernt hat, reproduziert es dieses.
- Lokale LLMs sind production-ready: Mit llama3.1:8b und 12GB VRAM läuft ein vollwertiger Chatbot auf eigener Hardware.
Fazit
Ein RAG-Chatbot mit n8n, Qdrant und lokalen LLMs ist absolut machbar - auch ohne Cloud-Services. Die größten Herausforderungen liegen nicht in der grundlegenden Architektur, sondern in den Details: Text-Bereinigung, LLM-Verhalten und System-Integration.
Der Schlüssel zum Erfolg: Iteratives Vorgehen, gutes Logging und die Bereitschaft, Architektur-Entscheidungen zu hinterfragen, wenn etwas nicht funktioniert.
Technologie-Stack
- Workflow Automation: n8n (Self-Hosted)
- Vektordatenbank: Qdrant
- LLM Gateway: LiteLLM
- LLM: Ollama mit llama3.1:8b
- Embedding Model: nomic-embed-text
- CMS: Directus
- Datenbank: PostgreSQL
Haben Sie Fragen zu diesem Setup? Kontaktieren Sie uns über unser Kontaktformular.