Anthropic's Workflow Patterns: Simple Over Complex
Schluntz and Zhang (Anthropic, Dec 2024) draw one line: workflows run on predefined paths, agents direct their own tool use. Five workflow patterns cover most cases. Start with direct API calls, and add an agent only when you can't predict the steps.
Learning Objectives
- Name Anthropic's five workflow patterns: prompt chaining, routing, parallelization, orchestrator-workers, evaluator-optimizer.
- Explain the agent-vs-workflow distinction and the engineering cost of each.
- Identify when to pick a workflow over an agent (and vice versa).
- Implement all five patterns in stdlib against a scripted LLM.
The Problem
Teams reach for multi-agent frameworks to solve problems that want a single function call. The cost is real. Frameworks add layers that obscure prompts, hide control flow, and invite complexity before anyone has earned it. Schluntz and Zhang's Dec 2024 post from Anthropic makes the pushback case, and its advice is blunt: start simple, and add complexity only when it pays for itself.
The Concept
Workflows vs agents
- Workflow. LLMs and tools orchestrated through predefined code paths. Engineers own the graph.
- Agent. LLMs dynamically direct their own tools and take their own steps. The model owns the graph.
Both have a place. Workflows are cheaper, faster, and easier to debug. Agents unlock open-ended problems, but their failure modes are much harder to reason about.
The augmented LLM
Every one of the five patterns is built from the same unit: one LLM with three capabilities wired in. Search gives it retrieval, tools give it actions, and memory gives it persistence. Any API call in a workflow can use all three.
The five patterns
-
Prompt chaining. The output of call 1 is the input to call 2. Use it when a task decomposes cleanly into a linear sequence. You can add programmatic gates between steps to check an intermediate result before moving on.
-
Routing. A classifier LLM picks which downstream LLM or tool to invoke. Use it when categorically different inputs need different handling, such as tier-1 support, refunds, bugs, and sales.
-
Parallelization. Run N LLM calls concurrently and aggregate the results. It comes in two shapes: sectioning (each call gets a different chunk) and voting (the same prompt runs N times, then you take a majority or synthesize).
-
Orchestrator-workers. An orchestrator LLM decides at runtime which workers (also LLMs) to run, then synthesizes their output. It looks a lot like an agent loop, except the orchestrator does not loop indefinitely.
-
Evaluator-optimizer. One LLM proposes an answer and another evaluates it. Iterate until the evaluator passes. This is Self-Refine (Lesson 05) generalized.
Where workflows beat agents
- Predictable tasks. If you can enumerate the steps, write them down and run them.
- Cost-bound tasks. A workflow has a bounded step count. An agent can spiral.
- Compliance-bound tasks. Auditors want to read the graph, not infer it from trajectories.
Where agents beat workflows
- Open-ended research. The next step depends on what the last one returned.
- Variable-length tasks. Minutes to hours of work, with no way to know the step count up front.
- Novel domains. You don't yet know the right workflow, so explore first and codify later.
The context-engineering companion
"Effective context engineering for AI agents" (Anthropic 2025) formalizes the adjacent discipline. The 200k window is a budget, not a container: you decide what goes in, when to compact, and when to let context grow. Lesson 07 (Memory: Virtual Context and MemGPT) shows one way to manage that budget.
Build It
code/main.py implements all five workflow patterns against a ScriptedLLM:
prompt_chain(input, steps): sequential calls.route(input, classifier, handlers): classification, then dispatch.parallel_vote(prompt, n, aggregator): N runs, aggregated.orchestrator_workers(task, workers): the orchestrator picks the workers.evaluator_optimizer(task, proposer, evaluator, max_iter): loop until the evaluator passes.
Run it:
python3 code/main.py
Each pattern prints its trace. Every pattern is roughly 10-15 lines of code. The cost of a framework is measured in thousands.
Use It
- Use direct API calls for most tasks.
- Reach for a framework only when the pattern genuinely needs durable state (LangGraph), actor-model concurrency (AutoGen v0.4), or role templating (CrewAI).
- Use the Claude Agent SDK when you want the Claude Code harness shape without rebuilding it.
Ship It
outputs/skill-workflow-picker.md picks the right pattern for a given task description. It gives the decision rationale and the refactor path to an agent if the workflow falls short.
Draw the graph before you pick a tool. If you can sketch every step on a whiteboard, you have a workflow, and a few direct API calls will do the job with bounded cost and a trace an auditor can read. That is the default, and it should take real evidence to move off it.
The case for an agent is that you can't predict the steps. If the next move depends on what the last one returned, or you don't yet know the right workflow, let the model direct itself while you explore. Once the shape settles, codify it as a workflow. Exercise 5 is the habit to build: take a feature you already run, count its steps, and ask honestly whether an agent would be better. Most of the time the graph you drew is the answer.
Exercises
- Implement routing with a confidence threshold. Below threshold, escalate to human. Where does the threshold land for a tier-1 support use case?
- Add a timeout to
parallel_vote. What happens when one call hangs? How do you aggregate with missing votes? - Turn
evaluator_optimizerinto a bandit: keep the top-2 outputs across iterations so a late good result doesn't get overwritten by a late bad one. - Combine prompt chaining with routing: a router picks one of three chains. Measure token cost vs a single big-prompt alternative.
- Pick one of your production features. Draw the workflow graph. Count steps. Would an agent actually be better here?
Key Terms
| Term | What people say | What it actually means |
|---|---|---|
| Workflow | "Predefined flow" | Engineer-owned graph of LLM and tool calls |
| Agent | "Autonomous AI" | Model-owned graph; dynamic tool direction |
| Augmented LLM | "LLM with tools" | LLM + search + tools + memory; the atomic unit |
| Prompt chaining | "Sequential calls" | Output of call N is input to call N+1 |
| Routing | "Classifier dispatch" | Pick which chain/model handles the input |
| Parallelization | "Fan out" | N concurrent calls; aggregate by sectioning or voting |
| Orchestrator-workers | "Dispatcher agent" | Orchestrator LLM picks specialist LLMs dynamically |
| Evaluator-optimizer | "Proposer + judge" | Iterate until evaluator passes; Self-Refine generalized |
Further Reading
- Anthropic, Building Effective Agents (Dec 2024): the five workflow patterns
- Anthropic, Effective context engineering for AI agents: the companion discipline
- LangGraph overview: when stateful graphs earn their cost
- OpenAI Agents SDK: the orchestrator-workers pattern, productized
Code
- main.py (python, 239 lines)