AutomationFlowsAI & RAG › Build a Documentation Expert Chatbot with Gemini RAG

Build a Documentation Expert Chatbot with Gemini RAG

Original n8n title: 🤖 Build a Documentation Expert Chatbot with Gemini RAG Pipeline

ByLucas Peyrin @lucaspeyrin on n8n.io

This template is a complete, hands-on tutorial for building a RAG (Retrieval-Augmented Generation) pipeline. In simple terms, you'll teach an AI to become an expert on a specific topic—in this case, the official n8n documentation—and then build a chatbot to ask it questions.

Event trigger★★★★★ complexityAI-powered48 nodesMemory Buffer WindowDocument Default Data LoaderText Splitter Recursive Character Text SplitterGoogle Gemini ChatHTTP RequestGoogle Gemini EmbeddingsAgentChat Trigger
AI & RAG Trigger: Event Nodes: 48 Complexity: ★★★★★ AI nodes: yes Added:

This workflow corresponds to n8n.io template #6137 — we link there as the canonical source.

This workflow follows the Agent → Chat Trigger 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
{
  "nodes": [
    {
      "id": "26bd501a-d449-4bbf-aa25-a02e5cca7964",
      "name": "Simple Memory",
      "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
      "notes": "\u00a9 2025 Lucas Peyrin",
      "position": [
        -768,
        320
      ],
      "parameters": {},
      "typeVersion": 1.3
    },
    {
      "id": "2916c373-0c6b-4315-a14d-481d674a324f",
      "name": "Default Data Loader",
      "type": "@n8n/n8n-nodes-langchain.documentDefaultDataLoader",
      "notes": "\u00a9 2025 Lucas Peyrin",
      "position": [
        944,
        -1200
      ],
      "parameters": {
        "options": {},
        "jsonData": "={{ $json.documentation }}",
        "jsonMode": "expressionData",
        "textSplittingMode": "custom"
      },
      "typeVersion": 1.1
    },
    {
      "id": "8b411025-ad1f-4656-84d7-902ced049923",
      "name": "Recursive Character Text Splitter",
      "type": "@n8n/n8n-nodes-langchain.textSplitterRecursiveCharacterTextSplitter",
      "notes": "\u00a9 2025 Lucas Peyrin",
      "position": [
        1040,
        -992
      ],
      "parameters": {
        "options": {
          "splitCode": "markdown"
        },
        "chunkSize": 1500,
        "chunkOverlap": 200
      },
      "typeVersion": 1
    },
    {
      "id": "4855516e-4a0d-4881-8dc4-592cf8b133a9",
      "name": "Remove Duplicate Documentation Content",
      "type": "n8n-nodes-base.removeDuplicates",
      "notes": "\u00a9 2025 Lucas Peyrin",
      "position": [
        320,
        -1424
      ],
      "parameters": {
        "options": {
          "scope": "node",
          "historySize": 10000
        },
        "operation": "removeItemsSeenInPreviousExecutions",
        "dedupeValue": "={{ $json.documentation }}"
      },
      "typeVersion": 2
    },
    {
      "id": "a33a791a-e328-46fc-890e-e18649ab2231",
      "name": "Only Keep Doc Paths",
      "type": "n8n-nodes-base.filter",
      "notes": "\u00a9 2025 Lucas Peyrin",
      "position": [
        448,
        -2192
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "52b8b89a-30cd-4a0d-a428-e5d341bcebbf",
              "operator": {
                "type": "string",
                "operation": "endsWith"
              },
              "leftValue": "={{ $json.link }}",
              "rightValue": "/"
            },
            {
              "id": "d8019c4e-e1a1-43ec-93a8-dac3d8c083b6",
              "operator": {
                "type": "string",
                "operation": "notStartsWith"
              },
              "leftValue": "={{ $json.link }}",
              "rightValue": "https://"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "b07b416b-f5cd-439a-b935-ce58c2a2f180",
      "name": "Clean Documentation",
      "type": "n8n-nodes-base.set",
      "notes": "\u00a9 2025 Lucas Peyrin",
      "position": [
        -112,
        -1424
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "5ed964a6-5200-454c-b983-f3dc7c8c7a48",
              "name": "documentation",
              "type": "string",
              "value": "={{ $json.data.replace(/([^#\\n]+)\\s*#/g, '# $1').trim().replace(/^\\s*https?:\\/\\/\\S+\\s*/, '') }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "4198449e-feb7-43f2-be23-e8581ff9fd98",
      "name": "Gemini 2.5 Flash",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "notes": "\u00a9 2025 Lucas Peyrin",
      "position": [
        -1120,
        320
      ],
      "parameters": {
        "options": {
          "temperature": 0
        }
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "e1bad122-5df4-4018-8b50-fc67f70b55b7",
      "name": "Get All n8n Documentation Links",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "\u00a9 2025 Lucas Peyrin",
      "position": [
        -704,
        -2192
      ],
      "parameters": {
        "url": "https://docs.n8n.io/",
        "options": {}
      },
      "typeVersion": 4.2
    },
    {
      "id": "626cf083-8ae3-4e28-96d2-92b01f6d36cd",
      "name": "Extract Links from HTML",
      "type": "n8n-nodes-base.html",
      "notes": "\u00a9 2025 Lucas Peyrin",
      "position": [
        -416,
        -2192
      ],
      "parameters": {
        "options": {},
        "operation": "extractHtmlContent",
        "extractionValues": {
          "values": [
            {
              "key": "links",
              "attribute": "href",
              "cssSelector": "a",
              "returnArray": true,
              "returnValue": "attribute"
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "e980ad18-7857-4603-8e01-9a98520dd874",
      "name": "Split Out Links",
      "type": "n8n-nodes-base.splitOut",
      "notes": "\u00a9 2025 Lucas Peyrin",
      "position": [
        -80,
        -2192
      ],
      "parameters": {
        "options": {
          "destinationFieldName": "link"
        },
        "fieldToSplitOut": "links"
      },
      "typeVersion": 1
    },
    {
      "id": "2b441068-ead3-4114-baca-f26f95c2c2eb",
      "name": "Remove Duplicate Links",
      "type": "n8n-nodes-base.removeDuplicates",
      "notes": "\u00a9 2025 Lucas Peyrin",
      "position": [
        224,
        -2192
      ],
      "parameters": {
        "compare": "selectedFields",
        "options": {},
        "fieldsToCompare": "link"
      },
      "typeVersion": 2
    },
    {
      "id": "a9196d50-2a7a-4733-b6e4-2cb03a5cda46",
      "name": "Add Documentation Page to Vector Store",
      "type": "n8n-nodes-base.executeWorkflow",
      "notes": "\u00a9 2025 Lucas Peyrin",
      "position": [
        960,
        -2160
      ],
      "parameters": {
        "options": {
          "waitForSubWorkflow": true
        },
        "workflowId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $workflow.id }}"
        },
        "workflowInputs": {
          "value": {},
          "schema": [
            {
              "id": "path",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "path",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "data"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": true
        }
      },
      "typeVersion": 1.2,
      "alwaysOutputData": true
    },
    {
      "id": "1c772047-a2f9-427a-b090-dbf00a257c9c",
      "name": "Get Documentation Page",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "\u00a9 2025 Lucas Peyrin",
      "onError": "continueErrorOutput",
      "position": [
        -640,
        -1424
      ],
      "parameters": {
        "url": "=https://docs.n8n.io/{{ $json.link }}",
        "options": {}
      },
      "typeVersion": 4.2
    },
    {
      "id": "d7cd75ad-e76d-45c7-8791-e6b9cf0e2106",
      "name": "Extract Documentation Content",
      "type": "n8n-nodes-base.html",
      "notes": "\u00a9 2025 Lucas Peyrin",
      "position": [
        -336,
        -1424
      ],
      "parameters": {
        "options": {},
        "operation": "extractHtmlContent",
        "extractionValues": {
          "values": [
            {
              "key": "data",
              "cssSelector": "article",
              "skipSelectors": "img, footer, form"
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "5ac3f64f-0340-4a98-bace-1c156021a919",
      "name": "Gemini Query Embedding",
      "type": "@n8n/n8n-nodes-langchain.embeddingsGoogleGemini",
      "notes": "\u00a9 2025 Lucas Peyrin",
      "position": [
        -400,
        512
      ],
      "parameters": {},
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "cbcc6097-c4a7-45d4-a852-5ab69d8f1e14",
      "name": "Gemini Chunk Embedding",
      "type": "@n8n/n8n-nodes-langchain.embeddingsGoogleGemini",
      "notes": "\u00a9 2025 Lucas Peyrin",
      "position": [
        816,
        -1200
      ],
      "parameters": {},
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "ba1f2848-bd94-4180-8edd-38150cda7f0b",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1296,
        -2544
      ],
      "parameters": {
        "color": 7,
        "width": 2640,
        "height": 1760,
        "content": "## Part 1: Building the Knowledge Base (The Library)\n\n**Goal:** To read all n8n documentation, break it into small pieces, and store it in n8n's **in-memory vector store**.\n**Action:** You only need to run this part **ONCE** per n8n session by clicking the \"Execute workflow\" button on the `Start Indexing` trigger.\n**Time:** This will take several minutes to complete (~15 to 20).\n\n**Important:** The in-memory store is not permanent. If you restart n8n, you must run this indexing flow again to rebuild the knowledge base."
      },
      "typeVersion": 1
    },
    {
      "id": "3cda1636-2dfd-46c0-8d82-d072e7be673e",
      "name": "Loop Over Documentation Pages",
      "type": "n8n-nodes-base.splitInBatches",
      "notes": "\u00a9 2025 Lucas Peyrin",
      "position": [
        736,
        -2192
      ],
      "parameters": {
        "options": {},
        "batchSize": 10
      },
      "typeVersion": 3
    },
    {
      "id": "ffa9c491-00d0-4c70-8a59-64f627b6468f",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2256,
        -3088
      ],
      "parameters": {
        "color": 6,
        "width": 1064,
        "height": 520,
        "content": "# Tutorial: Build an AI Expert with RAG\n\nWelcome! This workflow teaches you **RAG (Retrieval-Augmented Generation)** using n8n's built-in tools.\n\n**The Goal:** To create an AI chatbot that is an expert on a specific topic (the n8n docs) and *never* makes up answers.\n\n**It has two parts:**\n1.  **TOP FLOW (Indexing):** You run this once manually to build the AI's knowledge base. It reads the n8n docs and stores them in n8n's **in-memory vector store**.\n2.  **BOTTOM FLOW (Chat):** This is the live chatbot. It retrieves relevant info from the knowledge base to answer your questions accurately.\n\n---\n\n### Automate your operations today\nYour time is valuable. Let us automate the boring stuff for you.\n\n**\ud83d\udc47 CHOOSE YOUR PATH:**\n\n[ **\u26a1\ufe0f I WANT A FREE AUDIT (2 min)** ](https://workflows.ac/audit?utm_source=n8n_template&utm_medium=workflow_note&utm_campaign=build_a_documentation_expert_chatbot_with_gemini_rag_pipeline&utm_content=6137)\n> *We've put our heart into this business evaluation machine.*\n\n[ **\ud83d\udca1 I HAVE A SPECIFIC REQUEST** ](https://workflows.ac/form?utm_source=n8n_template&utm_medium=workflow_note&utm_campaign=build_a_documentation_expert_chatbot_with_gemini_rag_pipeline&utm_content=6137)\n"
      },
      "typeVersion": 1
    },
    {
      "id": "6f33666c-868b-4032-99c6-9844a809a587",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2256,
        -2544
      ],
      "parameters": {
        "color": 7,
        "width": 924,
        "height": 1392,
        "content": "# Workflow Setup"
      },
      "typeVersion": 1
    },
    {
      "id": "6b8d3bba-6a47-4dc6-b970-219a35863782",
      "name": "n8n Docs AI Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "notes": "\u00a9 2025 Lucas Peyrin",
      "position": [
        -752,
        -288
      ],
      "parameters": {
        "options": {
          "systemMessage": "=<role>\nYou are a specialized AI assistant, an expert in n8n's official documentation. Your sole mission is to help users by providing accurate and factual information extracted exclusively from this documentation. You are meticulous, factual, and never deviate from your knowledge scope.\n</role>\n\n<instructions>\n<goal>\nYour primary goal is to provide precise and factual answers to user questions about the n8n automation platform, based **exclusively** on the excerpts from the official documentation provided in the context.\n</goal>\n\n<context>\nYou operate according to a RAG (Retrieval-Augmented Generation) model. For each user question, use the appropriate tool to retrieve the necessary information from the n8n documentation's vector database.\n\n**Mandatory rules:**\n\n1.  **Single source of truth:** Your answer MUST be entirely and solely derived from the information present in the provided documentation.\n2.  **Accuracy and implicit citation:** Base your answer as literally as possible on the documentation text. Rephrase for clarity and conciseness, but do not add any information not found there. Act as if the documentation is your only knowledge in the world.\n3.  **Do not mention the process:** Never mention your tool or the fact that you are a RAG system in your answer to the user. Respond as an expert who directly consults their documentation.\n</context>\n\n<output_format>\n*   **Clarity:** Provide a clear, concise, and direct answer.\n*   **Structuring:** If the context contains steps, lists, or code examples, use Markdown syntax to format them legibly (bullet points, numbered lists, code blocks for code snippets, JSON, etc.).\n*   **Tone:** Adopt a professional, helpful, and confident tone, that of a technical n8n expert.\n</output_format>\n</instructions>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "6a7912bb-20a6-44bc-ab08-7a1e227797ab",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -800,
        -2400
      ],
      "parameters": {
        "color": 7,
        "width": 288,
        "height": 400,
        "content": "### Step 1.1: Find All the 'Books'\n\n**What it does:** This node visits the main n8n documentation page.\n**Analogy:** We're asking the library's front desk for a complete list of every single book they have."
      },
      "typeVersion": 1
    },
    {
      "id": "a094ca81-3cb1-42b3-bcce-202da80ac5ea",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -496,
        -2400
      ],
      "parameters": {
        "color": 7,
        "width": 272,
        "height": 400,
        "content": "### Step 1.2: Read the List of Books\n\n**What it does:** It takes the HTML from the previous step and extracts every single link (`<a>` tag).\n**Analogy:** We're reading the list from the front desk and pulling out just the titles of the books (the links)."
      },
      "typeVersion": 1
    },
    {
      "id": "d3c9c411-34fb-4f5e-a46e-a1cfb5130f53",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -208,
        -2400
      ],
      "parameters": {
        "color": 7,
        "width": 336,
        "height": 400,
        "content": "### Step 1.3: Process One Book at a Time\n\n**What it does:** It takes the big list of links and turns each link into a separate item for n8n to process.\n**Analogy:** Instead of trying to read all the books at once, we're creating a separate to-do item for each book."
      },
      "typeVersion": 1
    },
    {
      "id": "0cec3147-5420-4f89-8dd9-b49462e6a631",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        144,
        -2400
      ],
      "parameters": {
        "color": 7,
        "width": 480,
        "height": 400,
        "content": "### Step 1.4: Tidy Up the To-Do List\n\n**What it does:** First, it removes any duplicate links. Then, it filters out any links that don't point to an actual documentation page (e.g., links to the homepage or external sites).\n**Analogy:** We're throwing away duplicate to-do items and any notes that aren't actually books."
      },
      "typeVersion": 1
    },
    {
      "id": "abf15718-553e-4226-8e85-28a7e2864c34",
      "name": "Sticky Note10",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        640,
        -2400
      ],
      "parameters": {
        "color": 4,
        "width": 512,
        "height": 464,
        "content": "### Step 1.5: The Librarian's Reading Loop\n\n**What it does:** This is the engine of the indexing process. It takes our clean list of pages and processes them one by one. The `Execute Workflow` node calls the \"sub-workflow\" below for each and every page.\n**Analogy:** This loop tells our librarian to pick up one book (link) at a time and go through the full process of reading and indexing it."
      },
      "typeVersion": 1
    },
    {
      "id": "162390aa-5dfa-4e2d-ad27-59bd00eea840",
      "name": "Sticky Note11",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -736,
        -1632
      ],
      "parameters": {
        "color": 7,
        "width": 288,
        "height": 384,
        "content": "### Step 1.5.1: Read a Single Page\n\n**What it does:** This node takes a single URL from the loop and fetches the HTML content of that page.\n**Analogy:** The librarian opens one book to the first page."
      },
      "typeVersion": 1
    },
    {
      "id": "c516a2da-d6c1-4da7-8a30-4540af69c2f0",
      "name": "Sticky Note12",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1264,
        -1776
      ],
      "parameters": {
        "color": 5,
        "width": 512,
        "height": 528,
        "content": "### Why Use a Sub-Workflow?\n\nThe main reason is **memory management**.\n\nProcessing a single web page, especially creating vector embeddings for all its chunks, uses a lot of memory (RAM). The n8n documentation has over 1,000 pages. If we tried to process all of them in a single, linear run, the memory usage would build up with each page and would likely crash your n8n instance.\n\nWhen a sub-workflow finishes its run for one item (one page), n8n **clears out the memory** (RAM) it used before starting the next one.\n\nBy using a sub-workflow, we process pages one-by-one in a memory-efficient loop, making the entire indexing process stable and reliable, even on a massive scale."
      },
      "typeVersion": 1
    },
    {
      "id": "c2474781-cffe-48e5-a8c3-c19b30821ab6",
      "name": "Sticky Note13",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -432,
        -1632
      ],
      "parameters": {
        "color": 7,
        "width": 512,
        "height": 384,
        "content": "### Step 1.5.2: Get the Good Stuff\n\n**What it does:** It extracts only the main text from the article on the page, ignoring menus, footers, and images. Then, it cleans up the formatting.\n**Analogy:** The librarian tears out only the useful pages from the book and cleans up any smudges or messy handwriting."
      },
      "typeVersion": 1
    },
    {
      "id": "70fbb1bd-1cfd-47ed-ad46-48f1d7ee9194",
      "name": "Sticky Note14",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        96,
        -1856
      ],
      "parameters": {
        "color": 5,
        "width": 544,
        "height": 608,
        "content": "### Step 1.5.3: Avoid Re-reading\n\n**What it does:** It checks if we have already processed this exact page content in a previous run. If so, it stops here to save time and resources.\n**Analogy:** The librarian checks their \"already read\" pile to avoid reading the same book twice.\n\n**A Powerful Feature Explained:**\n\nUsually, the \"Remove Duplicates\" node only looks at the items in the *current* execution. But here, it's set to **\"Remove items seen in previous executions.\"**\n\nThis is incredibly powerful in a sub-workflow. Even though our sub-workflow only sees one page at a time, this node has a long-term memory. It remembers every single page it has *ever* processed across all previous runs.\n\nThis makes the workflow robust. You can run the indexing process again and again to update the knowledge base with new documentation, and it will never waste resources re-processing old pages or creating duplicate chunks in the in-memory store."
      },
      "typeVersion": 1
    },
    {
      "id": "88930b6a-5ffb-428b-bdb3-689cda2f78d8",
      "name": "Sticky Note15",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        656,
        -1856
      ],
      "parameters": {
        "color": 6,
        "width": 656,
        "height": 1040,
        "content": "### Step 1.5.4: Create & Store the 'Magic Index Cards'\n\nThis is the most important step of indexing!\n\n1.  **`Recursive Character Text Splitter`:** The text is broken down into small, overlapping paragraphs (\"chunks\").\n    *   **Analogy:** The librarian breaks the book down into small, meaningful paragraphs. This is vital for finding very specific answers later.\n\n2.  **`Gemini Chunk Embedding`:** An AI model converts each chunk of text into a list of numbers (a \"vector\" or \"embedding\").\n    *   **Analogy:** The librarian uses a 'magic pen' to turn each paragraph into a unique set of numbers. Paragraphs with similar meanings get similar numbers.\n\n3.  **`Simple Vector Store (Insert)`:** The original text chunk and its new vector are saved together in n8n's in-memory vector store.\n    *   **Analogy:** The librarian files the original paragraph along with its magic number on an index card and puts it in a special filing cabinet (the in-memory vector store).\n    *   **The `Memory Key`** in this node acts as a label for the filing cabinet, ensuring the chat flow can find it later."
      },
      "typeVersion": 1
    },
    {
      "id": "cb9f3d2c-6eaf-4b6e-aa7f-d0662bc35740",
      "name": "Sticky Note16",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1296,
        -752
      ],
      "parameters": {
        "color": 7,
        "width": 1200,
        "height": 1456,
        "content": "## Part 2: The Chatbot (Talking to the Expert Librarian)\n\n**Goal:** To provide an interface where a user can ask a question, have the system find relevant information from the knowledge base, and get an accurate, AI-generated answer.\n**Action:** After running the Indexing flow, **Activate** this workflow. Then, open the `When chat message received` node and use its Public URL to chat."
      },
      "typeVersion": 1
    },
    {
      "id": "ae93c028-a7d2-4d05-b3a7-9789dd4211f9",
      "name": "Sticky Note17",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1264,
        -592
      ],
      "parameters": {
        "color": 4,
        "width": 368,
        "height": 448,
        "content": "### The Front Desk: Ask Your Question Here\n\n**What it does:** This is the public-facing chat interface. When you send a message here, the entire RAG process begins.\n\n**Action:**\n1.  **Activate** the entire workflow.\n2.  To test directly inside n8n, click the **\"Open Chat\"** button in this node's parameter panel.\n3.  To chat publicly, copy the **Public URL** from this node and open it in a new browser tab."
      },
      "typeVersion": 1
    },
    {
      "id": "d180b0ca-dd3b-40bb-8595-c178f74011e6",
      "name": "Sticky Note18",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -880,
        -480
      ],
      "parameters": {
        "color": 5,
        "width": 560,
        "height": 400,
        "content": "### The Brains: The Expert Librarian\n\n**What it does:** This is the AI agent that orchestrates the entire response. It understands your question, decides which tools to use, and formulates the final answer.\n**System Prompt:** Its instructions (in the System Message) are very strict: **\"Only use the provided documents to answer. Do not make things up.\"**"
      },
      "typeVersion": 1
    },
    {
      "id": "42d81e12-bfc9-4b9b-bb8a-40249e163bbb",
      "name": "Sticky Note19",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1264,
        -128
      ],
      "parameters": {
        "color": 7,
        "width": 368,
        "height": 592,
        "content": "### The 'Synthesizer' & 'Strategist'\n\n**What it does:** This is the Large Language Model (LLM). It has two critical jobs:\n\n1.  **The Strategist:** Based on your question and the conversation history, it decides *what information to look for* in the knowledge base (the library).\n2.  **The Synthesizer:** After getting the relevant documents, it generates the final, human-readable answer based *only* on that context.\n\n\n**Analogy:** This is the part of the librarian's brain that first decides which section of the library to search, and then reads the specific index cards to write a clear, helpful response.\n\nThe model used here is **Gemini 2.5 Flash**."
      },
      "typeVersion": 1
    },
    {
      "id": "567ecaf4-e42a-4275-bc39-ad7217b4a173",
      "name": "Sticky Note20",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -880,
        -64
      ],
      "parameters": {
        "color": 7,
        "width": 288,
        "height": 528,
        "content": "### Short-Term Memory\n\n**What it does:** This node stores the last few messages of your conversation.\n**Analogy:** This helps the librarian remember what you just talked about, so you can ask follow-up questions without having to repeat yourself."
      },
      "typeVersion": 1
    },
    {
      "id": "120f0062-4e6c-4cac-92ab-51cd7b55e892",
      "name": "Sticky Note21",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -576,
        -64
      ],
      "parameters": {
        "color": 6,
        "width": 448,
        "height": 736,
        "content": "### The Tool: The 'Magic Filing Cabinet' Retriever\n\nThis is the \"Retrieval\" part of RAG. When the agent gets your question, it uses this tool to find the most relevant information.\n\n1.  **`Gemini Query Embedding`:** Your question is converted into its own 'magic number' (vector).\n\n2.  **`Official n8n Documentation (Vector Store Retrieve)`:** It searches the in-memory vector store for the document chunks with the most similar 'magic numbers' to your question's number.\n\n\n**Analogy:** The librarian takes your question, finds the most relevant index cards from the filing cabinet, and hands them over to the 'Synthesizer' to formulate the answer."
      },
      "typeVersion": 1
    },
    {
      "id": "b83a63ac-403f-4717-ae8a-6756e42f4b3e",
      "name": "Start Indexing",
      "type": "n8n-nodes-base.manualTrigger",
      "notes": "\u00a9 2025 Lucas Peyrin",
      "disabled": true,
      "position": [
        -944,
        -2192
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "1271281d-ab81-4039-96a3-0bc42024d6f8",
      "name": "RAG Chatbot",
      "type": "@n8n/n8n-nodes-langchain.chatTrigger",
      "notes": "\u00a9 2025 Lucas Peyrin",
      "disabled": true,
      "position": [
        -1104,
        -288
      ],
      "parameters": {
        "public": true,
        "options": {
          "title": "",
          "subtitle": "",
          "customCss": "/* === THEME OVERRIDE: n8n Glass & Glow (Revised) === */\n\n/*\n  This theme is built upon the default n8n chat CSS variables.\n  We'll use your desired branding and layout, and then add\n  the \"glass\" effect using a semi-transparent background\n  and a backdrop-filter on the main window class.\n*/\n\n:root {\n  /* --- 1. CORE BRANDING & FONTS --- */\n  /* Your choices for font and primary color are applied here. */\n  --chat--font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n  --chat--color-primary: #EA4B71; /* n8n Red */\n  --chat--color-primary-shade-50: #D93A60;\n  --chat--color-primary-shade-100: #C82A50;\n  --chat--color-secondary: #20b69e; /* Kept default secondary for things like file uploads */\n  --chat--color-secondary-shade-50: #1ca08a;\n  --chat--color-white: #ffffff;\n  --chat--color-light: #f2f4f8;\n  --chat--color-dark: #1F2937; /* Darker, more modern text color */\n  --chat--color-disabled: #9CA3AF;\n  --chat--color-typing: #404040;\n\n  /* --- 2. WINDOW & LAYOUT --- */\n  /* Your dimensions and rounded corners. The actual glass effect is handled in the class override below. */\n  --chat--window--width: 430px;\n  --chat--window--height: 80vh;\n  --chat--window--border-radius: 16px;\n  --chat--window--border: 1px solid rgba(255, 255, 255, 0.3);\n  --chat--spacing: 1rem; /* 16px base spacing */\n  --chat--window--z-index: 9999;\n  --chat--window--bottom: var(--chat--spacing);\n  --chat--window--right: var(--chat--spacing);\n  --chat--window--margin-bottom: var(--chat--spacing);\n\n  /* --- 3. GLASSMORPHISM BACKGROUNDS --- */\n  /* We make the main sections transparent to let the glass window show through. */\n  --chat--header--background: transparent;\n  --chat--body--background: transparent;\n  --chat--footer--background: transparent;\n\n  /* --- 4. HEADER STYLING (REMOVED) --- */\n  /* The header is removed by setting its height, padding, and border to 0/none. */\n  --chat--header-height: 0;\n  --chat--header--padding: 0;\n  --chat--header--border-bottom: none;\n  /* The rest of the header variables are now irrelevant. */\n  --chat--header--color: var(--chat--color-dark);\n  --chat--heading--font-size: 1.5rem;\n  --chat--subtitle--font-size: 0.875rem;\n  --chat--subtitle--line-height: 1.4;\n  --chat--close--button--color-hover: var(--chat--color-primary);\n\n  /* --- 5. MESSAGE BUBBLES --- */\n  --chat--message--font-size: 0.875rem;\n  --chat--message--padding: 12px 16px;\n  --chat--message--border-radius: 12px;\n  --chat--message-line-height: 1.6;\n  --chat--message--margin-bottom: calc(var(--chat--spacing) * 0.75);\n  /* Adjusted padding: Top is 0, sides and bottom use the base spacing. */\n  --chat--messages-list--padding: 0 var(--chat--spacing) var(--chat--spacing);\n  --chat--message--bot--background: var(--chat--color-white);\n  --chat--message--bot--color: #111827;\n  --chat--message--bot--border: none;\n  --chat--message--user--background: var(--chat--color-primary);\n  --chat--message--user--color: var(--chat--color-white);\n  --chat--message--user--border: none;\n\n  /* --- 6. INPUT AREA --- */\n  --chat--textarea--height: 50px;\n  --chat--textarea--max-height: 10rem;\n  --chat--input--font-size: 0.9rem;\n  --chat--input--border: 0;\n  --chat--input--border-radius: 12px; /* Rounded input field */\n  --chat--input--padding: 12px 16px;\n  --chat--input--background: rgba(255, 255, 255, 0.5); /* Semi-transparent input */\n  --chat--input--text-color: #111827;\n  --chat--input--line-height: 1.5;\n  --chat--input--border-active: 0;\n\n  /* --- 7. SEND & FILE BUTTONS --- */\n  --chat--input--send--button--background: transparent;\n  --chat--input--send--button--color: var(--chat--color-primary);\n  --chat--input--send--button--background-hover: transparent;\n  --chat--input--send--button--color-hover: var(--chat--color-primary-shade-50);\n  --chat--input--file--button--background: transparent;\n  --chat--input--file--button--color: var(--chat--color-secondary);\n  --chat--input--file--button--background-hover: transparent;\n  --chat--input--file--button--color-hover: var(--chat--color-secondary-shade-50);\n\n  /* --- 8. TOGGLE BUTTON & OTHERS --- */\n  /* Using your primary brand color for the main toggle button */\n  --chat--toggle--size: 64px;\n  --chat--toggle--width: var(--chat--toggle--size);\n  --chat--toggle--height: var(--chat--toggle--size);\n  --chat--toggle--border-radius: 50%;\n  --chat--toggle--background: var(--chat--color-primary);\n  --chat--toggle--hover--background: var(--chat--color-primary-shade-50);\n  --chat--toggle--active--background: var(--chat--color-primary-shade-100);\n  --chat--toggle--color: var(--chat--color-white);\n}\n\n/* === CLASS OVERRIDES === */\n/*\n  These are essential for effects that CSS variables can't control,\n  like the glass blur, shadows, and max-height.\n*/\n\n.chat-window {\n  /* This is the magic for the glass effect! */\n  background-color: rgba(249, 243, 245, 0.6); /* A semi-transparent background color */\n  backdrop-filter: blur(20px);\n  -webkit-backdrop-filter: blur(20px); /* For Safari compatibility */\n\n  /* A subtle shadow helps lift the window off the page */\n  box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.1);\n\n  /* Here we apply the max-height you wanted */\n  max-height: 750px;\n}\n\n/* Add top margin to the first message only for initial spacing */\n.chat-messages-list .chat-message:first-child {\n  margin-top: var(--chat--spacing);\n}\n\n/* Make user messages slightly wider for better balance */\n.chat-message.is-user {\n\tmax-width: 70%;\n}\n\n.chat-message.is-bot {\n\tmax-width: 80%;\n}\n\n/* Add a subtle glow to messages on hover */\n.chat-message {\n    transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n.chat-message:hover {\n    transform: translateY(-2px);\n    box-shadow: 0 0 25px 0 rgba(234, 75, 113, 0.2);\n}\n\n/* === PAGE BACKGROUND === */\n/* Your dotted background to simulate the n8n canvas. Perfect as is! */\nbody {\n    background-color: #FDFBFF;\n    background-image:\n        radial-gradient(circle at 1px 1px, rgba(0,0,0,0.07) 1px, transparent 0),\n        linear-gradient(135deg, #F9F3F5 0%, #EFF3FB 100%);\n    background-size: 25px 25px, 100% 100%;\n}",
          "inputPlaceholder": "Type your n8n related question.."
        },
        "initialMessages": "Hello! I'm an AI assistant trained on the official n8n documentation.\nYou can ask me anything about n8n nodes, workflows, or concepts. For example:\n\"How does the IF node work?\"\n\"What is a sub-workflow?\""
      },
      "typeVersion": 1.1
    },
    {
      "id": "2ff38f0f-91ef-45c0-a419-ffeffe9bfea3",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2224,
        -1504
      ],
      "parameters": {
        "width": 624,
        "height": 320,
        "content": "## Setup Step 4: Chat with Your Expert!\n\nCongratulations, the knowledge base is built! Now it's time to ask the expert a question.\n\n**Action:**\n1.  **Activate** the entire workflow using the toggle switch at the top of the screen.\n2.  Open the **`RAG Chatbot`** chat trigger node (bottom-left).\n3.  To chat:\n    *   Copy its **Public URL** and open it in a new browser tab.\n    *   OR, click the **\"Open Chat\"** button in the node's panel to test it directly inside n8n.\n\n\n**Try asking:** \"How does the IF node work?\" or \"What is a sub-workflow?\""
      },
      "typeVersion": 1
    },
    {
      "id": "a42e96aa-a212-4fd8-b3f5-b70738428112",
      "name": "Sticky Note24",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2224,
        -2464
      ],
      "parameters": {
        "width": 656,
        "height": 272,
        "content": "## Setup Step 1: Connect Your Google AI Credentials\n\nThis workflow uses Google's Gemini models for generating embeddings and chat responses. You'll need a Google AI API key.\n\n**Action:**\n1.  Go to any of the Gemini nodes (e.g., **`Gemini 2.5 Flash`**).\n2.  Click the **Credential** dropdown and select **`+ Create New Credential`**.\n3.  In the window that opens, paste your **Google AI API Key**.\n4.  Click **Save**. Your new credential will be created and automatically selected for this node."
      },
      "typeVersion": 1
    },
    {
      "id": "22d91015-7d89-4f1c-bd30-cc1387cc24a3",
      "name": "Sticky Note27",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2224,
        -2176
      ],
      "parameters": {
        "width": 864,
        "height": 304,
        "content": "## Setup Step 2: Apply Credentials to All Gemini Nodes\n\nYour new Google AI credential is now saved. Let's make sure all the other Gemini nodes are using it.\n\n**Action:**\nGo to the remaining Gemini nodes on the canvas. Your new credential will now be available in their **Credential** dropdown lists. Simply select it for each one.\n\n**Nodes to check:**\n*   `Gemini 2.5 Flash`\n*   `Gemini Chunk Embedding`\n*   `Gemini Query Embedding`"
      },
      "typeVersion": 1
    },
    {
      "id": "497629d6-8b1b-4ab8-9e37-98d21da5fdc2",
      "name": "Sticky Note28",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2224,
        -1856
      ],
      "parameters": {
        "width": 784,
        "height": 336,
        "content": "## Setup Step 3: Build the Knowledge Base (Indexing)\n\nThis is the one-time step where the AI \"reads\" all the documentation.\n\n**Action:**\n1.  Find the **`Start Indexing`** manual trigger node at the top-left of the canvas.\n2.  Click its **\"Execute workflow\"** button.\n\n\n**\u26a0\ufe0f IMPORTANT:**\n*   **Be Patient!** This process will take **15-20 minutes** to scrape, process, and store the entire n8n documentation in memory.\n*   **The knowledge base is temporary.** It is stored in n8n's memory and will be **erased if you restart your n8n instance**. If that happens, you must run this indexing step again."
      },
      "typeVersion": 1
    },
    {
      "id": "7ab75be6-6cc7-4306-8f84-b101855cb65d",
      "name": "Ingest Web Page",
      "type": "n8n-nodes-base.executeWorkflowTrigger",
      "notes": "\u00a9 2025 Lucas Peyrin",
      "position": [
        -944,
        -1424
      ],
      "parameters": {
        "inputSource": "passthrough"
      },
      "typeVersion": 1.1
    },
    {
      "id": "6e3fc66d-e12e-4ef3-81c8-a205be1c26a0",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        512,
        -752
      ],
      "parameters": {
        "color": 2,
        "width": 832,
        "height": 544,
        "content": "## Video Tutorial\n\nA full video tutorial about RAG will be shown here in a future version of this template !"
      },
      "typeVersion": 1
    },
    {
      "id": "85ff7226-9931-41d7-9ca5-c9a6f153fe26",
      "name": "Simple Vector Store",
      "type": "@n8n/n8n-nodes-langchain.vectorStoreInMemory",
      "notes": "\u00a9 2025 Lucas Peyrin",
      "position": [
        848,
        -1424
      ],
      "parameters": {
        "mode": "insert",
        "memoryKey": {
          "__rl": true,
          "mode": "id",
          "value": "n8n_documentation_vector_store"
        },
        "embeddingBatchSize": 30
      },
      "typeVersion": 1.3
    },
    {
      "id": "e11b64ae-32ce-4fde-aba8-bbf6744b9edd",
      "name": "Official n8n Documentation",
      "type": "@n8n/n8n-nodes-langchain.vectorStoreInMemory",
      "notes": "\u00a9 2025 Lucas Peyrin",
      "position": [
        -496,
        320
      ],
      "parameters": {
        "mode": "retrieve-as-tool",
        "topK": 10,
        "memoryKey": {
          "__rl": true,
          "mode": "id",
          "value": "=n8n_documentation_vector_store"
        },
        "toolDescription": "Get related chunks of the official n8n documentation.",
        "includeDocumentMetadata": false
      },
      "typeVersion": 1.3
    },
    {
      "id": "677af764-b9e7-4478-8846-c7cf3ab4c42d",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -64,
        -752
      ],
      "parameters": {
        "color": 7,
        "width": 544,
        "height": 1088,
        "content": "## Was this helpful? Let me know!\n[![clic](https://supastudio.ia2s.app/storage/v1/object/public/assets/n8n/clic_down_lucas.gif)](https://workflows.ac/form)\n\nI really hope this template helped you. Your feedback is what helps me create better resources for the n8n community.\n\n### **Have Feedback, a Question, or a Project Idea?**\n\n\n#### \u27a1\ufe0f **[Click here to go to the Contact Form](https://workflows.ac/form?utm_source=n8n_template&utm_medium=workflow_note&utm_campaign=build_a_documentation_expert_chatbot_with_gemini_rag_pipeline&utm_content=6137)**\n\nUse this single link for anything you need:\n\n*   **Give Feedback:** Share your thoughts on this template, whether you found a typo, encountered an unexpected error, have a suggestion, or just want to say thanks!\n\n*   **Automation Coaching:** Get personalized, one-on-one guidance to master n8n. We can work together to help you reach an expert level.\n\n*   **Automation Consulting:** Have a complex business challenge or need custom workflows built from scratch? We offer a plug and play automation department for 8 to 88 people teams with unlimited automation requests.\n\n---\n\nHappy Automating!\nLucas Peyrin | [Workflows Accelerator](https://workflows.ac?utm_source=n8n_template&utm_medium=workflow_note&utm_campaign=build_a_documentation_expert_chatbot_with_gemini_rag_pipeline&utm_content=6137)"
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "RAG Chatbot": {
      "main": [
        [
          {
            "node": "n8n Docs AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Simple Memory": {
      "ai_memory": [
        [
          {
            "node": "n8n Docs AI Agent",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "Start Indexing": {
      "main": [
        [
          {
            "node": "Get All n8n Documentation Links",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Ingest Web Page": {
      "main": [
        [
          {
            "node": "Get Documentation Page",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Out Links": {
      "main": [
        [
          {
            "node": "Remove Duplicate Links",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Gemini 2.5 Flash": {
      "ai_languageModel": [
        [
          {
            "node": "n8n Docs AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Clean Documentation": {
      "main": [
        [
          {
            "node": "Remove Duplicate Documentation Content",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Default Data Loader": {
      "ai_document": [
        [
          {
            "node": "Simple Vector Store",
            "type": "ai_document",
            "index": 0
          }
        ]
      ]
    },
    "Only Keep Doc Paths": {
      "main": [
        [
          {
            "node": "Loop Over Documentation Pages",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Gemini Chunk Embedding": {
      "ai_embedding": [
        [
          {
            "node": "Simple Vector Store",
            "type": "ai_embedding",
            "index": 0
          }
        ]
      ]
    },
    "Gemini Query Embedding": {
      "ai_embedding": [
        [
          {
            "node": "Official n8n Documentation",
            "type": "ai_embedding",
            "index": 0
          }
        ]
      ]
    },
    "Get Documentation Page": {
      "main": [
        [
          {
            "node": "Extract Documentation Content",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Remove Duplicate Links": {
      "main": [
        [
          {
            "node": "Only Keep Doc Paths",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Links from HTML": {
      "main": [
        [
          {
            "node": "Split Out Links",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Official n8n Documentation": {
      "ai_tool": [
        [
          {
            "node": "n8n Docs AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Extract Documentation Content": {
      "main": [
        [
          {
            "node": "Clean Documentation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Documentation Pages": {
      "main": [
        [],
        [
          {
            "node": "Add Documentation Page to Vector Store",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get All n8n Documentation Links": {
      "main": [
        [
          {
            "node": "Extract Links from HTML",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Recursive Character Text Splitter": {
      "ai_textSplitter": [
        [
          {
            "node": "Default Data Loader",
            "type": "ai_textSplitter",
            "index": 0
          }
        ]
      ]
    },
    "Add Documentation Page to Vector Store": {
      "main": [
        [
          {
            "node": "Loop Over Documentation Pages",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Remove Duplicate Documentation Content": {
      "main": [
        [
          {
            "node": "Simple Vector Store",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

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

About this workflow

This template is a complete, hands-on tutorial for building a RAG (Retrieval-Augmented Generation) pipeline. In simple terms, you'll teach an AI to become an expert on a specific topic—in this case, the official n8n documentation—and then build a chatbot to ask it questions.

Source: https://n8n.io/workflows/6137/ — 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

Api Schema Extractor. Uses manualTrigger, httpRequest, splitOut, textSplitterRecursiveCharacterTextSplitter. Event-driven trigger; 88 nodes.

HTTP Request, Text Splitter Recursive Character Text Splitter, Document Default Data Loader +9
AI & RAG

Wait Splitout. Uses manualTrigger, httpRequest, splitOut, textSplitterRecursiveCharacterTextSplitter. Event-driven trigger; 88 nodes.

HTTP Request, Text Splitter Recursive Character Text Splitter, Document Default Data Loader +9
AI & RAG

This workflow automates the process of discovering and extracting APIs from various services, followed by generating custom schemas. It works in three distinct stages: research, extraction, and schema

HTTP Request, Text Splitter Recursive Character Text Splitter, Document Default Data Loader +9
AI & RAG

This simple philosophy changes the way we think about automated sales agents. Context changes everything. In this 4-part workflow, we start by creating a knowledge base that will act as context across

Pinecone Vector Store, Document Default Data Loader, Text Splitter Recursive Character Text Splitter +12
AI & RAG

Chat with docs - 5minAI New version. Uses httpRequest, documentDefaultDataLoader, textSplitterRecursiveCharacterTextSplitter, embeddingsOpenAi. Event-driven trigger; 62 nodes.

HTTP Request, Document Default Data Loader, Text Splitter Recursive Character Text Splitter +10