AutomationFlowsAI & RAG › Simple N8N Workflow

Simple N8N Workflow

Simple N8N Workflow. Uses agent, lmChatOpenAi, memoryBufferWindow, respondToWebhook. Webhook trigger; 14 nodes.

Webhook trigger★★★★☆ complexityAI-powered14 nodesAgentLm Chat Open AiMemory Buffer WindowOpen Ai
AI & RAG Trigger: Webhook Nodes: 14 Complexity: ★★★★☆ AI nodes: yes

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": [
    {
      "parameters": {
        "promptType": "define",
        "text": "={{ $json.body.query }}",
        "options": {
          "systemMessage": "={{ $json.body.system_prompt }}\n{{ $json.body && $json.body.structure != null ? \"You must return the final answer strictly as JSON that conforms to the following schema: \" + JSON.stringify($json.body.structure) : \"\" }}",
          "passthroughBinaryImages": true,
          "enableStreaming": "={{ $json.body.stream }}"
        }
      },
      "type": "@n8n/n8n-nodes-langchain.agent",
      "typeVersion": 2.2,
      "position": [
        288,
        -96
      ],
      "id": "067cd63e-55be-4c7b-a233-bdd172de2dd5",
      "name": "Agent"
    },
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "agent",
        "responseMode": "streaming",
        "options": {}
      },
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2.1,
      "position": [
        32,
        -96
      ],
      "id": "d6cb88e7-5273-4f69-9291-85545e50d305",
      "name": "Webhook"
    },
    {
      "parameters": {
        "jsCode": "return items.map(item => {\n  if (item.json?.body?.voice) {\n    item.json.body.voice = String(item.json.body.voice).toLowerCase();\n  }\n  return item;\n});\n"
      },
      "id": "39db000a-2584-4257-8b62-695f2c725bff",
      "name": "Parse Voice",
      "type": "n8n-nodes-base.code",
      "position": [
        160,
        -272
      ],
      "typeVersion": 1
    },
    {
      "parameters": {
        "model": {
          "__rl": true,
          "value": "gpt-5-mini",
          "mode": "list",
          "cachedResultName": "gpt-5-mini"
        },
        "options": {
          "responseFormat": "={{ ($json.body && $json.body.structure != null) ? 'json_object' : 'text' }}"
        }
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "typeVersion": 1.2,
      "position": [
        288,
        80
      ],
      "id": "08897615-add4-49dd-9f75-e066abe4ce91",
      "name": "LLM",
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "sessionIdType": "customKey",
        "sessionKey": "={{ $json.body.conversation_id }}"
      },
      "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
      "typeVersion": 1.3,
      "position": [
        384,
        80
      ],
      "id": "881a1f54-0edc-4b8f-b923-e03d8d34922a",
      "name": "Memory"
    },
    {
      "parameters": {
        "respondWith": "binary",
        "options": {}
      },
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.4,
      "position": [
        416,
        -272
      ],
      "id": "c57297cc-c125-4d9b-a12e-7010429cd695",
      "name": "TTS Response"
    },
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "tts",
        "responseMode": "responseNode",
        "options": {}
      },
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2.1,
      "position": [
        32,
        -272
      ],
      "id": "f7a1a52d-2847-48a6-9a6b-9f76b02739fa",
      "name": "Webhook TTS"
    },
    {
      "parameters": {
        "resource": "audio",
        "input": "={{ $json.body.text }}",
        "voice": "={{ $json.body.voice }}",
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "typeVersion": 1.8,
      "position": [
        288,
        -272
      ],
      "id": "3619c359-1c5e-410e-8649-07f8b166ca30",
      "name": "TTS",
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// n8n Code node (JavaScript) \u2014 Split binary_objects then merge into one item\n\nif (!items || items.length === 0) {\n  return [];\n}\n\nconst originalJson = items[0].json ?? {};\nconst binaryList = Array.isArray(originalJson?.body?.binary_objects)\n  ? originalJson.body.binary_objects\n  : [];\n\n/** Remove any data:...;base64, prefix from a base64 string */\nfunction stripDataUrlPrefix(value) {\n  return String(value ?? '').replace(/^data:.*?;base64,/, '');\n}\n\n/** Cross-platform basename */\nfunction getBaseName(pathValue) {\n  const s = String(pathValue ?? '');\n  const slash = s.split('/').pop();\n  const backslash = s.split('\\\\').pop();\n  return (slash && slash.length <= s.length ? slash : backslash) || '';\n}\n\n/** Sanitize a key; fallback to data<index> if empty */\nfunction makeSafeKey(name, index) {\n  const cleaned = String(name ?? '')\n    .trim()\n    .toLowerCase()\n    .replace(/[^a-z0-9_\\-]/g, '_');\n  return cleaned || `data${index}`;\n}\n\nconst mergedBinary = {};\n\n// If there are binaries, collect them all into a single `binary` object\nif (binaryList.length > 0) {\n  for (let i = 0; i < binaryList.length; i++) {\n    const binaryObject = binaryList[i];\n\n    const desiredKey = makeSafeKey(binaryObject?.name, i);\n    let finalKey = desiredKey;\n    if (mergedBinary[finalKey]) {\n      finalKey = `${finalKey}__${i}`; // avoid overwriting on collision\n    }\n\n    mergedBinary[finalKey] = {\n      data: stripDataUrlPrefix(binaryObject?.data),\n      fileName: getBaseName(binaryObject?.path) || desiredKey,\n      mimeType: binaryObject?.mime_type || 'application/octet-stream',\n    };\n  }\n}\n\n// Match the merger node: keep first JSON and add _sources reflecting the (virtual) split count\nconst outputJson = {\n  ...(originalJson ?? {}),\n  _sources:\n    binaryList.length > 0\n      ? Array.from({ length: binaryList.length }, (_, i) => ({ index: i, ...(originalJson ?? {}) }))\n      : [{ index: 0, ...(originalJson ?? {}) }],\n};\n\n// If no binaries existed, keep an empty `binary` object (merger node behavior)\nreturn [\n  {\n    json: outputJson,\n    binary: mergedBinary,\n  },\n];\n"
      },
      "id": "8930a0a0-57eb-4794-b409-2eb1bd8ba21f",
      "name": "Attachments",
      "type": "n8n-nodes-base.code",
      "position": [
        160,
        -96
      ],
      "typeVersion": 1
    },
    {
      "parameters": {
        "resource": "audio",
        "operation": "transcribe",
        "binaryPropertyName": "audio",
        "options": {
          "language": "={{ $json.body.language }}"
        }
      },
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "typeVersion": 1.8,
      "position": [
        288,
        -448
      ],
      "id": "e44f61fc-3454-4236-82c4-a16f804d1934",
      "name": "STT",
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "options": {}
      },
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.4,
      "position": [
        544,
        -448
      ],
      "id": "004e2ed1-7e40-4c33-8676-865b0150773e",
      "name": "STT Response"
    },
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "stt",
        "responseMode": "responseNode",
        "options": {}
      },
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2.1,
      "position": [
        32,
        -448
      ],
      "id": "992a0376-59f9-459f-b6d5-c9d6964d09d1",
      "name": "Webhook STT"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "09bd748c-5334-46ed-a9ed-a4f51c6d340a",
              "name": "output",
              "value": "={{ $json.text }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        416,
        -448
      ],
      "id": "ce888b04-8c32-45b7-8ef3-15da9c71ff41",
      "name": "Extract Output"
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "// n8n Code node \u2014 Extract WebhookSTTRequestPayload.audio into binary\n\nconst audio = $json.body.audio;\n\nfunction stripDataUrlPrefix(value) {\n  return String(value ?? '').replace(/^data:.*?;base64,/, '');\n}\n\nlet binary = {};\n\nif (audio && audio.data) {\n  binary['audio'] = {\n    data: stripDataUrlPrefix(audio.data), // base64 only\n    fileName: audio.name || 'audio',\n    mimeType: audio.mime_type || 'application/octet-stream',\n  };\n}\n\nreturn {\n  $json,\n  binary,\n};\n"
      },
      "id": "56bae826-a297-4d86-9190-bfefdd7a3e2d",
      "name": "Extract Audio",
      "type": "n8n-nodes-base.code",
      "position": [
        160,
        -448
      ],
      "typeVersion": 1
    }
  ],
  "connections": {
    "Agent": {
      "main": [
        []
      ]
    },
    "Webhook": {
      "main": [
        [
          {
            "node": "Attachments",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Voice": {
      "main": [
        [
          {
            "node": "TTS",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "LLM": {
      "ai_languageModel": [
        [
          {
            "node": "Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Memory": {
      "ai_memory": [
        [
          {
            "node": "Agent",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "Webhook TTS": {
      "main": [
        [
          {
            "node": "Parse Voice",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "TTS": {
      "main": [
        [
          {
            "node": "TTS Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Attachments": {
      "main": [
        [
          {
            "node": "Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "STT": {
      "main": [
        [
          {
            "node": "Extract Output",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "STT Response": {
      "main": [
        []
      ]
    },
    "Webhook STT": {
      "main": [
        [
          {
            "node": "Extract Audio",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Output": {
      "main": [
        [
          {
            "node": "STT Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Audio": {
      "main": [
        [
          {
            "node": "STT",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "meta": {
    "templateCredsSetupCompleted": true
  }
}

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.

About this workflow

Simple N8N Workflow. Uses agent, lmChatOpenAi, memoryBufferWindow, respondToWebhook. Webhook trigger; 14 nodes.

Source: https://github.com/EuleMitKeule/webhook-conversation/blob/master/examples/simple_n8n_workflow.json — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →