← Back to all articles

AI Agent Design Patterns

Introduction

With the rapid progress of LLMs and AI agents from 2025 onward, enterprise use of AI agents has moved on from the original chatbot-style, one-question-one-answer usage into a phase where agents are handed broader and more open-ended work.

At the same time, there is no single correct way to design an AI agent. Two requests that look identical on the surface, such as "we want to automate the task of researching our business partners", can call for very different architectures depending on the volume of information involved, the accuracy required, and the cost and latency constraints you are working under.

Because the goals and constraints keep moving, AI agent development has no best practice of the "just do it this way and you will be fine" kind. An AI agent is not a functionally closed system; how it connects to its environment is a large part of the point, so it is not unusual for an agent that worked in one environment to fail completely in another.

In other words, since there is no one correct pattern, what matters is how many methods and design patterns you have in your drawer, and whether you can pick the right one for the situation and constraints in front of you.

I have rarely built anything with design patterns consciously in mind (more often I find out afterwards that what I did already had a name). I work backwards from the goal, try the structure that seems right for the case, and then keep updating it through repeated rounds of tearing down and rebuilding, taking the situation, constraints, and phase into account. Still, I wanted to organize the main design patterns in AI agent design once, partly as a review of my own practice and what I have learned from it.

Strictly speaking, the number of patterns is unlimited once you start combining them. Here I have left out the idea-stage ones that are interesting as academic or demo material but probably cannot be used in practice, and narrowed this down to the approaches that appear consistently across the major vendors' own blogs.

Thinking in Seven Categories

AI agent design patterns can be grouped to some extent by purpose and by the concern they address, so I have sorted them into seven categories to make the overall picture easier to grasp.

When new approaches appear later on, I think they become easier to understand if you dig into them with the question "which problem is this meant to solve?" in mind.

No.CategoryFocusPatterns
1ReasoningHow it thinks and acts ReAct / Plan-and-Execute / Replanning / Goal-directed Loop / Parallel Exploration
2 Reflection & VerificationHow it detects and corrects mistakes Reflection / Local Reflection / Global Reflection / Generator-Evaluator / Self-Heal
3DecompositionHow it breaks a large task down Parallelization / Orchestrator-Workers / Hierarchical Decomposition / Query Decomposition
4CoordinationHow multiple agents work together Supervisor / Handoff / Group Chat / Blackboard
5 Context ManagementHow a limited context is used Skills / Scratchpad / Context Triage / Memory
6 Autonomy & ControlHow autonomous execution is controlled Step & Token Budget / Termination Condition / Human-in-the-loop / Approval Gate / Escalation
7Safety & SecurityHow input, output, and execution are kept safe Input Guardrail / Output Guardrail / Tool Guardrail / Pre-action Validation

Let's get into it. Each section stands on its own, so feel free to use it as a reference and jump straight to whatever is relevant to your own case.

1. Reasoning Patterns

How the agent thinks and acts. This is the most fundamental concern, since it determines the decision loop behind every individual move. The reasoning pattern you choose here has a large effect on cost, latency, and reliability downstream, which makes it one of the most important design decisions.

ReAct

Probably the best-known AI agent pattern, and the most basic reasoning loop: Thought, Action, and Observation, repeated one step at a time in alternation.

Because execution and observation are interleaved at every step, the agent can respond flexibly to unfamiliar environments and to changes in the situation.

Pros: The agent looks at the result of each step before deciding on the next, so it can correct course on the spot when an unexpected error or new information turns up. The more complex the environment, and the less you can read the procedure and steps in advance, the more this flexibility pays off.

Cons: The LLM is called once per step, so latency and cost pile up with every loop. This needs particular care where response speed matters. Also, because the agent decides moment by moment without an overall plan made in advance, it can end up taking a roundabout route overall (though in highly complex environments there are cases where drawing up an overall plan first is pointless, so being planned is not always better).

When to use it: It suits exploratory tasks where the procedure cannot be fixed in advance in the first place, such as web research or interactive debugging. Conversely, where what needs doing and the procedure are more or less fixed, it only makes control needlessly complicated, so there is little to gain from adopting it. It gives a very clear picture of how an AI agent behaves, so I strongly recommend it for hands-on sessions and exercises.

Plan-and-Execute

ReAct plans and executes moment by moment; this pattern instead draws up an execution plan for the whole task first and then carries out each step in order according to that plan. Where ReAct repeats "reason, then act" one step at a time, Plan-and-Execute explicitly creates an overall plan made up of multiple steps before execution begins. Because a planning phase comes first, what gets executed is also easier to trace (and easier to control).

Pros: Because the overall plan is set first, it is easier to keep a consistent direction even in tasks that span many steps. It can also be adapted so that a human or another AI reviews the plan before execution, which is a governance advantage for important processing.

Cons: Because everything proceeds on the basis of the initial plan, the plan and the actual results tend to drift apart when the situation or the assumptions change midway. The plan is made before any execution or observation, so when the initial hypothesis turns out to be wrong there is no way to correct course. In cases with many unexpected responses, ReAct copes more flexibly.

When to use it: It works when you want to draw up an overall plan and have the AI agent act from a task list, particularly for work that is simple but has a fair number of steps. I doubt it is often used exactly as is, but it may have a place in very simple cases where the initial plan almost never misses.

Replanning

