RAG-Workflows in n8n
Was dieser Artikel über RAG-Workflows in n8n behandelt
- Wie Du RAG-Pipelines komplett in n8n baust.
- Wie Dokumente indexiert, in Chunks geteilt und embeddet werden.
- Wie Du Qdrant, Weaviate oder Pinecone anbindest.
- Wie Retrieval, Reranking und Antwortgenerierung funktionieren.
- Praxisbeispiele für Wissensdatenbanken und Dokumenten-Q&A.
Einleitung: RAG-Workflows in n8n verständlich erklärt
RAG (Retrieval-Augmented Generation) bedeutet: Statt das Modell aus dem Gedächtnis antworten zu lassen, suchst Du zuerst relevante Dokumente und gibst sie als Kontext mit. In n8n baust Du diese Pipeline visuell: Dokument kommt rein, wird ge-chunked, embeddet, in einer Vektordatenbank gespeichert. Bei einer Frage suchst Du ähnliche Chunks und gibst sie dem Modell als Kontext.
Dieser Artikel richtet sich an Anwender, die RAG in n8n umsetzen wollen. Grundlagen findest Du in Lokales RAG und n8n-Ollama-Integration.
Warum brauche ich RAG-Workflows in n8n?
Stell Dir vor, Du hast 500 interne Dokumente. Ein Mitarbeiter fragt: „Wie funktioniert der Urlaubsantrag?” Ohne RAG halluziniert das Modell. Mit RAG sucht der Workflow das Urlaubs-Dokument, gibt es als Kontext und das Modell antwortet korrekt, mit Quellenangabe.
RAG-Workflows in n8n kurz erklärt
RAG in n8n besteht aus zwei Pipelines: Die Indexing-Pipeline (Dokument → Chunks → Embeddings → Vektordatenbank) und die Query-Pipeline (Frage → Embedding → ähnliche Chunks → Kontext → Antwort). Beide laufen als n8n-Workflows.
Der Kerngedanke lautet: Erst suchen, dann antworten.
Für wen ist dieser Artikel gedacht?
- n8n-Nutzer, die RAG-Pipelines bauen.
- Wissensmanager, die Dokumente durchsuchbar machen.
- Entwicklerinnen und Entwickler, die Q&A-Systeme bauen.
- Self-Hoster, die RAG lokal mit Ollama betreiben.
Vorkenntnisse in n8n und RAG sind erforderlich.
Wichtige Begriffe
- RAG - Retrieval-Augmented Generation. Wann nützlich: das Kernkonzept.
- Embeddings - Vektor-Repräsentationen. Wann nützlich: für semantische Suche.
- Chunking - Text in Stücke teilen. Wann nützlich: für bessere Retrieval-Qualität.
- Vektordatenbanken - Speicher für Embeddings. Wann nützlich: Qdrant, Weaviate, Pinecone.
- Ollama - Lokaler Modellserver. Wann nützlich: für Embeddings und Generierung.
- Reranking - Ergebnisse neu sortieren. Wann nützlich: für bessere Relevanz. Siehe Reranking.
- Hybrid Search - Semantik + Keywords. Wann nützlich: für bessere Treffer.
Architektur
INDEXING-PIPELINE:
Dokument (PDF/DOCX)
│
▼
Text-Extraktion ──► Chunking ──► Embeddings (Ollama)
│ │
│ ▼
└────────────────────────► Vektordatenbank (Qdrant)
│
QUERY-PIPELINE: │
Frage │
│ │
▼ │
Embedding (Ollama) │
│ │
▼ │
Vektorsuche ─────────────────────────┘
│
▼
Top-K Chunks ──► (Reranking) ──► Kontext + Frage ──► LLM (Ollama)
│
▼
Antwort
Setup: Qdrant + Ollama + n8n
version: "3.8"
services:
qdrant:
image: qdrant/qdrant:latest
container_name: qdrant
restart: unless-stopped
ports:
- "6333:6333"
volumes:
- qdrant_data:/qdrant/storage
networks:
- ai-network
ollama:
image: ollama/ollama:latest
container_name: ollama
restart: unless-stopped
ports:
- "11434:11434"
volumes:
- ollama_data:/root/.ollama
networks:
- ai-network
n8n:
image: n8nio/n8n:latest
container_name: n8n
restart: unless-stopped
ports:
- "5678:5678"
volumes:
- n8n_data:/home/node/.n8n
networks:
- ai-network
volumes:
qdrant_data:
ollama_data:
n8n_data:
networks:
ai-network:
driver: bridge
Indexing-Pipeline in n8n
Schritt 1: Dokument einlesen
// Read Binary File Node oder HTTP Request für Upload
// Danach: Text extrahieren
// Function Node: Text aus PDF
const pdfParse = require('pdf-parse');
const buffer = $input.item.binary.data;
const data = await pdfParse(Buffer.from(buffer, 'base64'));
return { text: data.text, filename: $input.item.json.filename };
Schritt 2: Chunking
// Function Node: Text in Chunks teilen
function chunkText(text, chunkSize = 500, overlap = 50) {
const chunks = [];
const sentences = text.split(/[.!?]\s+/);
let current = "";
for (const sentence of sentences) {
if ((current + sentence).length > chunkSize) {
chunks.push(current.trim());
current = sentence;
} else {
current += " " + sentence;
}
}
if (current) chunks.push(current.trim());
return chunks;
}
const chunks = chunkText($input.item.json.text);
return chunks.map((chunk, i) => ({
json: { text: chunk, index: i, source: $input.item.json.filename }
}));
Siehe Chunking für Strategien.
Schritt 3: Embeddings erstellen
// HTTP Request Node: Ollama Embeddings
{
"method": "POST",
"url": "http://ollama:11434/api/embeddings",
"body": {
"model": "nomic-embed-text",
"prompt": "{{$json.text}}"
}
}
Siehe Embedding-Modelle für Modellwahl.
Schritt 4: In Qdrant speichern
// HTTP Request Node: Qdrant Insert
{
"method": "PUT",
"url": "http://qdrant:6333/collections/dokumente/points",
"body": {
"points": [{
"id": "{{$json.index}}",
"vector": "{{$json.embedding}}",
"payload": {
"text": "{{$json.text}}",
"source": "{{$json.source}}"
}
}]
}
}
Query-Pipeline in n8n
Schritt 1: Frage embedden
// HTTP Request: Query-Embedding
{
"method": "POST",
"url": "http://ollama:11434/api/embeddings",
"body": {
"model": "nomic-embed-text",
"prompt": "{{$json.question}}"
}
}
Schritt 2: Ähnliche Chunks suchen
// HTTP Request: Qdrant Search
{
"method": "POST",
"url": "http://qdrant:6333/collections/dokumente/points/search",
"body": {
"vector": "{{$json.embedding}}",
"limit": 5,
"with_payload": true
}
}
Schritt 3: Kontext + Antwort generieren
// Function Node: Kontext aufbauen
const results = $input.item.json.result;
const context = results.map(r => r.payload.text).join("\n\n");
const sources = results.map(r => r.payload.source);
return {
context,
sources,
question: $('Webhook').item.json.question
};
// HTTP Request: Antwort generieren
{
"method": "POST",
"url": "http://ollama:11434/api/chat",
"body": {
"model": "llama3.1",
"messages": [
{"role": "system", "content": "Beantworte die Frage basierend auf dem Kontext. Gib Quellen an. Wenn der Kontext die Frage nicht beantwortet, sage das ehrlich."},
{"role": "user", "content": "Kontext:\n{{$json.context}}\n\nFrage: {{$json.question}}"}
],
"stream": false
}
}
Praxisbeispiel 1: Wissensdatenbank für FAQ
Workflow: FAQ-Bot mit RAG
Indexing (einmalig / bei Update):
1. Watch Folder: Neue Dokumente
2. Text extrahieren
3. Chunking
4. Embeddings (Ollama nomic-embed-text)
5. In Qdrant speichern
Query (bei jeder Frage):
1. Webhook: Frage kommt rein
2. Query-Embedding
3. Qdrant: Top-5 Chunks
4. Kontext + Frage → Ollama llama3.1
5. Antwort + Quellen zurückgeben
Praxisbeispiel 2: E-Mail-Anhänge indexieren
Workflow: E-Mail-Anhänge durchsuchbar machen
1. IMAP Trigger: Neue E-Mail mit Anhang
2. Binary File extrahieren
3. Wenn PDF: Text extrahieren
4. Chunking + Embeddings
5. In Qdrant speichern mit Metadaten (Absender, Datum)
Praxisbeispiel 3: Hybrid-Suche
// Function Node: Semantische + Keyword-Suche kombinieren
const semanticResults = $input.item.json.semantic;
const keywordResults = $input.item.json.keyword;
// Reciprocal Rank Fusion
function rrf(semantic, keyword, k = 60) {
const scores = {};
semantic.forEach((r, i) => {
scores[r.id] = (scores[r.id] || 0) + 1 / (k + i + 1);
});
keyword.forEach((r, i) => {
scores[r.id] = (scores[r.id] || 0) + 1 / (k + i + 1);
});
return Object.entries(scores).sort((a, b) => b[1] - a[1]);
}
return { ranked: rrf(semanticResults, keywordResults) };
Siehe Hybrid Search.
Qualität verbessern
Reranking
// Nach der Vektorsuche: Top-20 holen, dann reranken
{
"method": "POST",
"url": "http://ollama:11434/api/chat",
"body": {
"model": "llama3.1",
"messages": [
{"role": "user", "content": "Bewerte die Relevanz dieses Textes für die Frage [FRAGE] auf einer Skala 0-10:\n\n{{$json.chunk_text}}"}
]
}
}
Siehe Reranking.
Quellenangaben
// Immer Quellen mitliefern
return {
answer: response.message.content,
sources: results.map(r => ({
file: r.payload.source,
chunk: r.payload.text.substring(0, 100) + "..."
}))
};
Siehe Quellenangaben.
Sicherheitshinweise
- Zugriffskontrolle: Wer darf welche Dokumente abfragen? Filtere nach Berechtigungen.
- Prompt Injection: Dokumente können Injections enthalten. Siehe Prompt Injection.
- Datenqualität: Schlechte Dokumente = schlechte Antworten. Siehe Dokumente vorbereiten.
- Datenschutz: Alle Daten bleiben lokal bei Ollama + Qdrant. Siehe Datenschutz.
Typische Stolpersteine
- Chunks zu groß: Über 1000 Zeichen verlieren Präzision. 300-800 ist oft optimal.
- Zu wenige Chunks: Top-5 reicht nicht immer. Hole Top-20, reranke auf Top-5.
- Falsches Embedding-Modell: nomic-embed-text ist gut, aber multilingual-e5 für mehrsprachige Dokumente besser.
- Keine Quellenangaben: Ohne Quellen ist die Antwort nicht überprüfbar.
- Halluzinationen: Ohne gutes Retrieval halluziniert das Modell. Siehe Qualität testen.
- Kontext zu lang: Zu viele Chunks überlasten den Kontext. Siehe Kontextlänge.
Weiterführende Links
- Lokales RAG - RAG-Grundlagen.
- Chunking - Text-Aufteilung.
- Embedding-Modelle - Modellwahl.
- Vektordatenbanken - Qdrant, Weaviate & Co.
- Reranking - Ergebnisse verbessern.
- Hybrid Search - Semantik + Keywords.
- n8n-Ollama-Integration - Ollama in n8n.
- KI-Agenten in n8n - Agenten mit RAG.
Key Takeaways:
- RAG in n8n: Indexing-Pipeline + Query-Pipeline.
- Ollama für Embeddings (nomic-embed-text) und Generierung (llama3.1).
- Qdrant als Vektordatenbank, n8n orchestriert alles.
- Chunking-Strategie und Reranking entscheiden über Qualität.
- Immer Quellenangaben, nie blind vertrauen.
FAQ
Was ist RAG?
Welche Vektordatenbank?
Welches Embedding-Modell?
Wie groß sollten Chunks sein?
Wie viele Chunks soll ich holen?
Wie verhindere ich Halluzinationen?
Was ist Hybrid Search?
Was kostet RAG in n8n lokal?
Welche Dokumente kann ich indexieren?
Wie halte ich die Datenbank aktuell?
Quellen und weiterführende Literatur
- Qdrant - Vektordatenbank.
- Ollama Embeddings - Embedding-Modelle.
- n8n Vector Stores - Vector-Store-Nodes.
- RAG Guide - RAG-Techniken.


