AutomationFlowsAI & RAG › Draft Grounded Support Replies From a Notion Knowledge Base Using Groq and Gmail

Draft Grounded Support Replies From a Notion Knowledge Base Using Groq and Gmail

Draft grounded support replies from a Notion knowledge base using Groq and Gmail. Uses notion, vectorStoreInMemory, documentDefaultDataLoader, textSplitterRecursiveCharacterTextSplitter. Event-driven trigger; 32 nodes.

Event trigger★★★★★ complexityAI-powered32 nodesNotionIn-Memory Vector StoreDocument Default Data LoaderText Splitter Recursive Character Text SplitterGmail TriggerText ClassifierChain LlmGmail
AI & RAG Trigger: Event Nodes: 32 Complexity: ★★★★★ AI nodes: yes Added:

This workflow follows the Chainllm → Documentdefaultdataloader 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": "Draft grounded support replies from a Notion knowledge base using Groq and Gmail",
  "nodes": [
    {
      "id": "11d843a0-a945-4bcb-b8af-ec94d3c97c77",
      "name": "Run KB Ingestion",
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        -256,
        288
      ],
      "parameters": {}
    },
    {
      "id": "5c71ae62-9387-4141-afc8-d31ef3f6e9c6",
      "name": "Get KB Articles",
      "type": "n8n-nodes-base.notion",
      "typeVersion": 2.2,
      "position": [
        -64,
        288
      ],
      "parameters": {
        "resource": "databasePage",
        "operation": "getAll",
        "databaseId": {
          "__rl": true,
          "mode": "list",
          "value": "YOUR_NOTION_DATABASE_ID",
          "cachedResultName": "Cadence Knowledge Base"
        },
        "returnAll": true,
        "options": {}
      },
      "onError": "continueRegularOutput"
    },
    {
      "id": "b4bfbbe8-2deb-481b-b33a-d3bf7eb3ca9a",
      "name": "Check If Published",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        144,
        288
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose"
          },
          "conditions": [
            {
              "leftValue": "={{ $json.property_status }}",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "rightValue": "Published"
            }
          ],
          "combinator": "and"
        }
      }
    },
    {
      "id": "95babe45-8bbd-4238-8628-09c21c4c49f7",
      "name": "Get Article Body",
      "type": "n8n-nodes-base.notion",
      "typeVersion": 2.2,
      "position": [
        464,
        272
      ],
      "parameters": {
        "resource": "block",
        "operation": "getAll",
        "blockId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.id }}"
        },
        "returnAll": true
      },
      "onError": "continueRegularOutput"
    },
    {
      "id": "ed62031f-a67e-48d2-804a-111bdcef98b9",
      "name": "Assemble Article Documents",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        640,
        272
      ],
      "parameters": {
        "jsCode": "const pages = $('Get KB Articles').all().map((i) => i.json);\nconst norm = (s) => (s || '').toString().replace(/-/g, '');\nconst byId = {};\nfor (const p of pages) {\n  byId[norm(p.id)] = { title: p.property_title || p.name || 'Untitled', category: p.property_category || '', url: p.url || '', lastUpdated: (p.property_last_updated && p.property_last_updated.start) || '', parts: [] };\n}\nfor (const b of $input.all()) {\n  const j = b.json;\n  const pid = norm(j.root_id || j.parent_id || (j.parent && j.parent.page_id) || '');\n  const c = (j.content || '').trim();\n  if (byId[pid] && c) byId[pid].parts.push(c);\n}\nreturn Object.values(byId)\n  .filter((a) => a.parts.length > 0)\n  .map((a) => ({ json: { title: a.title, category: a.category, url: a.url, last_updated: a.lastUpdated, text: a.parts.join('\\n\\n') } }));"
      }
    },
    {
      "id": "51924453-ea25-44fa-9b7b-c26e79f027fd",
      "name": "Store KB Vectors",
      "type": "@n8n/n8n-nodes-langchain.vectorStoreInMemory",
      "typeVersion": 1.3,
      "position": [
        1024,
        224
      ],
      "parameters": {
        "mode": "insert",
        "memoryKey": {
          "__rl": true,
          "mode": "list",
          "value": "cadence_kb",
          "cachedResultName": "cadence_kb"
        },
        "clearStore": true
      }
    },
    {
      "id": "259251b9-ce90-438c-8612-78d98e25353f",
      "name": "Load Article Text",
      "type": "@n8n/n8n-nodes-langchain.documentDefaultDataLoader",
      "typeVersion": 1.1,
      "position": [
        1088,
        400
      ],
      "parameters": {
        "dataType": "json",
        "jsonMode": "expressionData",
        "jsonData": "={{ $json.text }}",
        "textSplittingMode": "custom",
        "options": {
          "metadata": {
            "metadataValues": [
              {
                "name": "title",
                "value": "={{ $json.title }}"
              },
              {
                "name": "category",
                "value": "={{ $json.category }}"
              },
              {
                "name": "url",
                "value": "={{ $json.url }}"
              },
              {
                "name": "last_updated",
                "value": "={{ $json.last_updated }}"
              },
              {
                "name": "indexed_at",
                "value": "={{ $now.toISO() }}"
              }
            ]
          }
        }
      }
    },
    {
      "id": "83fb4f82-8af9-40cf-a250-458032c9f0fd",
      "name": "Split Article Into Chunks",
      "type": "@n8n/n8n-nodes-langchain.textSplitterRecursiveCharacterTextSplitter",
      "typeVersion": 1,
      "position": [
        1088,
        544
      ],
      "parameters": {
        "chunkSize": 1000,
        "chunkOverlap": 100,
        "options": {
          "splitCode": "markdown"
        }
      }
    },
    {
      "id": "bafebe06-a755-4eec-bfb8-a4c09cf7bba4",
      "name": "When Support Email Arrives",
      "type": "n8n-nodes-base.gmailTrigger",
      "typeVersion": 1.4,
      "position": [
        -224,
        1056
      ],
      "parameters": {
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        },
        "simple": false,
        "filters": {
          "readStatus": "unread",
          "q": "to:support@yourcompany.com"
        },
        "options": {}
      }
    },
    {
      "id": "823effca-64d6-4967-b941-a901ba55841b",
      "name": "Normalize Email",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        -16,
        1056
      ],
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "a1",
              "name": "emailSubject",
              "value": "={{ $json.subject }}",
              "type": "string"
            },
            {
              "id": "a2",
              "name": "emailBody",
              "value": "={{ $json.text ?? $json.snippet ?? \"\" }}",
              "type": "string"
            },
            {
              "id": "a3",
              "name": "senderEmail",
              "value": "={{ $json.from }}",
              "type": "string"
            },
            {
              "id": "a4",
              "name": "threadId",
              "value": "={{ $json.threadId }}",
              "type": "string"
            },
            {
              "id": "a5",
              "name": "question",
              "value": "={{ $json.subject }}\n\n{{ $json.text }}",
              "type": "string"
            },
            {
              "id": "a6",
              "name": "companyName",
              "value": "Cadence",
              "type": "string"
            },
            {
              "id": "a7",
              "name": "signature",
              "value": "Cadence Support",
              "type": "string"
            },
            {
              "id": "a8",
              "name": "minRelevance",
              "value": 0.3,
              "type": "number"
            }
          ]
        },
        "options": {}
      }
    },
    {
      "id": "cfcae77d-93e4-4a75-9e47-635fcef15db8",
      "name": "Classify Inquiry",
      "type": "@n8n/n8n-nodes-langchain.textClassifier",
      "typeVersion": 1.1,
      "position": [
        256,
        1024
      ],
      "parameters": {
        "inputText": "={{ $json.question }}",
        "categories": {
          "categories": [
            {
              "category": "support_question",
              "description": "A genuine product or account question that the knowledge base could answer."
            },
            {
              "category": "noise",
              "description": "Spam, newsletters, auto-replies, out-of-office, or messages that contain no question."
            },
            {
              "category": "already_resolved",
              "description": "A thank-you, confirmation, or message saying the issue is already solved and needs no answer."
            }
          ]
        },
        "options": {
          "fallback": "other"
        }
      }
    },
    {
      "id": "69dd2cac-0c52-4d58-93a8-31fa6461f4d4",
      "name": "Retrieve From KB",
      "type": "@n8n/n8n-nodes-langchain.vectorStoreInMemory",
      "typeVersion": 1.3,
      "position": [
        752,
        976
      ],
      "parameters": {
        "mode": "load",
        "memoryKey": {
          "__rl": true,
          "mode": "list",
          "value": "cadence_kb",
          "cachedResultName": "cadence_kb"
        },
        "prompt": "={{ $('Normalize Email').item.json.question }}",
        "topK": 8,
        "includeDocumentMetadata": true,
        "useReranker": true
      }
    },
    {
      "id": "e13981a1-36bd-4496-8a98-8d5dab88dfef",
      "name": "Bundle Retrieved Sources",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1040,
        976
      ],
      "parameters": {
        "jsCode": "const docs = $input.all().map((i) => i.json);\nconst norm = $('Normalize Email').first().json;\nconst minRel = Number(norm.minRelevance);\nconst md = (d) => d.metadata || (d.document && d.document.metadata) || {};\nconst content = (d) => d.pageContent || (d.document && d.document.pageContent) || d.text || '';\nconst scoreOf = (d) => {\n  const m = md(d);\n  const cands = [d.relevanceScore, d.rerankScore, d.score, m.relevanceScore, m.rerankScore, m.score];\n  const n = cands.find((v) => typeof v === 'number');\n  return typeof n === 'number' ? n : null;\n};\nconst scores = docs.map(scoreOf).filter((v) => v !== null);\nconst topScore = scores.length ? Math.max.apply(null, scores) : null;\nconst retrievalConfident = (docs.length > 0) && (topScore === null || isNaN(minRel) || topScore >= minRel);\nconst sourcesText = docs.map((d, i) => '[' + (i + 1) + '] ' + (md(d).title || 'Source') + '\\n' + content(d)).join('\\n\\n');\nconst seen = new Set();\nconst list = [];\nfor (const d of docs) {\n  const t = md(d).title || 'Source';\n  const u = md(d).url || '';\n  if (!seen.has(t)) { seen.add(t); list.push('- ' + t + (u ? ' (' + u + ')' : '')); }\n}\nreturn [{ json: { sourcesText: sourcesText, sourcesList: list.join('\\n'), topScore: topScore, retrievalConfident: retrievalConfident, question: norm.question, emailSubject: norm.emailSubject, senderEmail: norm.senderEmail, threadId: norm.threadId } }];"
      }
    },
    {
      "id": "268acdb6-d236-4aa9-a195-2c14908d033d",
      "name": "Check Retrieval Confidence",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        1280,
        976
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose"
          },
          "conditions": [
            {
              "leftValue": "={{ $json.retrievalConfident }}",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        }
      }
    },
    {
      "id": "a9f0d27f-3a99-4571-8c0b-b1de269ee12d",
      "name": "Draft Grounded Reply",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "typeVersion": 1.9,
      "position": [
        1488,
        960
      ],
      "parameters": {
        "promptType": "define",
        "text": "=You are a customer support agent for Cadence, a team time-tracking and invoicing SaaS. Answer the customer question using ONLY the information in the sources below. Do not use any outside knowledge. If the sources do not contain enough information to answer, reply with exactly: NEEDS_HUMAN\n\nWrite a friendly, concise reply in plain text. Do not add a greeting line or a signature.\n\nSOURCES:\n{{ $json.sourcesText }}\n\nCUSTOMER QUESTION:\n{{ $json.question }}"
      }
    },
    {
      "id": "6a1181c8-ac7b-4f52-8651-ba645ec88ffb",
      "name": "Check If Answered",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        1760,
        960
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose"
          },
          "conditions": [
            {
              "leftValue": "={{ $json.text }}",
              "operator": {
                "type": "string",
                "operation": "notContains"
              },
              "rightValue": "NEEDS_HUMAN"
            }
          ],
          "combinator": "and"
        }
      }
    },
    {
      "id": "231dce17-957b-49e5-898b-fbf7f6b9c899",
      "name": "Build Reply With Sources",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        2096,
        944
      ],
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "b1",
              "name": "replyBody",
              "value": "={{ $('Draft Grounded Reply').item.json.text }}\n\nSources:\n{{ $('Bundle Retrieved Sources').item.json.sourcesList }}",
              "type": "string"
            },
            {
              "id": "b2",
              "name": "senderEmail",
              "value": "={{ $('Bundle Retrieved Sources').item.json.senderEmail }}",
              "type": "string"
            },
            {
              "id": "b3",
              "name": "threadId",
              "value": "={{ $('Bundle Retrieved Sources').item.json.threadId }}",
              "type": "string"
            },
            {
              "id": "b4",
              "name": "emailSubject",
              "value": "={{ $('Bundle Retrieved Sources').item.json.emailSubject }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      }
    },
    {
      "id": "e05078d8-19fc-47ff-a696-6957e42cb7da",
      "name": "Save Draft For Review",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.2,
      "position": [
        2304,
        944
      ],
      "parameters": {
        "resource": "draft",
        "operation": "create",
        "subject": "=Re: {{ $json.emailSubject }}",
        "emailType": "text",
        "message": "={{ $json.replyBody }}",
        "options": {
          "sendTo": "={{ $json.senderEmail }}",
          "threadId": "={{ $json.threadId }}"
        }
      }
    },
    {
      "id": "52d06bee-c98a-4a4d-b28e-02cc4cbd21b1",
      "name": "Groq Triage Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatGroq",
      "typeVersion": 1,
      "position": [
        256,
        1296
      ],
      "parameters": {
        "model": "llama-3.3-70b-versatile",
        "options": {
          "temperature": 0
        }
      }
    },
    {
      "id": "34f958e2-6da4-49af-a6f9-38fe5ec33c2f",
      "name": "Groq Draft Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatGroq",
      "typeVersion": 1,
      "position": [
        1488,
        1152
      ],
      "parameters": {
        "model": "llama-3.3-70b-versatile",
        "options": {
          "temperature": 0.2
        }
      }
    },
    {
      "id": "47cf81a6-e566-4f0f-b890-29d4cc74eda4",
      "name": "Embed Articles With Cohere",
      "type": "@n8n/n8n-nodes-langchain.embeddingsCohere",
      "typeVersion": 1,
      "position": [
        944,
        400
      ],
      "parameters": {
        "modelName": "embed-english-v3.0"
      }
    },
    {
      "id": "74bd073e-af79-4649-96a8-b95b46a17702",
      "name": "Embed Query With Cohere",
      "type": "@n8n/n8n-nodes-langchain.embeddingsCohere",
      "typeVersion": 1,
      "position": [
        752,
        1200
      ],
      "parameters": {
        "modelName": "embed-english-v3.0"
      }
    },
    {
      "id": "8380e5c0-36fe-484f-994d-744bbb12fa40",
      "name": "Rerank Matches With Cohere",
      "type": "@n8n/n8n-nodes-langchain.rerankerCohere",
      "typeVersion": 1,
      "position": [
        912,
        1200
      ],
      "parameters": {
        "modelName": "rerank-v3.5",
        "topN": 4
      }
    },
    {
      "id": "5e432721-723c-4f76-9300-9e6399acccb3",
      "name": "Sticky Note - Overview",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -816,
        192
      ],
      "parameters": {
        "content": "## Knowledge Base Inquiry Assistant (RAG)\n\n### How it works\n\n1. Run the ingestion trigger to read published articles from a Notion knowledge base, split each one into chunks, embed them with Cohere, and store the vectors in the built-in Simple Vector Store.\n2. When a support email arrives, a Groq classifier sorts it into a real question, noise, or an already-resolved thread, and only real questions continue.\n3. The question retrieves candidate chunks and a Cohere reranker reorders them by relevance, then a confidence gate stops weak matches before any model call.\n4. Groq drafts a reply using only the retrieved sources, and answers not found in the knowledge base are held back for a human.\n5. The grounded reply is saved as a Gmail draft with a sources list for a person to review and send.\n\n### Setup steps\n\n- [ ] Connect Notion, Groq, Cohere, and Gmail credentials in the credential store.\n- [ ] Point Get KB Articles at your own knowledge base database and set the Gmail trigger search query.\n- [ ] Run the ingestion trigger once to build the vector store, then activate the workflow.\n\n### Customization\n\nSwap the Groq model, tune topK and the reranker topN, or adjust minRelevance in Normalize Email to control how strict the confidence gate is. The Simple Vector Store is in-memory, so re-run ingestion after an n8n restart.",
        "width": 480,
        "height": 868
      }
    },
    {
      "id": "f215e47c-0eb0-4acf-8eaa-69a756809411",
      "name": "Sticky Note - Read Articles",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -304,
        160
      ],
      "parameters": {
        "content": "## Read published KB articles\nPull published pages from the Notion knowledge base. Draft articles are skipped.",
        "color": 7,
        "width": 664,
        "height": 304
      }
    },
    {
      "id": "f9f040cc-b474-4045-a716-735e647471ad",
      "name": "Sticky Note - Assemble Text",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        400,
        112
      ],
      "parameters": {
        "content": "## Fetch and assemble article text\nRead each page body and join the blocks into one document per article.",
        "color": 7,
        "width": 420,
        "height": 320
      }
    },
    {
      "id": "561a578b-857a-448c-8dd6-8f1860cd0599",
      "name": "Sticky Note - Embed Store",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        864,
        48
      ],
      "parameters": {
        "content": "## Embed and store KB vectors\nChunk the text, embed it with Cohere, and store the vectors in the Simple Vector Store. Each chunk keeps title, category, url, and last_updated metadata.",
        "color": 7,
        "width": 498,
        "height": 652
      }
    },
    {
      "id": "814999c2-244e-47dd-85de-e1a49a5b87ce",
      "name": "Sticky Note - Receive Email",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -288,
        880
      ],
      "parameters": {
        "content": "## Receive and normalize email\nCapture each new support email and pull out the question, sender, and thread.",
        "color": 7,
        "width": 424,
        "height": 368
      }
    },
    {
      "id": "93ae9837-6ad6-47ce-afe1-3e3d0cd7a47d",
      "name": "Sticky Note - Triage",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        192,
        848
      ],
      "parameters": {
        "content": "## Triage the inquiry\nDrop noise and already-resolved threads so only real questions continue.",
        "color": 7,
        "width": 412,
        "height": 572
      }
    },
    {
      "id": "4758ac0f-9037-4b6f-90ab-9c7862844bd9",
      "name": "Sticky Note - Retrieve Rerank",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        656,
        800
      ],
      "parameters": {
        "content": "## Retrieve and rerank sources\nFetch candidate chunks for the question and rerank them by relevance with Cohere, then bundle a sources list.",
        "color": 7,
        "width": 544,
        "height": 556
      }
    },
    {
      "id": "7ac4fb18-c5f3-4155-a53d-43374146847a",
      "name": "Sticky Note - Gate Draft",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        1248,
        784
      ],
      "parameters": {
        "content": "## Gate and draft the reply\nStop weak retrievals, then draft a reply from the sources only. Answers not found in the knowledge base are held back for a human.",
        "color": 7,
        "width": 721,
        "height": 504
      }
    },
    {
      "id": "210a31f9-ff36-4235-a46e-6666179be2d8",
      "name": "Sticky Note - Save Draft",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        2016,
        768
      ],
      "parameters": {
        "content": "## Build and save the draft\nSave a Gmail draft with sources for a person to review. Nothing is auto-sent.",
        "color": 7,
        "width": 484,
        "height": 364
      }
    }
  ],
  "connections": {
    "Run KB Ingestion": {
      "main": [
        [
          {
            "node": "Get KB Articles",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get KB Articles": {
      "main": [
        [
          {
            "node": "Check If Published",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check If Published": {
      "main": [
        [
          {
            "node": "Get Article Body",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "Get Article Body": {
      "main": [
        [
          {
            "node": "Assemble Article Documents",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Assemble Article Documents": {
      "main": [
        [
          {
            "node": "Store KB Vectors",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Embed Articles With Cohere": {
      "ai_embedding": [
        [
          {
            "node": "Store KB Vectors",
            "type": "ai_embedding",
            "index": 0
          }
        ]
      ]
    },
    "Load Article Text": {
      "ai_document": [
        [
          {
            "node": "Store KB Vectors",
            "type": "ai_document",
            "index": 0
          }
        ]
      ]
    },
    "Split Article Into Chunks": {
      "ai_textSplitter": [
        [
          {
            "node": "Load Article Text",
            "type": "ai_textSplitter",
            "index": 0
          }
        ]
      ]
    },
    "When Support Email Arrives": {
      "main": [
        [
          {
            "node": "Normalize Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize Email": {
      "main": [
        [
          {
            "node": "Classify Inquiry",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Classify Inquiry": {
      "main": [
        [
          {
            "node": "Retrieve From KB",
            "type": "main",
            "index": 0
          }
        ],
        [],
        [],
        []
      ]
    },
    "Groq Triage Model": {
      "ai_languageModel": [
        [
          {
            "node": "Classify Inquiry",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Retrieve From KB": {
      "main": [
        [
          {
            "node": "Bundle Retrieved Sources",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Embed Query With Cohere": {
      "ai_embedding": [
        [
          {
            "node": "Retrieve From KB",
            "type": "ai_embedding",
            "index": 0
          }
        ]
      ]
    },
    "Rerank Matches With Cohere": {
      "ai_reranker": [
        [
          {
            "node": "Retrieve From KB",
            "type": "ai_reranker",
            "index": 0
          }
        ]
      ]
    },
    "Bundle Retrieved Sources": {
      "main": [
        [
          {
            "node": "Check Retrieval Confidence",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Retrieval Confidence": {
      "main": [
        [
          {
            "node": "Draft Grounded Reply",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "Draft Grounded Reply": {
      "main": [
        [
          {
            "node": "Check If Answered",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Groq Draft Model": {
      "ai_languageModel": [
        [
          {
            "node": "Draft Grounded Reply",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Check If Answered": {
      "main": [
        [
          {
            "node": "Build Reply With Sources",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "Build Reply With Sources": {
      "main": [
        [
          {
            "node": "Save Draft For Review",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  },
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "tags": []
}
Pro

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

About this workflow

Draft grounded support replies from a Notion knowledge base using Groq and Gmail. Uses notion, vectorStoreInMemory, documentDefaultDataLoader, textSplitterRecursiveCharacterTextSplitter. Event-driven trigger; 32 nodes.

Source: https://github.com/exekyute/n8n-exekyute-templates/blob/main/published/n8n-kb-inquiry-assistant/workflow.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

This workflow ingests onboarding documents from Google Drive into an in-memory vector store with Google Gemini embeddings, then runs a multi-channel onboarding chatbot powered by Groq, sends role-base

Google Drive, In-Memory Vector Store, Google Gemini Embeddings +14
AI & RAG

This workflow is built for individuals, teams, and businesses that receive regular inquiries via email and want to automate responses in a way that’s intelligent, brand-aligned, and always up to date.

OpenAI Chat, Tool Vector Store, Pinecone Vector Store +14
AI & RAG

This workflow ingests published Notion knowledge base articles into an in-memory vector store using Cohere embeddings, then monitors a support Gmail inbox and uses Groq to draft grounded reply emails

Notion, In-Memory Vector Store, Document Default Data Loader +8
AI & RAG

n8n-4-1: Qdrant. Uses vectorStoreQdrant, embeddingsOpenAi, textClassifier, chainSummarization. Event-driven trigger; 27 nodes.

Qdrant Vector Store, OpenAI Embeddings, Text Classifier +11
AI & RAG

Alfred (funcional). Uses gmailTool, googleCalendarTool, gmail, embeddingsOpenAi. Event-driven trigger; 83 nodes.

Gmail Tool, Google Calendar Tool, Gmail +24