This pattern makes up for the weakness of Plan-and-Execute, which is that it gets dragged along by the initial plan: when a failure or new information comes up during execution, the original plan itself is rebuilt. Updating the plan as the situation changes makes a flexible response possible.

Pros: The plan itself can be rebuilt the moment its assumptions break, which directly covers the weakness of Plan-and-Execute: once decided, it has no give. The more uncertain the external environment, the more this ability to replan pays off.

Cons: Every replan means another LLM call, so as the loops increase, cost and latency both go up. Used without a limit, the agent can keep reworking the plan every time the situation shifts slightly and effectively fall into an infinite loop, so setting guardrails is important. In environments complex enough that the plan keeps missing, an exploratory approach like ReAct is sometimes the better choice.

When to use it: It works for tasks such as incident response or long-running autonomous work, where assumptions get overturned midway but the response should still proceed in a reasonably planned way. It does add complexity to the AI agent, though, so the design of the replanning rules and guardrails matters. Where response speed is important, there are probably quite a few cases where it is better not to replan at all, and instead have the agent report the Plan-and-Execute result for now and ask for instructions.

Goal-directed Loop

An execution structure in which the agent is given an explicit goal and, until that goal is achieved, repeats tool calls and reasoning while deciding its own next action.

Where ReAct defines what goes on inside a single step (Thought, Action, Observation), Goal-directed Loop defines the overall control structure: iterate autonomously until the goal is achieved. It does not define how the agent thinks or acts inside the loop, so in practice it is used in combination with reasoning patterns such as ReAct or Replanning.

Pros: Give the agent a clear goal to achieve, and it will keep running autonomously until it gets there. The AI tries whatever means it has, by trial and error, until the objective is met, so in the sense that little human intervention is needed, this is the form that receives the benefits of automation most directly.

Cons: Because autonomy is high, cost and latency have no ceiling unless termination conditions and the like are set properly. With no human intervention or correction, there is also the risk that errors made along the way compound across later steps, and the risk of getting stuck in a local optimum. Since the agent will try every available means to achieve the goal, it can also lead to unexpected accidents unless guardrails are set properly and the range in which the AI agent can act is narrowed beforehand. It gets you started quickly and looks attractive at first glance, but it is in a sense a way of skipping task design, and it often ends up costing more.

When to use it: It suits open-ended problem solving where mistakes are not particularly fatal (cases like batch processing with no cost or latency constraints). From a quality assurance standpoint it may not see much use in production operation within an organization, but it can be useful as a way of handing the AI nothing but a goal, letting it experiment, and drawing insights from the results. It offers the most autonomy of any pattern, so it is one I want to keep among the options under consideration, including the variant where the goal is set quite small.

Parallel Exploration

A pattern that generates multiple reasoning paths or candidate solutions for the same task in parallel and adopts the best one by voting or scoring.

Pros: Trying several candidates at once makes it easier to avoid the local solutions that single-track reasoning tends to get stuck in. In a sense this is a very good way of using AI. A person, constrained by effort, picks a small number of what look like the best options; for AI the cost of trying multiple options is much easier to bring down, so it can explore several reasoning paths in parallel. The idea is also close to ensemble learning.

Cons: The number of attempts feeds straight into cost, so spend grows linearly with the number of calls. On top of that, the logic for integrating multiple candidates (is a simple majority vote enough?) remains a design problem. Even so, I think it is very important from the standpoint of improving robustness against AI's arguably excessive flexibility and against changes such as model updates.

When to use it: It lets you integrate results obtained along several lines of consideration or from different LLM models, so it works for tasks that need breadth of exploration. If what you want is to run separate subtasks in parallel and combine all of them, that is Parallelization in category 3. It can be used across a wide range of tasks: reducing omissions in code vulnerability checks, improving robustness in reading tasks such as OCR, or adding more angles in design tasks. That said, while it makes sense to keep the options fairly wide in the trial phase, cost goes up with the number of parallel runs, so in the operational phase you need to prune the options that are not earning their keep.

2. Reflection & Verification Patterns

How do you detect mistakes and improve on them? This category is about lifting output quality with an inspection loop that runs after generation. How you design the evaluation mechanism is a major factor in how far an AI agent's output can be trusted.

Reflection

The most basic self-correction pattern: the agent evaluates its own output, points out the problems, and then revises. Where Goal-directed Loop judges whether the task is finished, Reflection differs in that the agent looks back on its own to ask whether the result is sound.

Pros: By making the agent switch between the mindset of doing the task and the mindset of assessing it (that is, by clearly separating the two tasks), you can expect better accuracy without any major design change, which makes this a low-cost option. It is the same as with people: asking someone to "look it over once more when you are done" improves the result more than you would expect.

Cons: The extra LLM calls for the review add cost and latency. For a task that almost never goes wrong and where speed matters most, you can simply skip reflection. It is a trade-off, so I think the right approach is to try it, see whether reflection actually helps, and then decide whether to adopt it.

When to use it: Suited to tasks like code generation or writing, where a self-check surfaces clear room for improvement. Conversely, on tasks where even the AI cannot judge what good and bad look like, the revisions may lower quality instead, or the loop may never end. Instructions that spell out what the self-assessment should be based on become important.

Local Reflection

A fine-grained form of reflection: rather than checking the final result of the whole task, the agent checks validity on the spot, right after each individual step or subtask.

