Skip to content

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

  1. Multi-agent is an architectural trade-off, not an upgrade path.
  2. Deterministic workflows with bounded agentic islands are often a strong default.
  3. Prefer one modular agent when one policy/context boundary is sufficient.
  4. Separate planner/executor logically before deciding to deploy them independently.
  5. Use explicit typed handoff contracts between supervisors and workers.
  6. Separate agents are most justified by real responsibility, permission, trust, scaling or ownership boundaries.
  7. Keep worker state isolated and merge structured results into canonical state.
  8. Measure whether extra agents improve outcomes enough to justify cost, latency and operational complexity.