Building an AI Agent Workflow in n8n

Learn how to build a fully automated AI content generation workflow in n8n, powered by a locally hosted Ollama model, triggered by a chat input and writing to a remote server via SSH.
Building an AI Agent Workflow in n8n
Let’s build a powerful, self-hosted AI content generation workflow using n8n. This workflow will take a user's input directly through a chat interface, feed it to a locally-running AI agent (powered by Ollama), have the agent generate content, and then write that content to a remote server using SSH. This setup isn’t just about automation; it’s a strategic pattern for repetitive creative or writing tasks – think drafting blog posts, generating marketing copy, or even brainstorming ideas. The beauty of this approach lies in its interactivity and control. You’re not relying on external APIs with potential rate limits or unpredictable behavior.
A chat-trigger-driven pipeline is particularly well-suited because it allows for real-time feedback and iteration. Unlike a simple webhook that passively receives data, the chat trigger allows you to directly refine the prompts and the generated content, creating a truly collaborative workflow. We’ll explore why this interactive control is so valuable, and how to build a robust, self-contained solution within n8n.
Setting Up the Chat Trigger Node
n8n’s Chat Trigger node is designed to handle interactive conversations directly within the n8n interface. This is different from standard webhooks or form triggers, which passively receive data. The Chat Trigger node provides you with the raw chat input as $json.chatInput, a structured JSON object containing the message, user ID, and other relevant conversation data. This allows you to not just receive the user's message, but to understand the context of the conversation and potentially use that context in subsequent steps.
For our use case, this is ideal. Imagine a scenario where the user provides a starting prompt, and the AI agent then asks clarifying questions – the Chat Trigger node captures those interactions as part of the conversation history.
Wiring Up the Ollama AI Agent
Now let's bring in the AI agent itself. We'll leverage Ollama, a fantastic open-source LLM platform that allows you to run models locally. The Ollama Chat Model sub-node sits under the AI Agent node and handles the communication with the model. We'll connect to it using the ai_languageModel connection type.
Here’s the breakdown:
- Create an Ollama Connection: In n8n, navigate to your credentials and create a new credential of type ‘Ollama’.
- Configure the Credential:
- Name: Give it a descriptive name like "Ollama-Local-Model".
- Base URL: This is the URL where Ollama is running. Typically, it's something like
http://localhost:1234/. - Model Name: This is the name of the model you want to use. For example, "mistralai/Mistral-7B-Instruct-v0.2".
- Connect the Nodes: Drag the Chat Trigger node and the AI Agent node into your workflow. Connect the output of the Chat Trigger node to the input of the AI Agent node. Make sure the AI Agent node is configured to use the Ollama credential you just created.
The Trade-off: Local vs. Hosted
Running a model locally via Ollama provides significant advantages over relying on hosted APIs, especially for sensitive data and cost-conscious projects. Hosted APIs often involve subscription fees and potential rate limits. More importantly, running locally grants you complete privacy and eliminates any concerns about data being processed by a third-party server. However, there are downsides:
- Slower Generation: Local models, especially on consumer hardware, will be slower than optimized hosted APIs.
- Model Quality Ceiling: The quality of the output will be limited by the capabilities of the model itself and the resources available to it. You won’t have the benefit of continual model updates or access to the very largest models.
This isn’t necessarily a bad thing. For many creative writing tasks, the difference in quality might be subtle, and the cost/privacy benefits of a local setup outweigh the slight performance impact.
Crafting a Robust System Message
The system message (also known as the “prompt”) provided to the AI agent significantly impacts the quality and consistency of its output. A vague system message like “Write a blog post about artificial intelligence” will yield unpredictable results. A structured, detailed system message, on the other hand, guides the agent toward the desired output format, tone, and subject matter.
Before:
{
"system": "Write a blog post about AI."
}After:
{
"system": "You are a knowledgeable and engaging technical writer. Your task is to write a blog post explaining the basics of artificial intelligence for a general audience. Keep the tone informative and approachable. The blog post should be approximately 500-700 words long and include a brief overview of different AI approaches, examples of AI applications, and a conclusion summarizing key takeaways. Use clear and concise language, avoiding jargon whenever possible.",
"instructions": "Write a blog post about AI. Please focus on the current state of large language models."
}Notice the added detail: We’ve defined the agent's role, specified the target audience, provided a length constraint, and included specific content requirements. This level of detail dramatically improves the agent's output.
Post-Processing with the Code Node
Raw LLM output is rarely perfect. It might contain extraneous information, formatting inconsistencies, or even hallucinated details. The Code node provides a place to clean and refine the agent's output. We're not simply passing the raw text straight through; we're actively extracting the relevant information and rebuilding the output structure.
For example, let’s say the agent generates a block of text. We don’t want to blindly use that whole block. We need to specifically target the paragraph containing the main point, strip out any conversational filler, and format it correctly for our file.
JavaScript Example (Code Node):
// Assuming $json.chatInput.agentOutput is the raw JSON output from the AI Agent node
const output = $json.chatInput.agentOutput;
// Extract the main paragraph (simplified example - adjust based on the model's output)
const mainParagraph = output.substring(output.indexOf("AI"), output.indexOf("\n\n"));
// Return the cleaned paragraph
const cleanedOutput = {
content: mainParagraph
};
$set($json.chatInput.agentOutput = cleanedOutput);
This demonstrates the fundamental principle: Don’t trust the model's raw output blindly. Extract precisely what you need and rebuild the structure from scratch.
SSH Integration for Remote File Writing
Now let’s get the content to a remote server. We'll use the SSH node to execute a shell command and write the content to a file.
-
Create an SSH Credential: In n8n, create an SSH credential with the necessary connection details for your remote server.
-
Connect the Nodes: Chain the Code node (with the output from the AI Agent) to the SSH node.
-
Configure the SSH Node:
- Command:
echo "$json.chatInput.agentOutput.content" > /path/to/remote/file.txt - Explanation: This command uses
echoto output the content (extracted from the agent’s response) and redirects it to a file on the remote server. The"$json.chatInput.agentOutput.content"part ensures that the JSON content is properly handled, preventing issues with special characters.
Important: Base64 Encoding: To handle multi-line content safely within the SSH command, it's highly recommended to base64-encode the content before piping it through the command. This prevents escaping headaches caused by quotes, backticks, and code blocks. The
Codenode handles this encoding for you – ensure your settings are configured to use base64. - Command:
End-to-End Workflow and Resilience
To make the entire pipeline truly functional, chain a second SSH node to run a build or deploy step after the file is written to the remote server. This could be anything from triggering a CI/CD pipeline to restarting a service.
Finally, let’s consider resilience. The AI Agent's output might occasionally be invalid or incomplete. To prevent the workflow from failing silently, we should implement validation:
- Validate Output: Use a
Validatenode to check that the agent's output contains the expected fields. - Handle Missing Fields: Use a
Filternode to handle missing fields with sane fallbacks. Perhaps if thecontentfield is missing, default to an empty string. - Never Trust the Model: Never rely on the model for things like the current date or time. Always compute these values in code.
By incorporating these resilience measures, you’ll build a significantly more robust and reliable workflow. Building an AI agent workflow in n8n can be a powerful combination, enabling rapid prototyping and automation of creative tasks.

Written by Robin te Hofstee
Technology enthusiast with a deep love for programming. Sharing practical guides on React, Next.js, Linux and self-hosting.
Related Posts
Self-Hosting n8n on Proxmox
Deploying n8n on Proxmox using the Community Scripts LXC installer offers data privacy, unlimited execution, and full control compared to n8n Cloud, ideal for a homelab.

