A fintech team had a document pipeline that worked: five model calls in a fixed order — extract, validate, classify, enrich, file — processing forty thousand invoices a month at about $180 in API spend, with a 1.4% error rate their reviewers could live with. Then agents became the thing to have, and the pipeline was rebuilt as one: a model with tools, deciding for itself what each invoice needed. Three weeks later the monthly projection was $5,400, the error rate had tripled, and — worse — the errors were no longer predictable, because the path through the system was different for every document. They rolled it back. Nothing was wrong with the agent's code. Something was wrong with the decision to build an agent.
This lesson is about making that decision on purpose. It pins down what an agent actually is — precisely, not vibes — then walks the five workflow patterns from Anthropic's Building Effective Agents as a spectrum of increasing model control, practices the discipline of choosing the simplest pattern that works on three concrete tasks, and closes with a light POMDP framing that gives you exact vocabulary for everything the rest of the course builds.
Strip the marketing and an agent is four things: a model, a set of tools, some memory (at minimum, the accumulating message history), and a control loop that the model directs. That last clause is the load-bearing one. In a workflow, your code decides what happens next — which prompt runs, in what order, how many times. In an agent, the model's own output decides: which tool to call, whether to keep going, when the task is done. Anthropic's definition draws exactly this line: workflows orchestrate models through predefined code paths; agents dynamically direct their own processes and tool usage.
The distinction has hard operational consequences. If the model directs control flow, then the number of steps is unknown in advance, so cost and latency are distributions, not numbers. The path is different per input, so failures do not cluster where you can catch them. And termination is the model's claim, not your code's guarantee — which is why the whole of Lesson 7 exists. None of that is bad; it is the price of handling tasks whose structure you cannot enumerate. The engineering sin is paying that price for tasks whose structure you can.
Between "one prompt" and "full agent" lies a small set of workflow shapes that solve most production problems. Anthropic's catalog names five; learn them as reusable parts, because you will assemble them for years.
| Pattern | Shape | Reach for it when |
|---|---|---|
| Prompt chaining | Fixed sequence: output of call N is input of call N+1 | The task decomposes into known stages (draft, then edit; extract, then format) |
| Routing | A classifier call picks which specialized path handles the input | Inputs fall into distinct categories that deserve different prompts, tools, or models |
| Parallelization | Independent calls run at once: split the work (sectioning) or repeat it and aggregate (voting) | Subtasks are independent (per-document, per-file) or you want ensemble confidence |
| Orchestrator-workers | A lead call decides the subtasks; workers execute them; the lead synthesizes | Subtasks cannot be enumerated upfront, but each one is bounded once named |
| Evaluator-optimizer | A generator call and a critic call alternate until the critic accepts | You can articulate acceptance criteria and iteration measurably improves output |
The first three are pure workflows: your code owns every branch. In code, the fintech team's correct architecture was a chain with a router in front — boring, cheap, and debuggable:
def process_invoice(doc: str) -> dict:
kind = classify(doc, ["standard", "credit_note", "foreign"]) # router
extractor = EXTRACTORS[kind] # per-category prompt + schema
fields = extractor(doc) # chain step 1: extract
issues = validate(fields) # chain step 2: deterministic checks
if issues:
fields = repair(doc, fields, issues) # chain step 3: one retry
return fields # code owned every branch above
The last two patterns cede real decisions to the model — which subtasks exist (orchestrator-workers), whether quality is acceptable (evaluator-optimizer) — while your code still owns the loop's shape and its termination. They are the bridge to agents, and they are also seeds you will meet again: evaluator-optimizer grows into the reflection loops of Lesson 6, and orchestrator-workers grows into Multi-Agent Systems Engineering.
Line the shapes up by how much control the model holds and you get a dial, not a dichotomy. At the far left, a single prompt: the model controls nothing but its own tokens. Chaining and routing give it influence over content but none over flow. Parallelization is still pure code. Orchestrator-workers hands the model one structural decision — what the subtasks are — then takes control back. Evaluator-optimizer hands it another — is this good enough — inside a code-owned loop with a code-owned iteration cap. And a full agent hands over the loop itself: the model decides every next action and asserts its own completion, bounded only by the budgets you enforce from outside.
Two things about the dial. First, cost variance and debugging difficulty rise with model control — a chained pipeline fails in the same place every time; an agent fails somewhere new per run, which is why tracing (Lesson 3) is not optional at the right end of the dial. Second, the dial is per-component, not per-product. A sane document system is a workflow at the top level with a small agent inside one box — say, a bounded research loop for the 3% of invoices that reference an unknown vendor — rather than an agent wrapping everything. You compose along the spectrum; you do not pick a religion.
The decision procedure is four questions. Can I draw the flowchart in advance? Is the step count bounded and small? What does one wrong output cost me? Is there a signal that tells the system it is succeeding? Walk them against three real tasks.
Task A: translate incoming support tickets to English and tag them by product area. Fifty thousand tickets a month. The flowchart is three boxes — detect language, translate, classify — identical for every ticket. Step count: fixed at three, and two of them can use a small fast model. A wrong tag costs a mis-routed ticket, caught downstream. Verdict: prompt chaining with a router. An agent here buys nothing except cost variance on a task you run 1,600 times a day.
Task B: given a bug report, find the offending commit and propose a fix. The flowchart cannot be drawn: the next action depends on what the last file read or test run revealed, and the step count is anywhere from five to fifty. There is a real feedback signal — the test suite — and a wrong fix is caught by review before merge. Verdict: , with budgets and a verifier. This is exactly the shape of the SWE-bench Verified tasks that coding agents are measured on, and no fixed pipeline survives contact with it.
Task C: produce a weekly competitor-pricing report from five known websites. Tempting to call this "research" and reach for an agent — but the sites are known, so this is five independent fetch-and-extract jobs (parallelization, sectioning) followed by one synthesis call (chaining). Cost: pennies, every week, predictably. The honest agent-shaped residue is tiny: when a page's structure changes and extraction fails, either alert a human or hand that one page to a bounded repair agent. Verdict: parallelization + chaining, with an optional small agent as the exception handler.
Check: You must summarize each of 900 archived PDFs and merge the summaries into one report, nightly. The simplest adequate architecture is:
One piece of formalism pays for itself across the whole course. An agent's situation is a partially observable Markov decision process: there is an environment state (the real filesystem, the real database, the real web), the agent takes actions (tool calls), and it receives observations (tool results) — which are a partial, sometimes stale view of the state, never the state itself. The model is the policy, choosing actions from the history of observations rather than from the true state:
The context window is therefore the agent's working approximation of a belief state — everything it can currently hold about the world is what its observations said, arranged in a window of finite length. This is why context discipline (the subject of Prompt & Context Engineering) is not a prompting nicety but a core architectural concern: managing the context is managing the agent's beliefs. And the horizon — how many steps the process runs — is not a hyperparameter you tune once; it is the step budget you enforce, because an unbounded horizon is an unbounded bill.
The vocabulary names failures precisely. "The agent greps the same file repeatedly" is perceptual aliasing: two different beliefs produce the same next action because the observations that would distinguish them never entered the window. "The agent acts on a file it already deleted" is a stale belief: the state changed, the observation history did not. You will meet both, with detectors, in Lessons 3 and 7.
Before any agent project, run the four questions — flowchart, step bound, error cost, feedback signal — and place the task on the spectrum honestly. Default to the leftmost pattern that survives the questions: chain what you can enumerate, route what clusters, parallelize what is independent, and spend model control only where observations genuinely determine the branch. When you do build the agent, you now know its formal shape — a policy over observation histories, with a horizon you own — and the next lesson makes that concrete: the complete ReAct loop, from scratch, in under two hundred lines.