- Design a local RAG flow without sending documents to external APIs.
- Separate ingestion, retrieval, generation, and response delivery.
- Avoid unsupported answers and cross-user data leaks.
Flow map
Input: Telegram / form / internal chat -> n8n validates user and question -> n8n creates embedding or calls an embeddings service -> Qdrant returns allowed chunks -> Ollama generates response with citations -> n8n saves trace and sends draft -> human approves if the action has real impact
Lab Docker Compose
This compose file is a local starting point. In production, add HTTPS, backups, user management, secrets outside the repository, and network boundaries.
services:
qdrant:
image: qdrant/qdrant:latest
ports:
- "6333:6333"
volumes:
- qdrant_data:/qdrant/storage
n8n:
image: n8nio/n8n:latest
ports:
- "5678:5678"
environment:
- N8N_ENCRYPTION_KEY=change-me
- GENERIC_TIMEZONE=Europe/Madrid
volumes:
- n8n_data:/home/node/.n8n
volumes:
qdrant_data:
n8n_data:Minimum nodes in n8n
- Chat, Telegram, or webhook trigger.
- User, tenant, and permission validation.
- Question normalization.
- Qdrant search with tenant filter.
- Call to Ollama with context and an "I don't know" rule.
- Response with citations and saved trace.
Response rule: - Answer only with the retrieved context. - Cite document and section when possible. - If the context is insufficient, say "I don't have enough evidence". - Do not execute external actions without human approval.
Official sources
- n8n Docs
- Qdrant documentation
- Ollama API
- Open WebUI documentation
- Docker Compose documentation