Skip to content
AI Support Agent

Module 08 · ai · intermediate

Lesson 08 · AI Support Agent

Goal

Build an AI agent: a model that decides which tools to call to answer a customer, instead of following a fixed flow. You'll see the difference between a chatbot that talks and an agent that acts.

Prerequisites

  • Module 06 (OpenAI credential, cluster nodes)
  • Module 04 helps: tools are like sub-workflows the model can call

Concepts

  • Chat Trigger: gives you a hosted chat page (public URL) and a chat API. Each browser session gets a sessionId.
  • AI Agent: a root node that loops: read the conversation → maybe call a tool → read the result → answer. You control it with the system message.
  • Tools: sub-nodes the agent can call. The tool description is how the model decides when to use it, so write it like documentation. With an input schema, the model fills in structured arguments.
  • Memory: Simple Memory keeps the last N messages per sessionId, so the agent can understand "when will it arrive?".
  • Grounding: the system message lists the only facts the agent may state. Everything else must come from tools. This is how you prevent made-up answers.

Build it

Step 1: Chat Trigger

Chat Trigger Support Chat: Make Chat Publicly Available on, mode Hosted Chat, initial message introducing what the bot can do. Options: title, subtitle, input placeholder.

Step 2: The agent

AI Agent Support Agent (source for prompt: Connected Chat Trigger Node). Options → System Message:

  • Who it is (Brewlab support assistant) and today's date ({{ $now.toFormat('yyyy-MM-dd') }})
  • Store policies: shipping times, free-shipping threshold, returns, order ID format, human support hours. "The only facts you may state about the store."
  • Rules: always use lookup_order for order questions and never guess; use create_support_ticket for damage, unresolved issues or "I want a human"; max 80 words; stay on topic.

Options → Max Iterations: 6.

Step 3: Model and memory

  • Chat Model input → OpenAI Chat Model, gpt-5-mini
  • Memory input → Simple Memory Conversation Memory, context window 10

Step 4: Tools

Add two Code Tool sub-nodes. With Specify Input Schema → Generate From JSON Example, the model passes an object you read as query:

  1. lookup_order: description "Look up an order by its ID (format A1234). Returns status, items, carrier, tracking number and estimated delivery…". Example input {"order_id": "A1001"}. The code holds a small demo orders object and returns JSON.stringify(...) of the match, or {found: false, message: …}.
  2. create_support_ticket: description "Create a ticket for the human support team. Use when…". Example input {"summary": "...", "customer_contact": "...", "priority": "normal"}. Returns a random T-12345 ticket ID.

Tool node names are the tool names the model sees, so keep them snake_case and descriptive. Tools must return a string.

Step 5: Try it

Publish, open the Chat Trigger's chat URL (http://localhost:5678/webhook/<id>/chat) and try:

  1. "Where is my order A1001?" → carrier + tracking
  2. "When will it arrive?" → uses memory
  3. "Order A1003 arrived damaged, I want a human" → ticket ID

Test it

./test/test.sh                 # chat page
WITH_CREDS=1 ./test/test.sh    # 5-turn conversation: tools, memory, unknown order, hand-off, off-topic

LLM answers vary, so the tests check for key facts (tracking number, ticket ID format), not exact wording.

Common problems

  • The agent invents order details: the tool description is too vague, or the system message doesn't say "never guess". Check the agent's Logs panel to see if the tool was called.
  • "Tool output must be a string": return JSON.stringify(...) from Code tools.
  • Forgets the previous message: memory isn't connected, or the client isn't sending the same sessionId.
  • Simple Memory resets on restart: it lives in n8n's process memory. Use Postgres/Redis memory in production (Exercise 3).
  • Long, chatty answers: put the word limit in the rules and lower the model's max tokens.