Agentic Design Patterns

Tool use, reflection, planning and multi-agent collaboration — the four reusable shapes, what each fixes, and what each costs.

Agent designs converge on a handful of patterns. They are not alternatives to pick between; they compose. What matters is knowing which failure each one addresses, because adding a pattern you do not need just adds turns, tokens and latency.

Tool use

The foundational pattern: the model is given callable functions and decides which to invoke. It fixes the model's two structural weaknesses — it does not know current state, and it cannot change anything. Everything else in this lesson assumes it.

The engineering work is almost entirely in tool design. Few tools, sharply described, with narrow inputs and small, already-filtered outputs. Twenty overlapping tools produce worse behaviour than six well-separated ones, because tool selection is a discrimination problem.

Reflection

The agent critiques its own output and revises it. In its simplest form this is a second call with the instruction "review this draft against these criteria and list the problems", followed by a third that applies the fixes. A stronger variant separates the roles: a generator agent and a distinct critic agent with its own rubric.

Reflection pays where quality is subjective and there is a rubric to judge against — code, long-form writing, plans. It pays badly where correctness is objectively checkable, because a compiler, a schema validator or a test suite is cheaper and never wrong. The failure mode is agreeable self-review: given a vague rubric, models tend to approve their own work, so make the criteria concrete and let the critic see the evidence rather than only the answer.

Planning

The agent decomposes the goal into ordered sub-tasks before acting, then works through them and re-plans on surprises. It fixes greedy behaviour on long tasks, and it gives you an artefact you can log, show to a user or approve before execution. The cost is a full extra reasoning turn and a tendency to over-decompose simple requests. A common guard is to plan only when the request is above a complexity threshold.

Multi-agent collaboration

Several specialised agents, each with its own instructions and tool set, coordinated by a supervisor. Amazon Bedrock Agents supports multi-agent collaboration, where a supervisor agent delegates to associated collaborator agents; a routing mode is available for simple requests that map cleanly to a single collaborator. In the Strands Agents SDK the equivalent shapes are agents-as-tools, plus swarm, graph and workflow primitives.

Use it when the sub-domains need genuinely different tools, instructions or permissions — and when one agent's tool list has grown unwieldy. Do not use it to make an architecture diagram look impressive. Every hand-off is another model call, another chance to lose context, and a harder trace to debug. A single well-scoped agent beats a committee of vague ones almost every time.

PatternFixesCosts
Tool useNo live data, no ability to actWrong tool selection; needs a security boundary
ReflectionSloppy or unchecked outputExtra turns; self-approval bias
PlanningGreedy, incoherent long tasksExtra turn; over-decomposition
Multi-agentToo many tools or domains for one agentLatency, cost, context loss at hand-offs

Example

Example · python
from strands import Agent, tool

# Specialists become tools of the supervisor - the "agents as tools" pattern.
@tool
def billing_specialist(query: str) -> str:
    """Answer invoice, refund and payment questions using billing systems."""
    agent = Agent(
        system_prompt="You handle billing only. Always look data up before answering.",
        tools=[get_invoice, list_payments],
    )
    return str(agent(query))

@tool
def network_specialist(query: str) -> str:
    """Diagnose connectivity problems using outage and line-test tools."""
    agent = Agent(
        system_prompt="You handle network faults only. Run a line test before concluding.",
        tools=[check_outages, run_line_test],
    )
    return str(agent(query))

@tool
def critic(draft: str) -> str:
    """Review a customer reply against the rubric and list concrete problems."""
    agent = Agent(system_prompt=(
        "Check: is every figure sourced from a tool result? Is the tone polite? "
        "Is the next step explicit? Reply with a bullet list of problems, or 'OK'."
    ))
    return str(agent(draft))

supervisor = Agent(
    system_prompt=(
        "Route each customer issue to the right specialist. For anything spanning both, "
        "plan the steps first. Before replying, send your draft to the critic and fix what it finds."
    ),
    tools=[billing_specialist, network_specialist, critic],
)

supervisor("I was charged twice this month and my broadband keeps dropping.")

When to use it

  • A code-review assistant generates a patch, runs the test suite, and only reflects on the failures rather than on its own opinion of the code.
  • A contact centre supervisor agent routes billing questions to one collaborator and network faults to another, each with separate tool permissions.
  • A report generator plans sections up front so a human can approve the outline before any expensive research runs.

Discussion

  • Be the first to comment on this lesson.