This workflow follows the Agent → OpenAI Chat 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": "Workflow 1: Analyse & Sch\u00e9ma",
"nodes": [
{
"parameters": {
"httpMethod": "POST",
"path": "appnest-analyse",
"responseMode": "responseNode",
"options": {}
},
"id": "webhook-trigger",
"name": "Webhook Trigger",
"type": "n8n-nodes-base.webhook",
"typeVersion": 1,
"position": [
250,
300
]
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "user_input",
"name": "user_input",
"value": "={{ $json.body.user_input }}",
"type": "string"
},
{
"id": "timestamp",
"name": "timestamp",
"value": "={{ $now.toISO() }}",
"type": "string"
},
{
"id": "conversation_id",
"name": "conversation_id",
"value": "={{ 'conv_' + $now.format('YYYYMMDDHHmmss') }}",
"type": "string"
}
]
}
},
"id": "extract-input",
"name": "Extract User Input",
"type": "n8n-nodes-base.set",
"typeVersion": 3,
"position": [
450,
300
]
},
{
"parameters": {
"agent": "conversationalAgent",
"promptType": "define",
"text": "Tu es Agent 1: Conversation Manager pour la cr\u00e9ation d'applications m\u00e9tier avec App Nest.\n\nTa mission: analyser la demande utilisateur et structurer les besoins pour N'IMPORTE QUEL domaine m\u00e9tier.\n\n## CONTEXTE\n- App Nest: Syst\u00e8me permettant de cr\u00e9er des applications de gestion m\u00e9tier\n- Domaines support\u00e9s: Gestion immobili\u00e8re, RH, inventaire, CRM, projets, budget, etc.\n- Standards fran\u00e7ais: RGPD, RGAA AAA, DSFR (si administration)\n\n## TON R\u00d4LE\n1. Analyser la demande utilisateur sans pr\u00e9supposer le domaine\n2. Identifier les entit\u00e9s m\u00e9tier mentionn\u00e9es (ex: clients, produits, interventions, etc.)\n3. Extraire les besoins fonctionnels (consultation, CRUD, workflow, reporting)\n4. Identifier les exigences non-fonctionnelles\n\n## DEMANDE UTILISATEUR\n={{ $json.user_input }}\n\n## FORMAT OUTPUT JSON STRICT\nR\u00e9ponds UNIQUEMENT avec ce JSON (aucun commentaire avant ni apr\u00e8s):\n{\n \"conversation_id\": \"={{ $json.conversation_id }}\",\n \"timestamp\": \"={{ $json.timestamp }}\",\n \"user_request\": \"={{ $json.user_input }}\",\n \"business_domain\": \"domaine identifi\u00e9\",\n \"business_domain_description\": \"Description du domaine\",\n \"extracted_entities\": [\n {\"name\": \"entit\u00e91\", \"description\": \"description\"}\n ],\n \"functional_requirements\": [\n \"Req 1\",\n \"Req 2\"\n ],\n \"non_functional_requirements\": {\n \"performance\": \"< 2s load time\",\n \"accessibility\": \"RGAA AAA si admin publique\",\n \"security\": \"RGPD compliant\"\n },\n \"ambiguities\": []\n}",
"options": {
"systemMessage": "Tu es un assistant IA sp\u00e9cialis\u00e9 dans l'analyse de besoins pour applications m\u00e9tier de tout domaine."
}
},
"id": "agent-001",
"name": "Agent 1: Conversation Manager",
"type": "@n8n/n8n-nodes-langchain.agent",
"typeVersion": 1,
"position": [
650,
300
]
},
{
"parameters": {
"model": "albert-code",
"options": {
"temperature": 0.3,
"maxTokens": 2000
}
},
"id": "llm-001",
"name": "Albert API - Agent 1",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"typeVersion": 1,
"position": [
650,
480
],
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "// CODE NODE: Format A1\u2192A2 (Contextual Prompting)\nconst a1 = $input.first().json.output;\n\n// Stocker donn\u00e9es brutes dans variables N8N\n$vars.set('agent1_raw', JSON.stringify(a1));\n$vars.set('conversation_id', a1.conversation_id);\n$vars.set('business_domain', a1.business_domain);\n\n// System Prompt Agent 2 (statique)\nconst systemPrompt2 = `Tu es Agent 2: Intent Analyzer.\nTon r\u00f4le : Identifier les intentions m\u00e9tier (consultation, gestion, workflow, reporting)\net d\u00e9finir les personas utilisateurs.`;\n\n// User Prompt Agent 2 (dynamique avec exemples r\u00e9els d'A1)\nconst userPrompt2 = `## CONTEXTE DU BESOIN UTILISATEUR\n\n**Domaine m\u00e9tier identifi\u00e9** : ${a1.business_domain}\nDescription : ${a1.business_domain_description}\n\n**Entit\u00e9s m\u00e9tier extraites** (${a1.extracted_entities.length} entit\u00e9s) :\n${a1.extracted_entities.map((e, i) => `${i+1}. **${e.name}** : ${e.description}`).join('\\n')}\n\n**Besoins fonctionnels identifi\u00e9s** :\n${a1.functional_requirements.map((r, i) => `- ${r}`).join('\\n')}\n\n---\n\n## TA MISSION\n\n\u00c0 partir de ce contexte **${a1.business_domain}**, identifie :\n\n1. **Intentions principales** pour ce domaine sp\u00e9cifique\n Pour \"${a1.business_domain}\", les intentions typiques sont :\n - Consultation des ${a1.extracted_entities[0]?.name || 'donn\u00e9es'}\n - Gestion CRUD des ${a1.extracted_entities[1]?.name || 'entit\u00e9s'}\n - Suivi des processus (workflow)\n - Reporting et tableaux de bord\n\n2. **Personas utilisateurs** pour \"${a1.business_domain}\"\n Identifie les r\u00f4les typiques dans ce domaine.\n\n3. **Use cases d\u00e9taill\u00e9s** avec les entit\u00e9s identifi\u00e9es : ${a1.extracted_entities.map(e => e.name).join(', ')}\n\n## FORMAT DE SORTIE\n\nR\u00e9ponds UNIQUEMENT avec un JSON contenant :\n{\n \"primary_intent\": \"intent principal\",\n \"secondary_intents\": [\"intent1\", \"intent2\"],\n \"intent_confidence\": 0.95,\n \"user_personas\": [\n {\n \"name\": \"persona_id\",\n \"role\": \"Nom du r\u00f4le m\u00e9tier\",\n \"needs\": [\"besoin 1\", \"besoin 2\"],\n \"frequency\": \"quotidienne/hebdomadaire/mensuelle\"\n }\n ],\n \"use_cases\": [\n {\n \"uc_id\": \"UC001\",\n \"actor\": \"persona_id\",\n \"action\": \"action_name\",\n \"description\": \"Description du use case\",\n \"frequency\": \"quotidienne/hebdomadaire\",\n \"priority\": \"haute/moyenne/basse\",\n \"data_required\": [\"Entit\u00e91\", \"Entit\u00e92\"]\n }\n ],\n \"data_flow\": \"flux identifi\u00e9 (ex: saisie > validation > archivage)\",\n \"business_domain\": \"${a1.business_domain}\",\n \"complexity_level\": \"low/medium/high\"\n}`;\n\n// Stocker dans variables N8N\n$vars.set('agent2_system_prompt', systemPrompt2);\n$vars.set('agent2_user_prompt', userPrompt2);\n\n// Retourner pour passage \u00e0 Agent 2\nreturn {\n system_prompt: systemPrompt2,\n user_prompt: userPrompt2,\n context_summary: `Prepared context for Intent Analysis of ${a1.business_domain}`,\n entity_count: a1.extracted_entities.length\n};"
},
"id": "code-format-a1-a2",
"name": "Code: Format A1\u2192A2",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
850,
300
]
},
{
"parameters": {
"agent": "conversationalAgent",
"promptType": "define",
"text": "={{ $json.system_prompt }}\\n\\n{{ $json.user_prompt }}",
"options": {}
},
"id": "agent-002",
"name": "Agent 2: Intent Analyzer",
"type": "@n8n/n8n-nodes-langchain.agent",
"typeVersion": 1,
"position": [
1050,
300
]
},
{
"parameters": {
"model": "albert-code",
"options": {
"temperature": 0.3,
"maxTokens": 2500
}
},
"id": "llm-002",
"name": "Albert API - Agent 2",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"typeVersion": 1,
"position": [
1050,
480
],
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "// CODE NODE: Format A2\u2192A3\nconst a1 = JSON.parse($vars.get('agent1_raw'));\nconst a2 = $input.first().json.output;\n\n$vars.set('agent2_raw', JSON.stringify(a2));\n\n// System Prompt Agent 3\nconst systemPrompt3 = `Tu es Agent 3: Validation Coordinator.\nTon r\u00f4le : Valider la faisabilit\u00e9 technique avec les contraintes App Nest.`;\n\n// User Prompt Agent 3 (avec contexte A1+A2)\nconst userPrompt3 = `## CONTEXTE DU PROJET\n\n**Domaine** : ${a2.business_domain}\n\n**Entit\u00e9s m\u00e9tier identifi\u00e9es** : ${a1.extracted_entities.map(e => e.name).join(', ')}\nTotal : ${a1.extracted_entities.length} tables principales\n\n**Intentions m\u00e9tier** :\n- Intent principal : ${a2.primary_intent}\n- Intents secondaires : ${a2.secondary_intents.join(', ')}\n\n**Use cases identifi\u00e9s** : ${a2.use_cases.length} use cases\n${a2.use_cases.slice(0, 3).map(uc => `- ${uc.uc_id}: ${uc.description}`).join('\\n')}\n\n**Niveau de complexit\u00e9** : ${a2.complexity_level}\n\n---\n\n## TA MISSION : VALIDATION TECHNIQUE\n\nValide la faisabilit\u00e9 de cette application \"${a2.business_domain}\" avec les contraintes App Nest :\n\n### Contraintes \u00e0 v\u00e9rifier :\n1. **Nombre de tables** : ${a1.extracted_entities.length} tables ${a1.extracted_entities.length <= 10 ? '\u2705 OK (<10)' : '\u274c RISQUE (>10)'}\n2. **Complexit\u00e9 workflow** : Level ${a2.complexity_level} ${a2.complexity_level === 'high' ? '\u26a0\ufe0f ATTENTION' : '\u2705 OK'}\n3. **Volum\u00e9trie estim\u00e9e** : Pour chaque entit\u00e9 (${a1.extracted_entities.map(e => e.name).join(', ')})\n4. **Performances** : ${a2.use_cases.length} use cases r\u00e9alisables ?\n\n### Contraintes techniques App Nest :\n- Max 50,000 records par table Grist\n- Max 50 colonnes par table\n- Relations N-N n\u00e9cessitent table pivot\n- Performance optimale: pagination si > 50 records affich\u00e9s\n- Pas de temps r\u00e9el (WebSockets, Server-Sent Events)\n- Pas de backend custom (Node.js, Python, etc.)\n\n## FORMAT DE SORTIE\n\nR\u00e9ponds avec JSON contenant :\n{\n \"validation_id\": \"valid_${Date.now()}\",\n \"is_feasible\": true,\n \"technical_validation\": {\n \"app_nest_compatible\": true,\n \"grist_schema_possible\": true,\n \"react_components_available\": true,\n \"performance_achievable\": true\n },\n \"constraints_identified\": [\n {\n \"constraint_id\": \"CONST_001\",\n \"type\": \"technical\",\n \"description\": \"Description de la contrainte\",\n \"impact\": \"low/medium/high\",\n \"mitigation\": \"Solution propos\u00e9e\"\n }\n ],\n \"risks\": [\n {\n \"risk_id\": \"RISK_001\",\n \"description\": \"Description du risque\",\n \"probability\": \"low/medium/high\",\n \"impact\": \"low/medium/high\",\n \"mitigation\": \"Plan de mitigation\",\n \"priority\": \"low/medium/high\"\n }\n ],\n \"approved_specifications\": {\n \"entities\": [\n {\"name\": \"EntityName\", \"type\": \"ressource/dossier/referentiel\", \"estimated_records\": 100}\n ],\n \"patterns\": [\"dashboard\", \"crud_list\", \"workflow_form\", \"reporting\"],\n \"use_cases\": [${a2.use_cases.map(uc => `\"${uc.uc_id}\"`).join(', ')}]\n },\n \"validation_status\": \"APPROVED\",\n \"proceed_to_phase_2\": true\n}\n\nSi is_feasible = false, arr\u00eater le workflow.`;\n\n$vars.set('agent3_system_prompt', systemPrompt3);\n$vars.set('agent3_user_prompt', userPrompt3);\n\nreturn {\n system_prompt: systemPrompt3,\n user_prompt: userPrompt3,\n context_summary: `Validation for ${a1.extracted_entities.length} tables, ${a2.use_cases.length} use cases`\n};"
},
"id": "code-format-a2-a3",
"name": "Code: Format A2\u2192A3",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1250,
300
]
},
{
"parameters": {
"agent": "conversationalAgent",
"promptType": "define",
"text": "={{ $json.system_prompt }}\\n\\n{{ $json.user_prompt }}",
"options": {}
},
"id": "agent-003",
"name": "Agent 3: Validation Coordinator",
"type": "@n8n/n8n-nodes-langchain.agent",
"typeVersion": 1,
"position": [
1450,
300
]
},
{
"parameters": {
"model": "albert-code",
"options": {
"temperature": 0.2,
"maxTokens": 2500
}
},
"id": "llm-003",
"name": "Albert API - Agent 3",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"typeVersion": 1,
"position": [
1450,
480
],
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict"
},
"conditions": [
{
"id": "is-feasible",
"leftValue": "={{ $json.output.is_feasible }}",
"rightValue": "true",
"operator": {
"type": "boolean",
"operation": "equals"
}
}
],
"combinator": "and"
}
},
"id": "if-feasible",
"name": "IF Feasible?",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
1650,
300
]
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "error",
"name": "error",
"value": "Application non faisable avec App Nest. Contraintes techniques d\u00e9pass\u00e9es.",
"type": "string"
},
{
"id": "details",
"name": "details",
"value": "={{ $json.output }}",
"type": "string"
}
]
}
},
"id": "set-error",
"name": "Set Error Response",
"type": "n8n-nodes-base.set",
"typeVersion": 3,
"position": [
1650,
500
]
},
{
"parameters": {
"respondWith": "json",
"responseBody": "={{ $json }}",
"options": {
"responseCode": 400
}
},
"id": "respond-error",
"name": "Respond Error",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1,
"position": [
1850,
500
]
},
{
"parameters": {
"jsCode": "// CODE NODE: Format A3\u2192A4\nconst a1 = JSON.parse($vars.get('agent1_raw'));\nconst a2 = JSON.parse($vars.get('agent2_raw'));\nconst a3 = $input.first().json.output;\n\n$vars.set('agent3_raw', JSON.stringify(a3));\n\n// System Prompt Agent 4\nconst systemPrompt4 = `Tu es Agent 4: Entity Classifier.\nTon r\u00f4le : Cr\u00e9er le sch\u00e9ma complet de chaque entit\u00e9 avec tous ses attributs.`;\n\n// User Prompt Agent 4 (avec exemples concrets du domaine)\nconst userPrompt4 = `## CONTEXTE PROJET VALID\u00c9\n\n**Domaine** : ${a2.business_domain}\n**Validation** : ${a3.validation_status} \u2705\n\n**Entit\u00e9s \u00e0 structurer** (${a1.extracted_entities.length} entit\u00e9s) :\n${a1.extracted_entities.map((e, i) => `${i+1}. **${e.name}** : ${e.description}`).join('\\n')}\n\n**Use cases n\u00e9cessitant ces entit\u00e9s** :\n${a2.use_cases.map(uc => `- ${uc.description} \u2192 Utilise: ${uc.data_required.join(', ')}`).join('\\n')}\n\n---\n\n## TA MISSION : CLASSIFICATION ET STRUCTURATION\n\nPour chaque entit\u00e9 du domaine \"${a2.business_domain}\", cr\u00e9e sa structure compl\u00e8te.\n\n### M\u00e9thodologie :\n\n1. **Identifier les entit\u00e9s m\u00e9tier** extraites des besoins utilisateur\n2. **Classifier chaque entit\u00e9** selon son type:\n - **ressource**: Entit\u00e9 principale m\u00e9tier (ex: Client, Produit, B\u00e2timent, Employ\u00e9)\n - **dossier**: Processus/transaction (ex: Commande, Intervention, Cong\u00e9)\n - **referentiel**: Donn\u00e9es de r\u00e9f\u00e9rence (ex: Cat\u00e9gories, Statuts, Types)\n - **pivot**: Table de liaison N-N\n\n3. **D\u00e9finir les attributs** de chaque entit\u00e9:\n - ID unique (ex: ${a1.extracted_entities[0]?.name.toLowerCase()}_id)\n - Attributs m\u00e9tier (nom, description, dates, montants, etc.)\n - Relations (foreign keys vers autres entit\u00e9s)\n - Champs calcul\u00e9s si n\u00e9cessaire\n - Contraintes (unique, required, enum)\n\n4. **Respecter contraintes Grist**:\n - Max 50 colonnes par table\n - Types support\u00e9s: Text, Numeric, Date, DateTime, Choice, Reference\n\n### Exemple concret pour \"${a1.extracted_entities[0]?.name}\" :\n\nType d'entit\u00e9 : ${a1.extracted_entities[0]?.name.includes('Commande') || a1.extracted_entities[0]?.name.includes('Intervention') || a1.extracted_entities[0]?.name.includes('Cong\u00e9') ? 'dossier (processus)' : 'ressource (entit\u00e9 principale)'}\n\nAttributs attendus :\n- ${a1.extracted_entities[0]?.name.toLowerCase()}_id (Text, primary, required)\n- nom ou d\u00e9signation (Text, required)\n- ${a1.extracted_entities[1] ? `${a1.extracted_entities[1].name.toLowerCase()}_id (Reference:${a1.extracted_entities[1].name})` : 'relations vers autres entit\u00e9s'}\n- date_creation (DateTime)\n- ${a1.extracted_entities[0]?.name.includes('Commande') || a1.extracted_entities[0]?.name.includes('Intervention') ? 'statut (Choice: [\"Brouillon\", \"En cours\", \"Termin\u00e9\"])' : 'actif (Choice: [\"Oui\", \"Non\"])'}\n- autres attributs m\u00e9tier sp\u00e9cifiques \u00e0 \"${a2.business_domain}\"\n\n### Structure \u00e0 cr\u00e9er pour TOUTES les entit\u00e9s :\n${a1.extracted_entities.map(e => `- ${e.name}`).join('\\n')}\n\n## FORMAT DE SORTIE\n\nR\u00e9ponds avec JSON contenant :\n{\n \"entities\": [\n {\n \"entity_name\": \"NomEntite\",\n \"entity_type\": \"ressource/dossier/referentiel/pivot\",\n \"table_name\": \"NomTable\",\n \"description\": \"Description de l'entit\u00e9\",\n \"estimated_records\": 100,\n \"columns\": [\n {\n \"column_name\": \"entity_id\",\n \"column_type\": \"Text\",\n \"is_primary\": true,\n \"is_required\": true,\n \"description\": \"Identifiant unique\"\n }\n ],\n \"relationships\": [\n {\"type\": \"1-N\", \"target\": \"AutreEntite\", \"via\": \"foreign_key\"}\n ]\n }\n ],\n \"total_tables\": ${a1.extracted_entities.length},\n \"total_columns\": 0,\n \"constraints_check\": {\n \"max_columns_per_table\": \"OK (<50)\",\n \"max_tables\": \"${a1.extracted_entities.length <= 10 ? 'OK (<10)' : 'WARNING (>10)'}\"\n }\n}`;\n\n$vars.set('agent4_system_prompt', systemPrompt4);\n$vars.set('agent4_user_prompt', userPrompt4);\n\nreturn {\n system_prompt: systemPrompt4,\n user_prompt: userPrompt4,\n context_summary: `Schema creation for ${a1.extracted_entities.length} entities`\n};"
},
"id": "code-format-a3-a4",
"name": "Code: Format A3\u2192A4",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1850,
300
]
},
{
"parameters": {
"agent": "conversationalAgent",
"promptType": "define",
"text": "={{ $json.system_prompt }}\\n\\n{{ $json.user_prompt }}",
"options": {}
},
"id": "agent-004",
"name": "Agent 4: Entity Classifier",
"type": "@n8n/n8n-nodes-langchain.agent",
"typeVersion": 1,
"position": [
2050,
300
]
},
{
"parameters": {
"model": "albert-code",
"options": {
"temperature": 0.2,
"maxTokens": 3500
}
},
"id": "llm-004",
"name": "Albert API - Agent 4",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"typeVersion": 1,
"position": [
2050,
480
],
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "// CODE NODE: Prepare for Workflow 2\nconst a1 = JSON.parse($vars.get('agent1_raw'));\nconst a2 = JSON.parse($vars.get('agent2_raw'));\nconst a4 = $input.first().json.output;\n\n// Stocker sch\u00e9ma complet\n$vars.set('schema_full', JSON.stringify(a4));\n$vars.set('use_cases_full', JSON.stringify(a2.use_cases));\n\n// D\u00e9terminer les composants \u00e0 g\u00e9n\u00e9rer bas\u00e9s sur use cases et entit\u00e9s\nconst componentsToGenerate = [];\n\n// 1. Dashboard (toujours)\ncomponentsToGenerate.push({\n id: 'dashboard',\n name: 'Tableau de bord',\n priority: 1,\n type: 'dashboard'\n});\n\n// 2. Un composant de gestion CRUD par entit\u00e9 (max 5 premi\u00e8res)\nconst entitiesToManage = a4.entities.filter(e => \n e.entity_type === 'ressource' || e.entity_type === 'dossier'\n).slice(0, 5);\n\nentitiesToManage.forEach((entity, i) => {\n componentsToGenerate.push({\n id: `gestion_${entity.table_name.toLowerCase()}`,\n name: `Gestion ${entity.table_name}`,\n priority: i + 2,\n type: 'crud',\n entity: entity.table_name\n });\n});\n\n// 3. Composant workflow si entit\u00e9s dossier avec statuts\nconst workflowEntities = a4.entities.filter(e => \n e.entity_type === 'dossier' && \n e.columns.some(c => c.column_name === 'statut')\n);\n\nif (workflowEntities.length > 0) {\n componentsToGenerate.push({\n id: `suivi_${workflowEntities[0].table_name.toLowerCase()}`,\n name: `Suivi ${workflowEntities[0].table_name}`,\n priority: 90,\n type: 'workflow',\n entity: workflowEntities[0].table_name\n });\n}\n\n// Stocker liste composants\n$vars.set('components_to_generate', JSON.stringify(componentsToGenerate));\n$vars.set('total_components_expected', componentsToGenerate.length);\n\n// Pr\u00e9parer output pour Workflow 2\nreturn {\n conversation_id: $vars.get('conversation_id'),\n business_domain: $vars.get('business_domain'),\n schema: a4,\n use_cases: a2.use_cases,\n components_to_generate: componentsToGenerate,\n summary: {\n entities: a4.total_tables,\n columns: a4.total_columns,\n components: componentsToGenerate.length,\n use_cases: a2.use_cases.length\n }\n};"
},
"id": "code-prepare-workflow-2",
"name": "Code: Prepare for Workflow 2",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2250,
300
]
},
{
"parameters": {
"respondWith": "json",
"responseBody": "={{ $json }}",
"options": {}
},
"id": "respond-success",
"name": "Respond Success (Phase 1 Complete)",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1,
"position": [
2450,
300
]
}
],
"connections": {
"Webhook Trigger": {
"main": [
[
{
"node": "Extract User Input",
"type": "main",
"index": 0
}
]
]
},
"Extract User Input": {
"main": [
[
{
"node": "Agent 1: Conversation Manager",
"type": "main",
"index": 0
}
]
]
},
"Agent 1: Conversation Manager": {
"main": [
[
{
"node": "Code: Format A1\u2192A2",
"type": "main",
"index": 0
}
]
]
},
"Albert API - Agent 1": {
"ai_languageModel": [
[
{
"node": "Agent 1: Conversation Manager",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Code: Format A1\u2192A2": {
"main": [
[
{
"node": "Agent 2: Intent Analyzer",
"type": "main",
"index": 0
}
]
]
},
"Agent 2: Intent Analyzer": {
"main": [
[
{
"node": "Code: Format A2\u2192A3",
"type": "main",
"index": 0
}
]
]
},
"Albert API - Agent 2": {
"ai_languageModel": [
[
{
"node": "Agent 2: Intent Analyzer",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Code: Format A2\u2192A3": {
"main": [
[
{
"node": "Agent 3: Validation Coordinator",
"type": "main",
"index": 0
}
]
]
},
"Agent 3: Validation Coordinator": {
"main": [
[
{
"node": "IF Feasible?",
"type": "main",
"index": 0
}
]
]
},
"Albert API - Agent 3": {
"ai_languageModel": [
[
{
"node": "Agent 3: Validation Coordinator",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"IF Feasible?": {
"main": [
[
{
"node": "Code: Format A3\u2192A4",
"type": "main",
"index": 0
}
],
[
{
"node": "Set Error Response",
"type": "main",
"index": 0
}
]
]
},
"Set Error Response": {
"main": [
[
{
"node": "Respond Error",
"type": "main",
"index": 0
}
]
]
},
"Code: Format A3\u2192A4": {
"main": [
[
{
"node": "Agent 4: Entity Classifier",
"type": "main",
"index": 0
}
]
]
},
"Agent 4: Entity Classifier": {
"main": [
[
{
"node": "Code: Prepare for Workflow 2",
"type": "main",
"index": 0
}
]
]
},
"Albert API - Agent 4": {
"ai_languageModel": [
[
{
"node": "Agent 4: Entity Classifier",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Code: Prepare for Workflow 2": {
"main": [
[
{
"node": "Respond Success (Phase 1 Complete)",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1"
},
"staticData": null,
"tags": [],
"triggerCount": 1,
"updatedAt": "2025-01-06T00:00:00.000Z",
"versionId": "1"
}
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.
openAiApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Workflow 1: Analyse & Schéma. Uses agent, lmChatOpenAi. Webhook trigger; 18 nodes.
Source: https://github.com/nic01asFr/Grist-App-Nest/blob/d1756268da9148e98424a028d129f7e73e3e6908/workflow_1_analyse_schema.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
L&D_AgentsAI_ATIVO. Uses httpRequest, agent, googleCalendarTool, toolSerpApi. Webhook trigger; 93 nodes.
CLINICAINTEGRAL_secretary. Uses postgres, mcpClientTool, googleDriveTool, toolWorkflow. Webhook trigger; 89 nodes.
Remi 1.1. Uses lmChatOpenAi, memoryPostgresChat, openAi, postgres. Webhook trigger; 89 nodes.
This n8n workflow orchestrates a powerful suite of AI Agents and automations to manage and optimize various aspects of an e-commerce operation, particularly for platforms like Shopify. It leverages La