Menu

AI Agents course · Lesson 2 of 7

Workflows vs AI Agents: When to Use Each

When to build a fixed LLM workflow and when you need an AI agent: predictability, cost, testing and flexibility compared, with a runnable Python workflow.

  • Intermediate
  • 5 min read
  • Updated Oct 2026
On this page
  1. A workflow in practice
  2. Side by side
  3. How to choose
  4. Common workflow patterns
  5. Common mistakes
  6. Key takeaway

Many AI features that are called “agents” work better as workflows. In a workflow, your code decides the steps and calls a model at fixed points, such as “classify this email, then extract the order number”. In an agent, the model decides the steps. Both use language models; the difference is who is in control of the path.

A workflow in practice

This workflow handles customer emails with fixed steps: classify, extract the order number only for refunds, then route. The model calls are stand-ins, so the code runs anywhere:

import re

model_calls = 0

def classify(email):              # stand-in for a model call that labels the email
    global model_calls; model_calls += 1
    text = email.lower()
    if "refund" in text or "money back" in text:
        return "refund"
    if "password" in text or "log in" in text:
        return "account"
    return "other"

def extract_order_id(email):      # stand-in for a model call that extracts one field
    global model_calls; model_calls += 1
    m = re.search(r"\b[A-Z]-\d{4}\b", email)
    return m.group(0) if m else None

ROUTES = {"refund": "billing team", "account": "self-service password reset", "other": "general queue"}

def workflow(email):
    """Fixed steps chosen by the developer: classify, extract if needed, then route. No surprises."""
    label = classify(email)
    order = extract_order_id(email) if label == "refund" else None
    if label == "refund" and order is None:
        return label, "ask the customer for the order number"
    return label, ROUTES[label] + (f" (order {order})" if order else "")

emails = [
    "I want my money back for order B-2210, it arrived broken.",
    "I can't log in since yesterday.",
    "Please refund me, the jacket doesn't fit.",
    "Do you sell gift cards?",
]
for e in emails:
    print(f"{workflow(e)}  <- {e[:40]}")
print("model calls:", model_calls, "for", len(emails), "emails")
('refund', 'billing team (order B-2210)')  <- I want my money back for order B-2210, i
('account', 'self-service password reset')  <- I can't log in since yesterday.
('refund', 'ask the customer for the order number')  <- Please refund me, the jacket doesn't fit
('other', 'general queue')  <- Do you sell gift cards?
model calls: 6 for 4 emails

Every email takes at most two model calls, the path is easy to read, and each step can be tested on its own. The missing-order case is handled by a rule, not by hoping the model asks.

Side by side

Workflow Agent
Who chooses the steps Your code The model
Predictability High: same path every time Lower: path depends on what it finds
Cost and speed Known and usually low Varies; more model calls
Testing Test each step separately Test whole tasks, many times
Best for Known processes: classify, extract, route, summarise Open problems: investigate, research, multi-system tasks
Main risk Rigid when cases fall outside the design Wrong actions, loops, cost spikes

How to choose

Ask: can I write down the steps in advance?

  • Yes, for nearly all cases: build a workflow. Add branches for the known variations.
  • Mostly, with a few open-ended cases: build a workflow, and use an agent only inside the step that needs it, such as “investigate unusual cases”.
  • No, the next step depends on what is found: build an agent, with clear tools, limits and approval rules.

Start with the simplest design that works, measure it, and add autonomy only where it clearly improves results.

Common workflow patterns

  • Chain: one step’s output feeds the next (extract, then summarise, then translate).
  • Router: classify the input, then send it down different paths, as in the example.
  • Parallel: run independent steps at the same time, such as checking several documents.
  • Check and retry: validate an output, and retry or escalate if it fails.

Common mistakes

  1. Calling everything an agent, and building a costly, unpredictable system for a simple process.
  2. Workflows with no escape hatch, so unusual cases fail silently; route them to a person or an agent.
  3. Agents without the workflow’s discipline: no tests, no limits, no logging.

Key takeaway

Workflows fix the steps in code and use models inside them; agents let the model choose the steps. Prefer workflows for known processes, because they are cheaper, faster and easier to test, and use agents where the path genuinely depends on what is discovered, often as one step inside a workflow. Next: connecting agents to tools in a standard way with MCP.

By , Data Engineer and Founder of DataDank · Last reviewed Oct 2026 · Design guidance that applies to any framework. The example uses stand-in functions in place of model calls so it runs anywhere; its output is real.

Progress is saved in this browser only. No account needed.

Search
Filter by type