AutomationFlowsAI & RAG › Handle Customer Support Queries with Cache-first RAG Using Redis, Langcache…

Handle Customer Support Queries with Cache-first RAG Using Redis, Langcache…

Original n8n title: Handle Customer Support Queries with Cache-first RAG Using Redis, Langcache and Openai

ByMohamed Abdelwahab @mohelwah on n8n.io

An end-to-end Retrieval-Augmented Generation (RAG) customer support workflow for n8n, using a cache-first strategy (LangCache) combined with a Redis vector store powered by OpenAI embeddings. This template is designed for fast, accurate, and cost-efficient customer support…

Chat trigger trigger★★★★★ complexityAI-powered38 nodesChat TriggerAgentOutput Parser StructuredHTTP RequestRedis Vector StoreOpenAI EmbeddingsDocument Default Data LoaderOpenAI Chat
AI & RAG Trigger: Chat trigger Nodes: 38 Complexity: ★★★★★ AI nodes: yes Added:

This workflow corresponds to n8n.io template #12400 — 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
{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "af6e85ef-2255-454f-8281-517b17a112c0",
      "name": "When chat message received",
      "type": "@n8n/n8n-nodes-langchain.chatTrigger",
      "position": [
        -80,
        736
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 1.4
    },
    {
      "id": "f5884164-83b2-48d0-806d-381c1ba9b802",
      "name": "decompose_query",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        496,
        736
      ],
      "parameters": {
        "text": "={{ $('When chat message received').item.json.chatInput }}",
        "options": {
          "systemMessage": "=Analyze this customer support query and determine if it needs to be broken down into sub-questions.\n        \n        Original query: {{ $('When chat message received').item.json.chatInput }}\n        \n        Rules:\n        - If the query is simple and focused on ONE topic, respond with: SINGLE_QUESTION\n        - If the query has multiple distinct aspects that would benefit from separate research, break it into 2-4 specific sub-questions\n        - Each sub-question should be self-contained and cacheable\n        \n        If breaking down, provide ONLY the sub-questions, one per line, no numbering.\n        If keeping as single question, respond with exactly: SINGLE_QUESTION\n---\noutput should be json object with the follwoing structure:\n{\n\"questions\": [\"Q1\", \"Q2\", \"Q3\",\"Q4\"]\n}"
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 3.1
    },
    {
      "id": "2c48cfdb-bba2-4d9e-88c5-72176c0d9595",
      "name": "Structured Output Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        704,
        1040
      ],
      "parameters": {
        "schemaType": "manual",
        "inputSchema": "{\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"type\": \"object\",\n  \"properties\": {\n    \"questions\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"type\": \"string\"\n      },\n      \"description\": \"List of generated questions.\"\n    }\n  },\n  \"required\": [\"questions\"]\n}\n"
      },
      "typeVersion": 1.3
    },
    {
      "id": "0c52729a-53e9-4f18-a4b4-845cc2384bec",
      "name": "Split Out",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        800,
        736
      ],
      "parameters": {
        "options": {
          "disableDotNotation": false,
          "destinationFieldName": "question"
        },
        "fieldToSplitOut": "output.questions"
      },
      "typeVersion": 1
    },
    {
      "id": "6410933e-dde4-4de5-9f72-5444f0f51891",
      "name": "Search LangCache",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueErrorOutput",
      "position": [
        1248,
        528
      ],
      "parameters": {
        "url": "={{ $('LangCache Config').item.json.langcacheBaseUrl }}/v1/caches/{{ $('LangCache Config').item.json.langcacheCacheId }}/entries/search",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "sendHeaders": true,
        "authentication": "genericCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "prompt",
              "value": "={{ $('Loop Over Items').item.json.question }}"
            },
            {
              "name": "similarityThreshold",
              "value": "={{ $('LangCache Config').item.json.similarityThreshold }}"
            }
          ]
        },
        "genericAuthType": "httpBearerAuth",
        "headerParameters": {
          "parameters": [
            {
              "name": "accept",
              "value": "application/json"
            }
          ]
        }
      },
      "credentials": {
        "httpBearerAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "65f6963c-6faf-46a4-971d-bf162a2cf49d",
      "name": "Is Cache Hit?",
      "type": "n8n-nodes-base.if",
      "position": [
        1488,
        448
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "a84a9a1c-f13b-465c-abc2-f27b9e24f605",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.data?.[0]?.similarity >= $('LangCache Config').item.json.similarityThreshold }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "0f16f03d-6fe1-4da8-9cc5-1fbba5012f30",
      "name": "LangCache Config",
      "type": "n8n-nodes-base.set",
      "position": [
        224,
        736
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "79a40928-d50d-4998-90d8-cea319e9a1b7",
              "name": "langcacheBaseUrl",
              "type": "string",
              "value": "https://aws-us-east-1.langcache.redis.io"
            },
            {
              "id": "b9f02205-4a11-4814-9971-ee840b32537f",
              "name": "langcacheCacheId",
              "type": "string",
              "value": "b83aa61d58be484ebc37c64f1f30c2fa"
            },
            {
              "id": "cdc69c29-a34f-40e1-a9dd-193aacae9c69",
              "name": "similarityThreshold",
              "type": "number",
              "value": 0.75
            },
            {
              "id": "2bebfa5b-9f31-4a60-8121-422ce9a5b846",
              "name": "max_iterations",
              "type": "string",
              "value": "2"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "b142939c-814c-4b36-87bd-45a955f3c564",
      "name": "Loop Over Items",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        1024,
        880
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "ea1352da-745e-4a86-8365-5ddfe8ed93ab",
      "name": "synthesize_response_node",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        1408,
        864
      ],
      "parameters": {
        "text": "=- Original query: \n        {{ $('When chat message received').item.json.chatInput }}\n- Information gathered:\n{{ $json.data.toJsonString() }}",
        "options": {
          "systemMessage": "= You are a helpful customer support assistant. Combine the following question-answer pairs \ninto a single, coherent, and comprehensive response to the user's original query.\n        \n1- If information gathered is enough to answer the question, Provide a natural, conversational response that:\n  - Directly addresses the user's question\n  - Integrates all relevant information smoothly\n  - Is helpful and actionable\n  - Maintains a professional, friendly tone.\n\n2- If information gathered is not enough or accurate to answer the question reply with: \n\"I apologize, but I couldn't find answers to your question. Please try rephrasing or contact support directly.\""
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 3.1
    },
    {
      "id": "7548562c-2a2a-4c4b-8aae-5ed08d5dfb25",
      "name": "Aggregate",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        1248,
        864
      ],
      "parameters": {
        "options": {},
        "aggregate": "aggregateAllItemData"
      },
      "typeVersion": 1
    },
    {
      "id": "aecc43ec-bb69-4d13-a7a4-00bb91453172",
      "name": "Redis Vector Store",
      "type": "@n8n/n8n-nodes-langchain.vectorStoreRedis",
      "position": [
        1440,
        -112
      ],
      "parameters": {
        "mode": "insert",
        "options": {},
        "redisIndex": {
          "__rl": true,
          "mode": "list",
          "value": "kb-3accd7ed",
          "cachedResultName": "kb-3accd7ed"
        }
      },
      "credentials": {
        "redis": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "2344ea11-5412-4d6d-9d59-005d5748a475",
      "name": "Redis Vector Store2",
      "type": "@n8n/n8n-nodes-langchain.vectorStoreRedis",
      "position": [
        2128,
        672
      ],
      "parameters": {
        "mode": "retrieve-as-tool",
        "options": {},
        "redisIndex": {
          "__rl": true,
          "mode": "list",
          "value": "kb-3accd7ed",
          "cachedResultName": "kb-3accd7ed"
        },
        "toolDescription": "Using search_knowledge_base tool for query"
      },
      "credentials": {
        "redis": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "84e92cea-0cf7-45c8-b346-d87126052efc",
      "name": "Embeddings OpenAI",
      "type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
      "position": [
        2112,
        816
      ],
      "parameters": {
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "7a76f285-d661-4fd7-83cc-f20f050dbcc9",
      "name": "Embeddings OpenAI1",
      "type": "@n8n/n8n-nodes-langchain.embeddingsOpenAi",
      "position": [
        1120,
        144
      ],
      "parameters": {
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "bfe94569-e5c7-4282-b2f9-c710a076907d",
      "name": "Default Data Loader",
      "type": "@n8n/n8n-nodes-langchain.documentDefaultDataLoader",
      "position": [
        1408,
        144
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 1.1
    },
    {
      "id": "27cd82d3-d938-49bc-92f2-213d80000e43",
      "name": "example Data",
      "type": "n8n-nodes-base.set",
      "position": [
        1216,
        -112
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "8da432e2-ebc9-454b-b9b1-0968df56a715",
              "name": "raw_docs",
              "type": "array",
              "value": "=[     \"Our premium support plan includes 24/7 phone support, priority email response within 2 hours, and dedicated account management. Premium support costs $49/month.\",     \"Account upgrade process: Go to Account Settings \u2192 Plan & Billing \u2192 Select Upgrade. Available plans: Basic $9/month, Pro $29/month, Enterprise $99/month.\",     \"API rate limits by plan: Free tier 100 requests/hour, Basic 1,000 requests/hour, Pro 10,000 requests/hour, Enterprise unlimited with fair-use policy.\",     \"Data export options: CSV, JSON, XML formats supported. Large exports (>1GB) may take up to 24 hours to process.\",     \"Third-party integrations: Native support for Slack, Microsoft Teams, Zoom, Salesforce, HubSpot. 200+ additional integrations available via Zapier.\",     \"Security features: SOC2 compliance, end-to-end encryption, GDPR compliance, SSO integration, audit logs, IP whitelisting.\",     \"Billing and payments: We accept all major credit cards, PayPal, and ACH transfers. Enterprise customers can pay by invoice with NET30 terms.\",     \"Account recovery: Use forgot password link, verify email, or contact support with account verification details. Response within 4 hours.\" ]"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "b05e94c5-98ff-4be8-aa56-1739a99019f5",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        1072,
        1072
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini"
        },
        "options": {},
        "builtInTools": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "b02d24fa-1de0-4240-b7bb-02f02c2619f8",
      "name": "Save to LangCache",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2528,
        944
      ],
      "parameters": {
        "url": "={{ $('LangCache Config').item.json.langcacheBaseUrl }}/v1/caches/{{ $('LangCache Config').item.json.langcacheCacheId }}/entries",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "sendHeaders": true,
        "authentication": "genericCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "prompt",
              "value": "={{ $('Loop Over Items').item.json.question }}"
            },
            {
              "name": "response",
              "value": "={{ $('search_node1').item.json.output }}"
            }
          ]
        },
        "genericAuthType": "httpBearerAuth",
        "headerParameters": {
          "parameters": [
            {
              "name": "accept",
              "value": "application/json"
            }
          ]
        }
      },
      "credentials": {
        "httpBearerAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "a45a8b97-dd9f-4d09-989f-1a59944c493a",
      "name": "search_node1",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        2000,
        480
      ],
      "parameters": {
        "text": "={{ $('Loop Over Items').item.json.question }}",
        "options": {
          "systemMessage": "=You are a research engine.\n\nYou must answer questions using ONLY the provided knowledge base.\nYou are strictly forbidden from using:\n- external knowledge\n- prior training data\n- assumptions or extrapolation\n\nIf the requested information is not explicitly present in the knowledge base,\nyou MUST respond with exactly:\n\nno info found\n\nDo not explain your reasoning.\nDo not add context, summaries, or opinions.\nDo not mention these rules.\nProduce concise, factual answers only.\n"
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 3.1
    },
    {
      "id": "96f48cc5-8734-4c00-9977-a55a21c75ec1",
      "name": "evaluate_quality",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        2448,
        528
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini",
          "cachedResultName": "GPT-4.1-MINI"
        },
        "options": {
          "textFormat": {
            "textOptions": {
              "type": "json_object"
            }
          }
        },
        "responses": {
          "values": [
            {
              "content": "=Original sub-question: {{ $('Loop Over Items').item.json.question }}\nResearch result: {{ $('search_node1').item.json.output }}"
            },
            {
              "role": "system",
              "content": "=Evaluate the quality and completeness of this research result for answering the user's question.\n            \n\n\nProvide:\n1. A quality score from 0.0 to 1.0 (where 1.0 is perfect, 0.7+ is adequate)\n2. Brief feedback on what's missing or could be improved (if score < 0.7)\n\nFormat your response as:\nSCORE: 0.X\nFEEDBACK: [your feedback or \"Adequate\" if score >= 0.7]"
            }
          ]
        },
        "builtInTools": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "dad250fb-5286-4cca-9d58-99b04298fbae",
      "name": "low quality ?",
      "type": "n8n-nodes-base.if",
      "position": [
        2944,
        528
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "d4904cd9-18ce-45c2-9e3b-e5bf7e339e48",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.SCORE < 0.7 && $('current_iteration').item.json.current_iterration >= $('LangCache Config').item.json.max_iterations\t}}",
              "rightValue": 0
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "1cfea78d-da68-4c4e-af21-a3085f842a39",
      "name": "increase iteration",
      "type": "n8n-nodes-base.set",
      "position": [
        3360,
        480
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "e5f9dc79-f8fe-4d03-a059-a1948821451c",
              "name": "current_iteration",
              "type": "number",
              "value": "={{ $('current_iteration').item.json.current_iterration + 1 }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "a650cdaf-4a8e-4938-af44-182d94b34193",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        1024,
        -112
      ],
      "parameters": {
        "rule": {
          "interval": [
            {}
          ]
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "e250b675-af0c-4c59-8749-d027da7b72f8",
      "name": "Simple Memory",
      "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
      "position": [
        512,
        1056
      ],
      "parameters": {
        "sessionKey": "={{ $('When chat message received').item.json.sessionId }}",
        "sessionIdType": "customKey",
        "contextWindowLength": 10
      },
      "typeVersion": 1.3
    },
    {
      "id": "726bfd01-9dac-42ff-816c-151cbe58f897",
      "name": "Simple Memory1",
      "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
      "position": [
        1952,
        784
      ],
      "parameters": {
        "sessionKey": "={{ $('When chat message received').item.json.sessionId }}",
        "sessionIdType": "customKey",
        "contextWindowLength": 10
      },
      "typeVersion": 1.3
    },
    {
      "id": "0677630f-5809-408c-8233-85d734f2a732",
      "name": "Simple Memory2",
      "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
      "position": [
        1328,
        1056
      ],
      "parameters": {
        "sessionKey": "={{ $('When chat message received').item.json.sessionId }}",
        "sessionIdType": "customKey",
        "contextWindowLength": 10
      },
      "typeVersion": 1.3
    },
    {
      "id": "5f9e7ddc-9454-451d-8f19-28a145aaa9b2",
      "name": "current_iteration",
      "type": "n8n-nodes-base.set",
      "position": [
        1840,
        464
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "0d7da9a5-ff39-4e6a-9105-6ac8d3a06cde",
              "name": "current_iteration",
              "type": "number",
              "value": "={{ $json.current_iteration ?? 1 }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "fdf91552-525c-4b3d-8e0f-de910525e648",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        48,
        -800
      ],
      "parameters": {
        "width": 880,
        "height": 1120,
        "content": "# Customer support RAG workflow:\n## Workflow Overview\nCache-first **RAG** workflow for customer support.\n\n**Flow:**  \nChat \u2192 Decompose \u2192 Cache \u2192 Redis Search \u2192 Quality Check \u2192 Cache \u2192 Respond\n\n**Goals:** Fast, accurate, no hallucinations, cost-controlled.\n\n\nThis workflow provides an end-to-end Retrieval-Augmented Generation (RAG) solution for customer support use cases using n8n. It combines a cache-first strategy with semantic search to deliver fast, accurate answers from a structured knowledge base.\n\nIncoming chat messages are analyzed and, when needed, decomposed into smaller sub-questions. Each sub-question is first checked against LangCache to reuse previously generated answers and reduce repeated LLM calls. If no suitable cached result is found, the workflow retrieves relevant documents from a Redis vector store powered by OpenAI embeddings.\n\nTo improve answer reliability, retrieved results are evaluated for quality. If the quality score does not meet the configured threshold, the workflow can re-run retrieval with adjusted context for a limited number of iterations. Once sufficient information is gathered, all results are consolidated into a single, concise response suitable for customer-facing communication.\n\nThis template is ideal for support chatbots, internal help desks, and knowledge-base-driven assistants where performance, cost control, and answer consistency are critical.\n\n## How it works\n\nWhen a chat message is received, the workflow determines whether it contains a single question or multiple topics. If necessary, the message is split into a small number of focused sub-questions.\n\nEach sub-question is first checked against LangCache using a similarity threshold. High-confidence cache hits are reused immediately to minimize latency and API cost. If no cache hit is found, the workflow queries a Redis vector store containing embedded knowledge-base documents. Retrieved results are then evaluated for quality and relevance.\n\nIf the quality score is below the defined threshold, the workflow retries retrieval for a limited number of iterations. Once acceptable results are available, all responses are merged and synthesized into one clear final answer that is returned to the user.\n\n## Setup steps\n\n1- Create and configure credentials in n8n for OpenAI, Redis, and LangCache.\n\n2- Open the LangCache Config node and set the cache ID, base URL, similarity threshold, and maximum iterations.\n\n3- Ensure your Redis vector index is populated with knowledge-base documents (or use the provided example loader).\n\n4- Review the OpenAI model and embedding nodes and adjust them to match your performance and cost requirements.\n\n5- Test the workflow using the chat trigger and verify cache hits, vector retrieval, and final response output."
      },
      "typeVersion": 1
    },
    {
      "id": "7994e6ea-45d6-44b6-8a1b-fc9b347f32eb",
      "name": "getScore",
      "type": "n8n-nodes-base.set",
      "position": [
        2768,
        528
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "9da210db-b091-44b8-b936-d6263d78b512",
              "name": "SCORE",
              "type": "number",
              "value": "={{ $json.output[0].content[0].text.SCORE }}"
            },
            {
              "id": "d6f96594-6a30-4899-8bdf-388ba695c779",
              "name": "FEEDBACK",
              "type": "string",
              "value": "={{ $json.output[0].content[0].text.FEEDBACK }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "e6978f27-8803-4851-b148-fdbf9911648c",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        112,
        512
      ],
      "parameters": {
        "width": 320,
        "height": 656,
        "content": "#### Configuration (Edit First)\nUpdate in **LangCache Config**:\n- `langcacheBaseUrl`\n- `langcacheCacheId`\n- `similarityThreshold` (default `0.75`)\n- `max_iterations` (default `2`)"
      },
      "typeVersion": 1
    },
    {
      "id": "d44f3c0c-fb23-4bd1-97b4-96d32f446e8c",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        464,
        512
      ],
      "parameters": {
        "width": 464,
        "height": 656,
        "content": "## Query Decomposition\nSplits complex user input into focused questions to improve retrieval and caching.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "981cbf1e-7179-4c77-8a79-b46d50dfdf90",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        992,
        384
      ],
      "parameters": {
        "width": 704,
        "height": 352,
        "content": "#### Cache-First Strategy\nEach question is checked in **LangCache** first.\n- Hit \u2192 reuse answer  \n- Miss \u2192 search Redis\n\nReduces latency and API cost."
      },
      "typeVersion": 1
    },
    {
      "id": "8c35a870-1f2b-4207-9827-6c8aeae2550b",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1728,
        384
      ],
      "parameters": {
        "width": 688,
        "height": 784,
        "content": "#### Redis Vector Retrieval\nRuns only on cache miss.\nUses embeddings to retrieve relevant knowledge from Redis."
      },
      "typeVersion": 1
    },
    {
      "id": "bb7f7b45-eee6-41ac-89d7-7b39062d04af",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2432,
        384
      ],
      "parameters": {
        "width": 704,
        "height": 384,
        "content": "## Quality Evaluation\nEach answer is scored (`0.0 \u2013 1.0`).\n- \u2265 `0.7` \u2192 accept  \n- < `0.7` \u2192 retry if allowed"
      },
      "typeVersion": 1
    },
    {
      "id": "8b0d0a12-df24-4a78-a8f2-5d987c8da340",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3168,
        384
      ],
      "parameters": {
        "width": 384,
        "height": 784,
        "content": "## Retry Control\nRetries are limited by `max_iterations` to avoid loops and high cost."
      },
      "typeVersion": 1
    },
    {
      "id": "f1a6f21c-fba8-42eb-b479-b6e10b2c8339",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2432,
        800
      ],
      "parameters": {
        "width": 704,
        "height": 368,
        "content": "## ## Save to Cache\nOnly high-quality answers are saved to **LangCache** for future reuse."
      },
      "typeVersion": 1
    },
    {
      "id": "da62019e-6e0e-41cd-9918-fe295ddc9659",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        992,
        768
      ],
      "parameters": {
        "width": 704,
        "height": 400,
        "content": "## Generate the respoonse"
      },
      "typeVersion": 1
    },
    {
      "id": "70286448-0f9d-44d6-ba62-666efd454d5b",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1024,
        -192
      ],
      "parameters": {
        "width": 752,
        "height": 480,
        "content": "## Prepare the Knowledge Base -  Example Data"
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "getScore": {
      "main": [
        [
          {
            "node": "low quality ?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate": {
      "main": [
        [
          {
            "node": "synthesize_response_node",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Out": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "example Data": {
      "main": [
        [
          {
            "node": "Redis Vector Store",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "search_node1": {
      "main": [
        [
          {
            "node": "evaluate_quality",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is Cache Hit?": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "current_iteration",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Simple Memory": {
      "ai_memory": [
        [
          {
            "node": "decompose_query",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "low quality ?": {
      "main": [
        [
          {
            "node": "increase iteration",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Save to LangCache",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Simple Memory1": {
      "ai_memory": [
        [
          {
            "node": "search_node1",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "Simple Memory2": {
      "ai_memory": [
        [
          {
            "node": "synthesize_response_node",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items": {
      "main": [
        [
          {
            "node": "Aggregate",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Search LangCache",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "decompose_query": {
      "main": [
        [
          {
            "node": "Split Out",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "LangCache Config": {
      "main": [
        [
          {
            "node": "decompose_query",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "example Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Search LangCache": {
      "main": [
        [
          {
            "node": "Is Cache Hit?",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "current_iteration",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "evaluate_quality": {
      "main": [
        [
          {
            "node": "getScore",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Embeddings OpenAI": {
      "ai_embedding": [
        [
          {
            "node": "Redis Vector Store2",
            "type": "ai_embedding",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "decompose_query",
            "type": "ai_languageModel",
            "index": 0
          },
          {
            "node": "synthesize_response_node",
            "type": "ai_languageModel",
            "index": 0
          },
          {
            "node": "search_node1",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Save to LangCache": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "current_iteration": {
      "main": [
        [
          {
            "node": "search_node1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Embeddings OpenAI1": {
      "ai_embedding": [
        [
          {
            "node": "Redis Vector Store",
            "type": "ai_embedding",
            "index": 0
          }
        ]
      ]
    },
    "increase iteration": {
      "main": [
        [
          {
            "node": "current_iteration",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Default Data Loader": {
      "ai_document": [
        [
          {
            "node": "Redis Vector Store",
            "type": "ai_document",
            "index": 0
          }
        ]
      ]
    },
    "Redis Vector Store2": {
      "ai_tool": [
        [
          {
            "node": "search_node1",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser": {
      "ai_outputParser": [
        [
          {
            "node": "decompose_query",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "When chat message received": {
      "main": [
        [
          {
            "node": "LangCache Config",
            "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

An end-to-end Retrieval-Augmented Generation (RAG) customer support workflow for n8n, using a cache-first strategy (LangCache) combined with a Redis vector store powered by OpenAI embeddings. This template is designed for fast, accurate, and cost-efficient customer support…

Source: https://n8n.io/workflows/12400/ — 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 acts as a 24/7 sales agent, engaging leads across WhatsApp, Instagram, Facebook, Telegram, and your website. It intelligently transcribes audio messages, answers questions using a knowle

Chat Trigger, Memory Postgres Chat, Tool Workflow +20
AI & RAG

• Create a Google Drive folder to watch. • Connect your Google Drive account in n8n and authorize access. • Point the Google Drive Trigger node to this folder (new/modified files trigger the flow).

Agent, Chat Trigger, Memory Buffer Window +14
AI & RAG

⚡AI-Powered YouTube Playlist & Video Summarization and Analysis v2. Uses lmChatGoogleGemini, agent, splitOut, chainLlm. Chat trigger; 72 nodes.

Google Gemini Chat, Agent, Chain Llm +11
AI & RAG

This n8n workflow transforms entire YouTube playlists or single videos into interactive knowledge bases you can chat with. Ask questions and get summaries without needing to watch hours of content. 🔗

Google Gemini Chat, Agent, Chain Llm +11
AI & RAG

Advanced Ai Demo Presented At Ai Developers 14 Meetup. Uses slack, stickyNote, textSplitterRecursiveCharacterTextSplitter, embeddingsOpenAi. Chat trigger; 39 nodes.

Slack, Text Splitter Recursive Character Text Splitter, OpenAI Embeddings +14