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
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
Fully automates your service order pipeline from incoming booking to supplier confirmation — with built-in SLA enforcement and automatic escalation if a supplier goes silent. 📥 Receives orders via web
A complete WhatsApp AI chatbot that handles class bookings, cancellations, FAQ responses, schedule lookups, location queries, waitlist management, booking reminders, and staff notifications — all thro