AutomationFlowsAI & RAG › AI Chat Agent with Memory & Vector Store

AI Chat Agent with Memory & Vector Store

Original n8n title: Insightslm - Chat

InsightsLM - Chat. Uses agent, memoryPostgresChat, vectorStoreSupabase, embeddingsOpenAi. Webhook trigger; 11 nodes.

Webhook trigger★★★☆☆ complexityAI-powered11 nodesAgentMemory Postgres ChatSupabase Vector StoreOpenAI EmbeddingsOutput Parser StructuredGoogle Gemini ChatAnthropic ChatOpenAI Chat
AI & RAG Trigger: Webhook Nodes: 11 Complexity: ★★★☆☆ AI nodes: yes Added:

This workflow follows the Agent → OpenAI Embeddings recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "name": "InsightsLM - Chat",
  "nodes": [
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "2fabf43f-6e6e-424b-8e93-9150e9ce7d6c",
        "authentication": "headerAuth",
        "options": {}
      },
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        -780,
        -320
      ],
      "id": "8720544c-77dd-4c95-85aa-bc46792f8f52",
      "name": "Webhook",
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "model": "qwen3:8b-q4_K_M",
        "options": {
          "format": "json"
        }
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatOllama",
      "typeVersion": 1,
      "position": [
        -120,
        100
      ],
      "id": "ae40613a-1713-4c65-a204-85ad4e05a93f",
      "name": "Ollama Chat Model",
      "credentials": {
        "ollamaApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsonSchemaExample": "{\n\t\"search_query\": \"<ADD>\"\n}",
        "autoFix": true
      },
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "typeVersion": 1.3,
      "position": [
        40,
        -80
      ],
      "id": "6f097c3f-fe56-4636-9c75-ea1ec3d17b7e",
      "name": "Structured Output Parser1"
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "=User Query: {{ $('Webhook').item.json.body.message }}\n\nConversation History: {{ JSON.stringify($json.data.slice(0,10))  }}",
        "hasOutputParser": true,
        "messages": {
          "messageValues": [
            {
              "message": "=Based on the provided user query and taking into context the conversation history, output a serach query that we can send to our vector database to retrieve relevant chunks of text"
            }
          ]
        },
        "batching": {}
      },
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "typeVersion": 1.7,
      "position": [
        -40,
        -320
      ],
      "id": "81189f62-f5f9-4396-bb80-22f3c9591c31",
      "name": "Generate Search Query"
    },
    {
      "parameters": {
        "mode": "load",
        "tableName": {
          "__rl": true,
          "value": "documents",
          "mode": "list",
          "cachedResultName": "documents"
        },
        "prompt": "={{ $json.output.search_query }}",
        "topK": 10,
        "options": {
          "metadata": {
            "metadataValues": [
              {
                "name": "notebook_id",
                "value": "={{ $('Webhook').item.json.body.session_id }}"
              }
            ]
          }
        }
      },
      "type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
      "typeVersion": 1.3,
      "position": [
        320,
        -320
      ],
      "id": "e6d5c9fa-a280-4b09-bc33-42945a42df7b",
      "name": "Supabase Vector Store1",
      "credentials": {
        "supabaseApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "model": "nomic-embed-text:latest"
      },
      "type": "@n8n/n8n-nodes-langchain.embeddingsOllama",
      "typeVersion": 1,
      "position": [
        380,
        -100
      ],
      "id": "c10decbe-3270-427f-be01-a1bf122286b2",
      "name": "Embeddings Ollama",
      "credentials": {
        "ollamaApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "aggregate": "aggregateAllItemData",
        "options": {}
      },
      "type": "n8n-nodes-base.aggregate",
      "typeVersion": 1,
      "position": [
        960,
        -320
      ],
      "id": "b6668ad1-3257-4e51-b34b-efe843e8cf2c",
      "name": "Aggregate"
    },
    {
      "parameters": {
        "jsonSchemaExample": "{\n\t\"output\": [\n      {\"sentence_paragraph_with_citation\": \"<ADD>\"},\n      {\"sentence_paragraph_with_citation\": \"<ADD>\"}\n    ]\n}",
        "autoFix": true
      },
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "typeVersion": 1.3,
      "position": [
        1340,
        -120
      ],
      "id": "4538519d-5d0f-4ed4-9d9f-597d64df3811",
      "name": "Structured Output Parser2"
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "=# User Query\n{{ $('Webhook').item.json.body.message }}\n\n# Conversation History \n{{ $('Aggregate1').item.json.data }}\n\n# Retrieved Chunks from Knowledgebase\n{{ JSON.stringify($json.data) }}",
        "hasOutputParser": true,
        "messages": {
          "messageValues": [
            {
              "message": "=# ROLE\n\nYou are tasked with answering a users question, in the context of a conversation, using provided chunks of information. \n\nYour goal is to provide an accurate answer from these chunks while citing your sources using the following syntax. \n\nBe as detailed as possible\n\n[0] \n\nWhere the number refers to the chunk_id of the specifc chunks that contains the information.\n\n## Example:\n\nMastering the foundational techniques for your serve, forehand, and backhand is crucial for developing overall tennis proficiency, as these techniques directly impact your ability to generate power, control, consistency, accuracy, spin, leverage, and prevent injuries.[2]\n\nThe serve is detailed through five steps: Grip, Ball Toss, Trophy Position, Pronation, and Follow Through and Finish [0][7]\n\nGrip: Using the continental grip (also known as the chopper grip) is fundamental for serve proficiency. It is the same grip used for slices, forehand and backhand volleys, and the overhead smash. [9]\n\nThe citation(s) should appear at the end of the sentence or paragraph where the information is used.\n\n# IMPORTANT\n\nOutput in JSON format\nImportant: Only based your answers on information in the provided chunks from the vector store or conversation history\nImportant: If you cannot answer the question using the provided chunks, set the response value as \"Sorry I don't know\".\nImportant: You MUST trigger the \"Supabase Vector Store\" tool every time"
            }
          ]
        },
        "batching": {}
      },
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "typeVersion": 1.7,
      "position": [
        1220,
        -320
      ],
      "id": "d7858d60-9fb0-4046-9b46-3b38aaa0b026",
      "name": "Generate Response"
    },
    {
      "parameters": {
        "model": "qwen3:8b-q4_K_M",
        "options": {
          "temperature": 0.4,
          "format": "json"
        }
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatOllama",
      "typeVersion": 1,
      "position": [
        1200,
        80
      ],
      "id": "518def0e-733e-4a59-b76e-b949d4946a9c",
      "name": "Ollama Chat Model1",
      "credentials": {
        "ollamaApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// Loop over input items and transform the citation format\nfor (const item of $input.all()) {\n  // Assuming chunks are available in item.json.chunks \n  // If chunks come from a different input, modify this line accordingly\n  const chunks = $('Aggregate').first().json.data || [];\n  \n  if (item.json.output && Array.isArray(item.json.output)) {\n    const transformedOutput = [];\n    \n    for (const outputItem of item.json.output) {\n      if (outputItem.sentence_paragraph_with_citation) {\n        const textWithCitations = outputItem.sentence_paragraph_with_citation;\n        \n        // Extract citation indices using regex to find [0], [1], etc.\n        const citationMatches = textWithCitations.match(/\\[(\\d+)\\]/g) || [];\n        const citationIndices = citationMatches.map(match => parseInt(match.replace(/[\\[\\]]/g, '')));\n        \n        // Remove citations from text to get clean text\n        const cleanText = textWithCitations.replace(/\\s*\\[\\d+\\]/g, '').trim();\n        \n        // Build citations array\n        const citations = [];\n        const processedIndices = new Set(); // To avoid duplicates\n        \n        for (const citationId of citationIndices) {\n          if (!processedIndices.has(citationId)) {\n            // Find chunk by chunk_id instead of using array index\n            const chunkItem = chunks.find(chunkItem => chunkItem.chunk_id === citationId);\n            \n            if (chunkItem && chunkItem.document) {\n              const chunk = chunkItem.document;\n              const metadata = chunk.metadata;\n              \n              citations.push({\n                chunk_index: citationId,\n                chunk_source_id: metadata.source_id,\n                chunk_lines_from: metadata.loc.lines.from,\n                chunk_lines_to: metadata.loc.lines.to\n              });\n              processedIndices.add(citationId);\n            }\n          }\n        }\n        \n        transformedOutput.push({\n          text: cleanText,\n          citations: citations\n        });\n      }\n    }\n    \n    // Create the exact output format you specified\n    item.json.output = {\n      type: \"ai\",\n      content: JSON.stringify({\n        output: transformedOutput\n      }),\n      tool_calls: [],\n      additional_kwargs: {},\n      response_metadata: {},\n      invalid_tool_calls: []\n    };\n  }\n}\n\nreturn $input.all();"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1580,
        -320
      ],
      "id": "648bd6ac-84d4-48da-bc33-7c8768f97c2c",
      "name": "Create Output Structure with Citations"
    },
    {
      "parameters": {
        "tableId": "n8n_chat_histories",
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldId": "session_id",
              "fieldValue": "={{ $('Webhook').item.json.body.session_id }}"
            },
            {
              "fieldId": "message",
              "fieldValue": "={{ $json.human }}"
            }
          ]
        }
      },
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        2040,
        -320
      ],
      "id": "1e45e3e9-f9f4-43e0-b2ef-46ec66a03e6d",
      "name": "Save Human Query",
      "alwaysOutputData": true,
      "credentials": {
        "supabaseApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "tableId": "n8n_chat_histories",
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldId": "session_id",
              "fieldValue": "={{ $('Webhook').item.json.body.session_id }}"
            },
            {
              "fieldId": "message",
              "fieldValue": "={{ $('Create Output Structure with Citations').item.json.output }}"
            }
          ]
        }
      },
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        2460,
        -320
      ],
      "id": "8ca8de19-928e-440e-b548-5d38828e1805",
      "name": "Save AI Response",
      "alwaysOutputData": true,
      "credentials": {
        "supabaseApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "amount": 1
      },
      "type": "n8n-nodes-base.wait",
      "typeVersion": 1.1,
      "position": [
        2260,
        -320
      ],
      "id": "0c66af07-1f85-45df-a72a-3e23c570b6ff",
      "name": "Wait"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "106e9fbb-8fe2-4bc0-8f91-50687c4ac2dd",
              "name": "human",
              "value": "={\"type\": \"human\", \"content\": {{ JSON.stringify(($('Webhook').item.json.body.message)) }}, \"additional_kwargs\": {}, \"response_metadata\": {}}",
              "type": "object"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        1800,
        -320
      ],
      "id": "9c75dec2-7ed4-41d1-8914-6f61541f9e32",
      "name": "Edit Fields"
    },
    {
      "parameters": {
        "jsCode": "// Loop over input items and add 'id' as the first field\n$input.all().forEach((item, index) => {\n  // Create a new object with id first, then spread the existing properties\n  item.json = {\n    chunk_id: index + 1,\n    ...item.json\n  };\n});\n\nreturn $input.all();"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        680,
        -320
      ],
      "id": "adc1814e-e4f8-4eea-895d-ae82c74dd90b",
      "name": "Code"
    },
    {
      "parameters": {
        "operation": "getAll",
        "tableId": "n8n_chat_histories",
        "returnAll": true,
        "filters": {
          "conditions": [
            {
              "keyName": "session_id",
              "condition": "eq",
              "keyValue": "={{ $json.body.session_id }}"
            }
          ]
        }
      },
      "type": "n8n-nodes-base.supabase",
      "typeVersion": 1,
      "position": [
        -560,
        -320
      ],
      "id": "e5526eaa-09e4-46c2-9c75-0b6600014ec0",
      "name": "Fetch Chat History",
      "alwaysOutputData": true,
      "credentials": {
        "supabaseApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "aggregate": "aggregateAllItemData",
        "options": {}
      },
      "type": "n8n-nodes-base.aggregate",
      "typeVersion": 1,
      "position": [
        -320,
        -320
      ],
      "id": "51ef9ec1-8f89-4835-991f-bde7373121d8",
      "name": "Aggregate1"
    },
    {
      "parameters": {
        "content": "[![The AI Automators](https://www.theaiautomators.com/wp-content/uploads/2025/03/gray-logo.png)](https://www.theaiautomators.com/)\n## InsightsLM Local - Chat\nhttps://github.com/theaiautomators/insights-lm-public\nhttps://github.com/theaiautomators/insights-lm-local-package",
        "height": 260,
        "width": 320,
        "color": 7
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -780,
        -680
      ],
      "id": "3be1ba88-4f52-4f17-8444-3c05fc98df3f",
      "name": "Sticky Note8"
    }
  ],
  "connections": {
    "Webhook": {
      "main": [
        [
          {
            "node": "Fetch Chat History",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Ollama Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Generate Search Query",
            "type": "ai_languageModel",
            "index": 0
          },
          {
            "node": "Structured Output Parser1",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser1": {
      "ai_outputParser": [
        [
          {
            "node": "Generate Search Query",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Generate Search Query": {
      "main": [
        [
          {
            "node": "Supabase Vector Store1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Embeddings Ollama": {
      "ai_embedding": [
        [
          {
            "node": "Supabase Vector Store1",
            "type": "ai_embedding",
            "index": 0
          }
        ]
      ]
    },
    "Supabase Vector Store1": {
      "main": [
        [
          {
            "node": "Code",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate": {
      "main": [
        [
          {
            "node": "Generate Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser2": {
      "ai_outputParser": [
        [
          {
            "node": "Generate Response",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Ollama Chat Model1": {
      "ai_languageModel": [
        [
          {
            "node": "Generate Response",
            "type": "ai_languageModel",
            "index": 0
          },
          {
            "node": "Structured Output Parser2",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Generate Response": {
      "main": [
        [
          {
            "node": "Create Output Structure with Citations",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Output Structure with Citations": {
      "main": [
        [
          {
            "node": "Edit Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Save Human Query": {
      "main": [
        [
          {
            "node": "Wait",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait": {
      "main": [
        [
          {
            "node": "Save AI Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Edit Fields": {
      "main": [
        [
          {
            "node": "Save Human Query",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code": {
      "main": [
        [
          {
            "node": "Aggregate",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Chat History": {
      "main": [
        [
          {
            "node": "Aggregate1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate1": {
      "main": [
        [
          {
            "node": "Generate Search Query",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "847a2686-5464-4cad-b823-517b26de76d9",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "id": "fMscTRsbgnrUFZ2S",
  "tags": [
    {
      "createdAt": "2025-07-01T11:04:36.330Z",
      "updatedAt": "2025-07-01T11:04:36.330Z",
      "id": "Wki6TfWIHzQoLAWa",
      "name": "TheAIAutomators.com"
    }
  ]
}

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.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

InsightsLM - Chat. Uses agent, memoryPostgresChat, vectorStoreSupabase, embeddingsOpenAi. Webhook trigger; 11 nodes.

Source: https://github.com/theaiautomators/insights-lm-public/blob/76cf9d808056c3b7afac3c1cb9bd180014ff6f64/n8n/InsightsLM___Chat.json — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

Chatbot Webhook. Uses lmChatGoogleGemini, agent, outputParserStructured, memoryPostgresChat. Webhook trigger; 14 nodes.

Google Gemini Chat, Agent, Output Parser Structured +4
AI & RAG

RagBook - Chat. Uses agent, memoryPostgresChat, vectorStoreSupabase, embeddingsOpenAi. Webhook trigger; 11 nodes.

Agent, Memory Postgres Chat, Supabase Vector Store +5
AI & RAG

Indoor Farming Agent. Uses lmChatOpenAi, documentDefaultDataLoader, embeddingsOpenAi, toolVectorStore. Webhook trigger; 36 nodes.

OpenAI Chat, Document Default Data Loader, OpenAI Embeddings +16
AI & RAG

AI-powered n8n workflow that creates viral LinkedIn posts by learning from successful content. Features two modules: (1) Telegram-based scraper that builds a vector database of viral LinkedIn posts, a

Telegram Trigger, Telegram, HTTP Request +9
AI & RAG

RAG_AI_Agent_PDFs_Excel. Uses lmChatOpenAi, documentDefaultDataLoader, embeddingsOpenAi, toolVectorStore. Webhook trigger; 28 nodes.

OpenAI Chat, Document Default Data Loader, OpenAI Embeddings +7