Module 02
Anthropic Workflow Patterns
On this page
In plain words
In your hostel mess the steps never change, so nobody re-plans them daily. A college fest is the opposite: you decide the next move after seeing what just broke. Software with language models has the same two shapes. When you can list the steps, write them yourself as a workflow. Only when the steps cannot be listed should the model own the order.
How it flows
- 1Look at the task
- 2Can you list steps?
- 3Yes: write workflow
- 4No: use an agent
- 5Keep it simple
A tiny example
kind = classify(message)
if kind == "refund":
reply = run_tool("refund_prompt", message)
else:
reply = run_tool("bug_prompt", message)
print(reply)Notice the order of steps is written by you in plain Python; the model only fills in the two boxes.
What you will learn
- The difference between a workflow and an agent, in one line each.
- The five workflow patterns almost every real system uses.
- How to pick a workflow instead of a full agent, and when to flip.
- How to write all five in plain Python, no library.
The problem, simply
Think about your hostel mess. Every day the steps are the same: token counter, then rice counter, then sabzi, then curd, then wash your plate. Nobody stands there deciding the order fresh each morning. The path is fixed because the path is known.
Now think about the college fest. Sponsor calls, a vendor cancels, the sound system dies, somebody has to run to the market. There is no fixed path. Somebody senior has to look at what just happened and decide the next move.
Software with language models has exactly these two shapes. And most teams get it wrong in one direction. Somebody gets a task like "read a support message and reply politely", and immediately builds a five-agent system for it. It works on demo day. Then a bug comes and nobody can tell which part made which call.
See, the problem is not that agents are bad. The problem is that people pay the price of an agent for a job that a plain if-else plus two model calls would finish. This lesson is about learning to spot which one you actually need.
The idea
Workflow vs agent
Two definitions. Learn these word for word, because interviewers ask them.
- Workflow — you, the engineer, write the code path. The model fills in the boxes, but the order of the boxes is yours.
- Agent — the model decides the next step by itself, again and again, until it thinks it is done. The order of the boxes belongs to the model.
Workflows are cheap, fast, and easy to debug. You know exactly how many model calls will happen. Agents can solve open-ended things a workflow cannot, but they can also loop, wander, and burn your API credits at 2 AM.
IMPImportant: "Agent" is not the advanced version of "workflow". They are two different tools. Picking the simpler one is a senior move, not a lazy one.
The augmented LLM
Before the patterns, one building block. An augmented LLM just means a model with three things wired in:
- Search — it can look things up (documents, database, notes).
- Tools — it can do things (send email, run code, hit an API).
- Memory — it can keep something from earlier.
Every pattern below is made of these blocks stuck together in different shapes.
The five patterns
1. Prompt chaining. Output of call 1 goes into call 2, which goes into call 3. Straight line. Use it when the task splits cleanly into steps. You can also put a normal Python check between two steps — if the middle result looks wrong, stop early.
- 1Raw complaint
- 2Model summarises
- 3Check length
- 4Model writes reply
- 5Send
2. Routing. A small classifier call first decides "what kind of thing is this?", then you send it to a different handler. A support inbox gets refunds, bugs, sales questions and plain "how do I login". Each deserves a different prompt.
3. Parallelization. Fire several calls at the same time and combine the results. Two flavours: sectioning (split a big document into parts, one call per part) and voting (same question asked five times, take the majority answer).
4. Orchestrator-workers. One model call looks at the task and decides which specialist calls to run, then joins their answers. It feels agent-like, but it does not loop forever — it dispatches once and stops.
5. Evaluator-optimizer. One call writes an answer, a second call grades it, and you loop until the grader says pass. This is the Self-Refine idea from the Self-Refine and Critic lesson in Module 1, just given a workflow shape.
A worked example
Suppose Priya is building the support bot for a small Flipkart-style seller. Ten messages a day. Categories: refund, delivery delay, product question.
If she builds an agent, the model must figure out what to do for every message. Slow, costly, hard to explain when it goes wrong.
If she builds a workflow, it is one small classify call, then one reply call using the prompt written for that category. Two calls, fixed cost. If a refund reply is bad, she knows exactly which prompt to fix.
- 1Message arrives
- 2Classify type
- 3Pick prompt
- 4Write reply
- 5Human approves
Now suppose next month she wants "look at this customer's full order history across three systems and figure out what went wrong". Nobody can enumerate those steps in advance. That one deserves an agent.
Remember: if you can write down the steps on paper, write them in code. Only when you genuinely cannot list the steps should the model own the order.
Build it
"""Five workflow patterns with a toy 'model'. Standard library only."""
def fake_model(prompt):
"""A pretend LLM: keyword rules instead of a real API call."""
p = prompt.lower()
if p.startswith("classify"):
return "refund" if "money back" in p else "bug"
if p.startswith("shorten"):
return prompt.split(":", 1)[1].strip()[:40]
if p.startswith("rate"):
return "PASS" if len(prompt) < 120 else "FAIL"
return "We will look into this and get back to you soon. " * 3
# 1. Prompt chaining: output of one step feeds the next
def prompt_chain(text, steps):
for step in steps:
text = fake_model(step + ": " + text)
return text
# 2. Routing: classify first, then send to the right handler
def route(text, handlers):
kind = fake_model("classify: " + text)
handler = handlers[kind]
return kind, handler(text)
# 3. Parallelization (voting): same question N times, majority wins
def parallel_vote(text, n):
votes = [fake_model("classify: " + text) for _ in range(n)]
return max(set(votes), key=votes.count), votes
# 4. Orchestrator-workers: one call picks the specialists, then joins them
def orchestrator_workers(task, workers):
picked = [name for name in workers if name in task]
out = {}
for name in picked:
worker = workers[name]
out[name] = worker(task)
return out
# 5. Evaluator-optimizer: propose, grade, repeat until it passes
def evaluator_optimizer(task, max_rounds=3):
answer = fake_model("draft: " + task)
for r in range(1, max_rounds + 1):
verdict = fake_model("rate: " + answer)
print(" round", r, "length", len(answer), "->", verdict)
if verdict == "PASS":
return answer
answer = fake_model("shorten: " + answer)
return answer
if __name__ == "__main__":
print("1 chain :", prompt_chain("laptop not charging", ["draft", "shorten"]))
print("2 route :", route("I want my money back", {
"refund": lambda t: "Refund team will call you.",
"bug": lambda t: "Engineering is checking this.",
}))
print("3 vote :", parallel_vote("please return my money back", 5)[0])
print("4 workers :", orchestrator_workers("write intro and summary", {
"intro": lambda t: "Intro text",
"summary": lambda t: "Summary text",
}))
print("5 loop :")
print(" final :", evaluator_optimizer("explain the refund policy"))Run it with python3 file.py. Look at three things. The route line prints the category the classifier picked, so you can see the dispatch. The vote line shows five calls collapsing into one answer. The loop prints one line per round: round 1 fails because the draft is too long, round 2 passes after shortening. Each pattern is about ten lines. That is the whole point.
Where you will see this
- Customer support bots at banks and e-commerce sites: routing first, then a category-specific prompt.
- Coding assistants like Claude Code and Cursor: a real agent for "fix this failing test", but a plain chain for "write a commit message".
- GitHub Copilot's inline suggestions: no agent at all, one fast call with your file as context.
- Food delivery and travel assistants: routing between "where is my order", "cancel", and "talk to a human".
- Report tools: sectioning a long document into chunks, one call each, then a joining call at the end.
Common mistakes
- Starting with a multi-agent framework. You pay in hidden control flow and hidden prompts. When output is wrong you cannot see which prompt did it. Start with plain function calls.
- Using an agent for a fixed process. If the steps never change, an agent just adds cost and randomness to something that was already deterministic.
- Voting without an odd number of runs or a tie rule. With four votes you can get 2-2 and your code silently picks whatever came first.
- Evaluator-optimizer without a round limit. The grader may never say pass. Always cap the loop, and keep the best answer seen so far.
- Never revisiting the choice. A workflow that keeps getting new
ifbranches every week is telling you the real task is open-ended. That is the moment to move to an agent.
If they ask in an interview
Q: What is the difference between a workflow and an agent?
A: In a workflow the engineer writes the control flow and the model only fills in steps, so the number of calls is known in advance. In an agent the model decides the next step each turn, so it handles open-ended tasks but the path and cost are not fixed. Workflows are easier to debug and audit.
Q: Name the five workflow patterns and give one use case each.
A: Prompt chaining for clean linear tasks like summarise-then-reply. Routing for support inboxes with different categories. Parallelization for chunking long documents or voting on a risky answer. Orchestrator-workers when one call should pick which specialists to run. Evaluator-optimizer when quality matters enough to grade and retry.
Q: How do you decide when to add a framework?
A: Default to direct API calls. Add a framework only when you need something it genuinely gives you — durable state across restarts, real concurrency between many actors, or reusable role templates. Otherwise you are paying complexity for nothing.
Try these
- Add a confidence score to the routing example. If confidence is below your threshold, send the message to a human queue instead. Decide where that threshold should sit for a support inbox and write down why.
- Make voting robust. Use an even number of votes, create a deliberate tie, and add an explicit tie-breaking rule instead of letting the code guess.
- Change the evaluator-optimizer to remember the two best answers across rounds, so a good round-2 answer is not thrown away by a bad round-3 answer.
- Combine routing with chaining: a router picks one of three different chains. Count how many model calls each path takes and compare it with doing everything in one giant prompt.
Words, simply
| Word | Meaning in simple words |
|---|---|
| Workflow | You write the order of steps; the model just fills them in |
| Agent | The model decides the next step by itself, again and again |
| Augmented LLM | A model with search, tools and memory attached |
| Prompt chaining | Answer of one call becomes the question for the next |
| Routing | Classify the input first, then send it to the matching handler |
| Parallelization | Run several calls at once and combine the results |
| Orchestrator-workers | One call picks the specialists and joins their answers |
| Evaluator-optimizer | One call writes, another grades, repeat until it passes |
Quick recap
- If you can list the steps, write a workflow. Only unlistable steps deserve an agent.
- Five patterns cover most real work: chaining, routing, parallelization, orchestrator-workers, evaluator-optimizer.
- Start with plain function calls; add a framework only when it clearly earns its cost.