July 16, 2026
AI log, day 10: chatbot vs. agent vs. workflow, what genuinely separates the three
AI log series · part 10 of 18

Day 09 closed with a promise to go after a word that’s been doing a lot of unexamined work across this whole log: “agent,” and its two close cousins, “chatbot” and “workflow.” Every product page in this space uses all three, often for the same feature, sometimes in the same sentence. I’ve now built and read enough of the underlying mechanics, the model-call loop from day 06, the cost and latency shape from day 07, the trust boundary from day 08 and day 09, that I want to pin the three terms down structurally rather than by vibes. There is a real line between them. It’s just not the line marketing draws.
The line isn’t capability, it’s who decides what happens next
My first instinct was to rank the three by how “smart” they are, chatbot at the bottom, agent at the top, workflow somewhere in between. That instinct is wrong, and it’s wrong in a way that matters for actually building one of these things. The real difference is about control flow: who decides what the next step is, and how far in advance that decision was fixed.
A chatbot is a single model call, or a short back-and-forth of them, where the human is the control flow. The model answers, the human reads it, the human decides what to ask next. Nothing the model outputs changes what happens next except by going back through a person first. This is the shape from day 01, one forward pass at a time, and it’s the shape most people mean when they say “I used ChatGPT for this.”
A workflow is a fixed sequence of steps, some of which happen to be model calls, wired together in advance by whoever built the system. Step two always runs after step one. The branches, if there are any, are enumerated ahead of time by the developer: if the classifier says “refund,” go to path A, if it says “complaint,” go to path B. The model has no say over which step comes next beyond filling in the content of the step it’s currently on. This is most of what actually ships in production today, and it’s the shape I’d reach for by default, because it’s the shape that’s cheapest to reason about, test, and debug.
An agent, in the sense that’s actually earned the word rather than borrowed it for marketing, is a loop where the model itself decides what the next step is, chooses which tool to call, and decides when it’s done. That’s exactly the loop from day 06: read state, pick a tool, get a result, decide again, repeat until the model itself calls it finished. The control flow lives inside the model call, not outside it in code someone wrote in advance.
# Workflow: the developer wrote this branch. The model never sees the "if."
result = classify(ticket)
if result == "refund":
run_refund_flow(ticket)
elif result == "complaint":
run_complaint_flow(ticket)
# Agent: the model decides, on every iteration, what happens next.
while not done:
action = model.decide_next_step(state, available_tools)
state = execute(action)
done = model.judge_if_finished(state)
That code sketch is the whole distinction. Everything else people argue about, autonomy, intelligence, “does it feel agentic,” falls out of that one structural fact once you look for it.
Why this line, and not some fuzzier one
I could have drawn the line at “does it use tools” or “does it maintain memory across turns,” and a lot of writing on this topic does exactly that. I think both of those are surface features that happen to correlate with the real thing rather than the real thing itself. A workflow can use tools too, a step in the pipeline can call a search API or hit a database, and nobody would call that step agentic, because the workflow’s author decided in advance that this step calls that tool. The tool call isn’t evidence of agency. The model choosing, at runtime, whether to call it, which tool, and what to do with the result, is.
Memory across turns has the same problem. A chatbot with a long conversation history isn’t more of an agent than one without, it’s still a human deciding the next message every single turn. What changes the category isn’t how much context persists, it’s who’s driving.
This is also why “agent” is the term that gets abused the most in the current wave. It’s the one that sounds most impressive, so a workflow with a single tool-calling step gets called an agent in a pitch deck, and a genuine decide-your-own-next-step loop gets called an agent in a research paper, and from the outside both demos can look identical for the one example the person chose to show you. The word tells you almost nothing about the actual system until you ask the control-flow question directly: who decided what happens after this step, a person who wrote it in code, or the model, right now, based on what it just saw.
What that structural difference actually predicts
Here’s why I think this distinction is worth having rather than pedantry: it predicts, cleanly, where each shape breaks and what it costs to operate.
A chatbot fails the way day 01 through day 05 described a single model call failing: bad prompt, bad context, occasional hallucination, bounded blast radius because a human is reading every output before anything happens in the world.
A workflow’s failure modes are almost entirely the failure modes of the code around the model calls, the same categories I’ve been writing about long before this log existed. An unhandled branch, a step that isn’t idempotent and gets retried into a duplicate charge, a classifier that’s wrong just often enough that the “if” routes real tickets down the wrong path silently. These are ordinary software bugs wearing an AI costume, and they get fixed with ordinary software tools: tests, retries with idempotency keys, monitoring on the branch distribution. The cost profile is also predictable up front, because the number of model calls per run is fixed by the code, not by the model’s own judgment about how many steps this particular problem needs.
An agent inherits every one of the workflow’s failure modes and adds a genuinely new one on top: the loop itself can go wrong in ways nobody wrote down, because nobody wrote the branch, the model did, at runtime, and it can decide badly. This is where day 07’s point about cost trending quadratic with loop length actually bites, an agent that talks itself into six extra tool calls it didn’t need also reruns a growing context on every one of them, so a bad control-flow decision isn’t just a wrong answer, it’s a wrong answer with a bill attached. It’s also where day 09’s tool-privilege argument does its real work, because the entire reason least-privilege tool access matters more for an agent than a workflow is that a workflow’s tool calls were reviewed once, by a person, at build time, while an agent’s tool calls are decided fresh, by the model, every single run.
So which one should I actually build
The honest answer, and the one I didn’t expect to land on before working through the mechanics, is to default to the workflow and only reach for the agent shape when the branching genuinely can’t be enumerated in advance. If I can write down the “if” myself, I should, because a workflow is cheaper to run, cheaper to test, and fails in ways I can predict and catch before they ship. The agent shape earns its cost specifically when the space of “what to do next” is too open-ended to hand-code, research tasks where the right next search depends entirely on what the last search turned up, multi-step tool use where the right tool depends on a judgment call that would otherwise need a combinatorial pile of if-statements to approximate.
The chatbot shape, meanwhile, isn’t the beginner tier the other two get built on top of, it’s just the right shape whenever a human should stay in the loop deciding what happens next, which is most of the times a person is actually using the thing themselves rather than deploying it to run unattended.
What’s next
Regular posts continue in between, as always, and I’m not committing to a fixed day 11 topic yet the way this series usually doesn’t. The natural next thread, now that chatbot, workflow, and agent have an actual definition each, is evaluating an agent specifically, since day 05’s eval framing was written before this distinction existed and an agent’s failure mode (a bad step three turns deep in a loop) needs a different eval shape than a single call’s right-or-wrong answer does.