The honest version of this comparison starts with an admission: for a lot of use cases, the chatbot is still the right answer, and the industry has spent two years pretending otherwise.
So here is the difference, and then the part where we tell you when not to build the agent.
The actual difference
A chatbot follows a path a human wrote. Someone drew the tree: if the customer taps "Track my order", ask for the order number, call the tracking endpoint, show the result. Every branch exists because a person put it there.
An agent decides. It is given a goal, a set of tools, and permission to choose. Nobody wrote the path, because the path is different every time.
That is the whole distinction. Not intelligence, not the model, not whether it "understands natural language" (chatbots have handled natural language for years). The question is: who chose what happens next, a person at design time or the model at runtime?
The same request, both ways
A customer writes: "hey I ordered something last week for my mum's birthday and it still hasn't shown up, her birthday is Saturday, can you check?"
The chatbot:
Sorry, I didn't understand that. Choose an option:
1. Track an order
2. Returns
3. Talk to an agentIt did not fail. It did exactly what it was built to do. The message did not match any branch, so it fell to the default.
The agent:
turn 1 no order number in the message
calls: find_orders(customerPhone) -> one order, placed Aug 4
turn 2 calls: lookup_order("4471") -> in_transit, eta Aug 14
turn 3 answers"I found your order from August 4th. It is in transit and the carrier estimates the 14th, which is after Saturday. I can ask them to expedite or start a refund. Which would you prefer?"
Two things happened that no branch could have covered: it inferred that the missing order number was findable from the phone number, and it noticed the delivery date lands after the birthday the customer mentioned. Nobody scripted "compare the ETA to a date the customer mentioned in passing."
That is the case for agents, stated as strongly as it deserves.
Now the case against
Chatbots are predictable, and predictability has real value. You can enumerate everything a chatbot will ever say. You cannot do that with an agent. In regulated contexts, that is not a preference, it is a requirement.
Chatbots are cheaper. A button tap costs nothing. An agent turn is a model call carrying the whole conversation, and complex requests take several.
Chatbots are faster. No model in the path means an instant reply. An agent that calls two tools takes a few seconds, which on WhatsApp is fine and on a phone call is not.
Chatbots fail visibly. When a chatbot breaks, you see a broken menu. When an agent breaks, it produces a fluent, confident, wrong answer, and you find out from a customer.
The decision
| Your situation | Build |
|---|---|
| Five options, and 90 percent of people want one of them | Chatbot |
| Answers must be word-for-word approved (legal, medical, financial) | Chatbot |
| Requests are open-ended and arrive in the customer's own words | Agent |
| Answering requires looking up two or three things and combining them | Agent |
| Your knowledge base changes weekly and nobody wants to redraw a tree | Agent |
| You are on a phone call with a one second latency budget | Agent, with very fast tools |
| The action is irreversible and expensive if wrong | Either one, with a human approving |
| You have no tools to give it | Neither. You want search over your docs |
The last row catches more teams than you would expect. An agent with no tools is a well-spoken FAQ, and building agent infrastructure to get one is a lot of work for something a search box does.
What actually ships: both
The pattern that survives production is not one or the other. It is a scripted flow on the path you know, and an agent on everything else.
Opt-out is the clearest example. When someone writes STOP, you do not want a model deciding. You want a deterministic branch that unsubscribes them, every time, in under a second. Same for "talk to a human": no interpretation, just a handoff.
Everything that is not on the list of known paths goes to the agent.
On Zavu this maps directly. Flows handle the deterministic paths with keyword triggers. The agent handles the rest, with tools for the things it needs to do and a transfer_to_human tool for the things it should not.
You describe that split rather than coding it. Install the skills and the CLI once (npx skills add zavudev/zavu-skills and npx zavudev@latest login), then hand your coding agent the policy:
> Keep our existing STOP and "talk to a human" keyword flows exactly as they are. Add an agent for everything else. Give it a transfer_to_human tool that posts to our on-call webhook, and make it use that tool for refunds over $200 rather than deciding itself.
What comes back:
TypeScriptimport { defineAgent, defineTool } from "@zavudev/functions" defineAgent({ senderId: process.env.SENDER_ID!, name: "Support", provider: "zavu", model: "openai/gpt-4o-mini", prompt:You are support for an online store. Never promise a delivery date the carrier has not given you. For refunds over $200, use transfer_to_human instead of deciding., }) defineTool({ name: "transfer_to_human", description: "Hand the conversation to a person. Use for refunds over $200, complaints about damage, or any time the customer asks for a human.", parameters: { type: "object", properties: { reason: { type: "string" } }, required: ["reason"], }, handler: async ({ reason }, ctx) => { await notifyOnCall({ conversation: ctx.sessionId, reason }) return { transferred: true } }, })
Read one thing in that diff before shipping it: the escalation rule lives in two places on purpose. In the prompt, so the model knows the policy, and in the tool description, so it recognises the moment. Prompts state policy. Tool descriptions trigger behaviour. Putting it in only one of them is the most common reason an agent that "knows" it should escalate never does, and it is the thing a coding agent most often gets half right.
How to tell which one you already have
If a vendor sells you an "AI agent", three questions settle it:
Migrating from one to the other
You do not need to throw the chatbot away. The path that works:
Starting at the fallback means the agent only ever handles conversations that were already failing, so the downside is bounded from day one.
Keep reading
- What is an AI agent: the definition and the four parts.
- How to build an AI agent: the loop from scratch, then deployed on a channel.
- How to create a WhatsApp chatbot: if the decision table sent you here.
- AI agent frameworks compared: once you have decided on the agent.