Pros: Because the check happens on the spot right after each step, you stop errors before they propagate into later stages. The fine granularity also makes it easy to pinpoint where the problem occurred, which makes improving individual modules and debugging easier. When there are many steps before the final output in particular, building up quality step by step like this is a good approach.

Cons: With a check on every step, the overhead reliably accumulates. Applying the same level of scrutiny to every step can end up lowering overall throughput instead. Finer is not automatically better, so deciding at what granularity to have the agent reflect is an important design question.

When to use it: Suited to tasks where a small mistake midway has a fatal effect downstream, such as multi-stage tool calls or code editing. Conversely, if a few errors can be cleaned up together at the end, the Global Reflection below is more efficient.

Global Reflection

Reflection that works not step by step but after the task is complete, standing back to evaluate and improve the deliverable together with the whole execution process.

Pros: It secures overall coherence and fitness for purpose in one go, the things a fine-grained step-by-step review cannot see. The pattern earns its keep on deliverables whose quality does not rise from stacking up local optima alone. It also does better than Local Reflection on cost and response time.

Cons: Feedback only arrives at the end of the task, so if major rework surfaces there, the cost of redoing it is correspondingly large. With nothing visible along the way, it also has a structural weakness: risks that develop during the run go undetected.

When to use it: Suited to deliverables where consistency of the whole matters more than any part, such as long reports or multi-step plans. In practice, you would try Global Reflection first and then add Local Reflection at the weak spots to make the system more robust.

Generator-Evaluator

One very important trait of LLMs is a tendency to rate their own output highly. This is my own hypothesis, but in the course of tuning models for alignment with users, an LLM that answers with confidence leaves a better impression than one that sounds unsure or always stays neutral, and I suspect the models have been biased in that direction. In other words, because an LLM's self-assessment is generally high, this pattern makes up for that weakness of self-checking by clearly separating two roles: an agent that generates, and an agent that verifies, judging pass or fail against acceptance criteria. It is the same as with people, where the author and the reviewer should as a rule be different.

Pros: Splitting the work across a different LLM model, or a separate agent whose purpose is adversarial review, makes third-party review possible. The verifying side sees only the deliverable, with no knowledge of how it was produced, which removes the lenient judgment that creeps in with "I wrote this myself, so it is probably fine". Anyone who has tried having Codex review what they built with Claude Code will know this well: it points out all sorts of problems from a different angle. Repeating this adversarial third-party review can be expected to raise quality substantially and cut down on gaps and omissions.

Cons: Passing over little context, such as how the work was produced, has a good side but also a bad side. If you ask someone who knows nothing of the background or the process to review a presentation deck, you may well get comments that miss the point. Unless you correctly tell the reviewing agent what perspective to review from and what the purpose is, you can end up with nothing but meaningless review and revision, over and over. Also, without a cap on the number of iterations there is a risk of a revision loop that never produces a pass and goes on indefinitely, so a cap and an escalation path must always be provided as a pair.

When to use it: Suited to tasks where pass/fail criteria can be defined to a reasonable degree, such as code review and security review, and to tasks where you want multiple perspectives, including a third party's, to cut down on gaps and omissions. If reflection is letting too much slip through, carving the Evaluator out as a separate agent can be expected to improve reliability. Incidentally, the Evaluator can also be several agents or models, so that the evaluation comes from multiple angles.

Self-Heal

A loop that executes and tests generated artifacts such as code, and feeds the failure results back to itself to repair them automatically. It is a staple pattern for coding agents, letting them proceed autonomously through test-based verification and repair with no human involvement.

Pros: Because repairs are driven by an objective signal, the tests, the agent can proceed autonomously through test-based verification and repair with no human involvement. For a coding agent, it is a basic mechanism that you could call more or less mandatory.

Cons: When test coverage is weak, it readily converges on a solution that "passes the tests but is fundamentally wrong". If the quality of the tests themselves is lax, the frightening part is that this mechanism appears to guarantee quality while in fact guaranteeing nothing, so the tests themselves need quality assurance too.

When to use it: Suited to coding agents in general, wherever an objective pass/fail signal (test results, build success or failure) is available. If you can put together a test script, it can also be applied to document preparation and other tasks as a way of securing a baseline.

3. Decomposition Patterns

How do you break down a large piece of work? This category is about handling work that does not fit into a single context, or breaking a large task into independent tasks with no dependencies between them. Decomposition can be static, where a person fixes the subtasks at design time, or dynamic, where the LLM looks at the input and decomposes it on the spot. Splitting the problem appropriately can also be expected to improve debugging and traceability through modularization, and to speed things up through better model placement and parallelization. Start with a simple shape, but when that does not work, considering this kind of task decomposition is an important angle. In a sense, this is where the designer's skill is tested most.

Parallelization

The representative form of static decomposition, where a person fixes the split at design time. It is what is usually called a workflow: you cut out only the information each process needs from the input, pass it to multiple agents, have them work in parallel, and combine the results at a single point. It is also sometimes called Fan-out/Fan-in or Scatter-Gather.

Pros: Because the subtasks do not depend on each other, you can expect a speedup from parallel processing. Since each agent receives only the information it needs, each process becomes simpler and accuracy more stable than when everything is packed into one giant prompt. The split is fixed, so behavior is easy to predict and easy to put into operation, which is a big advantage in practice. It can also be used to tune cost and latency, for example by splitting one giant problem into ten small ones and using a lightweight model, rather than solving it with a high-end model.

Cons: The key point is that these must be tasks that can be decomposed independently of each other. If you force a split on tasks that have dependencies, the lack of context can make accuracy worse than having a single agent do the work. Because two processes are added, splitting and combining, you need to take care both that the split is appropriate and that the combined result does not come out disjointed. In particular, for a task that ultimately produces one piece of writing, handing each chapter to a separate agent and combining them at the end can produce a text that has duplication and lacks consistency as a whole. Judging how far to split and where to stop splitting is important.

When to use it: Suited to cases where you run multiple processes with no dependencies on an input, such as researching a company from multiple sources or reviewing content from multiple angles. The gain in response time from parallelization is especially large, so I make a habit of always asking myself "can this be parallelized?". It is simple, but it is a pattern that comes up frequently in practice.

Orchestrator-Workers

A pattern in which a central orchestrator analyzes the input, decides the subtasks dynamically on the spot, delegates them to multiple workers, and integrates the results. Where Parallelization fixes the split at design time, here the difference is that the LLM decides the split itself at run time.

Pros: It has the flexibility to assemble subtasks on the spot, even for work whose structure cannot be read in advance. Its strength is complex, unpredictable tasks that a split fixed in advance cannot handle. The number of Workers is not fixed, so as many as needed can be created on the spot.

Cons: The price of that flexibility is that it becomes very hard to control. Reproducibility drops along with debuggability and traceability, so for business use inside a company it may be difficult from a quality assurance standpoint unless the task has fairly clear rules for splitting, or a reasonably clear scope, such as assigning multiple tickets to Workers that are each created dynamically.

When to use it: Suited to tasks where the required processing cannot be read in advance, as with coding agents: development or refactoring across a codebase spanning multiple files. Being so flexible, it suits tasks where a single failure has little impact, but for tasks that demand a high level of quality assurance, it is better to first consider whether you can turn the subtasks into rules and handle them with Parallelization. Being dynamic and highly flexible is, in the end, a trade-off.

Hierarchical Decomposition

The previous pattern split the work at a single level; this one decomposes subtasks further in a hierarchy, a structure in which managers sit under a manager. By decomposing tasks hierarchically, the design is intended to cope with quite large tasks.

Pros: Because subtasks can be decomposed further in a hierarchy, even very complex and refined deliverables can be built up systematically. Each layer can specialize, so it can handle work on a scale that a single-layer Orchestrator-Workers cannot manage.

Cons: The more layers you add, the more architectural complexity and the number of model calls shoot up, and both latency and cost increase significantly. Add layers carelessly and you can end up with things backwards, where the management overhead outweighs the work itself.

When to use it: Suited to large-scale research that is multi-stage and needs specialization at each stage, such as information gathering, then analysis, then report writing. If a single layer is enough for the scale, simply staying with Orchestrator-Workers will be easier to handle.

Query Decomposition

A technique that breaks one complex question into several simple sub-queries, searches and answers each separately, and then merges the answers; it is widely used in the RAG and search context. Where the three patterns so far decompose the work itself, this one is mainly about search. Parallelization is not the essence here; by breaking apart a query that mixes several intents and handling each part separately, you can expect better accuracy.

Pros: Dividing one complex question into simple sub-queries makes the instructions to the LLM clearer. Query splitting is an effective measure especially when you accept free-form input from users. In particular, if a query that mixes several perspectives is put through vector search as is, it is likely to miss the relevant passages, so this is a technique worth trying first when you want to raise RAG accuracy.

Cons: The more sub-queries there are, the more search cost and latency add up, straightforwardly. Answer accuracy is pulled along by the quality of the decomposition itself, so when the decomposition is poor, accuracy can actually end up lower than if you had searched with the original query. Whether to improve the accuracy of the decomposition into sub-queries or to improve the quality of the input in the first place is a design question.

When to use it: Suited to RAG systems that answer questions involving comparison across several perspectives. Especially where the input is unavoidably complex, working out the sub-queries, that is, the units at which search is needed, becomes important. If the target scope is reasonably narrow, I think it is better to also give explicit rules for how to split into sub-queries (including the cases where no split is made).

4. Coordination Patterns

How to make multiple agents work together: this is the question of topology, meaning who hands what to whom and who holds the final decision. "Just go multi-agent and it will get smarter" is a common misconception. It is easier to choose if you treat this as a design problem of access control and task delegation, such as whether to centralize or to have no center at all.

Supervisor

A pattern where a central Supervisor agent distributes tasks to specialist agents and oversees the results. This is probably the first pattern you would consider when going multi-agent. The specialist agents never talk to each other directly, and final decision-making authority and control of the conversation always stay with the Supervisor.

Pros: Because the specialist agents do not talk to each other directly, behavior is easy to trace, and access control and log design stay simple. Final decision-making authority always sits in one place, so this structure suits business agents where you want accountability to be clear. If you build each agent as a well-made module, it also becomes easier to roll out and reuse in other projects.

Cons: Since every exchange goes through the Supervisor, the Supervisor itself tends to become a bottleneck and a single point of failure. It is also a structure where, the more specialist agents you add, the more directly routing accuracy determines overall quality. And because the Supervisor tends to bloat, the design of the messages exchanged with each agent matters too, so that the Supervisor can be kept to simple decisions.

When to use it: Business agents where the division of roles is clear and you want accountability to be explicit. It fits cases where each agent completes its task in a more or less self-contained way and returns the result, rather than the Supervisor and the agents talking back and forth closely. Conversely, keep in mind that where exchanges between the Supervisor and the agents keep happening at high frequency, the process may never converge.

Handoff

A pattern where one agent passes control of the conversation to a more suitable agent and steps back. Whereas a Supervisor assigns work, collects the results and stays responsible to the end, in Handoff the agent that hands over is no longer involved, and the receiving agent talks to the user directly from then on. It is the same as a call center telling you "I'll put you through to the right person" and you speaking with that person from there.

The basic form is a one-way handover from a triage agent to a specialist agent. A setup where handovers can go from anywhere to anywhere, including between specialist agents, with no manager overseeing the whole, is called a Swarm. The only state is "which agent currently holds the conversation."

Pros: Even for tasks whose steps cannot be fixed in advance, the work can be handed over to the right specialist agent at the point where the need becomes apparent. Each agent only needs to know its own specialty and "who to hand over to," so adding a single agent widens the coverage, and each prompt stays small.

Cons: Control moves one agent at a time, so parallel execution is not possible, and since there is no commander or overall manager, you have to build your own mechanism to stop runaround loops from A to B and from B back to A. Tracing and controlling which agents a request passed through before completion is also far harder than with a Supervisor.

When to use it: Conversational tasks such as customer support, where the first point of contact and the one who finally handles the request are different, and where the topic shifts along the way so the routing cannot be decided up front. If the order of processing is fixed, building it as a workflow or putting a Supervisor in place is overwhelmingly easier to handle. In a world where the scope each AI agent covers keeps growing, this case may well become more common.

Group Chat

A pattern where multiple agents share the same conversation thread and speak in turn after reading what was said before. If Supervisor is the project manager model, assigning work to each agent and collecting the results, this is the meeting model, with everyone debating in the same room. Agents can simply speak in order, or you can have a moderator such as a Chat Manager that watches the conversation and names the next speaker.

Pros: The process of multiple agents building up a discussion in the same thread is preserved as is, so transparency between agents is very high. Another interesting aspect of this form is that ideas that would not come from a single viewpoint emerge naturally from the back-and-forth.

Cons: The more agents there are, the more likely things get out of hand, and in practice the rule of thumb is to keep it to about three. Unless someone directs traffic, it can end up like a meeting that never reaches a conclusion.

When to use it: Situations such as design reviews or proposal reviews, where the rebuttals and revisions between experts are themselves the value. If you only want several opinions separately, Parallelization is enough, and for business processing a Supervisor is easier to handle, so there may not be that many cases where you would choose Group Chat. Where the convergence rule is enforced becomes especially important, and before you know it you may have ended up with something that looks like a Supervisor.

Blackboard

A pattern where agents do not talk to each other, and instead coordinate indirectly by each reading from and writing to a shared working state (the blackboard). Whereas Group Chat shares a conversation and agents speak in turn, what is shared here is structured state such as hypotheses, intermediate results and task lists, and each agent does not wait for a turn: it watches the blackboard and writes when the state is one it can contribute to. It is easier to picture as everyone putting sticky notes on a shared whiteboard rather than as a meeting. What characterizes this pattern is that the blackboard itself converges toward the solution.

Pros: Agents do not need to interact directly, so they are loosely coupled and easy to add or remove. It is an especially good fit for exploratory problem solving where who contributes and when is not decided in advance (cases where you do not want agents to talk directly but do want them to share information loosely).

Cons: When writes to the shared state overlap in time, conflicts and inconsistencies occur easily. And because ordering is not controlled explicitly, it is hard to adopt for tasks with heavy ordering or dependency constraints.

When to use it: Exploratory problem solving where each agent contributes asynchronously and irregularly. If you want strict ordering or clear accountability, a centralized form such as Supervisor is the better fit.

5. Context Management Patterns

How to give the AI the knowledge it needs: this is the question of how to manage the context window, the most important resource an AI has. Rather than packing everything into the prompt, what matters is a design that also takes forgetting into account and pulls in only what is needed, when it is needed.

Skills

A mechanism for loading the procedures and specialist knowledge an agent needs on demand, rather than keeping them in the prompt at all times. Loading in stages makes it context-efficient, and because a skill can be packaged together with template files and scripts, it is also strong on portability and reusability. It is a way to bolt the capabilities an AI needs on from the outside. This staged loading is also called Progressive Disclosure, and it typically has three stages. Only a list of names and one-line descriptions is loaded at all times, the skill body is read at the point the skill is selected, and detailed documents and scripts are read only when the body refers to them. Even with 50 skills, you can have a state where all that sits in context permanently is a 50-line table of contents. The same idea applies to tool definitions, so it also helps when the number of tools balloons through MCP and the like.

Pros: Procedures and specialist knowledge are loaded on demand, so you can cover many domains without bloating the prompt. It is a practical way to widen the range of knowledge and capability a single agent can hold.

Cons: The more skills you have, the more the token cost of the routing itself, deciding which skill to load, goes up. Also, whether a skill gets used is the AI's call, so there is no guarantee that the needed skill is always invoked at the needed moment. For example, if there is post-processing that must always happen, it is better to split it out as a step than to add a skill and instruct it through the prompt.

When to use it: It pays off in general-purpose agents that you want to hand many routine tasks to. Separating knowledge out as skills and growing them also means they can be reused across the organization, which is another advantage. That said, in cases like specialized agents, where the rigor of having the required processing invoked at the required moment matters, it is better to build it in as logic, so you may not reach for skills all that often. As you can see from Cowork-style agents shipping it as a default feature, it is an essential mechanism for general-purpose agents.

Scratchpad

A pattern for long processes where context tends to run short: intermediate results are written out to a working area such as files so they can be referenced later without putting pressure on the context. It is strictly a working note used within a single task, on the assumption that it is thrown away once the task ends. Information you want to keep across sessions is the job of Memory, described later.

Pros: Intermediate results can be written out to the working area, so a long working process can be retained without putting pressure on the context window. A side benefit is that the state and progress of a long-running task can be reviewed afterwards. An execution plan held inside the context window steadily scrolls away, but externalizing it like this and using it as a checklist can be expected to improve both adherence to the plan and reliability.

Cons: Unless you properly design how it is managed, meaning what to keep and what to delete, the scratchpad itself turns into a pile of miscellaneous notes. Defining the rules for writing and reading is important.

When to use it: Long-running tasks with many intermediate steps. In long processes, older information gets pushed out of the context window or becomes subject to compression and summarization, so the strategy of moving important information outside the context window is very important. That said, rather than making one agent large and experimenting more than necessary with externalizing its memory, there are cases where splitting agents by purpose or by step and keeping each agent small makes the whole thing simpler.

Context Triage

A practice of sorting the contents of the context window, that is, the information passed to the current LLM call, into three groups according to relevance to the step: keep as is, keep as a summary, or discard. The targets are conversation history, tool outputs, documents picked up by retrieval, content pulled from memory and so on, and as the word triage suggests, the point is to treat them differently rather than all equally.

In practice there are a few clear triggers: a mechanical per-turn filter that truncates huge results right after a tool output comes back (essential for browser automation in particular), compaction that replaces older history with a summary in bulk once the context reaches 70 to 80 percent of the window, and a cleanup when a subtask completes, deciding whether to keep the intermediate progress or only the conclusion. Once processing grows more complex, this kind of triage thinking becomes essential.

Pros: Selecting information by importance and relevance prevents wasted context and avoids degraded response quality. It is not unusual for performance to improve visibly just by switching from a mindset of adding information to one of subtracting it. When you start to feel that the LLM's behavior or responses are somewhat missing the mark, it helps to consider triage first and keep the context compact.

Cons: If the selection criteria are wrong, there is a danger of dropping genuinely necessary information along with the rest. If the logic for deciding what to keep is itself sloppy, you may think you are trimming while actually lowering accuracy. There is of course no need to pass in unnecessary information, but in the early phase the performance loss from too little context tends to be the larger one, so an efficient strategy is to pass generous context at first and watch performance as you trim the unnecessary parts.

When to use it: For agents that run for a long time and tasks that handle large volumes of tool output, considering triage is a must. On the other hand, by keeping each agent's size and task scope small, there are also cases where you do not need to be that particular about it. Take care not to triage on a vague impression and end up dropping important information. Information that is clearly not needed by later steps (especially the responses that come with tool calls) is nothing but noise to the LLM, so it is fine to drop it aggressively.

Memory

A pattern for carrying information over not only within a single task but across sessions. The context window disappears once a conversation ends, and a Scratchpad has also done its job once its task is over. In other words, if you do nothing, the agent starts from a freshly initialized state every time. So you design short-term memory (Working Memory), which is complete within one conversation, separately from long-term memory (Long-term Memory), which is kept across sessions. Short-term memory is in substance the context window itself, and long-term memory is an external store. If you turn everything into long-term memory the context bloats quickly, so it is also important to design a step that judges whether something is a fact worth using later before promoting it to long-term memory, and to periodically delete information that is no longer needed from long-term memory.

Pros: Context is maintained across sessions, so the agent can learn from the successes and failures of previous task runs. Being able to build up an ongoing relationship per user or per project is a major value that one-off task execution does not have. This long-term memory can also be shared with other agents as knowledge.

Cons: The logic for deciding what to promote to long-term memory carries its own maintenance cost, and there is always the risk that outdated memories keep being used as wrong assumptions. A mechanism that stores things in long-term memory and reuses them looks effective intuitively, but if the agent misjudges a special case as important and commits it to long-term memory, that wrong assumption keeps being used in later sessions and can degrade performance continuously. As a rule it is better to have writes to long-term memory go through a person's approval, and if you let the AI update long-term memory directly, some kind of evaluation mechanism needs to come with it. How intuitive a mechanism is and how easy it is to use in practice are not necessarily the same thing.

When to use it: It shows its strength in building up knowledge for agents that interact repeatedly with the same user or the same project. Introduce it halfway and you get more things to manage, and since it affects how the agent behaves, control gets more complicated too. It may be best to start with a use such as referring to past cases.

6. Autonomy & Control Patterns

How to control autonomous execution: this category is about drawing the line on how freely an agent is allowed to act. If you get carried away by the phrase "acts autonomously" and hand everything over, you can end up in an infinite loop where the processing never finishes. More autonomy is not simply better. Whenever you consider making something autonomous, you also have to design a suitable harness around it: set limits, define what done means, have it check with or delegate to a human, and so on.

Step & Token Budget

A control mechanism that puts a limit, in advance, on the number of tool calls and reasoning loops an agent can run and on the number of tokens it can use. It exists to keep you from discovering that your LLM bill has quietly grown to an enormous amount, and it is the very first thing to consider when you start building an AI agent. Accidents are especially common when the developers are still inexperienced, so this is arguably the point a development team's manager should watch most closely. It is a design that lowers the impact of the worst case that comes with the trade-off for autonomy.

Pros: Simply setting limits on the number of runs and the number of tokens in advance reliably prevents infinite loops and runaway costs. The mechanism is simple, but it is an essential safety valve for any highly autonomous agent. I also measure execution time. For example, if the AI running for more than 10 minutes in a given use case would mean some kind of error has occurred, I set the execution time limit to 10 minutes and force it to terminate the moment it goes over.

Cons: Set the limit too low and a legitimate task gets forcibly terminated before it is finished. The right limit itself varies from task to task, so you need to set it with a little headroom above the real target and review it periodically.

When to use it: Highly autonomous agents in general, and it is a mandatory companion to loop-based patterns such as ReAct and Goal-directed Loop in particular. It is unnecessary for routine processing where the number of steps is fixed from the start, or where there is no loop mechanism at all.

Termination Condition

An explicit criterion for ending the agent's loop. Where Step & Token Budget is the abnormal-path cutoff that says "you are not allowed to loop any further", this one defines the normal-path exit: "stop because the goal has been reached". There are basically only these two ways for a loop to end, so whenever you put a loop in place you need to provide the normal path and the abnormal path as a pair.

Pros: Stating and checking the termination condition properly avoids situations where the agent keeps repeating unnecessary extra tasks even though it has already achieved its goal. Explicitly defining "when should this end" also raises the quality of the design in its own right.

Cons: If the condition is defined vaguely, there is a risk the agent considers itself finished while the result is actually incomplete. Make the condition too strict, on the other hand, and you can get the opposite problem: it never finishes.

When to use it: It is essential for dynamic planning agents in general, where you cannot fix the number of steps. Having the LLM make the call inevitably introduces ambiguity, so if the termination check can be mechanized in code, that is preferable. Splitting off a sub-agent dedicated to the termination check and having it evaluate objectively is another option.

Human-in-the-loop

A pattern that builds human judgment into the workflow somewhere: execution pauses at that point, waits for the person's response, and then resumes. It is, in itself, the idea of drawing a line between how much you leave to the AI and where a human takes over. Because a pause and a resume are involved, you also need separate infrastructure to support the exchange: a notification mechanism, preservation of state while waiting, and a UI that presents information to the person and lets them act on it.

There are broadly two ways of bringing a human in. One is the Approval Gate, where the designer decides in advance that the agent always stops before a given action. The other is Escalation, where the agent itself hands over at the point it judges that something is beyond what it can handle.

Approval Gate

The most basic form of Human-in-the-loop: a gate that makes approval mandatory immediately before executing an operation that matters in terms of permissions or impact, such as transferring money, deleting data, or deploying to production. Anyone who has used a general-purpose AI agent, or Claude Code or Codex, will know this well: the decision of whether to ask for approval before certain operations is basically built in.

So which operations do you put a gate on? The basic approach is to decide with a fixed list, but you can also assess the risk of each action from its blast radius and reversibility and route dynamically, executing automatically when the risk is low and sending to approval when it is high. This is also called Risk-based Routing. Note, though, that safety then depends on the accuracy of the risk assessment, so a high-risk operation misjudged as low-risk may simply be executed.

Pros: Asking for confirmation every time is tedious, and letting the agent handle everything on its own is dangerous, but because you can always insert a human decision before specific operations, you can make running an AI agent safer. Placing guardrails at the right moments prevents accidents such as every record in a database being deleted, or an email being sent outside the company, without anyone noticing. The approval log can also serve directly as an audit trail, which makes this a very important consideration in practice.

Cons: Build in too many approvals and waiting for a human becomes the bottleneck, which dilutes the very benefit of autonomy. When the number of approvals grows too large, checking turns into habit and approval tends to become a formality. It is important to keep approvals to the necessary minimum and to design for lower frequency, for example by pushing them as far as possible toward the beginning and the end.

When to use it: Reserve it for actions where recovering from a mistake is expensive, such as money movements, production environments, and customer-facing communication. Applying it even to low-risk, read-only operations means undermining the agent's autonomy yourself, so that is best avoided.

Escalation

A pattern where the agent hands the work itself over to a human when it judges that it has reached the limit of its own capability or authority. An Approval Gate is only a check on whether a specific operation may be executed; here, a human takes over the work itself.

Pros: Unexpected cases the agent cannot handle itself, and cases that AI must not handle for reasons of responsibility or authority, can be handed over to a human safely. Being able to build "knowing when to step back" into the system, so the AI does not decide on its own and press ahead, is very important in practice.

Cons: If the escalation criteria are vague, the agent swings to one extreme or the other: handing far too much over to humans, or handling things itself even when it should have handed over. It is no exaggeration to say the precision of the criteria directly determines the reliability of the whole system. Whether you lean toward the safe side or the permissive side is case by case, depending on the use case.

When to use it: It works as the final destination of a Handoff, or as the catch-all for incident response that goes beyond the scope of automation. A design where the AI agent takes first-line handling but hands over to a human once the exchange exceeds a certain number of turns, or when a case arrives that the AI was not designed for, is one you can operate without strain. Even while aiming for 100% automation as far as possible, designing operations on this premise widens the range of work the agent can be applied to, so the overall automation rate may well end up higher.

