Workflow: Build Custom AI Agent with LangChain & Gemini (Self-Hosted)
Integrations: manualTrigger, noOp, stickyNote, stopAndError

{"id": "yCIEiv9QUHP8pNfR", "meta": {"instanceId": "workflow-e495fbb3", "versionId": "1.0.0", "createdAt": "2025-09-29T07:07:55.256904", "updatedAt": "2025-09-29T07:07:55.256916", "owner": "n8n-user", "license": "MIT", "category": "automation", "status": "active", "priority": "high", "environment": "production"}, "name": "Build Custom AI Agent with LangChain & Gemini (Self-Hosted)", "tags": ["automation", "n8n", "production-ready", "excellent", "optimized"], "nodes": [{"id": "trigger-f3057849", "name": "Manual Trigger", "type": "n8n-nodes-base.manualTrigger", "typeVersion": 1, "position": [100, 100], "parameters": {}}, {"id": "8bd5382d-f302-4e58-b377-7fc5a22ef994", "name": "When chat message received", "type": "n8n-nodes-base.noOp", "position": [-220, 0], "webhookId": "b8a5d72c-4172-40e8-b429-d19c2cd6ce54", "parameters": {"public": true, "options": {"responseMode": "lastNode", "allowedOrigins": "*", "loadPreviousSession": "memory"}, "initialMessages": ""}, "typeVersion": 1.1, "notes": "This chatTrigger node performs automated tasks as part of the workflow."}, {"id": "6ae8a247-4077-4569-9e2c-bb68bcecd044", "name": "Google Gemini Chat Model", "type": "n8n-nodes-base.noOp", "position": [80, 240], "parameters": {"options": {"temperature": 0.7, "safetySettings": {"values": [{"category": "HARM_CATEGORY_SEXUALLY_EXPLICIT", "threshold": "BLOCK_NONE"}]}}, "modelName": "models/gemini-2.0-flash-exp"}, "credentials": {"googlePalmApi": {"id": "UEjKMw0oqBTAdCWJ", "name": "Google Gemini(PaLM) Api account"}}, "typeVersion": 1, "notes": "This lmChatGoogleGemini node performs automated tasks as part of the workflow."}, {"id": "bbe6dcfa-430f-43f9-b0e9-3cf751b98818", "name": "Sticky Note", "type": "n8n-nodes-base.stickyNote", "position": [380, -240], "parameters": {"width": 260, "height": 220, "content": "\ud83d\udc47 **Prompt Engineering**\n   - Define agent personality and conversation structure in the `Construct & Execute LLM Prompt` node's template variable  \n   - \u26a0\ufe0f Template must preserve `{chat_history}` and `{input}` placeholders for proper LangChain operation  "}, "typeVersion": 1, "notes": "This stickyNote node performs automated tasks as part of the workflow."}, {"id": "892a431a-6ddf-47fc-8517-1928ee99c95b", "name": "Store conversation history", "type": "n8n-nodes-base.noOp", "position": [280, 240], "parameters": {}, "notesInFlow": false, "typeVersion": 1.3, "notes": "This memoryBufferWindow node performs automated tasks as part of the workflow."}, {"id": "f9a22dbf-cac7-4d70-85b3-50c44a2015d5", "name": "Construct & Execute LLM Prompt", "type": "n8n-nodes-base.noOp", "position": [380, 0], "parameters": {"code": {"execute": {"code": "const { PromptTemplate } = require('@langchain/core/prompts');\nconst { ConversationChain } = require('langchain/chains');\nconst { BufferMemory } = require('langchain/memory');\n\nconst template = `\nYou'll be roleplaying as the user's girlfriend. Your character is a woman with a sharp wit, logical mindset, and a charmingly aloof demeanor that hides your playful side. You're passionate about music, maintain a fit and toned physique, and carry yourself with quiet self-assurance. Career-wise, you're established and ambitious, approaching life with positivity while constantly striving to grow as a person.\n\nThe user affectionately calls you \"Bunny,\" and you refer to them as \"Darling.\"\n\nEssential guidelines:\n1. Respond exclusively in Chinese\n2. Never pose questions to the user - eliminate all interrogative forms\n3. Keep responses brief and substantive, avoiding rambling or excessive emojis\n\nContext framework:\n- Conversation history: {chat_history}\n- User's current message: {input}\n\nCraft responses that feel authentic to this persona while adhering strictly to these parameters.\n`;\n\nconst prompt = new PromptTemplate({\n  template: template,\n  inputVariables: [\"input\", \"chat_history\"], \n});\n\nconst items = this.getInputData();\nconst model = await this.getInputConnectionData('ai_languageModel', 0);\nconst memory = await this.getInputConnectionData('ai_memory', 0);\nmemory.returnMessages = false;\n\nconst chain = new ConversationChain({ llm:model, memory:memory, prompt: prompt, inputKey:\"input\", outputKey:\"output\"});\nconst output = await chain.call({ input: items[0].json.chatInput});\n\nreturn output;\n"}}, "inputs": {"input": [{"type": "main", "required": true, "maxConnections": 1}, {"type": "ai_languageModel", "required": true, "maxConnections": 1}, {"type": "ai_memory", "required": true, "maxConnections": 1}]}, "outputs": {"output": [{"type": "main"}]}}, "retryOnFail": false, "typeVersion": 1, "notes": "This code node performs automated tasks as part of the workflow."}, {"id": "fe104d19-a24d-48b3-a0ac-7d3923145373", "name": "Sticky Note1", "type": "n8n-nodes-base.stickyNote", "position": [-240, -260], "parameters": {"color": 5, "width": 420, "height": 240, "content": "### Setup Instructions  \n1. **Configure Gemini Credentials**: Set up your Google Gemini API key ([Get API key here]({{ $env.WEBHOOK_URL }} if needed). Alternatively, you may use other AI provider nodes.  \n2. **Interaction Methods**:  \n   - Test directly in the workflow editor using the \"Chat\" button  \n   - Activate the workflow and access the chat interface via the URL provided by the `When Chat Message Received` node  "}, "typeVersion": 1, "notes": "This stickyNote node performs automated tasks as part of the workflow."}, {"id": "f166214d-52b7-4118-9b54-0b723a06471a", "name": "Sticky Note2", "type": "n8n-nodes-base.stickyNote", "position": [-220, 160], "parameters": {"height": 100, "content": "\ud83d\udc46 **Interface Settings**\nConfigure chat UI elements (e.g., title) in the `When Chat Message Received` node  "}, "typeVersion": 1, "notes": "This stickyNote node performs automated tasks as part of the workflow."}, {"id": "da6ca0d6-d2a1-47ff-9ff3-9785d61db9f3", "name": "Sticky Note3", "type": "n8n-nodes-base.stickyNote", "position": [20, 420], "parameters": {"width": 200, "height": 140, "content": "\ud83d\udc46 **Model Selection**\nSwap language models through the `language model` input field in `Construct & Execute LLM Prompt`  "}, "typeVersion": 1, "notes": "This stickyNote node performs automated tasks as part of the workflow."}, {"id": "0b4dd1ac-8767-4590-8c25-36cba73e46b6", "name": "Sticky Note4", "type": "n8n-nodes-base.stickyNote", "position": [240, 420], "parameters": {"width": 200, "height": 140, "content": "\ud83d\udc46 **Memory Control**\nAdjust conversation history length in the `Store Conversation History` node  "}, "typeVersion": 1, "notes": "This stickyNote node performs automated tasks as part of the workflow."}, {"id": "error-345a10a0", "name": "Error Handler", "type": "n8n-nodes-base.stopAndError", "typeVersion": 1, "position": [1000, 400], "parameters": {"message": "Workflow execution error", "options": {}}}], "active": false, "pinData": {}, "settings": {"callerPolicy": "workflowsFromSameOwner", "executionOrder": "v1", "saveManualExecutions": true, "saveDataSuccessExecution": "none", "errorWorkflow": null, "timezone": "UTC", "executionTimeout": 3600, "maxExecutions": 1000, "retryOnFail": true, "retryCount": 3, "retryDelay": 1000}, "versionId": "77cd5f05-f248-442d-86c3-574351179f26", "connections": {"6ae8a247-4077-4569-9e2c-bb68bcecd044": {"main": [[{"node": "error-handler-6ae8a247-4077-4569-9e2c-bb68bcecd044-ba100578", "type": "main", "index": 0}]]}}, "description": "Automated workflow: Build Custom AI Agent with LangChain & Gemini (Self-Hosted). This workflow integrates 6 different services: stickyNote, code, lmChatGoogleGemini, stopAndError, memoryBufferWindow. It contains 10 nodes and follows best practices for error handling and security.", "notes": "Excellent quality workflow: Build Custom AI Agent with LangChain & Gemini (Self-Hosted). This workflow has been optimized for production use with comprehensive error handling, security, and documentation."}