Module 1: From Chatbot to Agent: What Changes with Agentic AI
8. Mini-project: your first agent that responds
Description
Today you're going to leave theory behind for a while and build, start to finish, the simplest agent that actually works: a Chat Trigger, a chat model, and a single tool — no memory, no extra branches, nothing you don't need for the first test. You're going to send it a message from n8n's built-in chat and confirm, by looking at the execution log and not just the response, that the reason-act-observe loop you saw in lesson 3 really ran.
This matters because it's exactly the step a real team expects to see before building anything on top: "show me it responds" isn't the same as "show me the agent decides for itself when to use a tool." Anyone can connect a chat model alone and ask it some questions — that already existed before this module. What you're going to prove today is that the pieces you studied actually fit together and produce the behavior they promised: a model that decides to call a tool when it needs one, not when you dictate it to it step by step.
Connection to the module: this is the module's last lesson. Community self-hosted, the decision you made in the previous lesson, is where you're going to run this agent — $0 in infrastructure, with the AI nodes already included in the core. Today you bring that together with everything else: the node (lesson 4), the four pieces (lesson 5), and the criterion for when an agent is worth it (lesson 6) — applied, for the first time, to a real case on your own n8n.
What it means for the agent to "work"
When someone takes a practical driving test, the test isn't "start the car and drive around the block without crashing" — with a bit of luck, anyone passes that. The real test includes a situation where the evaluator knows, in advance, that you're going to have to make a decision: a yellow light, a pedestrian who might or might not be about to cross. It's not enough for the car to move; you need to see that you decided correctly at the exact moment there was a real decision to make.
The same thing happens with an agent. If you send the chat a question the model already knows how to answer from memory — "what's 2+2?", "what language do they speak in France?" — you're going to get a correct response even if the agent never touched any tool. That proves nothing: as you saw in lesson 3, the number of turns in the reason-act-observe cycle isn't fixed, and it can be zero. An agent with no tool connected, or with a broken tool, can give that exact same correct response, and you'd never find out something is wrong — until you ask it something that genuinely depends on external data.
That's why this mini-project has two goals, not one: that the agent responds (the easy part), and that you can point, in the execution log, to the exact moment where it reasoned, acted by calling your tool, and observed the result before responding. That second part is what actually proves you built an agent, and not just a chat with a loose model.
Worked example
You're going to build a general-reference agent with a single tool: it looks up a Wikipedia article's summary through Wikimedia's public API (no API key or account needed — zero cost, zero friction for this first test). The system message is written on purpose to force the behavior you want to verify: that the agent uses the tool for concrete facts, even when it thinks it knows the answer.
Step 1 — drag in the Chat Trigger. In a new workflow, add the "When chat message received" node (Trigger category). This is the node that opens, further down on the canvas, the Chat panel you're going to use for testing — no need to configure anything beyond leaving its defaults for a local test.
Step 2 — add the AI Agent and connect it to the Chat Trigger. Drag in the "AI Agent" node and connect the Chat Trigger's main output to its main input (the straight line, not the curved ports below). Without this connection — easy to overlook when you're focused on the AI connectors — the chat never triggers the agent.
Step 3 — connect the chat model. Click the "+ Chat Model" button that appears at the AI Agent's required port. Choose your credential (whichever you already have set up for your provider) and the model. Before continuing, confirm the credential is valid — it's this lesson's most common error, and you'll see it in the common-mistakes section.
Step 4 — connect the tool. Add an "HTTP Request Tool" node and connect it to the AI Agent's "Tool" port. Configure it like this:
- Node name:
Wikipedia Summary - Tool description: "Use this tool when you need to confirm a concrete fact about a person, a place, or a specific concept. Do not use it for calculations or opinion questions."
- URL:
https://en.wikipedia.org/api/rest_v1/page/summary/{{ $fromAI('title', 'Wikipedia page title in English, with spaces replaced by underscores, e.g. Ada_Lovelace', 'string') }}
Step 5 — write the system message. Under the AI Agent's "Options":
You are a general-reference assistant. Before answering any question about
a specific person, place, or historical concept, use the Wikipedia Summary
tool to confirm the fact, even if you think you know the answer. Briefly
cite the summary you got. For calculation or opinion questions, answer
directly without using the tool.
Also leave the "Return Intermediate Steps" option enabled — you're going to need it in the next section to confirm the cycle ran.
Here's the workflow exported as JSON (the connections that matter today):
{
"nodes": [
{
"name": "When chat message received",
"type": "@n8n/n8n-nodes-langchain.chatTrigger"
},
{
"name": "AI Agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"typeVersion": 3.1,
"parameters": {
"promptType": "auto",
"options": {
"systemMessage": "You are a general-reference assistant. Before answering any question about a specific person, place, or historical concept, use the Wikipedia Summary tool to confirm the fact, even if you think you know the answer. Briefly cite the summary you got. For calculation or opinion questions, answer directly without using the tool.",
"returnIntermediateSteps": true
}
}
},
{
"name": "Anthropic Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
"parameters": { "model": { "value": "claude-sonnet-5" } }
},
{
"name": "Wikipedia Summary",
"type": "@n8n/n8n-nodes-langchain.toolHttpRequest",
"typeVersion": 1.1,
"parameters": {
"url": "https://en.wikipedia.org/api/rest_v1/page/summary/{{ $fromAI('title', 'Wikipedia page title in English, with spaces replaced by underscores, e.g. Ada_Lovelace', 'string') }}"
}
}
],
"connections": {
"When chat message received": {
"main": [[ { "node": "AI Agent", "type": "main", "index": 0 } ]]
},
"Anthropic Chat Model": {
"ai_languageModel": [[ { "node": "AI Agent", "type": "ai_languageModel", "index": 0 } ]]
},
"Wikipedia Summary": {
"ai_tool": [[ { "node": "AI Agent", "type": "ai_tool", "index": 0 } ]]
}
}
}
What to expect. Save the workflow (you don't need to activate it for this test) and open the Chat panel that appears on the canvas — that panel is what the Chat Trigger node provides. Type:
Who was Ada Lovelace?
The response you should get, a couple of seconds later:
Ada Lovelace (1815–1852) was an English mathematician and writer, known primarily for her work on the analytical engine proposed by Charles Babbage — considered by many to be the first computer programmer in history. (Source: Wikipedia summary.)
That's already a sign that "something" worked. But this mini-project's real goal is in the next section: confirming that response didn't come only from the model's memory.
How to confirm the cycle really ran
With "Return Intermediate Steps" enabled, open the execution you just triggered (the executions panel, or the AI Agent node itself after running) and check the output. You should see something like this:
{
"output": "Ada Lovelace (1815–1852) was an English mathematician and writer...",
"intermediateSteps": [
{
"action": {
"tool": "Wikipedia Summary",
"toolInput": { "title": "Ada_Lovelace" }
},
"observation": "{\"title\":\"Ada Lovelace\",\"extract\":\"Augusta Ada King, Countess of Lovelace, also known as Ada Lovelace, was an English mathematician and writer chiefly known for her work on Charles Babbage's proposed mechanical general-purpose computer, the analytical engine...\"}"
}
]
}
That intermediateSteps array with one entry is your proof: the agent reasoned ("I need to confirm this fact"), acted (called Wikipedia Summary with title: "Ada_Lovelace" — notice it resolved the underscore on its own, from the description you gave it in $fromAI()), and observed the result (the JSON with the extract) before drafting the final response. If you click the "Wikipedia Summary" node inside the execution panel, you'll see that same exchange from the node's side: the resolved URL with the title already inserted, and the raw response from the Wikimedia API.
Now repeat the test with a question your system message deliberately excludes:
What's 15 times 12?
This time, if you open intermediateSteps, you'll find an empty array — zero act-and-observe turns. The agent reasoned once and decided it didn't need any tool, exactly as you saw in lesson 3 with the business-hours example. The two tests together — one with a tool, one without, both correct — are what leaves you certain the agent is deciding, not just repeating.
Common mistakes
Marking the mini-project as done just because the response sounded correct. This is this lesson's central conceptual mistake. What happens: you send a question, the response is coherent and well-written, and you close out the mini-project assuming you tested the agentic loop — when in reality you might have only tested that the chat model, on its own, knows how to answer general questions from its own training. Why it happens: a response that came from a real tool and a response that came from the model's parametric memory look identical from the chat; the only difference is recorded in intermediateSteps, which nobody checks if the chat "already answered fine." How to spot it: always check the execution log, not just the chat — and ask yourself before writing the test message: does this question force the model to use the tool, or can it resolve it on its own? How to fix it: design the test message (like the Ada Lovelace one) knowing your system message forces the tool call for that type of question, and confirm intermediateSteps before marking the mini-project as finished.
Testing with the canvas's "Test workflow" button instead of the Chat panel. What happens: you run the entire workflow with that general button, and the AI Agent gets an empty input or generic test data, not a real chat message — the execution fails or produces a nonsensical response, and it looks like the agent is broken. Why it happens: "Test workflow" runs the flow once with whatever data it has on hand, designed for regular data nodes, not for a chat conversation with turns. How to spot it: if you see the AI Agent running with an empty message field or an unresolved expression, that's the signal. How to fix it: use the Chat panel that appears on the canvas as soon as you add a Chat Trigger — that panel does simulate a real conversation, turn by turn.
Sending the first message without having configured the chat model's credential. What happens: the chat responds with an authentication error (or doesn't respond at all), and it's easy to read that as "the agent doesn't work" or "the loop is broken," when the real problem is that your provider's credential was never saved or has expired. Why it happens: in the previous lesson you saw that self-hosted Community gives you n8n's infrastructure for free — but that doesn't include the call to the chat model, which still has its own cost and its own key depending on the provider, unless you connect a model you run yourself. How to spot it: the chat's error message usually names the provider and an authentication code. How to fix it: check the Chat Model node's credential before suspecting the rest of the workflow — it's the first thing to rule out, not the last.
Exercises
Exercise 1. You sent "Who was Alan Turing?" to your agent and the response looks perfect, with correct dates and facts. Before marking the mini-project as done, what concrete step would you check, and what result at that step would confirm to you there really was a tool call?
See solution
Check that execution's intermediateSteps array (with "Return Intermediate Steps" enabled). It confirms a real tool call happened if you find at least one entry with "tool": "Wikipedia Summary" and a toolInput with the resolved title (for example "Alan_Turing"), along with an observation containing the raw JSON from the Wikimedia API. If the array comes back empty, the response — however correct it sounds — came only from the model's memory, without going through your tool.
Why it works: it's exactly this lesson's point — a correct response isn't evidence the loop ran; intermediateSteps is the only place where that evidence gets recorded.
Exercise 2. With the worked example's system message (use the tool for people, places, and concepts, not for calculations), you send: "Who discovered penicillin and in what year?" Would you expect to see one or two entries in intermediateSteps? Justify your answer with what you learned about the loop in lesson 3.
See solution
Most likely just one entry: the question asks for a compound fact (person and year), but both pieces of data usually appear together in a single Wikipedia article's summary (Alexander Fleming's, or "Penicillin"'s), so one call to the tool is probably enough for the agent to have everything it needs and respond. There's no fixed rule of "a question with two facts means two tool calls" — as you saw in lesson 3, the number of turns depends on whether the first call's observation already resolves the full question, not on how many parts the question has in the text.
Why it works: it applies the same criterion from lesson 3's travel-agent example — the number of turns is decided by what's still left to resolve after each observation, not by how many sub-questions the user wrote into a single sentence.
Exercise 3. You're handed this connections fragment from a workflow that never responds in the chat:
"connections": {
"AI Agent": {
"main": [[ { "node": "When chat message received", "type": "main", "index": 0 } ]]
},
"Anthropic Chat Model": {
"ai_languageModel": [[ { "node": "AI Agent", "type": "ai_languageModel", "index": 0 } ]]
}
}
What's reversed in this fragment, and why does that explain why the chat never triggers the agent?
See solution
The main connection is backwards: it says the AI Agent's output points to the Chat Trigger ("node": "When chat message received"), when what the workflow needs is the opposite — the Chat Trigger's output pointing to the AI Agent. With this direction reversed, the message that arrives at the Chat Trigger never flows to the Agent through the main connection; the Agent never receives the user's message as input, so there's nothing to trigger the reason-act-observe loop.
Why it works: the main connection — unlike the ai_* connections, which always point from the sub-node toward the root node — follows the normal direction of data flow in n8n: from whoever triggers the event toward whoever processes it. Reversing it doesn't produce a syntax error, but it leaves the Agent with no real input.
Summary and next step
You've now built, tested, and verified your first complete agent: a Chat Trigger triggering the AI Agent, a chat model deciding, a real tool connected, and — what actually closes out the mini-project — confirmation in intermediateSteps that the reason-act-observe cycle ran when the question needed it, and didn't run when it wasn't needed. That's exactly the loop you traced in lesson 3, running on your own self-hosted install.
This closes out Module 1: you can now tell an agent apart from a chatbot and from procedural AI, you understand the loop from the inside, you know the AI Agent node's anatomy and its four pieces, you know when an agent is worth it and when it isn't, you decided where to run it, and today you proved it actually working. Module 2 takes the first of those four pieces — the model and the prompt — and goes deeper into how to choose between providers and how to write a system message that genuinely guides the agent, beyond the minimal example you used today.
Before moving on you should be able to: build from memory the three required connections of an agent (Chat Trigger to Agent via main, Chat Model and at least one Tool via their ai_* ports), design a test message that forces a tool call, and explain why a correct response in the chat isn't, by itself, proof that the agentic loop ran.
Resources
- AI Agent node — n8n Docs — the node's official reference, the same one you cited in lessons 4 and 5, useful here to confirm the
returnIntermediateStepsoption. - Chat Trigger node — n8n Docs — how the Chat panel works, the access options (hosted vs. embedded), and what output field it expects from the Agent.
- What agents do — the source of n8n's official description of how the agent "runs multiple times" before responding, the basis for the loop you verified today.
- How tools work — the catalog of tools n8n ships out of the box, including the HTTP Request Tool you used in this mini-project.
- Test and improve AI workflows — n8n Docs — the next level after this manual test: repeatable evaluations for AI workflows.
- Wikimedia REST API — official interactive documentation for the public API the
Wikipedia Summarytool queries, including the/page/summary/{title}endpoint used in the example.