AutomationFlowsAI & RAG › Ultimate Agentic RAG AI Agent Template

Ultimate Agentic RAG AI Agent Template

Ultimate Agentic RAG AI Agent Template. Uses lmChatOpenAi, documentDefaultDataLoader, embeddingsOpenAi, stickyNote. Event-driven trigger; 42 nodes.

Event trigger★★★★★ complexityAI-powered42 nodesLm Chat Open AiDocument Default Data LoaderEmbeddings Open AiGoogle DriveGoogle Drive TriggerMemory Postgres ChatSupabaseChat Trigger
AI & RAG Trigger: Event Nodes: 42 Complexity: ★★★★★ AI nodes: yes

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 →

Download .json
{
  "name": "Ultimate Agentic RAG AI Agent Template",
  "nodes": [
    {
      "parameters": {
        "options": {}
      },
      "id": "384c2969-3b50-45a0-a79a-15a3d271820a",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "typeVersion": 1,
      "position": [
        -280,
        820
      ],
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsonMode": "expressionData",
        "jsonData": "={{ $json.data || $json.text || $json.concatenated_data }}",
        "options": {
          "metadata": {
            "metadataValues": [
              {
                "name": "=file_id",
                "value": "={{ $('Set File ID').first().json.file_id }}"
              },
              {
                "name": "file_title",
                "value": "={{ $('Set File ID').first().json.file_title }}"
              }
            ]
          }
        }
      },
      "id": "d5a8d046-72db-47a2-98bf-bafd7016c86d",
      "name": "Default Data Loader",
      "type": "@n8n/n8n-nodes-langchain.documentDefaultDataLoader",
      "typeVersion": 1,
      "position": [
        1460,
        1600
      ]
    },
    {
      "parameters": {
        "model": "text-embedding-3-small",
        "options": {}
      },
      "id": "b04ec97b-60e2-48c5-ae3a-55cfe6e658ab",
      "name": "Embeddings OpenAI1",
      "type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
      "typeVersion": 1,
      "position": [
        1220,
        1600
      ],
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "content": "## Agent Tools for RAG",
        "height": 528.85546469693,
        "width": 583.4552380860637,
        "color": 4
      },
      "id": "9893e05f-3719-4d40-aef6-c7ae9cedd92d",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        460,
        460
      ]
    },
    {
      "parameters": {
        "content": "## Tool to Add a Google Drive File to Vector DB",
        "height": 867,
        "width": 3073,
        "color": 5
      },
      "id": "9238ce80-bea8-425d-92c4-a2022b058ef3",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -1280,
        1000
      ]
    },
    {
      "parameters": {
        "operation": "download",
        "fileId": {
          "__rl": true,
          "value": "={{ $('Set File ID').item.json.file_id }}",
          "mode": "id"
        },
        "options": {
          "googleFileConversion": {
            "conversion": {
              "docsToFormat": "text/plain"
            }
          }
        }
      },
      "id": "b056897b-f729-484c-9fee-cff34b7b15de",
      "name": "Download File",
      "type": "n8n-nodes-base.googleDrive",
      "typeVersion": 3,
      "position": [
        -200,
        1280
      ],
      "executeOnce": true,
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        },
        "triggerOn": "specificFolder",
        "folderToWatch": {
          "__rl": true,
          "value": "1HtaIIK3kWwjbwhsmEbtJ-upalxVn3Ek9",
          "mode": "list",
          "cachedResultName": "n8n Documents",
          "cachedResultUrl": "https://drive.google.com/drive/folders/1HtaIIK3kWwjbwhsmEbtJ-upalxVn3Ek9"
        },
        "event": "fileCreated",
        "options": {}
      },
      "id": "4423e455-e36d-4679-b33b-c8a86c957291",
      "name": "File Created",
      "type": "n8n-nodes-base.googleDriveTrigger",
      "typeVersion": 1,
      "position": [
        -1220,
        1120
      ],
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        },
        "triggerOn": "specificFolder",
        "folderToWatch": {
          "__rl": true,
          "value": "1HtaIIK3kWwjbwhsmEbtJ-upalxVn3Ek9",
          "mode": "list",
          "cachedResultName": "n8n Documents",
          "cachedResultUrl": "https://drive.google.com/drive/folders/1HtaIIK3kWwjbwhsmEbtJ-upalxVn3Ek9"
        },
        "event": "fileUpdated",
        "options": {}
      },
      "id": "99f6a604-582a-4225-96f5-c08e13658759",
      "name": "File Updated",
      "type": "n8n-nodes-base.googleDriveTrigger",
      "typeVersion": 1,
      "position": [
        -1220,
        1280
      ],
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "text",
        "options": {}
      },
      "id": "987239a3-27b7-443b-bd80-c0f55fd3bfe1",
      "name": "Extract Document Text",
      "type": "n8n-nodes-base.extractFromFile",
      "typeVersion": 1,
      "position": [
        660,
        1600
      ],
      "alwaysOutputData": true
    },
    {
      "parameters": {},
      "id": "632b396b-c72b-4bb1-88a2-53c81cc5018b",
      "name": "Postgres Chat Memory",
      "type": "@n8n/n8n-nodes-langchain.memoryPostgresChat",
      "typeVersion": 1,
      "position": [
        -140,
        820
      ],
      "notesInFlow": false,
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "delete",
        "tableId": "documents",
        "filterType": "string",
        "filterString": "=metadata->>file_id=like.*{{ $json.file_id }}*"
      },
      "id": "a829b31f-7837-47dd-9610-c352fe55e954",
      "name": "Delete Old Doc Rows",
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        -680,
        1120
      ],
      "alwaysOutputData": true,
      "credentials": {
        "supabaseApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "10646eae-ae46-4327-a4dc-9987c2d76173",
              "name": "file_id",
              "value": "={{ $json.id }}",
              "type": "string"
            },
            {
              "id": "f4536df5-d0b1-4392-bf17-b8137fb31a44",
              "name": "file_type",
              "value": "={{ $json.mimeType }}",
              "type": "string"
            },
            {
              "id": "77d782de-169d-4a46-8a8e-a3831c04d90f",
              "name": "file_title",
              "value": "={{ $json.name }}",
              "type": "string"
            },
            {
              "id": "9bde4d7f-e4f3-4ebd-9338-dce1350f9eab",
              "name": "file_url",
              "value": "={{ $json.webViewLink }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "id": "59c11fb4-004b-46fa-8f83-61f1c541959b",
      "name": "Set File ID",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        -860,
        1280
      ]
    },
    {
      "parameters": {
        "content": "## RAG AI Agent with Chat Interface",
        "height": 464.8027193303974,
        "width": 1035.6381264595484
      },
      "id": "a94bbb39-42ac-4b32-a454-05c5efa1fa83",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -587.5058685188231,
        520
      ]
    },
    {
      "parameters": {
        "options": {}
      },
      "id": "72916c2e-0082-4348-a042-3b75c4469677",
      "name": "Respond to Webhook",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        280,
        600
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "9a9a245e-f1a1-4282-bb02-a81ffe629f0f",
              "name": "chatInput",
              "value": "={{ $json?.chatInput || $json.body.chatInput }}",
              "type": "string"
            },
            {
              "id": "b80831d8-c653-4203-8706-adedfdb98f77",
              "name": "sessionId",
              "value": "={{ $json?.sessionId || $json.body.sessionId}}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "id": "77a9daad-7a3c-4604-91f5-e8991ba1fdeb",
      "name": "Edit Fields",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        -280,
        600
      ]
    },
    {
      "parameters": {
        "public": true,
        "options": {}
      },
      "id": "c852b430-8b25-428b-94fb-27bbb9c83104",
      "name": "When chat message received",
      "type": "@n8n/n8n-nodes-langchain.chatTrigger",
      "typeVersion": 1.1,
      "position": [
        -540,
        600
      ]
    },
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "bf4dd093-bb02-472c-9454-7ab9af97bd1d",
        "authentication": "headerAuth",
        "responseMode": "responseNode",
        "options": {}
      },
      "id": "c3571210-80c4-4a7d-a3b9-451a05d48435",
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        -540,
        800
      ],
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "pdf",
        "options": {}
      },
      "id": "8d293f92-35fe-4df2-b352-40dd6ed71055",
      "name": "Extract PDF Text",
      "type": "n8n-nodes-base.extractFromFile",
      "typeVersion": 1,
      "position": [
        660,
        1040
      ]
    },
    {
      "parameters": {
        "aggregate": "aggregateAllItemData",
        "options": {}
      },
      "id": "98295451-11bb-43e2-95f0-b84cc16beb35",
      "name": "Aggregate",
      "type": "n8n-nodes-base.aggregate",
      "typeVersion": 1,
      "position": [
        700,
        1220
      ]
    },
    {
      "parameters": {},
      "id": "62ac2f5b-bd4d-4618-b362-4ab4796d7177",
      "name": "Character Text Splitter",
      "type": "@n8n/n8n-nodes-langchain.textSplitterCharacterTextSplitter",
      "typeVersion": 1,
      "position": [
        1360,
        1720
      ]
    },
    {
      "parameters": {
        "fieldsToSummarize": {
          "values": [
            {
              "aggregation": "concatenate",
              "field": "data"
            }
          ]
        },
        "options": {}
      },
      "id": "b866e62a-213a-47f0-849d-bb05bb5cfe00",
      "name": "Summarize",
      "type": "n8n-nodes-base.summarize",
      "typeVersion": 1,
      "position": [
        900,
        1300
      ]
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "={{ $json.chatInput }}",
        "options": {
          "systemMessage": "You are a personal assistant who helps answer questions from a corpus of documents. The documents are either text based (Txt, docs, extracted PDFs, etc.) or tabular data (CSVs or Excel documents).\n\nYou are given tools to perform RAG in the 'documents' table, look up the documents available in your knowledge base in the 'document_metadata' table, extract all the text from a given document, and query the tabular files with SQL in the 'document_rows' table.\n\nAlways start by performing RAG unless the question requires a SQL query for tabular data (fetching a sum, finding a max, something a RAG lookup would be unreliable for). If RAG doesn't help, then look at the documents that are available to you, find a few that you think would contain the answer, and then analyze those.\n\nAlways tell the user if you didn't find the answer. Don't make something up just to please them."
        }
      },
      "id": "60cf3257-36fa-44c6-8e46-c322ba776aa0",
      "name": "RAG AI Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "typeVersion": 1.6,
      "position": [
        -60,
        600
      ]
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 1
                },
                "conditions": [
                  {
                    "leftValue": "={{ $('Set File ID').item.json.file_type }}",
                    "rightValue": "application/pdf",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              }
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 1
                },
                "conditions": [
                  {
                    "id": "2ae7faa7-a936-4621-a680-60c512163034",
                    "leftValue": "={{ $('Set File ID').item.json.file_type }}",
                    "rightValue": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              }
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 1
                },
                "conditions": [
                  {
                    "id": "fc193b06-363b-4699-a97d-e5a850138b0e",
                    "leftValue": "={{ $('Set File ID').item.json.file_type }}",
                    "rightValue": "=application/vnd.google-apps.spreadsheet",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              }
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 1
                },
                "conditions": [
                  {
                    "id": "b69f5605-0179-4b02-9a32-e34bb085f82d",
                    "leftValue": "={{ $('Set File ID').item.json.file_type }}",
                    "rightValue": "application/vnd.google-apps.document",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              }
            }
          ]
        },
        "options": {
          "fallbackOutput": 3
        }
      },
      "id": "fe281ba4-319e-414f-a6e6-3c3677425236",
      "name": "Switch",
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3,
      "position": [
        0,
        1260
      ]
    },
    {
      "parameters": {
        "mode": "insert",
        "tableName": {
          "__rl": true,
          "value": "documents",
          "mode": "list",
          "cachedResultName": "documents"
        },
        "options": {
          "queryName": "match_documents"
        }
      },
      "id": "f2af2079-08da-4b6c-ae70-acca61e3f373",
      "name": "Insert into Supabase Vectorstore",
      "type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
      "typeVersion": 1,
      "position": [
        1380,
        1380
      ],
      "credentials": {
        "supabaseApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "xlsx",
        "options": {}
      },
      "id": "4e71197a-75f8-4bca-8f88-d692155073a7",
      "name": "Extract from Excel",
      "type": "n8n-nodes-base.extractFromFile",
      "typeVersion": 1,
      "position": [
        480,
        1220
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "f422e2e0-381c-46ea-8f38-3f58c501d8b9",
              "name": "schema",
              "value": "={{ $('Extract from Excel').isExecuted ? $('Extract from Excel').first().json.keys().toJsonString() : $('Extract from CSV').first().json.keys().toJsonString() }}",
              "type": "string"
            },
            {
              "id": "bb07c71e-5b60-4795-864c-cc3845b6bc46",
              "name": "data",
              "value": "={{ $json.concatenated_data }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        1340,
        1160
      ],
      "id": "b889e1d0-54cd-4924-a18a-f2d292256950",
      "name": "Set Schema"
    },
    {
      "parameters": {
        "options": {}
      },
      "type": "n8n-nodes-base.extractFromFile",
      "typeVersion": 1,
      "position": [
        480,
        1400
      ],
      "id": "fac60267-6d7c-49e4-a9c4-48cdbd69bc0f",
      "name": "Extract from CSV"
    },
    {
      "parameters": {
        "content": "## Run Each Node Once to Set Up Database Tables",
        "height": 300,
        "width": 680,
        "color": 3
      },
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1280,
        680
      ],
      "typeVersion": 1,
      "id": "796f3a52-7c9b-4250-b839-81bc78609c91",
      "name": "Sticky Note3"
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "CREATE TABLE document_metadata (\n    id TEXT PRIMARY KEY,\n    title TEXT,\n    url TEXT,\n    created_at TIMESTAMP DEFAULT NOW(),\n    schema TEXT\n);",
        "options": {}
      },
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.5,
      "position": [
        -1020,
        780
      ],
      "id": "376dec39-bc17-4335-950a-9524e9788406",
      "name": "Create Document Metadata Table",
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "CREATE TABLE document_rows (\n    id SERIAL PRIMARY KEY,\n    dataset_id TEXT REFERENCES document_metadata(id),\n    row_data JSONB  -- Store the actual row data\n);",
        "options": {}
      },
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.5,
      "position": [
        -800,
        780
      ],
      "id": "329dac90-2235-4fec-b1fe-29945f64b3d8",
      "name": "Create Document Rows Table (for Tabular Data)",
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "descriptionType": "manual",
        "toolDescription": "Use this tool to fetch all available documents, including the table schema if the file is a CSV or Excel file.",
        "operation": "select",
        "schema": {
          "__rl": true,
          "mode": "list",
          "value": "public"
        },
        "table": {
          "__rl": true,
          "value": "document_metadata",
          "mode": "list",
          "cachedResultName": "document_metadata"
        },
        "returnAll": true,
        "options": {}
      },
      "type": "n8n-nodes-base.postgresTool",
      "typeVersion": 2.5,
      "position": [
        0,
        820
      ],
      "id": "8a39edea-2d8f-43ed-a98a-60e5ba13ce6a",
      "name": "List Documents",
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "descriptionType": "manual",
        "toolDescription": "Given a file ID, fetches the text from the document.",
        "operation": "executeQuery",
        "query": "SELECT \n    string_agg(content, ' ') as document_text\nFROM documents\n  WHERE metadata->>'file_id' = $1\nGROUP BY metadata->>'file_id';",
        "options": {
          "queryReplacement": "={{ $fromAI('file_id') }}"
        }
      },
      "type": "n8n-nodes-base.postgresTool",
      "typeVersion": 2.5,
      "position": [
        140,
        820
      ],
      "id": "5bc252e7-6fc6-4647-9b31-e3b2b157e965",
      "name": "Get File Contents",
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "descriptionType": "manual",
        "toolDescription": "Run a SQL query - use this to query from the document_rows table once you know the file ID you are querying. dataset_id is the file_id and you are always using the row_data for filtering, which is a jsonb field that has all the keys from the file schema given in the document_metadata table.\n\nExample query:\n\nSELECT AVG((row_data->>'revenue')::numeric)\nFROM document_rows\nWHERE dataset_id = '123';\n\nExample query 2:\n\nSELECT \n    row_data->>'category' as category,\n    SUM((row_data->>'sales')::numeric) as total_sales\nFROM dataset_rows\nWHERE dataset_id = '123'\nGROUP BY row_data->>'category';",
        "operation": "executeQuery",
        "query": "{{ $fromAI('sql_query') }}",
        "options": {}
      },
      "type": "n8n-nodes-base.postgresTool",
      "typeVersion": 2.5,
      "position": [
        300,
        820
      ],
      "id": "f7a8bc27-48f3-402a-b6d5-9c6522a2f533",
      "name": "Query Document Rows",
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "mode": "retrieve-as-tool",
        "toolName": "documents",
        "toolDescription": "Use RAG to look up information in the knowledgebase.",
        "tableName": {
          "__rl": true,
          "value": "documents",
          "mode": "list",
          "cachedResultName": "documents"
        },
        "options": {
          "queryName": "match_documents"
        }
      },
      "type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
      "typeVersion": 1,
      "position": [
        620,
        600
      ],
      "id": "dd1f3999-fb23-4387-9245-eb77c566c480",
      "name": "Supabase Vector Store1",
      "credentials": {
        "supabaseApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
      "typeVersion": 1.2,
      "position": [
        720,
        780
      ],
      "id": "94c3b0aa-0e08-449a-b9a7-cb3034b70ea5",
      "name": "Embeddings OpenAI2",
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "options": {
          "reset": false
        }
      },
      "type": "n8n-nodes-base.splitInBatches",
      "typeVersion": 3,
      "position": [
        -1040,
        1120
      ],
      "id": "48444d0c-92a7-4c51-ad1a-d19579b117e2",
      "name": "Loop Over Items"
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "-- Enable the pgvector extension to work with embedding vectors\ncreate extension vector;\n\n-- Create a table to store your documents\ncreate table documents (\n  id bigserial primary key,\n  content text, -- corresponds to Document.pageContent\n  metadata jsonb, -- corresponds to Document.metadata\n  embedding vector(1536) -- 1536 works for OpenAI embeddings, change if needed\n);\n\n-- Create a function to search for documents\ncreate function match_documents (\n  query_embedding vector(1536),\n  match_count int default null,\n  filter jsonb DEFAULT '{}'\n) returns table (\n  id bigint,\n  content text,\n  metadata jsonb,\n  similarity float\n)\nlanguage plpgsql\nas $$\n#variable_conflict use_column\nbegin\n  return query\n  select\n    id,\n    content,\n    metadata,\n    1 - (documents.embedding <=> query_embedding) as similarity\n  from documents\n  where metadata @> filter\n  order by documents.embedding <=> query_embedding\n  limit match_count;\nend;\n$$;",
        "options": {}
      },
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.5,
      "position": [
        -1220,
        780
      ],
      "id": "5096ff00-4e42-4b3a-812f-29e1a87527cb",
      "name": "Create Documents Table and Match Function",
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "delete",
        "tableId": "document_rows",
        "filters": {
          "conditions": [
            {
              "keyName": "dataset_id",
              "condition": "eq",
              "keyValue": "={{ $('Set File ID').item.json.file_id }}"
            }
          ]
        }
      },
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        -520,
        1280
      ],
      "id": "4fb8f74d-9773-47bd-8f1a-c9754612043c",
      "name": "Delete Old Data Rows",
      "alwaysOutputData": true,
      "executeOnce": true,
      "credentials": {
        "supabaseApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "upsert",
        "schema": {
          "__rl": true,
          "mode": "list",
          "value": "public"
        },
        "table": {
          "__rl": true,
          "value": "document_metadata",
          "mode": "list",
          "cachedResultName": "document_metadata"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "id": "={{ $('Set File ID').item.json.file_id }}",
            "title": "={{ $('Set File ID').item.json.file_title }}",
            "url": "={{ $('Set File ID').item.json.file_url }}"
          },
          "matchingColumns": [
            "id"
          ],
          "schema": [
            {
              "id": "id",
              "displayName": "id",
              "required": true,
              "defaultMatch": true,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "title",
              "displayName": "title",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "url",
              "displayName": "url",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false,
              "removed": false
            },
            {
              "id": "created_at",
              "displayName": "created_at",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "dateTime",
              "canBeUsedToMatch": false
            },
            {
              "id": "schema",
              "displayName": "schema",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false,
              "removed": true
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {}
      },
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.5,
      "position": [
        -360,
        1140
      ],
      "id": "7c2762ca-2d53-4b03-81cd-db10ec3aba7c",
      "name": "Insert Document Metadata",
      "executeOnce": true,
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "schema": {
          "__rl": true,
          "mode": "list",
          "value": "public"
        },
        "table": {
          "__rl": true,
          "value": "document_rows",
          "mode": "list",
          "cachedResultName": "document_rows"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "dataset_id": "={{ $('Set File ID').item.json.file_id }}",
            "row_data": "={{ $json.toJsonString().replaceAll(/'/g, \"''\") }}"
          },
          "matchingColumns": [
            "id"
          ],
          "schema": [
            {
              "id": "id",
              "displayName": "id",
              "required": false,
              "defaultMatch": true,
              "display": true,
              "type": "number",
              "canBeUsedToMatch": true,
              "removed": true
            },
            {
              "id": "dataset_id",
              "displayName": "dataset_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "row_data",
              "displayName": "row_data",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "object",
              "canBeUsedToMatch": true
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {}
      },
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.5,
      "position": [
        700,
        1400
      ],
      "id": "33b554ea-2d4f-4736-88b9-9e6dfad611ab",
      "name": "Insert Table Rows",
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "upsert",
        "schema": {
          "__rl": true,
          "mode": "list",
          "value": "public"
        },
        "table": {
          "__rl": true,
          "value": "document_metadata",
          "mode": "list",
          "cachedResultName": "document_metadata"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "id": "={{ $('Set File ID').item.json.file_id }}",
            "schema": "={{ $json.schema }}"
          },
          "matchingColumns": [
            "id"
          ],
          "schema": [
            {
              "id": "id",
              "displayName": "id",
              "required": true,
              "defaultMatch": true,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true,
              "removed": false
            },
            {
              "id": "title",
              "displayName": "title",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false,
              "removed": true
            },
            {
              "id": "url",
              "displayName": "url",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false,
              "removed": true
            },
            {
              "id": "created_at",
              "displayName": "created_at",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "dateTime",
              "canBeUsedToMatch": false
            },
            {
              "id": "schema",
              "displayName": "schema",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false,
              "removed": false
            }
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {}
      },
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.5,
      "position": [
        1560,
        1160
      ],
      "id": "d10b2b8f-30d4-4589-bd28-e3a9d7ddbee3",
      "name": "Update Schema for Document Metadata",
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "content": "## \ud83d\ude80 Ultimate n8n Agentic RAG Template\n\n**Author:** [Cole Medin](https://www.youtube.com/@ColeMedin)\n\n## What is this?\nThis template provides a complete implementation of an **Agentic RAG (Retrieval Augmented Generation)** system in n8n that can be extended easily for your specific use case and knowledge base. Unlike standard RAG which only performs simple lookups, this agent can reason about your knowledge base, self-improve retrieval, and dynamically switch between different tools based on the specific question.\n\n## Why Agentic RAG?\nStandard RAG has significant limitations:\n- Poor analysis of numerical/tabular data\n- Missing context due to document chunking\n- Inability to connect information across documents\n- No dynamic tool selection based on question type\n\n## What makes this template powerful:\n- **Intelligent tool selection**: Switches between RAG lookups, SQL queries, or full document retrieval based on the question\n- **Complete document context**: Accesses entire documents when needed instead of just chunks\n- **Accurate numerical analysis**: Uses SQL for precise calculations on spreadsheet/tabular data\n- **Cross-document insights**: Connects information across your entire knowledge base\n- **Multi-file processing**: Handles multiple documents in a single workflow loop\n- **Efficient storage**: Uses JSONB in Supabase to store tabular data without creating new tables for each CSV\n\n## Getting Started\n1. Run the table creation nodes first to set up your database tables in Supabase\n2. Upload your documents through Google Drive (or swap out for a different file storage solution)\n3. The agent will process them automatically (chunking text, storing tabular data in Supabase)\n4. Start asking questions that leverage the agent's multiple reasoning approaches\n\n## Customization\nThis template provides a solid foundation that you can extend by:\n- Tuning the system prompt for your specific use case\n- Adding document metadata like summaries\n- Implementing more advanced RAG techniques\n- Optimizing for larger knowledge bases\n\n---\n\nI do intend on making a local version of this agent very soon!",
        "height": 1320,
        "width": 540,
        "color": 6
      },
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1860,
        540
      ],
      "typeVersion": 1,
      "id": "83742c02-2ab5-4c43-8b25-5dd4f9f0f451",
      "name": "Sticky Note9"
    }
  ],
  "connections": {
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "RAG AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Download File": {
      "main": [
        [
          {
            "node": "Switch",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "File Created": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Document Text": {
      "main": [
        [
          {
            "node": "Insert into Supabase Vectorstore",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Embeddings OpenAI1": {
      "ai_embedding": [
        [
          {
            "node": "Insert into Supabase Vectorstore",
            "type": "ai_embedding",
            "index": 0
          }
        ]
      ]
    },
    "Default Data Loader": {
      "ai_document": [
        [
          {
            "node": "Insert into Supabase Vectorstore",
            "type": "ai_document",
            "index": 0
          }
        ]
      ]
    },
    "Postgres Chat Memory": {
      "ai_memory": [
        [
          {
            "node": "RAG AI Agent",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "Delete Old Doc Rows": {
      "main": [
        [
          {
            "node": "Delete Old Data Rows",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set File ID": {
      "main": [
        [
          {
            "node": "Delete Old Doc Rows",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "File Updated": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Edit Fields": {
      "main": [
        [
          {
            "node": "RAG AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When chat message received": {
      "main": [
        [
          {
            "node": "Edit Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Webhook": {
      "main": [
        [
          {
            "node": "Edit Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract PDF Text": {
      "main": [
        [
          {
            "node": "Insert into Supabase Vectorstore",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate": {
      "main": [
        [
          {
            "node": "Summarize",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Character Text Splitter": {
      "ai_textSplitter": [
        [
          {
            "node": "Default Data Loader",
            "type": "ai_textSplitter",
            "index": 0
          }
        ]
      ]
    },
    "Summarize": {
      "main": [
        [
          {
            "node": "Set Schema",
            "type": "main",
            "index": 0
          },
          {
            "node": "Insert into Supabase Vectorstore",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "RAG AI Agent": {
      "main": [
        [
          {
            "node": "Respond to Webhook",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Switch": {
      "main": [
        [
          {
            "node": "Extract PDF Text",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Extract from Excel",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Extract from CSV",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Extract Document Text",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract from Excel": {
      "main": [
        [
          {
            "node": "Aggregate",
            "type": "main",
            "index": 0
          },
          {
            "node": "Insert Table Rows",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Schema": {
      "main": [
        [
          {
            "node": "Update Schema for Document Metadata",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract from CSV": {
      "main": [
        [
          {
            "node": "Aggregate",
            "type": "main",
            "index": 0
          },
          {
            "node": "Insert Table Rows",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Document Metadata Table": {
      "main": [
        [
          {
            "node": "Create Document Rows Table (for Tabular Data)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "List Documents": {
      "ai_tool": [
        [
          {
            "node": "RAG AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Get File Contents": {
      "ai_tool": [
        [
          {
            "node": "RAG AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Query Document Rows": {
      "ai_tool": [
        [
          {
            "node": "RAG AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Supabase Vector Store1": {
      "ai_tool": [
        [
          {
            "node": "RAG AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Embeddings OpenAI2": {
      "ai_embedding": [
        [
          {
            "node": "Supabase Vector Store1",
            "type": "ai_embedding",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items": {
      "main": [
        [],
        [
          {
            "node": "Set File ID",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Insert into Supabase Vectorstore": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Documents Table and Match Function": {
      "main": [
        [
          {
            "node": "Create Document Metadata Table",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Delete Old Data Rows": {
      "main": [
        [
          {
            "node": "Insert Document Metadata",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Insert Document Metadata": {
      "main": [
        [
          {
            "node": "Download File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Schema for Document Metadata": {
      "main": [
        []
      ]
    }
  },
  "active": true,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "d90e0120-4c7c-4a0e-a42b-5c5c6bc9cc90",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "id": "5ZyVGf8IZnyYCpkE",
  "tags": []
}

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.

About this workflow

Ultimate Agentic RAG AI Agent Template. Uses lmChatOpenAi, documentDefaultDataLoader, embeddingsOpenAi, stickyNote. Event-driven trigger; 42 nodes.

Source: https://github.com/Zie619/n8n-workflows — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →