Building an AI agent that works in a demo takes an afternoon. Building AI agents that work in production, every day, on inputs nobody anticipated, within a budget someone signs off on, is a different engineering problem. This guide covers the decisions that separate the two: whether you need an agent at all, tool design, orchestration, state, guardrails, evaluation and cost.
Agent or workflow? Decide before you write code
The most useful distinction in this field comes from Anthropic's Building effective agents. Workflows are "systems where LLMs and tools are orchestrated through predefined code paths." Agents are "systems where LLMs dynamically direct their own processes and tool usage, maintaining control over how they accomplish tasks."
The difference is who owns the control flow. In a workflow, your code decides the sequence of steps. In an agent, the model decides what to do next, which tool to call, and when it is finished. That autonomy makes agents useful for open-ended problems, and expensive and hard to test. The same guide puts it plainly: "The autonomous nature of agents means higher costs, and the potential for compounding errors." Its advice is to find the simplest solution possible, adding complexity only when needed, which "might mean not building agentic systems at all."
A practical test: if you can draw the complete decision flowchart, and no branch depends on interpreting natural language, you do not need an agent. Routing support tickets by product is a workflow with one classification call. Reading a complaint, checking three internal systems and deciding whether a refund policy applies is a candidate for an agent.
| Question | Workflow | Agent |
|---|---|---|
| Can you enumerate the steps in advance? | Yes | No, they depend on what the model finds |
| How predictable is cost per run? | Tight | Wide, with a long tail |
| How do you test it? | Unit tests per step | Scenario evals over many runs |
| What fails? | A known step | Any step, in combinations you did not foresee |
Most production systems are a mix: deterministic code for what you understand, a bounded agent loop for what you cannot specify in advance. Drawing that line and building each side properly is the core of AI Agents: Architecting and Automating Autonomous Systems.
The minimal production agent loop
Under every framework, an agent is a loop: send the conversation and the tool definitions to the model, execute any tool calls it returns, append the results, and repeat until the model answers without calling a tool. Anthropic recommends starting with the model APIs directly, because frameworks "often create extra layers of abstraction that can obscure the underlying prompts and responses, making them harder to debug."
The production version of that loop differs from the tutorial version in four places: a hard budget, a tool allowlist, an approval gate for irreversible actions, and a circuit breaker on repeated errors. Here is a provider-neutral sketch in Python; call_model wraps whichever model API you use.
from dataclasses import dataclass
@dataclass
class Budget:
max_steps: int = 20
max_tokens: int = 200_000
max_consecutive_errors: int = 3
steps: int = 0
tokens: int = 0
errors: int = 0
class BudgetExceeded(Exception):
pass
def run_agent(goal, call_model, tools, budget, approve):
messages = [{"role": "user", "content": goal}]
while True:
budget.steps += 1
if budget.steps > budget.max_steps or budget.tokens > budget.max_tokens:
raise BudgetExceeded(f"stopped at step {budget.steps}, {budget.tokens} tokens")
reply = call_model(messages, [t.schema for t in tools.values()])
budget.tokens += reply.usage_tokens
messages.append(reply.as_message())
if not reply.tool_calls:
return reply.text # the model decided the task is done
for call in reply.tool_calls:
tool = tools.get(call.name)
if tool is None: # allowlist: the model asked for something it was not given
result = {"error": f"Unknown tool {call.name}. Available: {sorted(tools)}"}
elif tool.risk == "irreversible" and not approve(call):
result = {"error": "A human rejected this action. Propose an alternative or stop."}
else:
try:
result = tool.run(**call.args)
budget.errors = 0
except Exception as exc:
budget.errors += 1
if budget.errors >= budget.max_consecutive_errors:
raise # circuit breaker: hand the run to a human
result = {"error": f"{type(exc).__name__}: {exc}"}
messages.append({"role": "tool", "tool_call_id": call.id, "content": result})
Errors and rejected approvals go back to the model as tool results, so it can correct itself or propose an alternative instead of crashing the run. And the stop conditions live in your code, not in the prompt: a model asked politely to "stop after ten steps" is not a budget.
Tools are the agent's real interface
An agent is only as good as the tools it can call. Anthropic's engineering guidance on writing tools for agents warns against tools that "merely wrap existing software functionality or API endpoints": exposing your whole REST API gives the model too many choices and too much raw data.
Design rules that hold up:
- Consolidate around tasks, not endpoints. Anthropic's example: implement a
search_contactsormessage_contacttool instead of alist_contactstool that forces the agent to read every record. - Namespace related tools (
crm_search_contacts,billing_get_invoice) so the model can tell similar tools apart when you have dozens. - Return high-signal fields. Names, statuses and short summaries beat internal IDs and full JSON dumps. Paginate and truncate by default.
- Write errors as instructions. "Date must be ISO 8601, for example 2026-10-31" lets the model fix its own call; a stack trace does not.
- Make writes idempotent. Agents retry. A refund tool that accepts an idempotency key cannot pay twice when the model repeats a call after a timeout.
- Validate arguments in code. The schema tells the model what to send; your handler must still reject what it should not accept.
Tool definitions are also input tokens, sent on every step of every run, so twenty verbose tools are a recurring cost. If tools must be shared across several agents or applications, package them as Model Context Protocol (MCP) servers; the design rules above apply unchanged.
Orchestration patterns, from simplest to most autonomous
The same Anthropic guide names five workflow patterns that cover most production needs before you reach a fully autonomous agent:
- Prompt chaining. Each call processes the previous step's output, with programmatic checks in between: extract, validate, then draft.
- Routing. Classify the input, then send it to a specialized prompt, tool set or cheaper model.
- Parallelization. Run calls at the same time and aggregate in code, by sectioning a task into independent parts or voting on the same task several times.
- Orchestrator-workers. A central model breaks the task down, delegates pieces to workers and combines the results; useful when the subtasks are not predictable.
- Evaluator-optimizer. One model generates, another evaluates against explicit criteria and sends feedback, for a fixed maximum number of rounds.
Multi-agent systems sit at the top of this ladder, and the evidence on them is specific. In How we built our multi-agent research system, Anthropic reports that a lead agent with parallel subagents "outperformed single-agent Claude Opus 4 by 90.2% on our internal research eval", and also that agents "typically use about 4× more tokens than chat interactions" while "multi-agent systems use about 15× more tokens than chats." The same post names the poor fits: domains "that require all agents to share the same context", and coding, where "most coding tasks involve fewer truly parallelizable tasks than research."
The rule of thumb: use multiple agents when the work splits into independent branches that each need their own context, such as broad research. Otherwise, one well-tooled agent is cheaper and easier to debug.
Memory and state: what the agent knows, and where it lives
A model call is stateless. Everything the agent "remembers" is either in the context window for this step or in a store your code reads from. Treating a large context window as a place to keep everything is a common production mistake: Anthropic's post on context engineering describes context rot, where "the model's ability to accurately recall information from that context decreases" as the context grows.
Four techniques keep long-running agents coherent:
- Tool result clearing. Drop old tool outputs once they have been used; Anthropic calls it "one of the safest lightest touch forms of compaction."
- Compaction. When the context nears its limit, summarize it and continue in a fresh window with the summary.
- Structured notes. The agent writes progress and open questions to a store outside the context and reloads them when needed.
- Just-in-time retrieval. Keep lightweight references (file paths, record IDs) in context and fetch content with a tool only when a step needs it; for large document collections, this is where a retrieval layer plugs in.
Separate memory from state. Memory is what the model sees. State is the durable record of the run: completed steps, tool results, pending approvals. It belongs in your database, checkpointed after every step, so a crash or deploy does not restart a half-finished task. Anthropic notes that "agents are stateful and errors compound" and built its systems to "resume from where the agent was when the errors occurred." LangGraph exposes the same idea: interrupt() pauses a run for human input and requires a checkpointer, and the run resumes on the same thread ID.
Deciding what enters the context at each step and what lives in long-term memory is a discipline of its own, covered in Context Engineering and Memory for AI Agents: Beyond Prompting.
Guardrails: limit what the agent can do, not only what it says
Output filters do not stop an agent from deleting the wrong record. The OWASP GenAI Security Project lists this risk as LLM06:2025 Excessive Agency (LLM03 in the 2026 edition of the list, released in August 2026): damaging actions performed in response to "unexpected, ambiguous or manipulated outputs from an LLM." It names three root causes, excessive functionality, excessive permissions and excessive autonomy, and the mitigations map directly onto agent design:
- Minimize tools and what each can do. An agent that summarizes tickets does not need a tool that closes them. Avoid open-ended tools such as "run any shell command".
- Minimize permissions. Scope each tool's credentials to what it needs, and act in the context of the user the agent serves, not a shared admin account.
- Require human approval for high-impact actions. Classify tools by risk: reads run directly, reversible writes are logged, irreversible actions (payments, deletions, external emails) wait for a person.
- Enforce authorization outside the model. OWASP calls this complete mediation: downstream systems validate every request against security policy instead of relying on the model to decide.
The threat that makes these controls non-negotiable is indirect prompt injection, which OWASP's LLM01:2025 entry describes as what happens when "an LLM accepts input from external sources, such as websites or files." An agent that reads web pages, emails or uploads will eventually read planted instructions. You cannot prompt your way out of that; you limit the blast radius. Anthropic's guide recommends "extensive testing in sandboxed environments, along with the appropriate guardrails" before an agent touches real systems.
Evaluation: measure reliability, not one lucky run
An agent that solves a task once has proved very little. The τ-bench paper (Yao et al., 2024) introduced pass^k, defined as "the chance that all k i.i.d. task trials are successful, averaged across tasks", precisely because single-run accuracy hides inconsistency. In that paper, state-of-the-art function-calling agents of mid-2024 succeeded on fewer than half of the tasks, and in the retail domain pass^8 fell below 25%.
A practical setup:
- Start small and real. Anthropic's research team started "with a set of about 20 queries representing real usage patterns." Real cases from your logs beat unread synthetic ones.
- Grade the end state. For agents that change data, check the final state (was the refund issued once, for the right amount?) rather than whether every step matched a script.
- Run each case several times and track the pass rate across runs, not the best result.
- Use LLM-as-judge for what code cannot check, such as tone or completeness, with a written rubric and human spot checks.
- Gate releases on the suite. Any change to a prompt, a tool description or the model version runs the evals in CI.
Writing a precise system prompt and tool descriptions is the first lever when evals fail; the fundamentals are in Prompt Engineering in 2026: From Beginner to Pro.
Observability and deployment
You cannot debug an agent from its final answer. Trace every step: prompt, response, each tool call with arguments and result, tokens and latency. OpenTelemetry's semantic conventions for generative AI now define agent spans (invoke_agent, execute_tool) and attributes such as gen_ai.usage.input_tokens, so traces can flow into the observability stack you already run. Those conventions are still marked Development, so pin the version you emit and expect changes.
Deployment has one extra constraint: runs can last minutes, and a deploy must not cut them off. Anthropic uses rainbow deployments "to avoid disrupting running agents", shifting traffic gradually while old and new versions run side by side. For behavior changes, run the new version in shadow mode on real traffic, compare its decisions, then roll out gradually with a rollback path.
Cost: budget the task, not the call
Agent cost is driven by the number of steps and the size of the context at each step, which grows with every tool result. Anthropic's research post found that on the BrowseComp benchmark, "token usage by itself explains 80% of the variance" in performance. More tokens often buy better answers, so cost has to be a design decision.
The levers:
- Route by difficulty. Send classification, extraction and simple subtasks to a small model; reserve the most capable one for planning and hard reasoning.
- Cache the stable prefix. System prompt and tool definitions repeat on every step. On the Claude API pricing page, a cache hit on Claude Opus 5.5 or Claude Sonnet 5.5 is billed at 0.05x the base input price, so a long, stable prefix becomes cheap after the first call.
- Batch what is not interactive. Overnight enrichment or document processing can go through a batch API, which the same pricing page lists at a 50 percent discount on input and output tokens.
- Trim the context. Tool result clearing and compaction cut the tokens you pay for on every later step.
- Set budgets per task, enforced in the loop, and alert when runs hit them; a spike in budget stops often signals a regression.
Routing, caching, fallbacks and the rest of the plumbing that keeps model calls fast and affordable at scale are covered in Advanced LLM Integration in Production Applications.
A production readiness checklist
Before an agent touches real users or data, each of these should be true:
- A simpler workflow was considered and rejected for a stated reason.
- Every tool is task-shaped, documented, validated in code and idempotent where it writes.
- Tools are classified by risk, and irreversible actions require human approval.
- Credentials are scoped per tool and per user; authorization is enforced outside the model.
- The loop enforces step, token and error budgets in code.
- Run state is checkpointed and a failed run can resume or be handed over.
- An eval suite built from real cases runs in CI, with multiple trials per case.
- Every step is traced, with tokens and latency, and cost per task is alerted on.
- Deploys do not interrupt running tasks, and there is a tested rollback.
None of this is tied to one vendor or framework: these habits carry over every time the models change, and they are much of what defines the role described in What Is an AI Engineer?.
Frequently Asked Questions (FAQ)
What is the difference between an AI agent and a workflow? In a workflow, your code defines the sequence of steps. In an agent, the model decides which tool to call next and when the task is complete. Workflows are cheaper and easier to test; agents handle tasks whose steps you cannot predict in advance.
Do I need a framework to build an AI agent? No. An agent is a loop around a model API with tool definitions, and a few dozen lines of code are enough to start. Frameworks help with checkpointing, human approval and tracing, but you should understand the underlying prompts and tool calls well enough to debug them without one.
When should I use multiple agents instead of one? When the work splits into independent branches that each benefit from their own context, such as broad research. Multi-agent systems use substantially more tokens and fit poorly when all agents need the same shared context.
How do I stop an AI agent from taking harmful actions? Limit what it can do, not only what it says: few narrow tools, credentials scoped per tool and per user, human approval for irreversible actions, and authorization enforced in the systems it calls. Treat every external document it reads as potentially carrying injected instructions.
How do I test an AI agent before production? Build a set of real cases from your logs, grade the final state rather than each intermediate step, run every case several times to measure consistency, and run the suite in CI on every change to prompts, tools or model versions.
Conclusion
Production agents are mostly ordinary software engineering applied to an unusual component. Ask first whether a workflow would do. If you need an agent, keep the loop simple and put the hard limits in code: budgets, an allowlist, approvals and a circuit breaker. Design tools around tasks, keep state outside the model, scope permissions as if every input were hostile, and measure reliability over repeated runs. With tracing and per-task cost tracking from day one, you ship an agent you can explain, debug and afford.
The course that continues this article
AI Agents: Architecting and Automating Autonomous Systems
You have read the theory. In the course you put it into practice: written lessons structured in modules, with examples and exercises, quizzes, the AI Professor in every lesson and progress saved automatically. Once you complete the lessons and reach the minimum quiz score, you get the Certificate of Completion, a private attestation.
From the course syllabus
- Fundamentals of Autonomous AI Agents
- Memory, State and Advanced Reasoning
- Frameworks and SDKs for AI Agents
- Model Context Protocol (MCP) and Interoperability
+ 7 more modules in the full syllabus
€99 per month for this course, VAT included · or pick it in a subscription of 3, 5 or 10 courses, from €199 per month, together with other IT courses; you can change them at every renewal (see what you learn across the whole track).
Monthly subscription with automatic renewal · stop the renewal anytime from your account · digital content with immediate access, see the withdrawal conditions. The certificate confirms that you completed the course and is private: it is not a diploma or a state-recognised qualification.