You can wire up an LLM and wow the room in an afternoon. Then it meets real traffic, and everything you weren't taught shows up at once. Tonight: the four ways it dies, and the first real decision, do you even need an agent?
A demo runs once, on a happy path, with you watching. Production runs a million times, on inputs you never imagined, while you sleep. Same model, an entirely different problem.
Getting an answer out of the model is the party trick. Making that answer cheap, fast, safe, and checkable every single time, for users you'll never meet, is the engineering. This course is about the second part.
Not one at a time, politely. All four, the first busy Monday.
Every one of these passed a demo. Production is adversarial users, edge cases, and a screenshot button.
In the demo you made one call, maybe 2k tokens, a fraction of a cent. In production the agent loops, think, call a tool, think again, and one request becomes 8 calls and 40k tokens. Spend and latency compound with every hop, and nobody budgeted for step seven.
The model is a probabilistic service wearing a deterministic API. The same prompt can return different answers, and a wrong one arrives with exactly the same confident tone as a right one. You cannot unit-test it away.
When it breaks, you can't answer the two questions that matter: did this change make it better or worse? and what did the model actually see and do? Without evals and traces you're guessing, live, in front of customers.
Anthropic's finding from shipping these at scale: the most reliable production systems are workflows, not autonomous agents. Agency is a cost, more tokens, more latency, more ways to go wrong. You buy it only when the task genuinely can't be scripted.
One question separates them: are the steps fixed in code, or does the model choose them at run time?
flowchart LR
subgraph WF["WORKFLOW · you drive"]
direction LR
A1["Step 1"] --> A2["Step 2"] --> A3["Step 3"] --> AO["Output"]
end
subgraph AG["AGENT · the model drives"]
direction LR
M{"Model picks
next step and tool"}
M --> T["Call a tool"]
T --> O["Observe result"]
O --> M
M -.-> DONE["Done"]
end
classDef wf fill:#D6F5E3,stroke:#1F2937,color:#0E1726;
classDef ag fill:#EEE6FF,stroke:#1F2937,color:#0E1726;
class A1,A2,A3,AO wf;
class M,T,O,DONE ag;
A workflow is a recipe: fixed steps, in order. An agent is a cook improvising with the pantry: it decides the next move based on what just happened, and loops until it's done. Recipes are predictable and cheap; improvising cooks are powerful and expensive.
Ordered simplest to most dynamic. Reach left first. An agent sits one step further right than all of these.
flowchart LR
A["1 call"] --> B["Chain"]
B --> C["Router"]
C --> D["Parallelize"]
D --> E["Orchestrator"]
E --> F["Agent"]
classDef simple fill:#D6F5E3,stroke:#1F2937,color:#0E1726;
classDef mid fill:#DCEBFE,stroke:#1F2937,color:#0E1726;
classDef agent fill:#EEE6FF,stroke:#1F2937,color:#0E1726;
class A,B simple;
class C,D,E mid;
class F agent;
Left is cheap, predictable, easy to test. Right is powerful, pricey, harder to trust. Every rung right is a cost, take it only when the task forces you.
1 · CHAINING — steps in order, checked
flowchart LR I["Input"] --> S1["LLM call 1
outline"] S1 --> G{"Gate
valid?"} G -- pass --> S2["LLM call 2
write"] G -- fail --> X["Stop / retry"] S2 --> O["Output"] classDef ok fill:#D6F5E3,stroke:#1F2937,color:#0E1726; classDef bad fill:#FEE4E2,stroke:#1F2937,color:#0E1726; class S1,S2,O ok; class X bad;
2 · ROUTING — classify, then dispatch
flowchart TB
I["Input"] --> R{"Router
classify"}
R -- simple --> A["Small model
cheap, fast"]
R -- complex --> B["Big model
slow, capable"]
R -- refund --> C["Refund flow"]
classDef a fill:#DCEBFE,stroke:#1F2937,color:#0E1726;
class A,B,C a;
3 · PARALLELIZATION — fan out, aggregate
flowchart LR
I["Input"] --> F(("Fan out"))
F --> A["Task A"]
F --> B["Task B"]
F --> C["Task C"]
A --> AG(("Aggregate"))
B --> AG
C --> AG
AG --> O["Output"]
classDef p fill:#D6F5E3,stroke:#1F2937,color:#0E1726;
class A,B,C p;
4 · ORCHESTRATOR — plan, then delegate
flowchart TB
O{"Orchestrator
plans subtasks"}
O --> W1["Worker 1"]
O --> W2["Worker 2"]
O --> W3["Worker 3"]
W1 --> S["Synthesize"]
W2 --> S
W3 --> S
classDef o fill:#EEE6FF,stroke:#1F2937,color:#0E1726;
class W1,W2,W3 o;
The difference: parallelization's branches are known in code; the orchestrator decides the branches at run time. That's the first taste of real agency.
One model drafts, another (or the same one with a rubric) judges and hands back feedback. Loop until it passes or you hit a cap. This is how you get quality without a human in every iteration.
flowchart LR I["Task"] --> GEN["Generator
drafts an answer"] GEN --> EV{"Evaluator
good enough?"} EV -- "no · feedback" --> GEN EV -- yes --> O["Ship it"] classDef g fill:#DCEBFE,stroke:#1F2937,color:#0E1726; classDef ok fill:#D6F5E3,stroke:#1F2937,color:#0E1726; class GEN g; class O ok;
Always cap the loop. "Revise until good" with no ceiling is how a $5 task becomes a $50 one.
flowchart LR
START(["A task to build"]) --> Q1{"Are the steps
known in advance?"}
Q1 -- yes --> WF["Use a WORKFLOW
chain / route / parallelize"]
Q1 -- "no · open-ended" --> Q2{"Must it loop:
act, observe, decide?"}
Q2 -- no --> WF
Q2 -- yes --> Q3{"Worth the cost,
latency and risk?"}
Q3 -- "not yet" --> WF
Q3 -- yes --> AG["Use an AGENT
with guardrails + evals"]
classDef wf fill:#D6F5E3,stroke:#1F2937,color:#0E1726;
classDef ag fill:#EEE6FF,stroke:#1F2937,color:#0E1726;
class WF wf;
class AG ag;
Three gates, and an agent has to clear all three. Most features stop at the first.
The cure for all three: start simple, make it observable, add agency only when a gate demands it.
Every week you build one slice of a real artifact against your system. Tonight's decision, workflow or agent, is slice zero.
Take the feature you brought (or one you're about to build). We'll do one together, then you run these three and drop your answer in the chat.
Four failure modes: cost, latency, confidently wrong, blind. One decision: workflow before agent, and five patterns to reach for first. An agent only when all three gates clear.