Workflows vs agents: common patterns

AI & LLM fundamentals · Advanced · 14 min

Picking the simplest pattern that works saves cost, latency and debugging time, and is the most common design decision in AI products.

Anthropic's widely cited distinction: in a workflow, models and tools are run through steps you defined in advance; in an agent, the model decides the steps itself. Workflows are predictable, cheaper and easier to test. Agents handle open-ended tasks where you cannot know the steps beforehand, at the cost of more tokens, more latency and errors that can compound.

The advice is to start with the simplest thing that works: often one well-prompted call with retrieval and examples. Add steps only when they measurably help.

Common workflow patterns:

  • Prompt chaining: a fixed sequence of calls, each using the previous output (outline, then draft, then edit), with checks in between.
  • Routing: one call classifies the input and sends it to a specialised prompt, tool or model, for example easy questions to a small fast model.
  • Parallelisation: run independent calls at the same time and combine them (split a long document into sections), or run the same task several times and take a vote.
  • Orchestrator-workers: one model breaks a task into subtasks at run time and hands them to worker calls, then merges the results.
  • Evaluator-optimizer: one call produces a draft, another critiques it against clear criteria, and the loop repeats until it passes.

A real system often mixes them: a routing workflow whose "complex" branch hands over to an agent. Most no-code automations (Zapier, Gumloop, n8n) are workflows by nature; their agent steps add model-directed loops where you need them.

Rule of thumb: if you can draw the flowchart, build a workflow. If the flowchart would be "it depends" at every box, consider an agent, with limits.

Example

# Routing workflow: a cheap model classifies, then a fixed branch runs.
# call_model(model, prompt) stands for any provider's API call.
def handle_ticket(text, call_model):
    label = call_model("small-fast-model",
        f"Label as refund, technical or other. Reply with the label only.\n\n{text}").strip()

    if label == "refund":
        return call_model("small-fast-model", f"Draft a refund reply using our policy:\n{text}")
    if label == "technical":
        return call_model("large-reasoning-model", f"Diagnose and draft a fix:\n{text}")
    return "Forward to a human"     # unknown cases go to staff

# Usage with a fake model for testing:
fake = lambda model, prompt: "refund" if prompt.startswith("Label") else f"[{model}] reply"
print(handle_ticket("I was charged twice", fake))   # [small-fast-model] reply

Remember

  • Workflow = you define the steps; agent = the model does
  • Start simple; add steps or autonomy only when it measurably helps
  • Know the patterns: chaining, routing, parallel, orchestrator-workers, evaluator-optimizer

Check yourself

  1. Invoices always need the same three steps: extract fields, validate totals, file to the right folder. What fits best?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: www.anthropic.com/engineering/building-effective-agents