{
  "name": "Contextual Retrieval",
  "nodes": [
    {
      "parameters": {
        "model": "gpt-4.1-mini",
        "options": {}
      },
      "id": "629a895b-249f-4b04-95d8-5322c6a0f78c",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "typeVersion": 1,
      "position": [
        -680,
        980
      ],
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsonMode": "expressionData",
        "jsonData": "={{\n{\n  \"content\": `${ $json.text }\\n---\\n${ $json.chunk }`\n}\n}}",
        "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": "file_url",
                "value": "={{ $('Set File ID').first().json.file_url }}"
              }
            ]
          }
        }
      },
      "id": "b1b305cc-59d1-4b3f-9561-bc2b77a34ff3",
      "name": "Default Data Loader",
      "type": "@n8n/n8n-nodes-langchain.documentDefaultDataLoader",
      "typeVersion": 1,
      "position": [
        1460,
        1700
      ]
    },
    {
      "parameters": {
        "model": "text-embedding-3-small",
        "options": {}
      },
      "id": "03aa41f8-a136-4245-aeb0-dec739b28d23",
      "name": "Embeddings OpenAI1",
      "type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
      "typeVersion": 1,
      "position": [
        1300,
        1700
      ],
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "content": "## Tool to Add Google Drive Files to Vector DB with Contextual Embeddings",
        "height": 867,
        "width": 2853,
        "color": 5
      },
      "id": "fd7c0f3f-6040-4312-ab4f-44becbefd071",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -980,
        1180
      ]
    },
    {
      "parameters": {
        "operation": "download",
        "fileId": {
          "__rl": true,
          "value": "={{ $('Set File ID').item.json.file_id }}",
          "mode": "id"
        },
        "options": {
          "googleFileConversion": {
            "conversion": {
              "docsToFormat": "text/plain"
            }
          }
        }
      },
      "id": "d3d96ca0-a464-487a-9685-b2729bb296f4",
      "name": "Download File",
      "type": "n8n-nodes-base.googleDrive",
      "typeVersion": 3,
      "position": [
        -80,
        1440
      ],
      "executeOnce": true,
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        },
        "triggerOn": "specificFolder",
        "folderToWatch": {
          "__rl": true,
          "value": "1iLcA4aE4rOe87BNXhiArRaHkG9dfzJqw",
          "mode": "list",
          "cachedResultName": "Neon",
          "cachedResultUrl": "https://drive.google.com/drive/folders/1iLcA4aE4rOe87BNXhiArRaHkG9dfzJqw"
        },
        "event": "fileCreated",
        "options": {}
      },
      "id": "a9e45a07-5f03-4f2d-a947-e71feae2c374",
      "name": "File Created",
      "type": "n8n-nodes-base.googleDriveTrigger",
      "typeVersion": 1,
      "position": [
        -920,
        1300
      ],
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        },
        "triggerOn": "specificFolder",
        "folderToWatch": {
          "__rl": true,
          "value": "1iLcA4aE4rOe87BNXhiArRaHkG9dfzJqw",
          "mode": "list",
          "cachedResultName": "Neon",
          "cachedResultUrl": "https://drive.google.com/drive/folders/1iLcA4aE4rOe87BNXhiArRaHkG9dfzJqw"
        },
        "event": "fileUpdated",
        "options": {}
      },
      "id": "c1edc043-6c13-4161-b8c6-9d22655da94a",
      "name": "File Updated",
      "type": "n8n-nodes-base.googleDriveTrigger",
      "typeVersion": 1,
      "position": [
        -920,
        1460
      ],
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "text",
        "options": {}
      },
      "id": "ab685f23-0081-49dc-a91e-51f929e101f0",
      "name": "Extract Document Text",
      "type": "n8n-nodes-base.extractFromFile",
      "typeVersion": 1,
      "position": [
        120,
        1300
      ],
      "alwaysOutputData": true
    },
    {
      "parameters": {
        "sessionIdType": "customKey",
        "sessionKey": "={{ $(\"When chat message received\").item.json.sessionId }}"
      },
      "id": "e4f7272e-0ef4-45f5-b9cb-ada6c29a7db5",
      "name": "Postgres Chat Memory",
      "type": "@n8n/n8n-nodes-langchain.memoryPostgresChat",
      "typeVersion": 1,
      "position": [
        -500,
        980
      ],
      "notesInFlow": false,
      "credentials": {
        "postgres": {
          "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": "a4f9c240-bd71-420d-973e-5bcf19d172a1",
      "name": "Set File ID",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        -520,
        1440
      ]
    },
    {
      "parameters": {
        "content": "## RAG AI Agent with Contextual Retrieval",
        "height": 485,
        "width": 1036
      },
      "id": "d81eeed4-bbd7-4074-ba91-4976a78a1c42",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -980,
        680
      ]
    },
    {
      "parameters": {
        "options": {
          "systemMessage": "=## Role\n\nYou are a Retrieval-Augmented Generation (RAG) assistant designed to answer questions a user has. You use a corpus of documents that are all text based. Your primary goal is to provide accurate, up-to-date, and relevant information based on what the user asks and the documents you retrieve.\n\n## Responsibilities\n\n- Answer user queries with a good mix of being comprehensive but still concise\n- Present information in an easy-to-understand and professional manner  \n- Clarify misconceptions or misinformation\n\n## Other Key Information and Instructions\n\n- Always tell the user if you didn't find the answer. Don't make something up just to please them.\n- Keep your language neutral and factual. Do not show bias or opinion  \n\n## Error Handling\n- If the information cannot be found using the provided instructions respond with:  \n  \u201cI\u2019m sorry, I couldn\u2019t find relevant information based on your documents.\u201d\n"
        }
      },
      "id": "701de0d9-5ece-44da-9aa6-b4cdfeec3f88",
      "name": "RAG AI Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "typeVersion": 1.6,
      "position": [
        -600,
        760
      ]
    },
    {
      "parameters": {
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
      "typeVersion": 1.2,
      "position": [
        -160,
        1020
      ],
      "id": "1643bbef-d8c6-49d7-828e-eec86ca0df2d",
      "name": "Embeddings OpenAI2",
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "options": {
          "reset": false
        }
      },
      "type": "n8n-nodes-base.splitInBatches",
      "typeVersion": 3,
      "position": [
        -700,
        1300
      ],
      "id": "0d74aee4-7188-4e6d-8ce7-18e37a30bd5f",
      "name": "Loop Over Items"
    },
    {
      "parameters": {
        "chunkSize": 2000,
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.textSplitterRecursiveCharacterTextSplitter",
      "typeVersion": 1,
      "position": [
        1580,
        1860
      ],
      "id": "d74c50f4-99cf-49cc-9d27-b885f3bc84d9",
      "name": "Recursive Character Text Splitter"
    },
    {
      "parameters": {
        "public": true,
        "options": {}
      },
      "id": "870b78ea-00cd-4187-9cf3-72c120d592ff",
      "name": "When chat message received",
      "type": "@n8n/n8n-nodes-langchain.chatTrigger",
      "typeVersion": 1.1,
      "position": [
        -880,
        760
      ]
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const chunks = [];\nconst chunkSize = 400;\nconst chunkOverlap = 0;\nconst text = $json.data.replace(/\\n/, '');\n\nfor (let i=0, j=Math.round(text.length/chunkSize); i<j; i++) {\n  chunks.push(\n    text.substr(\n      Math.max(0,(i * chunkSize)-chunkOverlap),\n      chunkSize\n    )\n  );\n}\n\nreturn { chunks };"
      },
      "id": "714947e8-e62a-4c3e-b454-35ff2fb28037",
      "name": "Create Chunks From Doc",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        360,
        1460
      ]
    },
    {
      "parameters": {
        "fieldToSplitOut": "chunks",
        "options": {
          "destinationFieldName": "chunk"
        }
      },
      "id": "e4b50ede-9e2e-4a58-9929-831a66a2fa63",
      "name": "Chunks To List",
      "type": "n8n-nodes-base.splitOut",
      "typeVersion": 1,
      "position": [
        580,
        1320
      ]
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "=<document> \n{{ $('Extract Document Text').first().json.data }} \n</document>\nHere is the chunk we want to situate within the whole document \n<chunk> \n{{ $json.chunk }}\n</chunk> \nPlease give a short succinct context to situate this chunk within the overall document for the purposes of improving search retrieval of the chunk. Answer only with the succinct context and nothing else. "
      },
      "id": "2337b1e4-cb00-4e2b-b0df-7eb2e3cd2a43",
      "name": "Generate Contextual Text",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "typeVersion": 1.4,
      "position": [
        800,
        1460
      ]
    },
    {
      "parameters": {
        "model": {
          "__rl": true,
          "value": "gpt-4.1-nano",
          "mode": "list",
          "cachedResultName": "gpt-4.1-nano"
        },
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "typeVersion": 1.2,
      "position": [
        760,
        1700
      ],
      "id": "49a94474-d8c8-4d6a-a62d-27e5e16945cb",
      "name": "OpenAI Chat Model3",
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "069d067c-3534-4939-8ff4-34dee02a9436",
              "name": "chunk",
              "value": "={{ $('Chunks To List').item.json.chunk }}",
              "type": "string"
            },
            {
              "id": "24e01f4f-e156-47e9-a89e-9cbdccda6bd4",
              "name": "text",
              "value": "={{ $('Generate Contextual Text').item.json.text }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "id": "4a569383-b3b6-470f-a567-df168ac22400",
      "name": "Get Values",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        1160,
        1340
      ]
    },
    {
      "parameters": {
        "mode": "insert",
        "tableName": "documents_pg",
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.vectorStorePGVector",
      "typeVersion": 1.1,
      "position": [
        1380,
        1440
      ],
      "id": "f188cb0e-64cb-4389-a97e-bd53f82bab48",
      "name": "Postgres PGVector Store",
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "mode": "retrieve-as-tool",
        "toolName": "documents_pg",
        "toolDescription": "Use RAG to look up information in the knowledgebase.",
        "tableName": "documents_pg",
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.vectorStorePGVector",
      "typeVersion": 1.1,
      "position": [
        -280,
        880
      ],
      "id": "10bf0453-c3a8-4584-8209-65e79a542b45",
      "name": "Document RAG Tool1",
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "DO $$\nBEGIN\n    IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'documents_pg') THEN\n        EXECUTE 'DELETE FROM documents_pg WHERE metadata->>''file_id'' LIKE ''%' || $1 || '%''';\n    END IF;\nEND\n$$;",
        "options": {
          "queryReplacement": "={{ $json.file_id }}"
        }
      },
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.5,
      "position": [
        -300,
        1300
      ],
      "id": "48754246-3a5d-4a4d-a815-b77ad68242e4",
      "name": "Delete Old Doc Records",
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    }
  ],
  "connections": {
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "RAG AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Download File": {
      "main": [
        [
          {
            "node": "Extract Document Text",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "File Created": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Document Text": {
      "main": [
        [
          {
            "node": "Create Chunks From Doc",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Embeddings OpenAI1": {
      "ai_embedding": [
        [
          {
            "node": "Postgres PGVector Store",
            "type": "ai_embedding",
            "index": 0
          }
        ]
      ]
    },
    "Default Data Loader": {
      "ai_document": [
        [
          {
            "node": "Postgres PGVector Store",
            "type": "ai_document",
            "index": 0
          }
        ]
      ]
    },
    "Postgres Chat Memory": {
      "ai_memory": [
        [
          {
            "node": "RAG AI Agent",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "Set File ID": {
      "main": [
        [
          {
            "node": "Delete Old Doc Records",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "File Updated": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Embeddings OpenAI2": {
      "ai_embedding": [
        [
          {
            "node": "Document RAG Tool1",
            "type": "ai_embedding",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items": {
      "main": [
        [],
        [
          {
            "node": "Set File ID",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Recursive Character Text Splitter": {
      "ai_textSplitter": [
        [
          {
            "node": "Default Data Loader",
            "type": "ai_textSplitter",
            "index": 0
          }
        ]
      ]
    },
    "When chat message received": {
      "main": [
        [
          {
            "node": "RAG AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Chunks To List": {
      "main": [
        [
          {
            "node": "Generate Contextual Text",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Chunks From Doc": {
      "main": [
        [
          {
            "node": "Chunks To List",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model3": {
      "ai_languageModel": [
        [
          {
            "node": "Generate Contextual Text",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Generate Contextual Text": {
      "main": [
        [
          {
            "node": "Get Values",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Values": {
      "main": [
        [
          {
            "node": "Postgres PGVector Store",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Postgres PGVector Store": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Document RAG Tool1": {
      "ai_tool": [
        [
          {
            "node": "RAG AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Delete Old Doc Records": {
      "main": [
        [
          {
            "node": "Download File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "bf4b5d55-ee85-4bac-ba54-8212c00dba4f",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "id": "Tbo3PW1c2qp2gZJi",
  "tags": []
}