n8n RAG Agent Tutorial
Retrieval-Augmented Generation (RAG) lets your AI agent answer questions from your own documents instead of just its training data. n8n's AI Agent node combined with Vector Store nodes makes building RAG agents visual and code-free. This tutorial walks you through building a complete RAG agent in n8n.
What You'll Build
A RAG agent that: 1. Ingests documents (PDFs, web pages, Notion, etc.) 2. Chunks and embeds them into a vector store 3. Retrieves relevant chunks for user questions 4. Generates answers grounded in your documents 5. Cites sources so users can verify
Prerequisites
- n8n instance (Cloud or self-hosted v1.0+)
- OpenAI API key (or Anthropic, Ollama, etc.)
- Vector store (Pinecone, Qdrant, Chroma, PGVector, Weaviate, etc.)
- Documents to ingest (PDFs, URLs, Notion, etc.)
Architecture Overview
User Question
↓
Embed Query → Vector Store Search
↓
Top-K Chunks → AI Agent (with context)
↓
Generated Answer + Citations
Step 1: Set Up Vector Store
Option A: Pinecone (Managed, Easy)
1. Create Pinecone account
2. Create index: dimension: 1536 (for OpenAI embeddings), metric: cosine
2. Copy API Key and Environment
Option B: Qdrant (Self-Hosted or Cloud)
1. Deploy Qdrant (Docker, Railway, or Qdrant Cloud)
2. Create collection: vector_size: 1536, distance: Cosine
3. Copy URL and API Key
Option C: PostgreSQL + pgvector (Self-Hosted)
1. Enable pgvector extension: CREATE EXTENSION vector;
2. Create table:
``sql
CREATE TABLE documents (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
content TEXT,
metadata JSONB,
embedding VECTOR(1536)
);
CREATE INDEX ON documents USING ivfflat (embedding vector_cosine_ops);
``
Add Vector Store Credential in n8n
1. n8n → Credentials → New Credential 2. Search your vector store (Pinecone, Qdrant, PostgreSQL, etc.) 3. Enter credentials 4. Test → Save
Step 2: Document Ingestion Workflow
Create a workflow to ingest documents into the vector store.
Workflow Structure
Trigger (Webhook / Schedule / Manual)
↓
Get Documents (HTTP Request / Google Drive / Notion / Local File)
↓
Extract Text (Extract from PDF / HTML / Markdown)
↓
Split Text (Recursive Character Text Splitter)
↓
Generate Embeddings (OpenAI Embeddings)
↓
Store in Vector Store (Pinecone / Qdrant / PGVector)
Detailed Nodes
#### 1. Trigger - Webhook for on-demand ingestion - Schedule for periodic re-indexing (daily/weekly) - Manual for one-off runs
#### 2. Get Documents
| Source | Node |
|---|---|
| **PDFs from URL** | HTTP Request → Extract from File |
| **Google Drive** | Google Drive (search files) → Download |
| **Notion** | Notion (query database) |
| **Web pages** | HTTP Request → Extract from HTML |
| **Local files** | Read Binary File (self-hosted) |
#### 3. Extract Text
- Extract from File node → Handles PDF, DOCX, TXT, CSV
- Extract from HTML node → Cleans web content
- Markdown → Use as-is or convert
#### 4. Split Text (Critical for RAG Quality)
Add Text Splitter node (or use Code node):
const splitter = new RecursiveCharacterTextSplitter({ chunkSize: 1000, chunkOverlap: 200, separators: ['\n\n', '\n', ' ', ''] });
const chunks = await splitter.splitText($json.content); return chunks.map((chunk, i) => ({ content: chunk, metadata: { ...$json.metadata, chunkIndex: i } }));; ```
Recommended settings:
- chunkSize: 1000 (tokens)
- chunkOverlap: 200 (tokens)
- Separators: ['\n\n', '\n', ' ', '']
#### 5. Generate Embeddings
Add Embeddings node:
- Provider: OpenAI (or Anthropic, Cohere, Ollama)
- Model: text-embedding-3-small (1536 dim, cheap) or text-embedding-3-large (3072 dim)
- Input: Connect to chunked text output
#### 6. Store in Vector Store
Add your Vector Store node:
- Operation: Upsert (insert or update)
- Documents: Connect embeddings output
- Metadata: Include source, chunkIndex, sourceUrl, ingestedAt
Step 3: RAG Query Workflow
Create a separate workflow for answering questions.
Workflow Structure
User Question (Webhook / Chat Trigger)
↓
Embed Query (OpenAI Embeddings)
↓
Vector Store Search (Top-K Retrieval)
↓
Format Context (Combine chunks + citations)
↓
AI Agent (Answer with context)
↓
Format Response (Answer + Citations)
↓
Respond (Webhook Response / Chat)
Detailed Nodes
#### 1. Trigger - Webhook for API access - Chat Trigger for chat widget - Slack/Discord for bot integration
#### 2. Embed Query
- Embeddings node (same model as ingestion)
- Input: User question from trigger
#### 3. Vector Store Search
- Vector Store node → Search operation
- Top K: 4-6 (balance relevance vs context window)
- Filter: Optional (e.g., by
source,date,category) - Score Threshold: 0.7-0.8 (filter irrelevant chunks)
#### 4. Format Context
Add Code node to format retrieved chunks:
chunks.forEach((chunk, i) => {
const citationNum = i + 1;
context += [${citationNum}] ${chunk.metadata.source || 'Source'}: ${chunk.content}\n\n;
citations.push({
num: citationNum,
source: chunk.metadata.sourceUrl || chunk.metadata.source,
snippet: chunk.content.substring(0, 200) + '...'
});
});
return { context, citations }; ```
#### 5. AI Agent Node
Add AI Agent node: - System Prompt: ``` You are a helpful assistant that answers questions using ONLY the provided context.
Rules:
1. Answer ONLY from the provided context
2. If context doesn't contain the answer, say "I don't have enough information to answer that."
3. Cite sources using [1], [2], etc. format
4. Be concise but complete
``
- User Prompt: Question: {{ $json.question }}\n\nContext:\n{{ $json.context }}`
- Model: GPT-4o-mini (cheap) or GPT-4o (better reasoning)
- Temperature: 0.1 (factual)
#### 6. Format Response
Add Code node:
``javascript
return {
answer: $json.output,
citations: $json.citations,
confidence: $json.confidence || 'high'
};
``
Step 4: Chat Interface (Optional)
n8n Chat Trigger
1. Add Chat Trigger node 2. Connect to RAG query workflow 3. Configure: welcome message, placeholder, theme 3. Embed in website via iframe or n8n Chat Cloud
Custom Frontend
// Simple fetch to n8n webhook
const response = await fetch('https://your-n8n.com/webhook/ask', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ question: userInput })
});
const { answer, citations } = await response.json();
Step 5: Test & Optimize
Test Ingestion 1. Run ingestion workflow with test documents 2. Check vector store: verify chunks stored with metadata 3. Verify chunk count and sizes
Test Query 1. Ask questions with known answers 2. Verify citations are correct 3. Check for hallucinations (answers not in context) 4. Adjust `Top K`, `Score Threshold`, `Chunk Size`
Common Tuning Parameters
| Parameter | Default | Tune If |
|---|---|---|
| `chunkSize` | 1000 | Answers too long/short |
| `chunkOverlap` | 200 | Context lost between chunks |
| `topK` | 4 | Missing context / too much noise |
| `scoreThreshold` | 0.7 | Irrelevant chunks retrieved |
| `temperature` | 0.1 | Hallucinations / too rigid |
Advanced: Hybrid Search
Combine keyword + vector search for better recall:
1. Vector Search (semantic) 2. Keyword Search (BM25/PostgreSQL full-text) 3. Reciprocal Rank Fusion to combine
In n8n: Run both searches in parallel → Code node → RRF merge → Feed to agent.
Advanced: Metadata Filtering
Filter by metadata for multi-tenant or categorized search:
// In Vector Store Search node
Filter: {
tenantId: '{{ $json.user.tenantId }}',
category: '{{ $json.category }}',
date: { $gte: '2024-01-01' }
}
Advanced: Conversational Memory
Add memory to your RAG agent for multi-turn conversations:
1. AI Agent Node → Memory section 2. Select: Window Buffer (last N turns) or Vector Store (semantic) 3. Configure session ID from trigger (user ID, session ID)
Cost Estimation
| Component | Monthly Cost (10K queries) |
|---|---|
| n8n Cloud Pro | $50 |
| OpenAI Embeddings (3-small) | ~$3 |
| OpenAI GPT-4o-mini | ~$15 |
| Pinecone (Starter) | $70 |
| **Total** | **~$138/mo** |
Self-hosted n8n: ~$30-50/mo (infrastructure only)
Common Issues
| Issue | Fix |
|---|---|
| `401 Unauthorized` on vector store | Check API key, environment, URL |
| `400 Dimension mismatch` | Embedding model dim ≠ index dim (1536 vs 3072) |
| Empty results | Lower score threshold, check ingestion |
| Hallucinations | Lower temperature, stricter system prompt |
| Slow queries | Reduce topK, use smaller embeddings |
| Citations wrong | Check context formatting, metadata |
Related Tutorials
- n8n AI Agent Node Tutorial - AI Agent basics
- n8n AI Agent Memory Setup - Memory types
- No Code RAG Agent Builder - Platform comparison
- n8n Google Sheets Automation - Data ingestion patterns