Créer un chatbot RAG auto-mis à jour (Google Drive, Gemini et Supabase)

Avancé

Ceci est unContent Creation, Multimodal AIworkflow d'automatisation du domainecontenant 45 nœuds.Utilise principalement des nœuds comme Set, Code, Merge, Switch, Postgres. Utiliser Google Drive, Gemini et Supabase pour créer un chatbot RAG auto-mis à jour

Prérequis
  • Informations de connexion à la base de données PostgreSQL
  • URL et Clé API Supabase
  • Informations d'identification Google Drive API
  • Clé API Google Gemini
Aperçu du workflow
Visualisation des connexions entre les nœuds, avec support du zoom et du déplacement
Exporter le workflow
Copiez la configuration JSON suivante dans n8n pour importer et utiliser ce workflow
{
  "meta": {
    "instanceId": "3d5da29ecb74ce7e2d987bbf535eab46b9724880017cbe267c2cb8d22899447c"
  },
  "nodes": [
    {
      "id": "fbeb9ada-34d8-440a-b843-ff139e8e979c",
      "name": "Reranker Cohere",
      "type": "@n8n/n8n-nodes-langchain.rerankerCohere",
      "position": [
        1456,
        368
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "11e0434a-904c-48ca-b119-978dd68996db",
      "name": "Supabase Vector Store",
      "type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
      "position": [
        1216,
        224
      ],
      "parameters": {
        "mode": "retrieve-as-tool",
        "topK": 20,
        "options": {},
        "tableName": {
          "__rl": true,
          "mode": "list",
          "value": "documents",
          "cachedResultName": "documents"
        },
        "useReranker": true,
        "toolDescription": "Use this tool to search the database"
      },
      "typeVersion": 1.3
    },
    {
      "id": "68112d8c-e204-451f-b5b3-a10f69738506",
      "name": "Note adhésive 1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        272,
        80
      ],
      "parameters": {
        "color": 4,
        "width": 1372,
        "height": 396,
        "content": "## RAG Agent (Step 2)\n"
      },
      "typeVersion": 1
    },
    {
      "id": "b011d310-348d-4726-b2b3-785ac9b081e0",
      "name": "Note adhésive 2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1072,
        80
      ],
      "parameters": {
        "color": 6,
        "width": 572,
        "height": 396,
        "content": "## Vector Store\n"
      },
      "typeVersion": 1
    },
    {
      "id": "9f12dcc8-423c-42f6-a0de-522b5897c620",
      "name": "Agent RAG",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        528,
        176
      ],
      "parameters": {
        "options": {
          "systemMessage": "=You are a helpful and friendly AI assistant for our company. Your primary goal is to assist users by answering their questions based on a knowledge base, but you should also be ableto handle simple conversation. You have access to the Supabase tool. Always call on this tool to answer questions if the user is asking for information.\n\nFirst, analyze the user's message to determine their intent.\n\n**Behavior 1: If the user's message is a simple greeting, thank you, or other conversational filler (e.g., \"hello\", \"thanks!\", \"how are you?\").**\n- You should respond politely and conversationally.\n- Do NOT use the provided [CONTEXT].\n- Do NOT mention the documents or your knowledge base.\n\n**Behavior 2: If the user's message is a question asking for information, instructions, or specific details.**\n- You must switch to your role as a specialized knowledge base assistant and follow these strict rules:\n1.  **Analyze the Context:** Carefully read the provided [CONTEXT] section. This is your only source of truth.\n2.  **Answer the Question:** Formulate a direct and concise answer to the [QUESTION] using only the information from the [CONTEXT].\n3.  **Strictly Adhere to Context:** Do NOT use any external knowledge, make assumptions, or fill in gaps.\n4.  **Handling Insufficient Information:** If the answer cannot be found within the [CONTEXT], you must respond with the exact phrase: \"I could not find an answer in the provided documents.\" Do not apologize or offer to search elsewhere.\n5.  **Cite Your Sources:** After your answer, add a \"Sources:\" section. List the title of each source document you used. Use the metadata provided in the context to format each source as a clickable Markdown link.\n\n**[CONTEXT]**\n{context_from_retriever}\n**[/CONTEXT]**\n\n**[QUESTION]**\n{user_question}\n**[/QUESTION]**"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "61d43f61-e071-4d2d-a714-eac42d4acbd2",
      "name": "Fichier créé",
      "type": "n8n-nodes-base.googleDriveTrigger",
      "disabled": true,
      "position": [
        128,
        560
      ],
      "parameters": {
        "event": "fileCreated",
        "options": {},
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        },
        "triggerOn": "specificFolder",
        "folderToWatch": {
          "__rl": true,
          "mode": "list",
          "value": "Your Folder ID",
          "cachedResultUrl": "https://drive.google.com/drive/folders/Your Folder ID",
          "cachedResultName": "1) RAG Demo"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "52fa8440-7c5a-4a2e-bd6b-17cbb22c7d6a",
      "name": "Fichier mis à jour",
      "type": "n8n-nodes-base.googleDriveTrigger",
      "disabled": true,
      "position": [
        128,
        1024
      ],
      "parameters": {
        "event": "fileUpdated",
        "options": {},
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        },
        "triggerOn": "specificFolder",
        "folderToWatch": {
          "__rl": true,
          "mode": "list",
          "value": "Your Folder ID",
          "cachedResultUrl": "https://drive.google.com/drive/folders/Your Folder ID",
          "cachedResultName": "1) RAG Demo"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "06cd8ce9-4d3c-412e-9688-a181f6aadc38",
      "name": "Extraire le texte du document",
      "type": "n8n-nodes-base.extractFromFile",
      "position": [
        1296,
        944
      ],
      "parameters": {
        "options": {},
        "operation": "text"
      },
      "typeVersion": 1,
      "alwaysOutputData": true
    },
    {
      "id": "8a280ac3-a27f-469c-9885-3482051e2268",
      "name": "Supprimer les anciennes lignes de document",
      "type": "n8n-nodes-base.supabase",
      "position": [
        576,
        880
      ],
      "parameters": {
        "tableId": "documents",
        "operation": "delete",
        "filterType": "string",
        "filterString": "=metadata->>file_id=like.*{{ $json.file_id }}*"
      },
      "typeVersion": 1,
      "alwaysOutputData": true
    },
    {
      "id": "2fca17ab-ec90-4877-936b-45a651a567d1",
      "name": "Définir l'ID du fichier",
      "type": "n8n-nodes-base.set",
      "position": [
        672,
        624
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "10646eae-ae46-4327-a4dc-9987c2d76173",
              "name": "file_id",
              "type": "string",
              "value": "={{ $json.id }}"
            },
            {
              "id": "f4536df5-d0b1-4392-bf17-b8137fb31a44",
              "name": "file_type",
              "type": "string",
              "value": "={{ $json.mimeType }}"
            },
            {
              "id": "77d782de-169d-4a46-8a8e-a3831c04d90f",
              "name": "file_title",
              "type": "string",
              "value": "={{ $json.name }}"
            },
            {
              "id": "9bde4d7f-e4f3-4ebd-9338-dce1350f9eab",
              "name": "file_url",
              "type": "string",
              "value": "={{ $json.webViewLink }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "a3a6aca4-5932-4b13-9466-de1fadee3392",
      "name": "Extraire le texte PDF",
      "type": "n8n-nodes-base.extractFromFile",
      "position": [
        1296,
        784
      ],
      "parameters": {
        "options": {},
        "operation": "pdf"
      },
      "typeVersion": 1
    },
    {
      "id": "86094f10-2a02-431f-b0ec-d7cd5dffb98b",
      "name": "Séparateur de texte par caractères",
      "type": "@n8n/n8n-nodes-langchain.textSplitterCharacterTextSplitter",
      "position": [
        1552,
        1280
      ],
      "parameters": {
        "chunkSize": 750,
        "chunkOverlap": 200
      },
      "typeVersion": 1
    },
    {
      "id": "35366f16-4f00-4544-9f7e-aac1a5571e7f",
      "name": "Commutateur",
      "type": "n8n-nodes-base.switch",
      "position": [
        1072,
        880
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "version": 1,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $('Set File ID').item.json.file_type }}",
                    "rightValue": "application/pdf"
                  }
                ]
              }
            },
            {
              "conditions": {
                "options": {
                  "version": 1,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "b69f5605-0179-4b02-9a32-e34bb085f82d",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $('Set File ID').item.json.file_type }}",
                    "rightValue": "application/vnd.google-apps.document"
                  }
                ]
              }
            }
          ]
        },
        "options": {
          "fallbackOutput": 3
        }
      },
      "typeVersion": 3
    },
    {
      "id": "0edf1ac5-2469-451e-81cb-6b6267427b9f",
      "name": "Insérer dans Supabase Vectorstore",
      "type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
      "onError": "continueRegularOutput",
      "position": [
        1552,
        928
      ],
      "parameters": {
        "mode": "insert",
        "options": {
          "queryName": "match_documents"
        },
        "tableName": {
          "__rl": true,
          "mode": "list",
          "value": "documents",
          "cachedResultName": "documents"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "f5c2d73e-fdb7-4e2c-8fae-74e2dd483b99",
      "name": "Boucler sur les éléments",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        448,
        608
      ],
      "parameters": {
        "options": {
          "reset": false
        }
      },
      "typeVersion": 3
    },
    {
      "id": "80ca7123-c4d6-4184-83db-3a9cd7eea5be",
      "name": "Insérer les métadonnées du document",
      "type": "n8n-nodes-base.postgres",
      "position": [
        752,
        880
      ],
      "parameters": {
        "table": {
          "__rl": true,
          "mode": "list",
          "value": "document_metadata",
          "cachedResultName": "document_metadata"
        },
        "schema": {
          "__rl": true,
          "mode": "list",
          "value": "public"
        },
        "columns": {
          "value": {
            "id": "={{ $('Set File ID').item.json.file_id }}",
            "url": "={{ $('Set File ID').item.json.file_url }}",
            "title": "={{ $('Set File ID').item.json.file_title }}"
          },
          "schema": [
            {
              "id": "id",
              "type": "string",
              "display": true,
              "removed": false,
              "required": true,
              "displayName": "id",
              "defaultMatch": true,
              "canBeUsedToMatch": true
            },
            {
              "id": "title",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "title",
              "defaultMatch": false,
              "canBeUsedToMatch": false
            },
            {
              "id": "url",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "url",
              "defaultMatch": false,
              "canBeUsedToMatch": false
            },
            {
              "id": "created_at",
              "type": "dateTime",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "created_at",
              "defaultMatch": false,
              "canBeUsedToMatch": false
            },
            {
              "id": "schema",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "schema",
              "defaultMatch": false,
              "canBeUsedToMatch": false
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "id"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "upsert"
      },
      "executeOnce": true,
      "typeVersion": 2.5
    },
    {
      "id": "75602bb9-30a7-409c-8aaa-38f9923cf08d",
      "name": "Chargeur de données par défaut 1",
      "type": "@n8n/n8n-nodes-langchain.documentDefaultDataLoader",
      "position": [
        1632,
        1136
      ],
      "parameters": {
        "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 }}"
              },
              {
                "name": "url",
                "value": "={{ $('Set File ID').first().json.file_url }}"
              }
            ]
          }
        },
        "jsonData": "={{ $json.data || $json.text || $json.concatenated_data }}",
        "jsonMode": "expressionData"
      },
      "typeVersion": 1
    },
    {
      "id": "902bfe64-17c3-45aa-8434-cb4241aa150b",
      "name": "Télécharger le fichier 1",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        928,
        880
      ],
      "parameters": {
        "fileId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Set File ID').item.json.file_id }}"
        },
        "options": {
          "googleFileConversion": {
            "conversion": {
              "docsToFormat": "text/plain"
            }
          }
        },
        "operation": "download"
      },
      "executeOnce": true,
      "retryOnFail": true,
      "typeVersion": 3
    },
    {
      "id": "87aecf50-86dc-48db-9eac-b34fd6a4938d",
      "name": "Note adhésive",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -144,
        480
      ],
      "parameters": {
        "color": 3,
        "width": 2192,
        "height": 976,
        "content": "## RAG Ingestion System (Step 1)\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n                                                                                              \n\n\n\n\n\n\n\n\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "e67da326-ff09-4f72-a146-19c342dc8b1f",
      "name": "Obtenir les ID des fichiers",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        816,
        1568
      ],
      "parameters": {
        "filter": {},
        "options": {
          "fields": [
            "id"
          ]
        },
        "resource": "fileFolder",
        "returnAll": true,
        "queryString": "'Your Folder ID' in parents and trashed=false",
        "searchMethod": "query"
      },
      "typeVersion": 3
    },
    {
      "id": "b5b91dde-0afb-493f-b336-ea84017d8171",
      "name": "Fusionner",
      "type": "n8n-nodes-base.merge",
      "position": [
        1088,
        1648
      ],
      "parameters": {},
      "typeVersion": 3
    },
    {
      "id": "74a8e170-040a-42f4-b593-a2206527f655",
      "name": "Supabase",
      "type": "n8n-nodes-base.supabase",
      "position": [
        816,
        1728
      ],
      "parameters": {
        "tableId": "documents",
        "operation": "getAll",
        "returnAll": true
      },
      "typeVersion": 1
    },
    {
      "id": "a763d918-e045-461a-b081-2670f7d3f1af",
      "name": "Code 1",
      "type": "n8n-nodes-base.code",
      "position": [
        1312,
        1648
      ],
      "parameters": {
        "jsCode": "// Grab the raw data from all inputs\nconst inputData = $input.all().map(item => item.json);\n\n// Separate out the Google Drive items (no \"metadata\") vs. Supabase items (have \"metadata\")\nconst googleDriveItems = inputData.filter(item => item.id && !item.metadata);\nconst supabaseItems = inputData.filter(item => item.metadata);\n\n// Extract just the file IDs from Google Drive\nconst googleDriveIds = googleDriveItems.map(item => item.id);\n\n// Build a Set for quick membership checks (recommended for large arrays)\nconst driveIdSet = new Set(googleDriveIds);\n\n// Filter Supabase rows to find those whose file_id is not in the Drive set\nconst orphanedSupabaseRows = supabaseItems.filter(item => {\n  return !driveIdSet.has(item.metadata.file_id);\n});\n\n// Return each orphaned row as a separate n8n item\nreturn orphanedSupabaseRows.map(row => ({ json: row }));\n"
      },
      "typeVersion": 2
    },
    {
      "id": "c5a5c9c8-07fe-4c09-87ac-c0dd0dbaf17e",
      "name": "Déclencheur planifié",
      "type": "n8n-nodes-base.scheduleTrigger",
      "disabled": true,
      "position": [
        512,
        1904
      ],
      "parameters": {
        "rule": {
          "interval": [
            {}
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "ec4c1998-6079-4a91-a8ba-b6fed99e93a7",
      "name": "Lors d'un clic sur 'Tester le workflow'",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        -112,
        784
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "29b49cd7-64ce-4752-a07b-3afebf19219b",
      "name": "Supprimer les lignes",
      "type": "n8n-nodes-base.supabase",
      "position": [
        1536,
        1648
      ],
      "parameters": {
        "filters": {
          "conditions": [
            {
              "keyName": "id",
              "keyValue": "={{ $json.id }}",
              "condition": "eq"
            }
          ]
        },
        "tableId": "documents",
        "matchType": "allFilters",
        "operation": "delete"
      },
      "typeVersion": 1
    },
    {
      "id": "3c1b0427-02df-481a-94b1-63a22ca243af",
      "name": "Note adhésive 5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        368,
        1456
      ],
      "parameters": {
        "color": 6,
        "width": 1440,
        "height": 956,
        "content": "## RAG: Clean up (Step 3)"
      },
      "typeVersion": 1
    },
    {
      "id": "3ea2baf0-fac7-440b-bd6c-4f7f689844cc",
      "name": "Obtenir les ID des fichiers 2",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        816,
        1968
      ],
      "parameters": {
        "filter": {},
        "options": {
          "fields": [
            "id"
          ]
        },
        "resource": "fileFolder",
        "returnAll": true,
        "queryString": "'Your Folder ID' in parents and trashed=false",
        "searchMethod": "query"
      },
      "typeVersion": 3
    },
    {
      "id": "8002bd2f-29da-40fe-b909-cdcc7d3f5fde",
      "name": "Supabase 2",
      "type": "n8n-nodes-base.supabase",
      "position": [
        816,
        2192
      ],
      "parameters": {
        "tableId": "document_metadata",
        "operation": "getAll",
        "returnAll": true
      },
      "typeVersion": 1
    },
    {
      "id": "f11e2063-d42c-4d07-86d8-b916467b5b3a",
      "name": "Fusionner 2",
      "type": "n8n-nodes-base.merge",
      "position": [
        1104,
        2048
      ],
      "parameters": {},
      "typeVersion": 3
    },
    {
      "id": "4b4a4689-2767-49a9-8f8f-2a33d9cd7e84",
      "name": "Code 2",
      "type": "n8n-nodes-base.code",
      "position": [
        1328,
        2048
      ],
      "parameters": {
        "jsCode": "// Simple code to handle empty Google Drive\n\n// Determine if we have Google Drive data\nlet hasDriveData = false;\nlet driveFileIds = new Set();\n\n// Check the first item to see if it's a Google Drive file or a file list\nif (items[0] && items[0].json) {\n  // Is it a files array?\n  if (items[0].json.files && Array.isArray(items[0].json.files)) {\n    hasDriveData = true;\n    for (const file of items[0].json.files) {\n      if (file && file.id) driveFileIds.add(file.id);\n    }\n  }\n  // Is it a single file with no metadata-like properties?\n  else if (items[0].json.id && !items[0].json.title && !items[0].json.created_at) {\n    hasDriveData = true;\n    driveFileIds.add(items[0].json.id);\n  }\n}\n\nconsole.log(\"Has Drive data:\", hasDriveData);\nconsole.log(\"Drive file IDs:\", Array.from(driveFileIds));\n\n// Determine which items are metadata records\nlet metadataRecords = [];\n\n// If the first item looks like a metadata record (has title, url, created_at)\nif (!hasDriveData) {\n  // All items are metadata records\n  metadataRecords = items.map(item => item.json).filter(Boolean);\n  console.log(\"All items are metadata records:\", metadataRecords.length);\n} else {\n  // Only items after the first are metadata records\n  metadataRecords = items.slice(1).map(item => item.json).filter(Boolean);\n  console.log(\"Items after first are metadata records:\", metadataRecords.length);\n}\n\n// If there are no Drive files, mark all metadata records for deletion\nconst recordsToDelete = [];\n\nif (driveFileIds.size === 0) {\n  console.log(\"No Drive files, marking ALL metadata records for deletion\");\n  for (const record of metadataRecords) {\n    if (record && record.id) {\n      recordsToDelete.push({\n        ...record,\n        _shouldDelete: true\n      });\n    }\n  }\n} else {\n  // Otherwise, only mark records not in Drive\n  console.log(\"Checking metadata records against Drive files\");\n  for (const record of metadataRecords) {\n    if (record && record.id && !driveFileIds.has(record.id)) {\n      recordsToDelete.push({\n        ...record,\n        _shouldDelete: true\n      });\n    }\n  }\n}\n\nconsole.log(\"Records to delete:\", recordsToDelete.length);\nreturn recordsToDelete;"
      },
      "typeVersion": 2
    },
    {
      "id": "d12aeac5-f570-49c7-8276-5a53648026cb",
      "name": "Supprimer les lignes 2",
      "type": "n8n-nodes-base.supabase",
      "position": [
        1568,
        2048
      ],
      "parameters": {
        "filters": {
          "conditions": [
            {
              "keyName": "id",
              "keyValue": "={{ $json.id }}",
              "condition": "eq"
            }
          ]
        },
        "tableId": "document_metadata",
        "matchType": "allFilters",
        "operation": "delete"
      },
      "typeVersion": 1
    },
    {
      "id": "5b4cd434-4799-4981-a585-21c69d8329d5",
      "name": "Rechercher fichiers et dossiers",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        128,
        784
      ],
      "parameters": {
        "filter": {},
        "options": {
          "fields": [
            "webViewLink",
            "id",
            "name",
            "mimeType"
          ]
        },
        "resource": "fileFolder",
        "returnAll": true,
        "queryString": "='Your Folder ID' in parents and trashed=false",
        "searchMethod": "query"
      },
      "typeVersion": 3
    },
    {
      "id": "e2bbc2ba-cce7-4410-b5e9-60fc1bf7dacb",
      "name": "Mémoire de chat Postgres",
      "type": "@n8n/n8n-nodes-langchain.memoryPostgresChat",
      "position": [
        592,
        352
      ],
      "parameters": {},
      "typeVersion": 1.3
    },
    {
      "id": "33dbd2eb-d1dc-426c-9939-45461780cffe",
      "name": "Lors de la réception d'un message de chat",
      "type": "@n8n/n8n-nodes-langchain.chatTrigger",
      "position": [
        304,
        176
      ],
      "webhookId": "d105c3ad-3488-438c-b405-b856c90ce80e",
      "parameters": {
        "options": {}
      },
      "typeVersion": 1.1
    },
    {
      "id": "554ad606-2bd7-49c9-a415-0c9f88ae4ac8",
      "name": "Google Gemini Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        448,
        352
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 1
    },
    {
      "id": "0b83f6fc-e67c-4a00-a26d-80efdf87213b",
      "name": "Embeddings Google Gemini",
      "type": "@n8n/n8n-nodes-langchain.embeddingsGoogleGemini",
      "position": [
        1200,
        368
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "052b2e8f-de1a-4bea-b67c-387c362f23f7",
      "name": "Embeddings Google Gemini 1",
      "type": "@n8n/n8n-nodes-langchain.embeddingsGoogleGemini",
      "position": [
        1488,
        1136
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "17f0d107-e2e4-4719-826d-33e647c96ed5",
      "name": "Note adhésive 3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -400,
        -688
      ],
      "parameters": {
        "width": 560,
        "height": 320,
        "content": "=========================\n        RAG Agent with G-Drive Sync\n=======================================\nFor any questions or support, please contact:\n    anirudh.n.aeran@gmail.com\n\nExplore more tips here:\n   - LinkedIn: https://www.linkedin.com/in/anirudh-narayan-a-/\n\nHappy learning! -- Anirudh Aeran\n\n\n======================================="
      },
      "typeVersion": 1
    },
    {
      "id": "0a09459f-ceeb-44f9-93ee-c3bdbfa3a527",
      "name": "Note adhésive 6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -416,
        752
      ],
      "parameters": {
        "width": 256,
        "height": 208,
        "content": "#### This Manual Trigger is Used \n#### for the Initial Ingestion of \n#### Documents to the Vectorbase\n\n**-->After the initial ingestion, \n activate the 2 Google drive \ntriggers to make this \nworkflow Production Ready**"
      },
      "typeVersion": 1
    },
    {
      "id": "7a52403a-8ba4-4a07-81fe-f5ee0c3b63d8",
      "name": "Note adhésive 7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        512,
        -16
      ],
      "parameters": {
        "width": 272,
        "height": 80,
        "content": "\n**--> The Prompt inside the RAG agent can be fine tuned according to your needs**"
      },
      "typeVersion": 1
    },
    {
      "id": "1a0f8c51-1376-4520-a123-75d400095ecf",
      "name": "Note adhésive 8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -400,
        -336
      ],
      "parameters": {
        "color": 5,
        "width": 380,
        "height": 776,
        "content": "## Try It Out!\n\nThis is a comprehensive, production-ready Retrieval-Augmented Generation (RAG) system. It builds a sophisticated AI agent that can answer questions based on documents in a specific Google Drive folder, and it automatically keeps its knowledge base up-to-date as you add, update, or remove files.\n\n**To get started:**\n\n1. **Connect all credentials** (Gemini, supabase, postgres, drive, and Cohere). Refer the Sticky Notes and [n8n docs](https://docs.n8n.io/)\n\n2. **Create the Tables** inside Supabase by copying the code from here. If You don't have an account create one and then on the side panel click on SQL Editor to copy paste the code [Code](https://docs.google.com/document/d/1tLJ7fndrDjYMfyQ1R61q5NbqDs5ZMgvhzcMzkoIzj5M/edit?usp=sharing)\n\n3. **Activate the workflow** by replacing the [Folder ID] with your drive folder ID inside \"Search files and folders\" Node and then upload file(s) which are of doc or pdf format.\n\n4. **For the First Time** use the manual Trigger to vectorize and push the contents of the files to Supabase\n\n5. **Ask any question** related to the the contents of the file using the Chat Trigger in Step 2 and Experience the magic of the RAG Agent.\n\n6. **Once The test is completed**, activate both the google drive trigger nodes in the step 1 flow. This will make sure that the workflow is production ready."
      },
      "typeVersion": 1
    },
    {
      "id": "9c12acb0-3516-4573-8468-eabb1548fbac",
      "name": "Note adhésive 9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        816,
        -224
      ],
      "parameters": {
        "width": 304,
        "height": 288,
        "content": "## --> Postgres Connection\n\nClick on \"connect\" on the top of your Supabase account. Then click on the \"Connection Pooling\" tab and make sure the \"Transaction\" pooler is selected. \n\nYou will see something similar to this screenshot: [View Image](https://i.postimg.cc/htxnsprc/Screenshot-2025-10-02-143424.png)\n\nReplace the fields inside your n8n Postgres credential with the matching values from that page."
      },
      "typeVersion": 1
    },
    {
      "id": "67aac6f9-e5aa-4c7f-aea3-e19d32e36367",
      "name": "Note adhésive 10",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1664,
        336
      ],
      "parameters": {
        "height": 128,
        "content": "**Go to this website, https://dashboard.cohere.com/  create an account and copy the API key to connect Reranker Cohere**"
      },
      "typeVersion": 1
    },
    {
      "id": "a34b0cd1-51fd-469e-9ba0-7961cea3f2d1",
      "name": "Note adhésive 4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        16,
        1536
      ],
      "parameters": {
        "width": 304,
        "height": 576,
        "content": "## How the Cleanup Works\n\nThis is a scheduled process that runs automatically once every day. Its purpose is to keep your knowledge base synchronized by removing data from files that have been deleted in Google Drive.\n\nHere’s the step-by-step process:\n\n* The workflow fetches a list of all current file IDs from your designated Google Drive folder.\n* It also fetches a list of all file IDs stored in your Supabase tables.\n* A **Code node** compares these two lists to identify \"orphaned\" data—entries in Supabase that no longer have a matching file in Google Drive.\n* Finally, the workflow deletes all data associated with those orphaned IDs.\n\nThis cleanup process targets **two separate tables** to ensure all related information is removed: the main `documents` table (storing the content) and the `document_metadata` table (storing the file titles and URLs)."
      },
      "typeVersion": 1
    }
  ],
  "pinData": {},
  "connections": {
    "a763d918-e045-461a-b081-2670f7d3f1af": {
      "main": [
        [
          {
            "node": "29b49cd7-64ce-4752-a07b-3afebf19219b",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "4b4a4689-2767-49a9-8f8f-2a33d9cd7e84": {
      "main": [
        [
          {
            "node": "d12aeac5-f570-49c7-8276-5a53648026cb",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "b5b91dde-0afb-493f-b336-ea84017d8171": {
      "main": [
        [
          {
            "node": "a763d918-e045-461a-b081-2670f7d3f1af",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "f11e2063-d42c-4d07-86d8-b916467b5b3a": {
      "main": [
        [
          {
            "node": "4b4a4689-2767-49a9-8f8f-2a33d9cd7e84",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "35366f16-4f00-4544-9f7e-aac1a5571e7f": {
      "main": [
        [
          {
            "node": "a3a6aca4-5932-4b13-9466-de1fadee3392",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "06cd8ce9-4d3c-412e-9688-a181f6aadc38",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "74a8e170-040a-42f4-b593-a2206527f655": {
      "main": [
        [
          {
            "node": "b5b91dde-0afb-493f-b336-ea84017d8171",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "8002bd2f-29da-40fe-b909-cdcc7d3f5fde": {
      "main": [
        [
          {
            "node": "f11e2063-d42c-4d07-86d8-b916467b5b3a",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "2fca17ab-ec90-4877-936b-45a651a567d1": {
      "main": [
        [
          {
            "node": "8a280ac3-a27f-469c-9885-3482051e2268",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "61d43f61-e071-4d2d-a714-eac42d4acbd2": {
      "main": [
        [
          {
            "node": "f5c2d73e-fdb7-4e2c-8fae-74e2dd483b99",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "52fa8440-7c5a-4a2e-bd6b-17cbb22c7d6a": {
      "main": [
        [
          {
            "node": "f5c2d73e-fdb7-4e2c-8fae-74e2dd483b99",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "e67da326-ff09-4f72-a146-19c342dc8b1f": {
      "main": [
        [
          {
            "node": "b5b91dde-0afb-493f-b336-ea84017d8171",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "3ea2baf0-fac7-440b-bd6c-4f7f689844cc": {
      "main": [
        [
          {
            "node": "f11e2063-d42c-4d07-86d8-b916467b5b3a",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "902bfe64-17c3-45aa-8434-cb4241aa150b": {
      "main": [
        [
          {
            "node": "35366f16-4f00-4544-9f7e-aac1a5571e7f",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "f5c2d73e-fdb7-4e2c-8fae-74e2dd483b99": {
      "main": [
        [],
        [
          {
            "node": "2fca17ab-ec90-4877-936b-45a651a567d1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "fbeb9ada-34d8-440a-b843-ff139e8e979c": {
      "ai_reranker": [
        [
          {
            "node": "11e0434a-904c-48ca-b119-978dd68996db",
            "type": "ai_reranker",
            "index": 0
          }
        ]
      ]
    },
    "a3a6aca4-5932-4b13-9466-de1fadee3392": {
      "main": [
        [
          {
            "node": "0edf1ac5-2469-451e-81cb-6b6267427b9f",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "c5a5c9c8-07fe-4c09-87ac-c0dd0dbaf17e": {
      "main": [
        [
          {
            "node": "e67da326-ff09-4f72-a146-19c342dc8b1f",
            "type": "main",
            "index": 0
          },
          {
            "node": "74a8e170-040a-42f4-b593-a2206527f655",
            "type": "main",
            "index": 0
          },
          {
            "node": "3ea2baf0-fac7-440b-bd6c-4f7f689844cc",
            "type": "main",
            "index": 0
          },
          {
            "node": "8002bd2f-29da-40fe-b909-cdcc7d3f5fde",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "8a280ac3-a27f-469c-9885-3482051e2268": {
      "main": [
        [
          {
            "node": "80ca7123-c4d6-4184-83db-3a9cd7eea5be",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "75602bb9-30a7-409c-8aaa-38f9923cf08d": {
      "ai_document": [
        [
          {
            "node": "0edf1ac5-2469-451e-81cb-6b6267427b9f",
            "type": "ai_document",
            "index": 0
          }
        ]
      ]
    },
    "e2bbc2ba-cce7-4410-b5e9-60fc1bf7dacb": {
      "ai_memory": [
        [
          {
            "node": "9f12dcc8-423c-42f6-a0de-522b5897c620",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "06cd8ce9-4d3c-412e-9688-a181f6aadc38": {
      "main": [
        [
          {
            "node": "0edf1ac5-2469-451e-81cb-6b6267427b9f",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "11e0434a-904c-48ca-b119-978dd68996db": {
      "ai_tool": [
        [
          {
            "node": "9f12dcc8-423c-42f6-a0de-522b5897c620",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "86094f10-2a02-431f-b0ec-d7cd5dffb98b": {
      "ai_textSplitter": [
        [
          {
            "node": "75602bb9-30a7-409c-8aaa-38f9923cf08d",
            "type": "ai_textSplitter",
            "index": 0
          }
        ]
      ]
    },
    "0b83f6fc-e67c-4a00-a26d-80efdf87213b": {
      "ai_embedding": [
        [
          {
            "node": "11e0434a-904c-48ca-b119-978dd68996db",
            "type": "ai_embedding",
            "index": 0
          }
        ]
      ]
    },
    "554ad606-2bd7-49c9-a415-0c9f88ae4ac8": {
      "ai_languageModel": [
        [
          {
            "node": "9f12dcc8-423c-42f6-a0de-522b5897c620",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "80ca7123-c4d6-4184-83db-3a9cd7eea5be": {
      "main": [
        [
          {
            "node": "902bfe64-17c3-45aa-8434-cb4241aa150b",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "5b4cd434-4799-4981-a585-21c69d8329d5": {
      "main": [
        [
          {
            "node": "f5c2d73e-fdb7-4e2c-8fae-74e2dd483b99",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "052b2e8f-de1a-4bea-b67c-387c362f23f7": {
      "ai_embedding": [
        [
          {
            "node": "0edf1ac5-2469-451e-81cb-6b6267427b9f",
            "type": "ai_embedding",
            "index": 0
          }
        ]
      ]
    },
    "33dbd2eb-d1dc-426c-9939-45461780cffe": {
      "main": [
        [
          {
            "node": "9f12dcc8-423c-42f6-a0de-522b5897c620",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "0edf1ac5-2469-451e-81cb-6b6267427b9f": {
      "main": [
        [
          {
            "node": "f5c2d73e-fdb7-4e2c-8fae-74e2dd483b99",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "ec4c1998-6079-4a91-a8ba-b6fed99e93a7": {
      "main": [
        [
          {
            "node": "5b4cd434-4799-4981-a585-21c69d8329d5",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Foire aux questions

Comment utiliser ce workflow ?

Copiez le code de configuration JSON ci-dessus, créez un nouveau workflow dans votre instance n8n et sélectionnez "Importer depuis le JSON", collez la configuration et modifiez les paramètres d'authentification selon vos besoins.

Dans quelles scénarios ce workflow est-il adapté ?

Avancé - Création de contenu, IA Multimodale

Est-ce payant ?

Ce workflow est entièrement gratuit et peut être utilisé directement. Veuillez noter que les services tiers utilisés dans le workflow (comme l'API OpenAI) peuvent nécessiter un paiement de votre part.

Informations sur le workflow
Niveau de difficulté
Avancé
Nombre de nœuds45
Catégorie2
Types de nœuds22
Description de la difficulté

Adapté aux utilisateurs avancés, avec des workflows complexes contenant 16+ nœuds

Liens externes
Voir sur n8n.io

Partager ce workflow

Catégories

Catégories: 34