This workflow follows the Agent → HTTP Request 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 →
{
"name": "WF3 - Consulta RAG | JurisAI",
"nodes": [
{
"id": "sticky_wf3",
"name": "\ud83d\udccb WF3 - Consulta RAG Principal",
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
-220,
-140
],
"parameters": {
"content": "## WF3 \u2014 Consulta RAG Principal\n\n**Endpoint:** `POST /webhook/jurisai/query` \n**Rate Limits:** estagi\u00e1rio=10rpm \u00b7 advogado=25rpm \u00b7 curador=50rpm \u00b7 admin=100rpm\n\n**Body esperado:**\n```json\n{\n \"query\": \"texto da pergunta\",\n \"session_id\": \"uuid-da-sessao\",\n \"legal_area\": [\"urbanistico\"],\n \"territory\": \"federal\",\n \"uf\": \"SP\" \n}\n```\n\n**Fluxo:**\n1. JWT validate \u2192 rate limit\n2. Roteamento de inten\u00e7\u00e3o (Haiku)\n3. Busca hist\u00f3rico da sess\u00e3o\n4. Embed query \u2192 Qdrant search (status=em_vigor)\n5. Rerank top 8 \u2192 preparar contexto\n6. AI Agent (Claude Sonnet) via LangChain\n7. SHA-256 query, log LGPD-compliant\n8. Salvar sess\u00e3o + responder\n\n\u2699\ufe0f Configure credencial Anthropic no n\u00f3 'Claude Sonnet (LLM)'",
"height": 370,
"width": 470,
"color": 6
}
},
{
"id": "webhook_wf3",
"name": "Webhook Consulta",
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [
250,
400
],
"parameters": {
"path": "jurisai/query",
"httpMethod": "POST",
"responseMode": "responseNode",
"options": {
"allowedOrigins": "*"
}
}
},
{
"id": "validate_jwt_wf3",
"name": "Validar JWT",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
500,
400
],
"parameters": {
"jsCode": "const authHeader = $('Webhook Consulta').first().json.headers?.authorization || '';\nconst token = authHeader.replace(/^Bearer\\s+/i, '').trim();\nif (!token) throw new Error('401:Token de autentica\u00e7\u00e3o n\u00e3o fornecido');\n\ntry {\n const parts = token.split('.');\n if (parts.length !== 3) throw new Error('401:Token JWT inv\u00e1lido');\n const payloadB64 = parts[1].replace(/-/g, '+').replace(/_/g, '/');\n const padded = payloadB64 + '='.repeat((4 - (payloadB64.length % 4)) % 4);\n const payload = JSON.parse(Buffer.from(padded, 'base64').toString('utf8'));\n if (payload.exp && payload.exp < Math.floor(Date.now() / 1000)) throw new Error('401:Token expirado');\n\n const userId = payload.sub;\n const role = payload.user_metadata?.role || payload.role || 'estagiario';\n const body = $('Webhook Consulta').first().json.body || {};\n\n if (!body.query || body.query.trim().length < 10) throw new Error('400:Query deve ter pelo menos 10 caracteres');\n if (body.query.length > 2000) throw new Error('400:Query n\u00e3o pode exceder 2000 caracteres');\n\n const rateLimits = { estagiario: 10, advogado: 25, curador: 50, admin: 100 };\n const rpmLimit = rateLimits[role] || 10;\n\n return [{ json: {\n user_id: userId,\n role,\n rpm_limit: rpmLimit,\n query: body.query.trim(),\n session_id: body.session_id || `sess_${userId}_${Date.now()}`,\n legal_area: Array.isArray(body.legal_area) ? body.legal_area : (body.legal_area ? [body.legal_area] : []),\n territory: body.territory || null,\n uf: body.uf || null\n } }];\n} catch(e) {\n const msg = e.message || 'Erro';\n if (/^(400|401|403):/.test(msg)) throw new Error(msg);\n throw new Error('401:Falha na valida\u00e7\u00e3o do token');\n}"
}
},
{
"id": "check_rate_limit",
"name": "Verificar Rate Limit (Supabase)",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
750,
400
],
"parameters": {
"method": "GET",
"url": "={{ $env.SUPABASE_URL }}/rest/v1/query_logs?user_id=eq.{{ $json.user_id }}&created_at=gte.{{ new Date(Date.now() - 60000).toISOString() }}&select=id",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "={{ $env.SUPABASE_SERVICE_KEY }}"
},
{
"name": "Authorization",
"value": "=Bearer {{ $env.SUPABASE_SERVICE_KEY }}"
},
{
"name": "Prefer",
"value": "count=exact"
}
]
}
},
"continueOnFail": true
},
{
"id": "eval_rate_limit",
"name": "Rate Limit Excedido?",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
1000,
400
],
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict"
},
"conditions": [
{
"id": "cond_rate",
"leftValue": "={{ ($('Verificar Rate Limit (Supabase)').first().json?.length || 0) >= $('Validar JWT').first().json.rpm_limit }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "equals"
}
}
],
"combinator": "and"
}
}
},
{
"id": "respond_rate_limit",
"name": "Responder 429 Rate Limit",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1,
"position": [
1250,
520
],
"parameters": {
"respondWith": "json",
"responseBody": "={{ JSON.stringify({ success: false, error: 'Rate limit excedido. Tente novamente em alguns instantes.', rpm_limit: $('Validar JWT').first().json.rpm_limit }) }}",
"options": {
"responseCode": 429
}
}
},
{
"id": "route_intent",
"name": "Rotear Inten\u00e7\u00e3o (Claude Haiku)",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1250,
300
],
"parameters": {
"method": "POST",
"url": "https://api.anthropic.com/v1/messages",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "x-api-key",
"value": "={{ $env.ANTHROPIC_API_KEY }}"
},
{
"name": "anthropic-version",
"value": "2023-06-01"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"contentType": "json",
"body": "={{ JSON.stringify({ model: $env.LLM_TRIAGE, max_tokens: 64, temperature: 0, system: 'Classifique a consulta jur\u00eddica. Responda APENAS com uma destas palavras: consulta, analise, producao_doc, multitematica, fora_do_escopo. Escopo: direito urban\u00edstico, imobili\u00e1rio, tribut\u00e1rio, trabalhista, contratual, civil, penal e administrativo brasileiro.', messages: [{ role: 'user', content: $('Validar JWT').first().json.query }] }) }}"
}
},
{
"id": "parse_intent",
"name": "Parse Inten\u00e7\u00e3o",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1500,
300
],
"parameters": {
"jsCode": "const text = ($('Rotear Inten\u00e7\u00e3o (Claude Haiku)').first().json?.content?.[0]?.text || 'consulta').trim().toLowerCase();\nconst validTypes = ['consulta', 'analise', 'producao_doc', 'multitematica', 'fora_do_escopo'];\nconst intent = validTypes.includes(text) ? text : 'consulta';\nconst jwtData = $('Validar JWT').first().json;\nreturn [{ json: { ...jwtData, intent, is_out_of_scope: intent === 'fora_do_escopo' } }];"
}
},
{
"id": "if_out_of_scope",
"name": "Fora do Escopo?",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
1750,
300
],
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict"
},
"conditions": [
{
"id": "cond_scope",
"leftValue": "={{ $json.is_out_of_scope }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "equals"
}
}
],
"combinator": "and"
}
}
},
{
"id": "respond_out_of_scope",
"name": "Responder Fora do Escopo",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1,
"position": [
2000,
450
],
"parameters": {
"respondWith": "json",
"responseBody": "={{ JSON.stringify({ success: false, intent: 'fora_do_escopo', error: 'Esta consulta est\u00e1 fora do escopo jur\u00eddico do JurisAI. Por favor, fa\u00e7a perguntas sobre direito urban\u00edstico, imobili\u00e1rio, tribut\u00e1rio, trabalhista, contratual, civil, penal ou administrativo brasileiro.' }) }}",
"options": {
"responseCode": 422
}
}
},
{
"id": "get_history",
"name": "Buscar Hist\u00f3rico da Sess\u00e3o",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
2000,
250
],
"parameters": {
"method": "GET",
"url": "={{ $env.SUPABASE_URL }}/rest/v1/chat_sessions?session_id=eq.{{ $json.session_id }}&user_id=eq.{{ $json.user_id }}&select=role,content&order=created_at.desc&limit=10",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "={{ $env.SUPABASE_SERVICE_KEY }}"
},
{
"name": "Authorization",
"value": "=Bearer {{ $env.SUPABASE_SERVICE_KEY }}"
}
]
}
},
"continueOnFail": true
},
{
"id": "embed_query",
"name": "Gerar Embedding da Query",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
2250,
250
],
"parameters": {
"method": "POST",
"url": "https://api.openai.com/v1/embeddings",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "=Bearer {{ $env.OPENAI_API_KEY }}"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"contentType": "json",
"body": "={{ JSON.stringify({ model: $env.EMBEDDING_MODEL, input: $('Parse Inten\u00e7\u00e3o').first().json.query }) }}"
}
},
{
"id": "search_qdrant",
"name": "Buscar no Qdrant",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
2500,
250
],
"parameters": {
"method": "POST",
"url": "={{ $env.QDRANT_URL }}/collections/{{ $env.QDRANT_COLLECTION }}/points/search",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "api-key",
"value": "={{ $env.QDRANT_API_KEY }}"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"contentType": "json",
"body": "={{ (() => { const intentData = $('Parse Inten\u00e7\u00e3o').first().json; const embedding = $json.data?.[0]?.embedding || []; const mustFilters = [{ key: 'status', match: { value: 'em_vigor' } }]; if (intentData.legal_area && intentData.legal_area.length > 0) { mustFilters.push({ key: 'legal_area', match: { any: intentData.legal_area } }); } if (intentData.uf) { mustFilters.push({ key: 'uf', match: { value: intentData.uf } }); } return JSON.stringify({ vector: embedding, limit: 10, with_payload: true, with_vector: false, filter: { must: mustFilters } }); })() }}"
}
},
{
"id": "prepare_context",
"name": "Reranking e Prepara\u00e7\u00e3o do Contexto",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2750,
250
],
"parameters": {
"jsCode": "const intentData = $('Parse Inten\u00e7\u00e3o').first().json;\nconst rawQuery = intentData.query;\nconst qdrantResults = $('Buscar no Qdrant').first().json?.result || [];\nconst historyRaw = $('Buscar Hist\u00f3rico da Sess\u00e3o').first().json || [];\nconst history = Array.isArray(historyRaw) ? historyRaw.reverse() : [];\n\n// Rerank por score e relev\u00e2ncia (top 8)\nconst ranked = qdrantResults\n .sort((a, b) => (b.score || 0) - (a.score || 0))\n .slice(0, 8);\n\n// Montar contexto\nconst contextChunks = ranked.map((r, i) => {\n const p = r.payload || {};\n return `[${i+1}] ${p.doc_type?.toUpperCase() || 'DOC'} | ${p.issuer || ''} | ${p.published_at || ''} | ${p.territory || ''}\\n${p.text || ''}`;\n}).join('\\n\\n---\\n\\n');\n\n// Fontes para cita\u00e7\u00e3o\nconst sources = ranked.map(r => ({\n document_id: r.payload?.document_id,\n doc_type: r.payload?.doc_type,\n issuer: r.payload?.issuer,\n published_at: r.payload?.published_at,\n score: r.score\n}));\n\n// Hist\u00f3rico de conversa formatado\nconst chatHistory = history.slice(-8).map(m => `${m.role === 'user' ? 'Usu\u00e1rio' : 'JurisAI'}: ${m.content}`).join('\\n');\n\n// System prompt\nconst systemPrompt = `Voc\u00ea \u00e9 o JurisAI, assistente jur\u00eddico especializado em direito brasileiro. Responda com precis\u00e3o e cite os documentos fornecidos usando [N] onde N \u00e9 o n\u00famero do documento.\n\nDOCUMENTOS DO CORPUS:\n${contextChunks || 'Nenhum documento relevante encontrado no corpus.'}\n\nINSTRU\u00c7\u00d5ES:\n- Seja preciso e cite sempre as fontes com [N]\n- Se n\u00e3o encontrar informa\u00e7\u00e3o no corpus, declare explicitamente\n- Use linguagem jur\u00eddica apropriada mas acess\u00edvel\n- Limite a resposta a 800 palavras`;\n\n// Human prompt com hist\u00f3rico\nconst humanPrompt = chatHistory \n ? `HIST\u00d3RICO DESTA SESS\u00c3O:\\n${chatHistory}\\n\\nNOVA PERGUNTA: ${rawQuery}`\n : rawQuery;\n\nreturn [{ json: {\n ...intentData,\n systemPrompt,\n humanPrompt,\n sources,\n context_count: ranked.length\n} }];"
}
},
{
"id": "lm_claude_sonnet",
"name": "Claude Sonnet (LLM)",
"type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
"typeVersion": 1.3,
"position": [
3000,
500
],
"parameters": {
"model": "={{ $env.LLM_MAIN || 'claude-sonnet-4-5' }}",
"options": {
"maxTokens": 2048,
"temperature": 0.3
}
},
"credentials": {
"anthropicApi": {
"name": "<your credential>"
}
}
},
{
"id": "ai_agent_rag",
"name": "AI Agent RAG",
"type": "@n8n/n8n-nodes-langchain.agent",
"typeVersion": 1.7,
"position": [
3000,
250
],
"parameters": {
"agent": "conversationalAgent",
"promptType": "define",
"text": "={{ $json.humanPrompt }}",
"hasOutputParser": false,
"options": {
"systemMessage": "={{ $json.systemPrompt }}",
"maxIterations": 3,
"returnIntermediateSteps": false
}
}
},
{
"id": "parse_agent_response",
"name": "Parsear Resposta e Cita\u00e7\u00f5es",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
3250,
250
],
"parameters": {
"jsCode": "const agentOutput = $json.output || $json.text || '';\nconst intentData = $('Reranking e Prepara\u00e7\u00e3o do Contexto').first().json;\n\n// Extrair cita\u00e7\u00f5es [N] usadas na resposta\nconst citationMatches = [...agentOutput.matchAll(/\\[(\\d+)\\]/g)];\nconst citedIndices = [...new Set(citationMatches.map(m => parseInt(m[1]) - 1))];\nconst usedSources = citedIndices\n .map(i => intentData.sources[i])\n .filter(Boolean);\n\n// SHA-256 da query para LGPD\nconst crypto = require('crypto');\nconst queryHash = crypto.createHash('sha256').update(intentData.query).digest('hex');\n\nreturn [{ json: {\n user_id: intentData.user_id,\n role: intentData.role,\n session_id: intentData.session_id,\n intent: intentData.intent,\n query_hash: queryHash,\n response: agentOutput,\n sources: usedSources,\n context_count: intentData.context_count\n} }];"
}
},
{
"id": "save_session_user",
"name": "Salvar Mensagem Usu\u00e1rio",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
3500,
200
],
"parameters": {
"method": "POST",
"url": "={{ $env.SUPABASE_URL }}/rest/v1/chat_sessions",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "={{ $env.SUPABASE_SERVICE_KEY }}"
},
{
"name": "Authorization",
"value": "=Bearer {{ $env.SUPABASE_SERVICE_KEY }}"
},
{
"name": "Content-Type",
"value": "application/json"
},
{
"name": "Prefer",
"value": "return=minimal"
}
]
},
"sendBody": true,
"contentType": "json",
"body": "={{ JSON.stringify({ session_id: $json.session_id, user_id: $json.user_id, role: 'user', content: $('Reranking e Prepara\u00e7\u00e3o do Contexto').first().json.query }) }}"
},
"continueOnFail": true
},
{
"id": "save_session_assistant",
"name": "Salvar Resposta JurisAI",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
3500,
320
],
"parameters": {
"method": "POST",
"url": "={{ $env.SUPABASE_URL }}/rest/v1/chat_sessions",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "={{ $env.SUPABASE_SERVICE_KEY }}"
},
{
"name": "Authorization",
"value": "=Bearer {{ $env.SUPABASE_SERVICE_KEY }}"
},
{
"name": "Content-Type",
"value": "application/json"
},
{
"name": "Prefer",
"value": "return=minimal"
}
]
},
"sendBody": true,
"contentType": "json",
"body": "={{ JSON.stringify({ session_id: $json.session_id, user_id: $json.user_id, role: 'assistant', content: $json.response }) }}"
},
"continueOnFail": true
},
{
"id": "log_query",
"name": "Log LGPD (query_logs)",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
3750,
260
],
"parameters": {
"method": "POST",
"url": "={{ $env.SUPABASE_URL }}/rest/v1/query_logs",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "={{ $env.SUPABASE_SERVICE_KEY }}"
},
{
"name": "Authorization",
"value": "=Bearer {{ $env.SUPABASE_SERVICE_KEY }}"
},
{
"name": "Content-Type",
"value": "application/json"
},
{
"name": "Prefer",
"value": "return=representation"
}
]
},
"sendBody": true,
"contentType": "json",
"body": "={{ (() => { const d = $('Parsear Resposta e Cita\u00e7\u00f5es').first().json; return JSON.stringify({ user_id: d.user_id, session_id: d.session_id, query_hash: d.query_hash, query_type: d.intent, docs_retrieved: d.context_count, created_at: new Date().toISOString() }); })() }}"
},
"continueOnFail": true
},
{
"id": "respond_success_wf3",
"name": "Responder Consulta",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1,
"position": [
4000,
260
],
"parameters": {
"respondWith": "json",
"responseBody": "={{ (() => { const d = $('Parsear Resposta e Cita\u00e7\u00f5es').first().json; const logId = $('Log LGPD (query_logs)').first().json?.[0]?.id || null; return JSON.stringify({ success: true, response: d.response, sources: d.sources, intent: d.intent, session_id: d.session_id, log_id: logId }); })() }}",
"options": {
"responseCode": 200
}
}
}
],
"connections": {
"Webhook Consulta": {
"main": [
[
{
"node": "Validar JWT",
"type": "main",
"index": 0
}
]
]
},
"Validar JWT": {
"main": [
[
{
"node": "Verificar Rate Limit (Supabase)",
"type": "main",
"index": 0
}
]
]
},
"Verificar Rate Limit (Supabase)": {
"main": [
[
{
"node": "Rate Limit Excedido?",
"type": "main",
"index": 0
}
]
]
},
"Rate Limit Excedido?": {
"main": [
[
{
"node": "Rotear Inten\u00e7\u00e3o (Claude Haiku)",
"type": "main",
"index": 0
}
],
[
{
"node": "Responder 429 Rate Limit",
"type": "main",
"index": 0
}
]
]
},
"Rotear Inten\u00e7\u00e3o (Claude Haiku)": {
"main": [
[
{
"node": "Parse Inten\u00e7\u00e3o",
"type": "main",
"index": 0
}
]
]
},
"Parse Inten\u00e7\u00e3o": {
"main": [
[
{
"node": "Fora do Escopo?",
"type": "main",
"index": 0
}
]
]
},
"Fora do Escopo?": {
"main": [
[
{
"node": "Buscar Hist\u00f3rico da Sess\u00e3o",
"type": "main",
"index": 0
}
],
[
{
"node": "Responder Fora do Escopo",
"type": "main",
"index": 0
}
]
]
},
"Buscar Hist\u00f3rico da Sess\u00e3o": {
"main": [
[
{
"node": "Gerar Embedding da Query",
"type": "main",
"index": 0
}
]
]
},
"Gerar Embedding da Query": {
"main": [
[
{
"node": "Buscar no Qdrant",
"type": "main",
"index": 0
}
]
]
},
"Buscar no Qdrant": {
"main": [
[
{
"node": "Reranking e Prepara\u00e7\u00e3o do Contexto",
"type": "main",
"index": 0
}
]
]
},
"Reranking e Prepara\u00e7\u00e3o do Contexto": {
"main": [
[
{
"node": "AI Agent RAG",
"type": "main",
"index": 0
}
]
]
},
"Claude Sonnet (LLM)": {
"ai_languageModel": [
[
{
"node": "AI Agent RAG",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"AI Agent RAG": {
"main": [
[
{
"node": "Parsear Resposta e Cita\u00e7\u00f5es",
"type": "main",
"index": 0
}
]
]
},
"Parsear Resposta e Cita\u00e7\u00f5es": {
"main": [
[
{
"node": "Salvar Mensagem Usu\u00e1rio",
"type": "main",
"index": 0
}
],
[
{
"node": "Salvar Resposta JurisAI",
"type": "main",
"index": 0
}
]
]
},
"Salvar Mensagem Usu\u00e1rio": {
"main": [
[
{
"node": "Log LGPD (query_logs)",
"type": "main",
"index": 0
}
]
]
},
"Salvar Resposta JurisAI": {
"main": [
[
{
"node": "Log LGPD (query_logs)",
"type": "main",
"index": 0
}
]
]
},
"Log LGPD (query_logs)": {
"main": [
[
{
"node": "Responder Consulta",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1",
"saveManualExecutions": false,
"errorWorkflow": ""
},
"meta": {
"templateCredsSetupCompleted": false
},
"tags": [
{
"id": "jurisai",
"name": "JurisAI"
},
{
"id": "rag",
"name": "rag-query"
}
]
}
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.
anthropicApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
WF3 - Consulta RAG | JurisAI. Uses httpRequest, lmChatAnthropic, agent. Webhook trigger; 21 nodes.
Source: https://github.com/JeffersonMFti/JurisAI/blob/f883fa2f162a02b1a2aa83da7d6d5f8fed2964b3/workflows/WF3_rag_query.json — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
⏺ 🚀 How it works
WhatsApp AI Agent - Template. Uses redis, httpRequest, postgres, agent. Webhook trigger; 89 nodes.
Airtable Operations System: Leads, AI Agent, Outreach, Sync, Canva, Make/Zapier Bridge. Uses airtable, anthropic, slack, agent. Webhook trigger; 82 nodes.
Lead Pipeline v3.0. Uses httpRequest, agent, lmChatAnthropic, toolThink. Webhook trigger; 77 nodes.
What if AI didn't just write content—but actually thought about how to write it? This n8n workflow revolutionizes content creation by deploying multiple specialized AI agents that handle every aspect