This workflow corresponds to n8n.io template #15707 — we link there as the canonical source.
This workflow follows the Chainretrievalqa → Retrievervectorstore recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"id": "gXsUbMsPtMifVXPg",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "AI Knowledge Base Assistant Using Ollama + PGVector + Telegram",
"tags": [],
"nodes": [
{
"id": "0c226fa3-5bec-4d3d-9240-ca4154bb5b2e",
"name": "On form submission",
"type": "n8n-nodes-base.formTrigger",
"position": [
-2208,
-576
],
"parameters": {
"options": {},
"formTitle": "Input File",
"formFields": {
"values": [
{
"fieldType": "radio",
"fieldLabel": "select",
"fieldOptions": {
"values": [
{
"option": "File"
},
{
"option": "Text"
}
]
}
}
]
}
},
"typeVersion": 2.5
},
{
"id": "84b12219-198e-4d22-8c64-8b2318930449",
"name": "Postgres PGVector Store",
"type": "@n8n/n8n-nodes-langchain.vectorStorePGVector",
"position": [
-624,
-624
],
"parameters": {
"mode": "insert",
"options": {},
"tableName": "n8n_vectors_new"
},
"credentials": {
"postgres": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "f0ac891d-138f-49a7-9af1-2cd698c6aa9a",
"name": "Embeddings Ollama",
"type": "@n8n/n8n-nodes-langchain.embeddingsOllama",
"position": [
-624,
-176
],
"parameters": {
"model": "llama3.2:3b-text-q4_0"
},
"credentials": {
"ollamaApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "be89bfa8-bf6e-4f13-b007-a87c4ac03c18",
"name": "Default Data Loader",
"type": "@n8n/n8n-nodes-langchain.documentDefaultDataLoader",
"position": [
-576,
-416
],
"parameters": {
"options": {},
"jsonData": "={{ $json.text }}",
"jsonMode": "expressionData"
},
"typeVersion": 1.1
},
{
"id": "ce1f67bd-104f-449a-978a-1b99d444e608",
"name": "Question and Answer Chain",
"type": "@n8n/n8n-nodes-langchain.chainRetrievalQa",
"position": [
608,
-944
],
"parameters": {
"options": {}
},
"typeVersion": 1.7
},
{
"id": "b7558232-cbf5-4b54-b87d-bbbb9d3adc51",
"name": "Ollama Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOllama",
"position": [
608,
-720
],
"parameters": {
"model": "llama3:latest",
"options": {}
},
"credentials": {
"ollamaApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "95d7576c-2658-464c-9cfe-e7c4fabee024",
"name": "Vector Store Retriever",
"type": "@n8n/n8n-nodes-langchain.retrieverVectorStore",
"position": [
576,
-560
],
"parameters": {},
"typeVersion": 1
},
{
"id": "d88f60a3-2eea-4d08-82eb-b289b4fa6488",
"name": "Postgres PGVector Store1",
"type": "@n8n/n8n-nodes-langchain.vectorStorePGVector",
"position": [
496,
-384
],
"parameters": {
"options": {},
"tableName": "n8n_vectors_new"
},
"credentials": {
"postgres": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "75e8e00b-d1a3-45e8-a981-ffb342e0fb5b",
"name": "Embeddings Ollama1",
"type": "@n8n/n8n-nodes-langchain.embeddingsOllama",
"position": [
496,
-240
],
"parameters": {
"model": "llama3.2:3b-text-q4_0"
},
"credentials": {
"ollamaApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "a3894f8b-9fc7-4510-b812-6026c7235a98",
"name": "Extract from File",
"type": "n8n-nodes-base.extractFromFile",
"position": [
-1168,
-1056
],
"parameters": {
"options": {},
"operation": "pdf",
"binaryPropertyName": "=data"
},
"typeVersion": 1.1
},
{
"id": "f68d442c-d868-4dc9-9a37-184b7f5687d4",
"name": "If",
"type": "n8n-nodes-base.if",
"position": [
-2016,
-576
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "b010c0dc-629f-46fd-bb97-0fd5fe37e230",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.select }}",
"rightValue": "File"
}
]
}
},
"typeVersion": 2.3
},
{
"id": "1b7cf9e6-9a42-4cc6-adf5-5759df7db411",
"name": "Form",
"type": "n8n-nodes-base.form",
"position": [
-1152,
-32
],
"parameters": {
"options": {},
"formFields": {
"values": [
{
"fieldType": "textarea",
"fieldLabel": "Description"
}
]
}
},
"typeVersion": 2.5
},
{
"id": "2ec2f880-2807-4fa4-bad0-5b4e8bcd621c",
"name": "Form1",
"type": "n8n-nodes-base.form",
"position": [
-1712,
-592
],
"parameters": {
"options": {},
"formFields": {
"values": [
{
"fieldType": "file",
"fieldLabel": "FIleUpload"
}
]
}
},
"typeVersion": 2.5
},
{
"id": "bc1d6ba1-b1f5-4685-8dc3-1a02e75fc435",
"name": "Switch",
"type": "n8n-nodes-base.switch",
"position": [
-1472,
-640
],
"parameters": {
"rules": {
"values": [
{
"outputKey": "PDF",
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "ffd7ee28-b60e-423c-997f-d3b50ad49e1f",
"operator": {
"type": "string",
"operation": "contains"
},
"leftValue": "={{ $json.FIleUpload[0].filename }}",
"rightValue": ".pdf"
}
]
},
"renameOutput": true
},
{
"outputKey": "XLS",
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "550eb778-8c29-4f17-8c1d-3e246a8f056b",
"operator": {
"type": "string",
"operation": "contains"
},
"leftValue": "{{ $json.FIleUpload[0].filename }}",
"rightValue": ".xls"
}
]
},
"renameOutput": true
},
{
"outputKey": "XLSX",
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "7cb7cde9-0660-485f-9378-1499020480db",
"operator": {
"type": "string",
"operation": "contains"
},
"leftValue": "={{ $json.FIleUpload[0].filename }}",
"rightValue": ".xlsx"
}
]
},
"renameOutput": true
},
{
"outputKey": "CSV",
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "7d4ce134-aab6-45d7-b759-642cbdd1ebfb",
"operator": {
"type": "string",
"operation": "contains"
},
"leftValue": "={{ $json.FIleUpload[0].filename }}",
"rightValue": ".csv"
}
]
},
"renameOutput": true
},
{
"outputKey": "JSON",
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "54470b7b-cdbb-436f-b557-dc0b97cbbeb1",
"operator": {
"type": "string",
"operation": "contains"
},
"leftValue": "={{ $json.FIleUpload[0].filename }}",
"rightValue": ".json"
}
]
},
"renameOutput": true
}
]
},
"options": {}
},
"typeVersion": 3.4
},
{
"id": "175f7826-d0e5-49a5-a571-8c4ae1d83939",
"name": "Extract from File1",
"type": "n8n-nodes-base.extractFromFile",
"position": [
-1168,
-864
],
"parameters": {
"options": {},
"operation": "xls"
},
"typeVersion": 1.1
},
{
"id": "f8e0e8d8-e190-411d-8b83-b0ee5149fd06",
"name": "Extract from File2",
"type": "n8n-nodes-base.extractFromFile",
"position": [
-1152,
-656
],
"parameters": {
"options": {},
"operation": "xlsx"
},
"typeVersion": 1.1
},
{
"id": "fdd02068-5a8c-4581-ad04-7a05d8c0abf8",
"name": "Extract from File4",
"type": "n8n-nodes-base.extractFromFile",
"position": [
-1152,
-256
],
"parameters": {
"options": {},
"operation": "fromJson"
},
"typeVersion": 1.1
},
{
"id": "b1ae11bd-c539-4bbf-9f0b-235335e86138",
"name": "Extract from File5",
"type": "n8n-nodes-base.extractFromFile",
"position": [
-1152,
-448
],
"parameters": {
"options": {}
},
"typeVersion": 1.1
},
{
"id": "3bbe4d90-d7bf-4a3a-b57f-084dac515577",
"name": "No Operation, do nothing",
"type": "n8n-nodes-base.noOp",
"position": [
-304,
-624
],
"parameters": {},
"typeVersion": 1
},
{
"id": "d9c84f69-1da3-42b1-926c-b6d5c83bd10d",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2288,
-1184
],
"parameters": {
"width": 2288,
"height": 1376,
"content": "# Feed AI Knowledge Base"
},
"typeVersion": 1
},
{
"id": "946b26bf-7654-4d35-aef4-8e62bf4d9f41",
"name": "Telegram Trigger",
"type": "n8n-nodes-base.telegramTrigger",
"position": [
304,
-944
],
"parameters": {
"updates": [
"message"
],
"additionalFields": {}
},
"typeVersion": 1.2
},
{
"id": "0824d102-32b9-4ee6-a291-d1e7a7e23f90",
"name": "Send a text message",
"type": "n8n-nodes-base.telegram",
"position": [
960,
-944
],
"parameters": {
"additionalFields": {}
},
"typeVersion": 1.2
},
{
"id": "ba4d54ff-b744-4885-8f59-3fe5a272b62d",
"name": "No Operation, do nothing1",
"type": "n8n-nodes-base.noOp",
"position": [
1168,
-944
],
"parameters": {},
"typeVersion": 1
},
{
"id": "a806e5ef-439b-4aea-8955-c8207640559b",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
0,
-1184
],
"parameters": {
"color": 4,
"width": 1920,
"height": 1376,
"content": "# RAG Query Engine"
},
"typeVersion": 1
},
{
"id": "80e2ec73-8f5c-4030-91fb-9f3c4c2abdfb",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2288,
-1344
],
"parameters": {
"color": 3,
"width": 4208,
"content": "# AI-Powered Knowledge Base Assistant with Local RAG\n## Supports multi-format document ingestion and semantic question answering."
},
"typeVersion": 1
},
{
"id": "4c9091c6-08df-4f62-a459-39698db8af40",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2272,
-688
],
"parameters": {
"color": 5,
"width": 230,
"height": 320,
"content": "## User selects input type (File or Text)"
},
"typeVersion": 1
},
{
"id": "4a94ac51-4fd1-400e-830d-cf9e7fd9388e",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1600,
-784
],
"parameters": {
"color": 5,
"width": 262,
"height": 416,
"content": "Detects uploaded file type dynamically and routes processing to the correct extraction node.\nSupported formats:\n- PDF\n- XLS\n- XLSX\n- CSV\n- JSON"
},
"typeVersion": 1
},
{
"id": "787e4bdf-5d4d-4649-8d0d-b1204eaf18bb",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1216,
-1168
],
"parameters": {
"color": 5,
"width": 230,
"height": 1072,
"content": "## Data Extract"
},
"typeVersion": 1
},
{
"id": "6bc9eced-fae6-4801-8d95-ccdfc46d04b1",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
-672,
-32
],
"parameters": {
"color": 5,
"width": 230,
"height": 176,
"content": "## Ollama generates embeddings locally"
},
"typeVersion": 1
},
{
"id": "5ad5e4c1-60a2-49f3-a132-bc47fd8d5cb4",
"name": "Sticky Note7",
"type": "n8n-nodes-base.stickyNote",
"position": [
-624,
-832
],
"parameters": {
"color": 5,
"width": 230,
"height": 176,
"content": "## Embeddings are stored in PostgreSQL PGVector"
},
"typeVersion": 1
},
{
"id": "d98e1939-916f-422d-aab7-4ab7842761f7",
"name": "Sticky Note8",
"type": "n8n-nodes-base.stickyNote",
"position": [
-400,
-32
],
"parameters": {
"color": "#D11A1A",
"width": 230,
"height": 176,
"content": "## # AI Components:\n### Embedding Model:\n### llama3.2:3b-text-q4_0"
},
"typeVersion": 1
},
{
"id": "763da3dc-13c5-4a23-b645-ecc69cd41d27",
"name": "Sticky Note9",
"type": "n8n-nodes-base.stickyNote",
"position": [
32,
-960
],
"parameters": {
"color": 5,
"width": 230,
"height": 176,
"content": "## Telegram messages trigger Retrieval QA"
},
"typeVersion": 1
},
{
"id": "5cb34eed-9bb8-4598-8fd8-6177a82b2262",
"name": "Sticky Note10",
"type": "n8n-nodes-base.stickyNote",
"position": [
768,
-464
],
"parameters": {
"color": 5,
"width": 230,
"height": 176,
"content": "## Relevant context is retrieved from vector DB"
},
"typeVersion": 1
},
{
"id": "84399306-078e-407e-be31-6891aa6e6c8b",
"name": "Sticky Note11",
"type": "n8n-nodes-base.stickyNote",
"position": [
704,
-128
],
"parameters": {
"color": "#D11A1A",
"width": 230,
"height": 176,
"content": "## # AI Components:\n### Embedding Model:\n### llama3.2:3b-text-q4_0"
},
"typeVersion": 1
},
{
"id": "3116aa96-04d9-4422-8bd1-91221ff9e17f",
"name": "Sticky Note12",
"type": "n8n-nodes-base.stickyNote",
"position": [
448,
-128
],
"parameters": {
"color": 5,
"width": 230,
"height": 176,
"content": "## Ollama generates embeddings locally"
},
"typeVersion": 1
},
{
"id": "29139227-e586-4bbd-b94a-8dc4468da76a",
"name": "Sticky Note13",
"type": "n8n-nodes-base.stickyNote",
"position": [
368,
-784
],
"parameters": {
"color": 5,
"width": 230,
"height": 176,
"content": "## Ollama LLM generates contextual responses"
},
"typeVersion": 1
},
{
"id": "0d5f7206-a098-4da0-a141-4637b81a8ae7",
"name": "Sticky Note14",
"type": "n8n-nodes-base.stickyNote",
"position": [
928,
-1136
],
"parameters": {
"color": 5,
"width": 230,
"height": 176,
"content": "## Answers are returned to Telegram users"
},
"typeVersion": 1
},
{
"id": "fbdc906b-94b7-4819-a072-db216654aa20",
"name": "Sticky Note15",
"type": "n8n-nodes-base.stickyNote",
"position": [
-3056,
-1344
],
"parameters": {
"color": 7,
"width": 768,
"height": 1536,
"content": "# AI Knowledge Base Assistant | n8n + Ollama + PGVector + Telegram\n\n## Overview\nThis workflow implements a complete Retrieval-Augmented Generation (RAG) system using n8n, Ollama, PostgreSQL PGVector, and Telegram. It enables users to upload documents or text content, convert them into semantic vector embeddings, and interact with the knowledge base conversationally through Telegram.\n\nThe workflow supports multi-format document ingestion including PDF, XLS, XLSX, CSV, JSON, and direct text input.\n\n---\n\n# Workflow Use Case\n\nOrganizations often store important information across multiple files such as SOPs, training manuals, policies, reports, spreadsheets, and documentation. Searching these files manually is time-consuming and inefficient.\n\nThis workflow solves that problem by creating a private AI-powered knowledge assistant that can:\n\n- Ingest business documents\n- Generate semantic embeddings locally\n- Store vectors in PostgreSQL PGVector\n- Retrieve relevant context intelligently\n- Answer user questions through Telegram\n\nThe assistant understands document meaning using semantic search instead of traditional keyword matching.\n\n---\n\n# Workflow Architecture\n\n## 1. Knowledge Base Ingestion Pipeline\n\nThis section handles document uploads and text ingestion.\n\n### On form submission\n```text\nTrigger node that starts the ingestion workflow.\nUsers choose whether they want to upload a file or submit raw text."
},
"typeVersion": 1
},
{
"id": "6a9afcf4-d147-464f-91e3-a3d2003d92e2",
"name": "Sticky Note16",
"type": "n8n-nodes-base.stickyNote",
"position": [
592,
-1152
],
"parameters": {
"height": 208,
"content": "Core Retrieval QA engine.\n\nProcess:\n1. Receive user question\n2. Retrieve relevant document chunks\n3. Inject context into LLM prompt\n4. Generate grounded response"
},
"typeVersion": 1
},
{
"id": "659891f3-648b-4634-93c2-7d9ca36922db",
"name": "Sticky Note17",
"type": "n8n-nodes-base.stickyNote",
"position": [
1536,
-192
],
"parameters": {
"width": 384,
"height": 368,
"content": "# Key Features\n\n- Multi-format document ingestion\n- Semantic search using vector embeddings\n- Local-first AI architecture\n- Private self-hosted deployment\n- Telegram-based conversational assistant\n- PostgreSQL vector storage\n- Retrieval-Augmented Generation (RAG)\n- Low-code AI automation using n8n\n- Enterprise knowledge assistant architecture\n- Open-source AI stack"
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"binaryMode": "separate",
"executionOrder": "v1"
},
"versionId": "c7786bd4-f248-4eb2-98e4-f1b12b21f6bf",
"connections": {
"If": {
"main": [
[
{
"node": "Form1",
"type": "main",
"index": 0
}
],
[
{
"node": "Form",
"type": "main",
"index": 0
}
]
]
},
"Form": {
"main": [
[
{
"node": "Postgres PGVector Store",
"type": "main",
"index": 0
}
]
]
},
"Form1": {
"main": [
[
{
"node": "Switch",
"type": "main",
"index": 0
}
]
]
},
"Switch": {
"main": [
[
{
"node": "Extract from File",
"type": "main",
"index": 0
}
],
[
{
"node": "Extract from File1",
"type": "main",
"index": 0
}
],
[
{
"node": "Extract from File2",
"type": "main",
"index": 0
}
],
[
{
"node": "Extract from File5",
"type": "main",
"index": 0
}
],
[
{
"node": "Extract from File4",
"type": "main",
"index": 0
}
]
]
},
"Telegram Trigger": {
"main": [
[
{
"node": "Question and Answer Chain",
"type": "main",
"index": 0
}
]
]
},
"Embeddings Ollama": {
"ai_embedding": [
[
{
"node": "Postgres PGVector Store",
"type": "ai_embedding",
"index": 0
}
]
]
},
"Extract from File": {
"main": [
[
{
"node": "Postgres PGVector Store",
"type": "main",
"index": 0
}
]
]
},
"Ollama Chat Model": {
"ai_languageModel": [
[
{
"node": "Question and Answer Chain",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Embeddings Ollama1": {
"ai_embedding": [
[
{
"node": "Postgres PGVector Store1",
"type": "ai_embedding",
"index": 0
}
]
]
},
"Extract from File1": {
"main": [
[
{
"node": "Postgres PGVector Store",
"type": "main",
"index": 0
}
]
]
},
"Extract from File2": {
"main": [
[
{
"node": "Postgres PGVector Store",
"type": "main",
"index": 0
}
]
]
},
"Extract from File4": {
"main": [
[
{
"node": "Postgres PGVector Store",
"type": "main",
"index": 0
}
]
]
},
"Extract from File5": {
"main": [
[
{
"node": "Postgres PGVector Store",
"type": "main",
"index": 0
}
]
]
},
"On form submission": {
"main": [
[
{
"node": "If",
"type": "main",
"index": 0
}
]
]
},
"Default Data Loader": {
"ai_document": [
[
{
"node": "Postgres PGVector Store",
"type": "ai_document",
"index": 0
}
]
]
},
"Send a text message": {
"main": [
[
{
"node": "No Operation, do nothing1",
"type": "main",
"index": 0
}
]
]
},
"Vector Store Retriever": {
"ai_retriever": [
[
{
"node": "Question and Answer Chain",
"type": "ai_retriever",
"index": 0
}
]
]
},
"Postgres PGVector Store": {
"main": [
[
{
"node": "No Operation, do nothing",
"type": "main",
"index": 0
}
]
]
},
"Postgres PGVector Store1": {
"ai_vectorStore": [
[
{
"node": "Vector Store Retriever",
"type": "ai_vectorStore",
"index": 0
}
]
]
},
"Question and Answer Chain": {
"main": [
[
{
"node": "Send a text message",
"type": "main",
"index": 0
}
]
]
}
}
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
ollamaApipostgres
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow automatically converts uploaded documents and text into an AI-powered searchable knowledge base using semantic vector embeddings and Retrieval-Augmented Generation (RAG). Users can upload PDFs, JSON, CSV, XLS, XLSX, or raw text files, which are automatically…
Source: https://n8n.io/workflows/15707/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
This comprehensive workflow bundle is designed as a powerful starter kit, enabling you to build a multi-functional AI assistant on Telegram. It seamlessly integrates AI-powered voice interactions, an
Indexation. Uses formTrigger, embeddingsOllama, textSplitterRecursiveCharacterTextSplitter, modelSelector. Event-driven trigger; 36 nodes.
It uses Retrieval-Augmented Generation (RAG) to allow users to upload documents, which are then indexed into a vector database, enabling the bot to answer questions based only on the provided content.
Indexation. Uses formTrigger, embeddingsOllama, textSplitterRecursiveCharacterTextSplitter, modelSelector. Event-driven trigger; 25 nodes.
Telegram RAG pdf. Uses telegramTrigger, embeddingsOpenAi, documentDefaultDataLoader, textSplitterRecursiveCharacterTextSplitter. Event-driven trigger; 20 nodes.