7. Safety & Security Patterns

Ensuring safe input, output, and execution: this category is about inspecting the inputs and outputs an agent deals with and the tool calls it makes. These are the guardrail patterns that should be placed at various points in an AI agent's processing.

Input Guardrail

A guardrail that inspects and filters input-stage risks such as prompt injection, placed just before the input reaches the agent. It is essential in cases where you take input from a user and call an LLM based on its content.

Pros: Attacks such as prompt injection can be blocked early, at the entrance, before they reach the agent. In externally exposed systems that accept chat input from users, this is the point that deserves the most attention. You basically never pass a user's query to the LLM as is; you put appropriate routing and filtering in place first and then let it flow on to the agent. Rather than a benefit, it is better described as a design requirement.

Cons: False positives (rejecting legitimate input) and missed detections are always in a trade-off, and keeping the balance takes continuous tuning. Too strict and you hurt the user experience; too loose and the guardrail has no reason to exist. Another countermeasure is to reduce the freedom on the input side in the first place, for example by disallowing free-text input and offering choices instead.

When to use it: It is needed at the entrance of every agent system that involves user input. If the system sits in a closed internal environment and only receives trusted input, you can relax the rigor a little, but when you expose it outside the company this is the point to design with the most care.

Output Guardrail

A guardrail that inspects the final output for leaks of confidential information and for harmful content before it is returned to the user. It can also be used to keep output of a quality that should not be shown to users, such as garbled text or a broken layout, from going out.

Pros: Right before anything reaches the user, you get one last inspection for leaked confidential information and harmful content. Even if something slips past the measures at the entrance or along the way, a well-designed final gate gives you the reassurance that it will be stopped before it is shown to the user. There is a further advantage: if you prioritize this output guardrail before experimenting with all sorts of intermediate steps in development and prototyping, you avoid spreading unnecessary concern and risk among stakeholders.

Cons: As with the input side, make it too strict and output that is actually fine gets excluded as well. Being kept waiting for a while and then receiving no final output is about the most negative experience a user can have, so the best state is one where the output guardrail exists but nothing gets caught by it in the first place. When something does get caught, you need to go back over the input and the intermediate steps and resolve the root cause.

When to use it: It is essential for any service that returns LLM output to users. Where use is internal only and the output destination is limited, or where people want to see the output even at the cost of some mistakes, you tune it a little looser. You can also consider a design that returns only fixed choices instead of free-form LLM output, which removes the need for an output guardrail altogether.

Tool Guardrail

This guardrail matters most when calling external tools (APIs, MCP servers, and so on) that are hard to control from your side. It is unnecessary for things like your own functions, particularly ones with no LLM call inside. But with external tools and third-party MCP servers, where the callee may invoke yet another LLM or run complex processing, you cannot control the internal processing or the output. So, just as with user input, you need to put an inspection step in place instead of using the response content as is.

Pros: It also stops unexpected responses and contaminated tool responses from propagating into downstream processing. And by placing a guardrail before the tool call, you can use it to keep things like personal information from being passed to an external tool.

Cons: Designing the checks requires domain knowledge of each tool, and generic rules alone will not give enough coverage. Every tool you add brings a guardrail that has to be maintained individually, so the operational cost gets heavy. If you adopt a highly general-purpose external tool, you also need to watch for behavior changing with a sudden version upgrade.

When to use it: It becomes important when you use external tools whose processing is complex and highly general-purpose. For a tool whose response format is fixed to begin with and which is not very flexible, there is no need to be that strict.

Pre-action Validation

A step that mechanically checks whether the plan and its parameters comply with constraints and business rules immediately before an action, especially an irreversible one, is actually executed. Basically this should be Human-in-the-loop, but where it is hard for a human to check every case and you want the AI to go all the way through execution, providing a separate validation step like this, apart from the LLM's own judgment, lets you prevent unexpected actions before they happen.

Pros: Checking mechanically just before an irreversible action is executed prevents the worst case of noticing the mistake only after the fact. As a design that involves no human, it is a practical mechanism for not getting in the way of automation.

Cons: Building and maintaining a comprehensive set of rules to check has a cost, and once the rules go stale, things naturally start slipping through. As long as it is rule-based, the limitation remains that it cannot handle cases nobody anticipated. In practice you will need a design that combines the validation step with Human-in-the-loop and routes anything doubtful to a human.

When to use it: It suits work that does not warrant constant human review but has clear constraints, where an automated check can catch many of the mistakes. For work whose criteria are hard to turn into rules, and for critical cases where mistakes are not acceptable, it is better to simply go with Human-in-the-loop.

Closing Thoughts

That is the full set of patterns.

Designing AI agents is something of a composite craft with no single right answer. This article introduced design patterns with the AI agent at the center, but in practice the overall design matters, including the surrounding systems, business processes, and input and output data.

And precisely because there is no single right answer, what matters in actual design work is whether you have a well-stocked drawer of options for responding to the situation (including, for example, the cases where it is better not to use AI at all).

Personally, I think an architect's skill shows in how far complexity can be reduced and how simple the design can be made. With a multi-agent AI agent, launching and getting it running for now is an entirely different matter from being able to operate it stably and continuously (that is, to keep producing value).

References