This workflow corresponds to n8n.io template #4551 — we link there as the canonical source.
This workflow follows the Agent → Chainllm 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 →
{
"nodes": [
{
"id": "dcd42ca2-abff-41a7-b392-6e0de1b6999f",
"name": "Loop Over Items",
"type": "n8n-nodes-base.splitInBatches",
"position": [
1320,
2380
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "8eb7679b-eec3-40e4-afb0-2bd7f544ec9e",
"name": "Extract from PDF",
"type": "n8n-nodes-base.extractFromFile",
"position": [
2500,
2340
],
"parameters": {
"options": {},
"operation": "pdf"
},
"typeVersion": 1
},
{
"id": "cf0a457c-2555-4375-86b8-bbb676d1ee82",
"name": "Extract from CSV",
"type": "n8n-nodes-base.extractFromFile",
"position": [
2500,
2540
],
"parameters": {
"options": {}
},
"typeVersion": 1
},
{
"id": "21b6bae8-a26e-47e5-8b14-ba43bf8f9295",
"name": "Default Data Loader",
"type": "@n8n/n8n-nodes-langchain.documentDefaultDataLoader",
"position": [
4580,
2540
],
"parameters": {
"options": {
"metadata": {
"metadataValues": [
{
"name": "file_id",
"value": "={{ $('Set File ID').first().json.file_id}}"
},
{
"name": "title",
"value": "={{ $('Create Metadata Title & Description').item.json.output.title }}"
},
{
"name": "description",
"value": "={{ $('Create Metadata Title & Description').item.json.output.description }}"
}
]
}
},
"jsonData": "={{ $json.concatenated_text }}",
"jsonMode": "expressionData"
},
"typeVersion": 1
},
{
"id": "12ee63ca-5662-400f-a0a0-b9e12346091d",
"name": "Google Drive Trigger File Created",
"type": "n8n-nodes-base.googleDriveTrigger",
"position": [
1060,
2380
],
"parameters": {
"event": "fileCreated",
"options": {},
"pollTimes": {
"item": [
{
"mode": "everyMinute"
}
]
},
"triggerOn": "specificFolder",
"folderToWatch": {
"__rl": true,
"mode": "url",
"value": "https://drive.google.com/drive/u/0/folders/1B-Wl-ktVFbTmX685DB978jNvs9Ihnxiv"
}
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "915d117f-69aa-4f56-9051-cb3d3ba862c2",
"name": "Character Text Splitter",
"type": "@n8n/n8n-nodes-langchain.textSplitterCharacterTextSplitter",
"position": [
4680,
2720
],
"parameters": {
"separator": "###SPLIT###"
},
"typeVersion": 1
},
{
"id": "741ee49a-04d3-47e5-89cc-2a8f50a94ad8",
"name": "Set File ID",
"type": "n8n-nodes-base.set",
"position": [
1580,
2400
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "0144a9a7-6e73-46c4-979f-838ad5c62b89",
"name": "file_id",
"type": "string",
"value": "={{ $json.id }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "94f4b238-7365-4fd0-b7fd-1cdc9c5bbc00",
"name": "Download FIle",
"type": "n8n-nodes-base.googleDrive",
"position": [
1820,
2400
],
"parameters": {
"fileId": {
"__rl": true,
"mode": "id",
"value": "={{ $('Set File ID').item.json.file_id }}"
},
"options": {
"googleFileConversion": {
"conversion": {
"docsToFormat": "application/pdf"
}
}
},
"operation": "download"
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 3
},
{
"id": "c3ed78a0-7ff3-40f0-a4be-038d4908d0bc",
"name": "Switch",
"type": "n8n-nodes-base.switch",
"position": [
2100,
2400
],
"parameters": {
"rules": {
"values": [
{
"outputKey": "application/pdf",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "e959d5a8-d311-4a29-b400-7c07468a72fe",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $binary.data.mimeType }}",
"rightValue": "application/pdf"
}
]
},
"renameOutput": true
},
{
"outputKey": "text/csv",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "d5ae6f2d-e62d-4e08-aa06-629e6dfa7ee8",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $binary.data.mimeType }}",
"rightValue": "text/csv"
}
]
},
"renameOutput": true
}
]
},
"options": {}
},
"typeVersion": 3.2
},
{
"id": "c8c85b4c-b568-4e44-96dc-b6feabc463f5",
"name": "Structured Output Parser",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
3320,
2620
],
"parameters": {
"jsonSchemaExample": "{\n\t\"title\": \"Test Title (Replace it with real title\",\n \"description\":\"Test Description (Replace it with real description)\"\n}"
},
"typeVersion": 1.2
},
{
"id": "5d448edf-f219-4edb-90a3-a5b64bd2239a",
"name": "Google Gemini Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
4100,
2500
],
"parameters": {
"options": {},
"modelName": "models/gemini-1.5-flash"
},
"credentials": {
"googlePalmApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "5a399f9f-df56-4c0f-913a-8f02c15bf334",
"name": "Process Context",
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"position": [
3940,
2340
],
"parameters": {
"text": "=<document> \n{{ $('Document Data').first().json.data }}\n</document> \n\nHere is the chunk we want to situate within the overall document:\n\n<chunk> \n{{ $json.chunk }}\n</chunk> \n\nPlease:\n- Provide a short and succinct **context** to situate this chunk within the document for improved search retrieval.\n- Return the **original chunk** exactly as provided unless a correction is necessary.\n- If the chunk contains an **incomplete number, percentage, or entity**, correct it using the full document.\n- If part of a **sentence is cut off**, reconstruct the missing words only if necessary for clarity.\n- If the chunk is part of a table, include the complete table entry to maintain data integrity\n- Do not add any additional explanations or formatting beyond the required output.\n\nFill in the following format:\n[succinct context] : [original chunk or corrected version if necessary]\n\nYour response should contain only the text that replaces these placeholders, without including the placeholder labels themselves.",
"promptType": "define"
},
"typeVersion": 1.6
},
{
"id": "04138472-84dc-47d6-8909-7ff9404613b1",
"name": "Document Data",
"type": "n8n-nodes-base.set",
"position": [
2760,
2340
],
"parameters": {
"mode": "raw",
"options": {},
"jsonOutput": "={\n \"data\": {{ JSON.stringify($json.text) }}\n} "
},
"typeVersion": 3.4
},
{
"id": "aec980bc-6f3f-43b9-bd11-bd1fd07c9f5c",
"name": "Split Out",
"type": "n8n-nodes-base.splitOut",
"position": [
3560,
2340
],
"parameters": {
"options": {
"destinationFieldName": "chunk"
},
"fieldToSplitOut": "chunks"
},
"typeVersion": 1
},
{
"id": "ca2fb84a-db88-488c-a240-3a2e4ddd40af",
"name": "Limit",
"type": "n8n-nodes-base.limit",
"position": [
3740,
2340
],
"parameters": {
"maxItems": 20
},
"typeVersion": 1
},
{
"id": "fc015ac7-c474-40d0-91fd-9502d0bd4b25",
"name": "Summarize",
"type": "n8n-nodes-base.summarize",
"position": [
4260,
2340
],
"parameters": {
"options": {},
"fieldsToSummarize": {
"values": [
{
"field": "text",
"separateBy": "other",
"aggregation": "concatenate",
"customSeparator": "###SPLIT###"
}
]
}
},
"typeVersion": 1.1
},
{
"id": "0873b091-e714-41d6-b23e-1a3222061806",
"name": "Embeddings OpenAI",
"type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
"position": [
4460,
2540
],
"parameters": {
"options": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "5f4ccb20-f17b-41b6-9700-06cccfd10fee",
"name": "Add Data to Supabase Vector Store",
"type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
"position": [
4460,
2340
],
"parameters": {
"mode": "insert",
"options": {},
"tableName": {
"__rl": true,
"mode": "list",
"value": "documents",
"cachedResultName": "documents"
}
},
"credentials": {
"supabaseApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.1
},
{
"id": "1f99f8b9-3335-4c82-b04d-873637914605",
"name": "Google Gemini Chat Model1",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
3120,
2640
],
"parameters": {
"options": {},
"modelName": "models/gemini-1.5-flash"
},
"credentials": {
"googlePalmApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "ecb8a6de-2937-4658-b063-be11253350ed",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
980,
2200
],
"parameters": {
"color": 4,
"width": 1960,
"height": 560,
"content": "## \ud83d\udcc1 Data Processing from Google Drive\nAutomatically monitors your Google Drive folder and processes new files. When you upload a PDF, CSV, or Google Doc, this section downloads the file, extracts all the text content, and prepares it for AI analysis. Think of it as your automatic document reader that never sleeps."
},
"typeVersion": 1
},
{
"id": "52e22d2e-4633-484b-bd00-d6baa7659366",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
3000,
2200
],
"parameters": {
"color": 4,
"width": 1940,
"height": 700,
"content": "## \ud83e\udde0 RAG Data Upload Pipeline\nTakes your extracted document text and makes it AI-ready. It creates smart summaries, breaks documents into digestible chunks, adds context to each piece, and stores everything in a searchable database. This is where your documents become \"AI-searchable\" knowledge that can answer questions."
},
"typeVersion": 1
},
{
"id": "935fb434-2404-42f2-9a46-0830a1dfe01c",
"name": "Create Metadata Title & Description",
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"position": [
3060,
2340
],
"parameters": {
"text": "=Create metadata title and metadata description based on the document specified below (below ##Document). Metadata title and metadata description will be used to seperate data in vector DB that will be used for RAG.\n\n##Document\n{{ $('Document Data').item.json.data }}",
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 1.6
},
{
"id": "803601cb-5289-493a-8475-4fb99817c513",
"name": "Split into chunks",
"type": "n8n-nodes-base.code",
"position": [
3400,
2340
],
"parameters": {
"jsCode": "const chunkSize = 1000;\nconst chunkOverlap = 200;\n//const text = $node[\"ABC\"].json.data.replace(/\\n/, '');\nconst text = $items(\"Document Data\")[0].json.data.replace(/\\n/, '');\n\nconst chunks = [];\nlet remainingText = text;\n\nwhile (remainingText.length > 0) {\n let splitPoint;\n\n // Try splitting at paragraph level first\n splitPoint = remainingText.lastIndexOf(\"\\n\\n\", chunkSize);\n \n // If no paragraph split, try splitting at sentence level\n if (splitPoint === -1) {\n splitPoint = remainingText.lastIndexOf(\". \", chunkSize);\n }\n\n // If no sentence split, try splitting at word level\n if (splitPoint === -1) {\n splitPoint = remainingText.lastIndexOf(\" \", chunkSize);\n }\n\n // If still no split point, force cut at chunkSize\n if (splitPoint === -1 || splitPoint < chunkSize * 0.5) { \n splitPoint = chunkSize; // Hard split if no good split point\n }\n\n // Extract chunk and adjust remaining text with overlap\n let chunk = remainingText.substring(0, splitPoint).trim();\n chunks.push(chunk);\n\n // Move the pointer forward while keeping the overlap\n remainingText = remainingText.substring(Math.max(0, splitPoint - chunkOverlap)).trim();\n\n // Break if remaining text is too small to form another chunk\n if (remainingText.length < chunkSize * 0.2) {\n chunks.push(remainingText);\n break;\n }\n}\n\nreturn { chunks };"
},
"typeVersion": 2
},
{
"id": "3b6c1bab-b11f-499b-8fba-b2b12449aadc",
"name": "OpenAI Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
2680,
1720
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-4o-mini"
},
"options": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "4dcc7e04-d939-47de-9b37-41abc4c9c2c3",
"name": "Supabase Vector Store",
"type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
"position": [
2980,
1760
],
"parameters": {
"mode": "retrieve-as-tool",
"topK": 20,
"options": {},
"toolName": "documents",
"tableName": {
"__rl": true,
"mode": "list",
"value": "documents",
"cachedResultName": "documents"
},
"toolDescription": "Work with your data in Supabase Vector Store"
},
"credentials": {
"supabaseApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.1
},
{
"id": "21016db6-a271-4306-ac0d-941a2c459322",
"name": "AI Agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
2720,
1500
],
"parameters": {
"text": "=User Input:\n{{ $json.chatInput }}",
"options": {
"systemMessage": "=You're an internal company knowledge assistants. Your job is to answer questions using the files in the Vector Database. Here's how to do it:\n\nCheck Vector Database First\n- Search for similar test chunks using RAG.\n- If you find matches, use them to answer the question. \n- If you find relevant matches and need additional context to support the answer, prioritize retrieving it from documents that share the same metadata \"file_id\" & \"title\" before exploring other sources.\"\n\nNo Answer Found?\n- Clearly say: \"I couldn't find this in the databases\"\n- Never guess or invent answers.\n\nExample Response:\n\"Netflix grew revenue in Streaming services by 20% in 2024.\""
},
"promptType": "define"
},
"typeVersion": 1.8
},
{
"id": "0f5e7c7c-8adf-4688-92cd-f0195e972346",
"name": "Embeddings OpenAI1",
"type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
"position": [
3060,
1940
],
"parameters": {
"options": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "525f1628-a913-400e-895e-d009be257293",
"name": "When chat message received",
"type": "@n8n/n8n-nodes-langchain.chatTrigger",
"position": [
2480,
1500
],
"parameters": {
"options": {}
},
"typeVersion": 1.1
},
{
"id": "aea2befa-20ce-4f27-999b-95c682f70f50",
"name": "Simple Memory",
"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
"position": [
2840,
1760
],
"parameters": {
"contextWindowLength": 10
},
"typeVersion": 1.3
},
{
"id": "465f36f8-5d33-4580-867c-cd854f16a871",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
2300,
1380
],
"parameters": {
"color": 4,
"width": 1180,
"height": 760,
"content": "## AI Chat Agent - Chat with your documents stored in Supabase Vector Store\nour personal AI assistant that can answer questions about all your uploaded documents. Ask anything in plain English - it searches through your document database, finds relevant information, and gives you accurate answers with source references. It remembers your conversation and never makes up information."
},
"typeVersion": 1
},
{
"id": "f15e6542-dccf-457b-af0a-d2d6a9eab48f",
"name": "Sticky Note7",
"type": "n8n-nodes-base.stickyNote",
"position": [
1120,
1380
],
"parameters": {
"color": 5,
"width": 460,
"height": 320,
"content": "## \ud83d\udcc4 AI-Powered RAG Document Processing & Chatbot with Google Drive, Supabase, OpenAI\n\n**What This Workflow Does:**\n- Watches a Google Drive folder for new documents\n- Extracts text from PDF/CSV files\n- Enhances the text using AI (Google Gemini)\n- Chunks and embeds the text using OpenAI\n- Stores vector data in Supabase for semantic search\n- Enables users to chat with documents using OpenAI"
},
"typeVersion": 1
},
{
"id": "dfd4d156-8f0b-4a27-ac69-3578d1602722",
"name": "Sticky Note8",
"type": "n8n-nodes-base.stickyNote",
"position": [
300,
2200
],
"parameters": {
"color": 5,
"width": 660,
"height": 1500,
"content": "## \ud83d\udccb Data Processing & RAG Workflow\n\n### \ud83d\udcc1 Step 1: Google Drive Trigger \nWatches a specific Google Drive folder for new file uploads. Triggers every minute.\n\n### \ud83d\udd01 Step 2: Loop Over Uploaded Files \nEnsures each uploaded file is processed one-by-one to avoid bulk processing issues.\n\n### \ud83c\udd94 Step 3: Set File ID \nExtracts and stores the Google Drive file ID for reference in later steps.\n\n### \ud83d\udce5 Step 4: Download File \nDownloads the file (PDF, CSV, or Google Docs). Google Docs are auto-converted to PDF.\n\n### \ud83e\udded Step 5: File Type Switch \nRoutes file based on type:\n- PDF \u2192 Go to PDF Text Extractor\n- CSV \u2192 Go to CSV Extractor\n\n### \ud83d\udcc4 Step 6A: Extract Text from PDF \nExtracts raw text content from the PDF file.\n\n### \ud83d\udcca Step 6B: Extract Text from CSV \nExtracts and formats CSV data into a readable string.\n\n### \ud83d\udce6 Step 7: Format Document Data \nWraps extracted text into JSON: `{\"data\": \"text content\"}`.\n\n### \ud83e\udde0 Step 8: Generate Metadata (Gemini) \nUses Gemini AI to create a document title and description.\n\n### \u2702\ufe0f Step 9: Split into Chunks \nSplits the document text into 1000-character chunks with 200-character overlap, intelligently at paragraph/sentence/word level.\n\n### \ud83d\udd04 Step 10: Split Out Chunks \nConverts array of chunks into individual workflow items.\n\n### \ud83d\udeab Step 11: Limit to 20 Chunks \nLimits processing to first 20 chunks to control API and processing load.\n\n### \ud83e\udde0 Step 12: Enhance Chunk Context (Gemini) \nEach chunk is enhanced for better clarity, continuity, and context using Gemini.\n\n### \ud83e\udde9 Step 13: Summarize \nCombines enhanced chunks using `###SPLIT###` separator for further processing.\n\n### \ud83e\uddf7 Step 14: Re-Split Enhanced Chunks \nSplits combined text back into chunks using `###SPLIT###` separator.\n\n### \ud83e\uddec Step 15: Generate Embeddings (OpenAI) \nConverts text chunks into vector embeddings for semantic search.\n\n### \ud83d\uddc2\ufe0f Step 16: Add Metadata \nEach chunk is wrapped with metadata (file ID, title, description) for vector DB.\n\n### \ud83e\udde0 Step 17: Store in Supabase Vector DB \nStores embeddings in Supabase vector store for later semantic retrieval.\n\n"
},
"typeVersion": 1
},
{
"id": "122852a9-eb55-4af6-a959-f0a95a9b61c3",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
2300,
820
],
"parameters": {
"color": 5,
"width": 1160,
"height": 520,
"content": "\n## SETUP REQUIRED \n**Author:** [Billy Christi](https://n8n.io/creators/billy/)\n\n---\n\n### \ud83d\udcda Database: Supabase Table `documents`\n\nTo manage and store embeddings and metadata, we use a Supabase table with the following schema:\n\n```sql\nCREATE TABLE public.documents (\n id bigserial PRIMARY KEY, -- Unique identifier\n content text, -- Textual content of the document\n metadata jsonb, -- Additional metadata (e.g., title, source)\n embedding vector -- Vector embeddings (for similarity search, etc.)\n);\n````\n### \ud83d\udd10 Required Credentials & Keys\n\u2705 **Google Drive Credential** \n\u2705 **Supabase API Key & Project URL** \n\u2705 **OpenAI API Key**\n\u2705 **Google Gemini API Key**\n\n\n"
},
"typeVersion": 1
},
{
"id": "851bb367-bcc4-4444-9b01-21dd9666265f",
"name": "Sticky Note9",
"type": "n8n-nodes-base.stickyNote",
"position": [
1600,
1380
],
"parameters": {
"color": 5,
"width": 660,
"height": 760,
"content": "\n## \ud83e\udd16 CHAT INTERFACE WORKFLOW\n\n### \ud83d\udcac Step 1: Chat Trigger \nListens for user chat input (e.g., question about a document).\n\n### \ud83e\udde0 Step 2: Simple Memory \nStores last 10 messages to maintain conversation context.\n\n### \ud83d\udd0d Step 3: Vector Search (Supabase) \nSearches Supabase vector DB for relevant chunks related to the user's question.\n\n### \ud83e\uddec Step 4: Convert Question to Embedding \nUses OpenAI to embed the question text for similarity search.\n\n### \ud83d\udde8\ufe0f Step 5: Generate Response (OpenAI GPT-4o-mini) \nUses context + question to generate a natural language answer.\n\n### \ud83e\udde0 Step 6: AI Agent \nFinal agent logic:\n- Searches vector DB first\n- Answers based on found chunks\n- Attributes response to correct document\n- Admits if answer not found (no hallucination)"
},
"typeVersion": 1
},
{
"id": "7429d34b-af0f-476c-893f-285cfe8e28ba",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
3640,
2480
],
"parameters": {
"color": 5,
"width": 340,
"height": 300,
"content": "\ud83d\udccc **Understanding the Limit Node**\nThe **Limit Node** restricts the number of records or items processed in your workflow. This is especially useful for:\n\u2705 **Testing** your setup with a smaller dataset\n\u2705 **Controlling resource usage** during processing\n\n\ud83d\udca1 **You can**:\n* **Adjust the limit value** to suit your workflow's needs\n* **Remove the Limit Node** altogether to process all available data"
},
"typeVersion": 1
},
{
"id": "c4ad1f43-43ff-4f19-8e68-915c5ffeeb37",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
3520,
1380
],
"parameters": {
"color": 4,
"width": 380,
"height": 760,
"content": "# \ud83d\udc4b Hi, I\u2019m Billy\n\nI help businesses build **n8n workflows** & **AI automation projects**. \nNeed help with n8n or AI Automation projects? \nContact me and let\u2019s build your automation together.\n\n\ud83d\udce9 **Email:** billychartanto@gmail.com \n\ud83e\udd1d **n8n Creator:** [n8n.io/creators/billy](https://n8n.io/creators/billy/)\n\ud83c\udf10 **My n8n Projects:** [billychristi.com/n8n](https://www.billychristi.com/n8n) \n\n\n\n---\n\ud83d\udca1 Feel free to get in touch if you\u2019d like help on your next automation project or if you have any feedback or thoughts to share.\n"
},
"typeVersion": 1
}
],
"connections": {
"Limit": {
"main": [
[
{
"node": "Process Context",
"type": "main",
"index": 0
}
]
]
},
"Switch": {
"main": [
[
{
"node": "Extract from PDF",
"type": "main",
"index": 0
}
],
[
{
"node": "Extract from CSV",
"type": "main",
"index": 0
}
]
]
},
"Split Out": {
"main": [
[
{
"node": "Limit",
"type": "main",
"index": 0
}
]
]
},
"Summarize": {
"main": [
[
{
"node": "Add Data to Supabase Vector Store",
"type": "main",
"index": 0
}
]
]
},
"Set File ID": {
"main": [
[
{
"node": "Download FIle",
"type": "main",
"index": 0
}
]
]
},
"Document Data": {
"main": [
[
{
"node": "Create Metadata Title & Description",
"type": "main",
"index": 0
}
]
]
},
"Download FIle": {
"main": [
[
{
"node": "Switch",
"type": "main",
"index": 0
}
]
]
},
"Simple Memory": {
"ai_memory": [
[
{
"node": "AI Agent",
"type": "ai_memory",
"index": 0
}
]
]
},
"Loop Over Items": {
"main": [
[],
[
{
"node": "Set File ID",
"type": "main",
"index": 0
}
]
]
},
"Process Context": {
"main": [
[
{
"node": "Summarize",
"type": "main",
"index": 0
}
]
]
},
"Extract from CSV": {
"main": [
[
{
"node": "Document Data",
"type": "main",
"index": 0
}
]
]
},
"Extract from PDF": {
"main": [
[
{
"node": "Document Data",
"type": "main",
"index": 0
}
]
]
},
"Embeddings OpenAI": {
"ai_embedding": [
[
{
"node": "Add Data to Supabase Vector Store",
"type": "ai_embedding",
"index": 0
}
]
]
},
"OpenAI Chat Model": {
"ai_languageModel": [
[
{
"node": "AI Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Split into chunks": {
"main": [
[
{
"node": "Split Out",
"type": "main",
"index": 0
}
]
]
},
"Embeddings OpenAI1": {
"ai_embedding": [
[
{
"node": "Supabase Vector Store",
"type": "ai_embedding",
"index": 0
}
]
]
},
"Default Data Loader": {
"ai_document": [
[
{
"node": "Add Data to Supabase Vector Store",
"type": "ai_document",
"index": 0
}
]
]
},
"Supabase Vector Store": {
"ai_tool": [
[
{
"node": "AI Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Character Text Splitter": {
"ai_textSplitter": [
[
{
"node": "Default Data Loader",
"type": "ai_textSplitter",
"index": 0
}
]
]
},
"Google Gemini Chat Model": {
"ai_languageModel": [
[
{
"node": "Process Context",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Structured Output Parser": {
"ai_outputParser": [
[
{
"node": "Create Metadata Title & Description",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"Google Gemini Chat Model1": {
"ai_languageModel": [
[
{
"node": "Create Metadata Title & Description",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"When chat message received": {
"main": [
[
{
"node": "AI Agent",
"type": "main",
"index": 0
}
]
]
},
"Google Drive Trigger File Created": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"Create Metadata Title & Description": {
"main": [
[
{
"node": "Split into chunks",
"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.
googleDriveOAuth2ApigooglePalmApiopenAiApisupabaseApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow is perfect for: Businesses and teams who need an automated solution to organize, analyze, and retrieve insights from their internal documents. Researchers who want to quickly analyze and query large collections of research papers, reports, or datasets. Customer…
Source: https://n8n.io/workflows/4551/ — 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.
A lightweight, self-hosted AI assistant built entirely in n8n. Multi-channel messaging (Telegram, WhatsApp, Gmail), persistent memory, task management, and autonomous work — all in a single visual wor
Your AI workforce is ready. Are you?
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
This advanced n8n workflow automates the full lead enrichment, qualification, and personalized outreach process tailored specifically for the B2B real estate sector. Integrating top platforms like Api
This n8n template automatically classifies incoming emails (Sales, Support, Internal, Finance, Promotions) and routes them to a dedicated OpenAI LLM Agent for processing. Depending on the category, th