Module 09 · ai · advanced
Solutions 09 · RAG Q&A over Your Docs
Exercise 1
On Add to Knowledge Base, set Clear Store to the expression {{ $('Ingest API').item.json.body.replace === true }}.
jq -n --rawfile t assets/sample-handbook.md '{text: $t, source: "handbook", replace: true}' \
| curl -X POST http://localhost:5678/webhook/kb/ingest -H 'Content-Type: application/json' -d @-
Clearing wipes everything under that key. For multi-document knowledge bases, use a persistent store with a delete-by-metadata step (filter source) instead.
Exercise 2
Qdrant (self-hosted): add to playground/docker-compose.yml:
qdrant:
image: qdrant/qdrant
volumes:
- qdrant_data:/qdrant/storage
(and qdrant_data: under volumes:). Create a Qdrant credential in n8n with URL http://qdrant:6333. Replace both Simple Vector Store nodes with Qdrant Vector Store (collection course09_kb): insert mode for ingest, Retrieve Documents (As Tool) for search_docs. The embedding sub-nodes stay the same.
Supabase: create a project, run the pgvector setup SQL from n8n's Supabase Vector Store docs (a documents table + match_documents function), add the Supabase credential, and swap the nodes the same way.
Exercise 3
- Change
Has Text?to also accept a PDF:{{ String($json.body?.text ?? '').trim().length >= 20 || Object.values($binary ?? {}).some(f => f.mimeType === 'application/pdf') }}(Boolean is true). - Set the Default Data Loader's type with an expression, or simpler: add a second insert branch for PDFs with a loader of type Binary, loader PDF Loader, input field taken from the upload (
file). - Set metadata
source={{ Object.values($binary ?? {})[0]?.fileName ?? $json.body?.source ?? 'unnamed' }}.
curl -X POST http://localhost:5678/webhook/kb/ingest -F "file=@policy.pdf;type=application/pdf"