Agent Patterns Cheat Sheet

Reference intermediate

A one-page reference for the architectural patterns covered in this course. Keep it open while you build. For deeper treatment see Agent Architectures and Building Your First Agent.

Vocabulary

Term Meaning
Step / turn One model call plus any tool execution it triggers
Trajectory The full sequence of steps from goal to final answer
Tool call The model's request to run a named function with arguments
Observation The result of a tool call, fed back to the model
Stop condition Rule that ends the loop (final answer, budget hit, error cap)

The Canonical Agent Loop

Every architecture below is a variation on one core loop: think, act, observe, repeat until done. In compact pseudocode:

function run_agent(goal, tools, max_steps):
    history = [system_prompt, goal]
    for step in 1..max_steps:
        response = model.call(history, tools)
        if response.has_tool_calls():
            for call in response.tool_calls:
                result = execute(call.name, call.args)   # may raise
                history.append(tool_result(call.id, result))
        else:
            return response.text                          # final answer
        if over_budget() or too_many_errors():
            return abort("stop condition hit")
    return abort("max_steps exceeded")

The differences between patterns are where the reasoning happens and whether the agent revisits its own work.

Pattern Comparison

ReAct Plan-and-Execute Reflexion
Shape Interleave reason + act each step Plan all steps up front, then execute Act, then self-critique, then retry
Reasoning Inline, one step at a time Front-loaded into a static plan After-the-fact on a failed/weak result
Best for Open-ended, exploratory tasks Multi-step tasks with clear structure Tasks with a checkable success signal
Latency Low per step, can run long Higher up front, fast execution Highest (extra critique passes)
Token cost Moderate Moderate, predictable High (repeated attempts)
Pros Simple, adaptive, easy to debug Parallelisable steps, fewer dead ends Recovers from mistakes, higher quality
Cons Can loop or wander Brittle if the world changes mid-plan Slow and expensive; needs an evaluator
Failure mode Gets stuck repeating an action Executes a plan that no longer fits Critiques without improving (thrash)

When to pick which

Situation Pattern
"Find X by exploring tools/data" ReAct
"Do these N known steps in order" Plan-and-Execute
"Get it right; we can verify the result" Reflexion
Long task whose steps depend on findings ReAct, or Plan-and-Execute with re-planning
Cost-sensitive, latency-sensitive ReAct (cap max_steps tightly)

ReAct in One Block

Reasoning and acting interleaved. The model emits a thought, takes one action, sees the observation, then repeats. With native tool use the "thought" lives in the model's text and the "action" is a tool call.

loop until final answer or budget hit:
    thought  = model reasons about what to do next
    action   = model calls one tool
    observation = execute(action)
    append (thought, action, observation) to history

Plan-and-Execute in One Block

Separate the planner (one call that decomposes the goal into ordered sub-tasks) from the executor (a small ReAct loop per sub-task). Re-plan only when a step fails.

plan = planner.call(goal)            # -> ["step 1", "step 2", ...]
results = []
for step in plan:
    r = execute_subtask(step, tools) # mini agent loop
    results.append(r)
    if r.failed:
        plan = planner.replan(goal, results)   # optional recovery
synthesize(results) -> final answer

Reflexion in One Block

Add an evaluator and a memory of past attempts. The agent tries, gets scored or critiqued, writes a lesson to memory, and retries with that lesson in context.

for attempt in 1..max_retries:
    result = base_agent.run(goal, reflections)
    verdict = evaluator(result)          # pass/fail + critique
    if verdict.passed:
        return result
    reflections.append(verdict.critique) # carried into next attempt
return best_so_far(results)

Minimal Tool Definition (Claude Tool Use)

A tool is a name, a description the model reads to decide when to use it, and a JSON Schema for its arguments. Write descriptions for the model, not for humans — they are prompt.

weather_tool = {
    "name": "get_weather",
    "description": (
        "Get the current weather for a city. "
        "Use when the user asks about temperature, rain, or conditions. "
        "Returns temperature in Celsius and a short summary."
    ),
    "input_schema": {
        "type": "object",
        "properties": {
            "city": {
                "type": "string",
                "description": "City name, e.g. 'Berlin' or 'Tokyo'.",
            },
        },
        "required": ["city"],
    },
}

Wire it into a request and dispatch the tool call:

import anthropic

client = anthropic.Anthropic()

resp = client.messages.create(
    model="claude-sonnet-latest",
    max_tokens=1024,
    tools=[weather_tool],
    messages=[{"role": "user", "content": "What's the weather in Berlin?"}],
)

if resp.stop_reason == "tool_use":
    for block in resp.content:
        if block.type == "tool_use":
            result = get_weather(**block.input)   # your function
            # Send the result back as a tool_result block to continue the loop

Tool Design Checklist

Rule Why
One clear job per tool The model picks better between focused tools
Description states when to use it The description is the selection prompt
Type and constrain every argument Schema validation catches bad calls early
Return structured, compact results Saves context; easier to reason over
Return errors as data, not exceptions Lets the agent recover instead of crashing

Stop Conditions (always set these)

Guard Typical default
max_steps 10-25 per task
Token / cost budget Hard cap per run
Wall-clock timeout Per run and per tool call
Repeated-action detector Abort if same call repeats N times
Consecutive-error cap Abort after 3 failed tool calls

See Also