Skip to content

Which pattern should I use?

There are seventeen patterns. Most projects need one or two. This page helps you pick, and says what each one costs you in complexity.

Start with the simplest thing that could work: a single agent with a good prompt and a typed output. Add a pattern when a test or a real run shows you need it, not before.

What are you trying to do?

You need to... Use Why
Start from nothing blank One output type, one prompt, no tools
Do one job with one prompt single The baseline; nothing to coordinate
Let the agent look things up or act on your systems tool_calling Tools, with an error convention the model can recover from
Use tools that already exist as an MCP server mcp_tools Discovered at run time, called over the network
Pull structured data out of free text extraction A validated schema, with retries when the model gets it wrong
Answer from your own documents, and show sources rag Search by meaning, and citations the model cannot invent
Get exact answers that need many lookups and arithmetic code_mode The model writes code that calls your tools, in a sandbox
Keep a conversation going conversation Memory across turns, a bounded context window, streaming
Stop and ask a person before a risky action human_in_the_loop A tool call that pauses for approval, then resumes
Refuse bad input and unsafe output guardrails Checks in code and with a guard model, and safe fallbacks
Make a long run survive failures and crashes temporal A durable workflow: failing tools are retried, a dead worker is replaced
Split work across several agents see below Six shapes, and the choice matters

Several agents: which shape?

Six patterns use more than one agent. They differ in who decides what happens next, and that decides how predictable, how fast and how checkable the result is.

Pattern Who decides the steps The steps are... Reach for it when
pipeline Your code always the same, in order The task is a fixed sequence, and you want a check between steps
router Your code, from a cheap classification one specialist, chosen per input Different kinds of input need different handling
fan_out Your code the same job, in parallel, then combined Independent views or chunks, and time matters
evaluator_optimizer A critic, in a loop repeated until the criteria are met, up to a cap A first draft is usually close and you can state what "good" means
supervisor The model, one turn at a time whichever workers it chooses to call You cannot know the steps in advance
planner_executor The model, once, up front; code checks it a plan with dependencies, run in rounds The work varies by question, parts are independent, and you want the plan checked or shown before it runs

A rough order, from most predictable to most flexible: pipeline, router, fan_out, evaluator_optimizer, planner_executor, supervisor. Predictable is cheaper to test, to debug and to explain. Choose the first one on that list that fits, and move down only when the task forces you to.

  • If you can write the steps as a list today, use pipeline.
  • If the input decides which handler runs, use router.
  • If the pieces do not depend on each other, use fan_out.
  • If quality is the problem and you can describe it, use evaluator_optimizer.
  • If the steps depend on the question, but you want them checked before anything runs, use planner_executor.
  • If you cannot know the steps until you are partway through, use supervisor.

Where is the risk?

Your concern Use
The model might do something irreversible human_in_the_loop
Input might contain data you must not send to a model guardrails
The model might state something it cannot support rag (citations are checked against what was retrieved)
The model might get arithmetic wrong code_mode
A run might die halfway temporal

What does it need?

Most patterns need nothing beyond the template. These need more, and add_agent.py handles it:

Pattern Extra package A service
rag chromadb-client Chroma (Docker)
temporal temporalio Temporal (Docker)
mcp_tools none an MCP server (Docker)
code_mode pydantic-ai-harness[code-mode] none

Combining patterns

Every pattern is a single run_* function returning the same RunResult, so patterns compose in ordinary Python: you can call one from another, or run a guardrail before any of them. The examples each show one pattern and do not ship combinations, so a combination is yours to test. Copy each pattern you want with add_agent.py, and write the glue in a module of your own.

Not sure?

Run the single example on your real input and look at where it falls short. The shortfall usually names the pattern: wrong facts point to rag or a tool, bad structure to extraction, a task that is really three tasks to pipeline or planner_executor.