Single Agent, Workflow and Multi-Agent Patterns¶
Agent topology should be chosen from the problem's control-flow uncertainty, responsibility boundaries, permission boundaries and scaling needs. Multi-agent is not a maturity level that every system should eventually reach.
A useful default order is:
Deterministic code
↓ if semantic decision needed
Workflow with agentic step
↓ if task needs iterative autonomy
Single agent
↓ only with concrete separation need
Multi-agent
The simplest topology that preserves the required behavior is usually the easiest to test, secure and operate.
Pattern 1: Deterministic workflow¶
If the process is known, keep it explicit.
validate request
↓
load customer
↓
calculate eligibility
↓
generate explanation
↓
send response
Only the explanation step may need an LLM.
Benefits:
- predictable control flow,
- easy tracing,
- explicit retries,
- simple permissions,
- low cost,
- fewer failure modes.
Do not replace known application logic with an agent just because a model could execute it.
Pattern 2: Deterministic workflow with agentic islands¶
This is often a strong production pattern.
Deterministic workflow
│
├── deterministic step
│
├── [agentic island]
│ observe
│ decide
│ use tools
│ verify
│ stop
│
└── deterministic continuation
The overall business process stays visible while bounded sections can use semantic reasoning.
Example incident workflow:
create incident record
↓
collect known telemetry
↓
[agent investigates probable cause]
↓
human approves remediation
↓
deterministic remediation workflow
↓
close incident
This gives autonomy where it adds value without handing the whole process to an open-ended loop.
Pattern 3: Single agent¶
Use one agent when one coherent goal can be solved with one policy/context/permission boundary.
Agent Runtime
├── skills
├── tools
├── retrieval
├── state
└── policy
A single agent can still be highly modular internally.
Do not confuse:
one agent
with:
one giant class / prompt / context
The single agent can depend on many well-separated capabilities.
Good fit¶
- interactive research,
- coding tasks within one repo/policy scope,
- troubleshooting,
- document analysis,
- bounded operational assistance.
Warning signs¶
A single agent becomes problematic when it needs mutually incompatible:
permissions
trust levels
context scopes
models
ownership teams
latency/SLO profiles
Those may justify stronger boundaries.
Pattern 4: Plan → execute¶
The same runtime first creates a plan and then executes it.
Goal
↓
Plan
↓
Step 1
↓
Step 2
↓
replan if state changed
↓
complete
Useful when tasks have several dependent stages.
Do not treat the initial plan as truth. It is a hypothesis that must be updated after new observations.
Pattern 5: Planner / executor separation¶
Planner and executor are separate logical components.
Planner
↓ Plan / next objective
Executor
↓ Action result
Planner
The separation can be useful when:
- planning needs a stronger/slower model,
- execution needs a cheaper model,
- planner should not hold write credentials,
- plans need independent evaluation,
- execution is heavily constrained.
However, this does not automatically require two independently deployed agents.
It may be two components inside one runtime.
AgentRuntime
├── PlannerStrategy
└── ExecutorStrategy
Prefer logical separation before distributed-system separation.
Pattern 6: Supervisor / workers¶
A supervisor delegates bounded tasks to workers.
Supervisor
├── Worker A
├── Worker B
└── Worker C
Workers may represent:
specialized context
specialized capabilities
separate permissions
parallel work
independent ownership
Example:
Release Supervisor
├── Test Analysis Worker
├── Dependency Risk Worker
└── Documentation Worker
The supervisor should receive structured results rather than unlimited conversational transcripts.
Worker contract¶
A worker handoff should look like a normal API contract:
{
"task_id": "task_88",
"objective": "Analyze failing integration tests",
"input_artifacts": ["artifact_12"],
"constraints": {
"read_only": true,
"max_steps": 10
},
"expected_output": "TestFailureAnalysisV1"
}
The result should be similarly typed.
Supervisor
↓ explicit task contract
Worker
↓ structured result
Supervisor
This is much easier to trace than two agents chatting until they agree.
Pattern 7: Specialist handoff¶
Sometimes responsibility genuinely changes.
General Support Agent
↓ handoff
Billing Specialist Agent
A separate agent can be justified if the specialist has:
- different instructions,
- different data scope,
- different allowed tools,
- different compliance policy,
- different model/runtime configuration.
The handoff should explicitly transfer:
objective
relevant state
approved context
artifact references
permissions scope
reason for handoff
Do not implicitly pass the entire previous context if it violates least privilege or creates irrelevant baggage.
Pattern 8: Fan-out / fan-in¶
Independent analyses can run in parallel.
┌→ Security analysis ─┐
Task ──────┼→ Performance review ├→ Aggregator
└→ API compatibility ─┘
This can reduce latency and increase coverage when subtasks are genuinely independent.
The aggregator should understand conflicts and missing results explicitly.
Parallelism increases cost and can amplify errors, so fan-out should be bounded.
Pattern 9: Event-driven agent runs¶
Some tasks should wake up when an event happens rather than remain in a polling loop.
Run waits
↓
state = WAITING_FOR_EVENT
↓
external event arrives
↓
queue message
↓
worker reloads state
↓
continue
Examples:
- CI completed,
- human approved,
- deployment finished,
- new email arrived,
- asynchronous analysis returned.
This is more efficient and reliable than keeping a model loop alive.
When is a separate agent justified?¶
A useful test is whether the boundary would still make architectural sense without the word "agent".
Good reasons:
separate business responsibility
separate permission boundary
separate trust boundary
independent scaling
independent ownership/deployment
materially different context/model policy
parallel independent workload
Weak reasons:
"This prompt is long"
"Multi-agent sounds more advanced"
"We want agents to debate"
"Each function should be an agent"
Often a skill, module or deterministic service is a better abstraction.
Multi-agent cost model¶
Every additional agent can add:
model calls
context duplication
coordination messages
state synchronization
security boundaries
retry complexity
observability requirements
latency
Suppose one task becomes:
Supervisor call
+ 4 worker calls
+ 4 follow-up calls
+ aggregator call
A design that looked conceptually elegant may be 10× more expensive and harder to debug than one well-instrumented agent.
Shared vs isolated state¶
Avoid an unstructured global scratchpad shared by all agents.
Prefer:
canonical workflow/run state
↓
explicit task projection
↓
worker-local execution state
↓
structured result
↓
canonical state update
This reduces race conditions and accidental context leakage.
Permissions¶
Each worker should receive only the capabilities needed for its task.
Supervisor: may delegate
Security worker: repo read only
Deployment worker: deploy read + approved execute
Documentation worker: docs write only
Do not give every agent the union of all credentials.
Failure handling¶
Multi-agent systems need explicit partial-failure semantics.
3 workers requested
2 succeeded
1 timed out
Possible policies:
fail whole task
continue with partial evidence
retry one worker
use fallback worker
ask human
The supervisor should not improvise infrastructure retry semantics solely through natural language.
Common anti-patterns¶
Agent for every module¶
Normal software modules do not need autonomous decision loops.
Agents chatting freely¶
Open-ended agent-to-agent conversation hides state, increases cost and makes termination difficult.
Multi-agent before single-agent baseline¶
Without a baseline, you cannot tell whether the added architecture improves quality.
Shared unrestricted tool pool¶
All agents can perform every side effect.
Planner as unquestioned authority¶
The executor follows a stale plan even when the environment changed.
Distributed agents for logical separation only¶
Network boundaries, queues and deployments are introduced when simple in-process strategies were sufficient.
No handoff contract¶
The receiving agent must infer task scope from a transcript dump.
Decision heuristic¶
Is control flow known?
├─ yes → deterministic workflow
│ └─ semantic step needed? → agentic island
│
└─ no → does one coherent policy/context handle the task?
├─ yes → single agent
└─ no → is there a real responsibility/permission/scaling boundary?
├─ yes → multi-agent / worker pattern
└─ no → simplify
Engineering takeaways¶
- Multi-agent is an architectural trade-off, not an upgrade path.
- Deterministic workflows with bounded agentic islands are often a strong default.
- Prefer one modular agent when one policy/context boundary is sufficient.
- Separate planner/executor logically before deciding to deploy them independently.
- Use explicit typed handoff contracts between supervisors and workers.
- Separate agents are most justified by real responsibility, permission, trust, scaling or ownership boundaries.
- Keep worker state isolated and merge structured results into canonical state.
- Measure whether extra agents improve outcomes enough to justify cost, latency and operational complexity.