AI AgentsGuideWhatsApp

AI Agent vs Chatbot: The Difference, and When the Chatbot Wins

A chatbot follows branches a human wrote. An agent decides and calls tools. Here is the real difference, the same request handled both ways, and the cases where the chatbot is still correct.

Written by: Victor VillalobosReviewed by: Jennifer VillalobosAugust 11, 20268 min read
View as Markdown

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 agent

It 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 situationBuild
Five options, and 90 percent of people want one of themChatbot
Answers must be word-for-word approved (legal, medical, financial)Chatbot
Requests are open-ended and arrive in the customer's own wordsAgent
Answering requires looking up two or three things and combining themAgent
Your knowledge base changes weekly and nobody wants to redraw a treeAgent
You are on a phone call with a one second latency budgetAgent, with very fast tools
The action is irreversible and expensive if wrongEither one, with a human approving
You have no tools to give itNeither. 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:

TypeScript
import { 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:

  • What tools can it call? If the answer is a list of intents rather than functions, it is a chatbot with a language model on the front.
  • Can it call two tools in one conversation and use the first result to decide the second? This is the loop. If it cannot, there is no loop.
  • What does it do when it does not know? A real answer here ("it escalates, and here is the log") means someone designed for failure. No answer means you will find out in production.
  • Migrating from one to the other

    You do not need to throw the chatbot away. The path that works:

  • Keep the top flows exactly as they are. They work and they are cheap.
  • Point the "I didn't understand that" default at an agent instead of at a menu. That default branch is where you are losing people today, and it is the highest-value place to put a model.
  • Give the agent the tools your flows already call. They exist and they are tested.
  • Watch the escalation rate. When it drops, move another flow to the agent. When it rises, you moved one too many.
  • 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

    Need help? Contact us or join our Discord community for support.

    Get started

    Ready to get started?

    Start building for free, or schedule a call to discuss your specific use case.

    AI Agent vs Chatbot: Which to Build | Zavu Blog