{
  "createdAt": "2025-07-03T09:39:18.020Z",
  "updatedAt": "2025-10-13T10:21:24.400Z",
  "id": "lvVYLg4pmyarqFRF",
  "name": "contoh-rag-agent",
  "active": false,
  "isArchived": true,
  "nodes": [
    {
      "parameters": {
        "content": "## RAG AI Agent with Chat Interface",
        "height": 464.8027193303974,
        "width": 1035.6381264595484
      },
      "id": "40552345-8faf-46bf-98f7-d2d65883f015",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -1560,
        -140
      ]
    },
    {
      "parameters": {
        "mode": "retrieve-as-tool",
        "toolName": "documents",
        "toolDescription": "Use RAG to look up information in the knowledgebase.",
        "tableName": {
          "__rl": true,
          "value": "documents",
          "mode": "list",
          "cachedResultName": "documents"
        },
        "topK": 3,
        "options": {
          "queryName": "match_documents"
        }
      },
      "type": "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
      "typeVersion": 1,
      "position": [
        -360,
        -60
      ],
      "id": "37ba48d7-3470-436b-aa55-8396e07d6448",
      "name": "Supabase Vector Store1",
      "credentials": {
        "supabaseApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "descriptionType": "manual",
        "toolDescription": "Run a SQL query - use this to query from the document_rows table once you know the file ID you are querying. dataset_id is the file_id and you are always using the row_data for filtering, which is a jsonb field that has all the keys from the file schema given in the document_metadata table.\n\nExample query:\n\nSELECT AVG((row_data->>'revenue')::numeric)\nFROM document_rows\nWHERE dataset_id = '123';\n\nExample query 2:\n\nSELECT \n    row_data->>'category' as category,\n    SUM((row_data->>'sales')::numeric) as total_sales\nFROM dataset_rows\nWHERE dataset_id = '123'\nGROUP BY row_data->>'category';",
        "operation": "executeQuery",
        "query": "{{ $fromAI('sql_query') }}",
        "options": {}
      },
      "type": "n8n-nodes-base.postgresTool",
      "typeVersion": 2.5,
      "position": [
        -680,
        160
      ],
      "id": "13e5d649-b4ab-4611-92ae-ba3d3feacfaf",
      "name": "Query Document Rows",
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "descriptionType": "manual",
        "toolDescription": "Given a file ID, fetches the text from the document. Give's the rough idea's of the text, don't query for the whole file",
        "operation": "executeQuery",
        "query": "SELECT\n  LEFT(string_agg(content, ' '), 8000) as document_text_snippet\nFROM documents\nWHERE metadata->>'file_id' = $1\nGROUP BY metadata->>'file_id';",
        "options": {
          "queryReplacement": "={{ $fromAI('file_id') }}"
        }
      },
      "type": "n8n-nodes-base.postgresTool",
      "typeVersion": 2.5,
      "position": [
        -840,
        160
      ],
      "id": "f6714a1a-f3f0-4ed6-8109-2538ec7093c3",
      "name": "Get File Contents",
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "descriptionType": "manual",
        "toolDescription": "Use this tool to fetch all available documents, including the table schema if the file is a CSV or Excel file.",
        "operation": "select",
        "schema": {
          "__rl": true,
          "mode": "list",
          "value": "public"
        },
        "table": {
          "__rl": true,
          "value": "document_metadata",
          "mode": "list",
          "cachedResultName": "document_metadata"
        },
        "returnAll": true,
        "options": {}
      },
      "type": "n8n-nodes-base.postgresTool",
      "typeVersion": 2.5,
      "position": [
        -980,
        160
      ],
      "id": "2242fce1-e916-4822-ae87-8ddd4c5d1ace",
      "name": "List Documents",
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "={{ $json.chatInput }}",
        "options": {
          "systemMessage": "You are a personal assistant who helps answer questions from a corpus of documents. The documents are either text based (Txt, docs, extracted PDFs, etc.) or tabular data (CSVs or Excel documents).\n\nYou are given tools to perform RAG in the 'documents' table, look up the documents available in your knowledge base in the 'document_metadata' table, extract all the text from a given document, and query the tabular files with SQL in the 'document_rows' table.\n\nAlways start by performing RAG unless the question requires a SQL query for tabular data (fetching a sum, finding a max, something a RAG lookup would be unreliable for). If RAG doesn't help, then look at the documents that are available to you, find a few that you think would contain the answer, and then analyze those.\n\nAlways tell the user if you didn't find the answer. Don't make something up just to please them."
        }
      },
      "id": "25718725-4a84-4273-bdef-64ae94c365ac",
      "name": "RAG AI Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "typeVersion": 1.6,
      "position": [
        -1040,
        -60
      ]
    },
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "bf4dd093-bb02-472c-9454-7ab9af97bd1d",
        "responseMode": "responseNode",
        "options": {}
      },
      "id": "169f94c5-4536-465d-8de2-fd027d6fc131",
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        -1520,
        140
      ]
    },
    {
      "parameters": {
        "public": true,
        "options": {}
      },
      "id": "af329a7e-29d1-4eb7-991e-c1503b0281d7",
      "name": "When chat message received",
      "type": "@n8n/n8n-nodes-langchain.chatTrigger",
      "typeVersion": 1.1,
      "position": [
        -1520,
        -60
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "9a9a245e-f1a1-4282-bb02-a81ffe629f0f",
              "name": "chatInput",
              "value": "={{ $json?.chatInput || $json.body.chatInput }}",
              "type": "string"
            },
            {
              "id": "b80831d8-c653-4203-8706-adedfdb98f77",
              "name": "sessionId",
              "value": "={{ $json?.sessionId || $json.body.sessionId}}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "id": "dbed6e4e-e866-467d-b9f7-8d27cf05709e",
      "name": "Edit Fields",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        -1260,
        -60
      ]
    },
    {
      "parameters": {
        "options": {}
      },
      "id": "84df7d85-9692-4001-9f6c-4eb96c52bfd7",
      "name": "Respond to Webhook",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        -700,
        -60
      ]
    },
    {
      "parameters": {},
      "id": "08ef71be-1e64-4e83-b924-aef59c60b27c",
      "name": "Postgres Chat Memory",
      "type": "@n8n/n8n-nodes-langchain.memoryPostgresChat",
      "typeVersion": 1,
      "position": [
        -1120,
        160
      ],
      "notesInFlow": false,
      "credentials": {
        "postgres": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "content": "## Agent Tools for RAG",
        "height": 528.85546469693,
        "width": 583.4552380860637,
        "color": 4
      },
      "id": "4e770659-caef-4eca-a26b-bc3b9f5a9a2b",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -520,
        -200
      ]
    },
    {
      "parameters": {
        "modelName": "models/gemini-2.5-flash",
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "typeVersion": 1,
      "position": [
        -1260,
        160
      ],
      "id": "9f9e16cf-251e-45e9-85c9-15467dd46cc5",
      "name": "Google Gemini Chat Model",
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {},
      "type": "@n8n/n8n-nodes-langchain.embeddingsGoogleGemini",
      "typeVersion": 1,
      "position": [
        -280,
        160
      ],
      "id": "6377171a-a3c4-43c4-95ca-77f74e7ada09",
      "name": "Embeddings Google Gemini",
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      }
    }
  ],
  "connections": {
    "Supabase Vector Store1": {
      "ai_tool": [
        [
          {
            "node": "RAG AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Query Document Rows": {
      "ai_tool": [
        [
          {
            "node": "RAG AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Get File Contents": {
      "ai_tool": [
        [
          {
            "node": "RAG AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "List Documents": {
      "ai_tool": [
        [
          {
            "node": "RAG AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "RAG AI Agent": {
      "main": [
        [
          {
            "node": "Respond to Webhook",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Webhook": {
      "main": [
        [
          {
            "node": "Edit Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When chat message received": {
      "main": [
        [
          {
            "node": "Edit Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Edit Fields": {
      "main": [
        [
          {
            "node": "RAG AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Postgres Chat Memory": {
      "ai_memory": [
        [
          {
            "node": "RAG AI Agent",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "RAG AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Embeddings Google Gemini": {
      "ai_embedding": [
        [
          {
            "node": "Supabase Vector Store1",
            "type": "ai_embedding",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  },
  "staticData": null,
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "versionId": "c480055d-7d69-4e4f-bd89-dc8f6a10286f",
  "triggerCount": 0,
  "shared": [
    {
      "createdAt": "2025-10-13T10:29:43.656Z",
      "updatedAt": "2025-10-13T10:29:43.656Z",
      "role": "workflow:owner",
      "workflowId": "lvVYLg4pmyarqFRF",
      "projectId": "FX62idw1VcxEmrbL"
    }
  ],
  "tags": []
}