Three shapes of LLM system
Most confusion about agents comes from using one word for three different things. It helps to name them.
A pipeline is a fixed sequence of steps, some of which call a model. Extract the invoice fields, validate them, post to the ledger. The code decides the order; the model fills in a step. This is how most document processing works, and it is the right shape for anything repetitive and well understood.
A workflow with LLM decisions adds branching. The model classifies a ticket, and the code routes it. The model still does not choose what happens next beyond a menu you defined.
An agent inverts control. You give the model a goal and a set of tools, and it decides which tools to call, in what order, how many times, until it judges the goal met. The code's job becomes enforcing limits rather than dictating steps.
The further right you go on that spectrum, the more the system can handle situations you did not anticipate, and the less you can predict what it will do. That trade is the whole subject of this guide.
The loop
Every agent, whatever the framework, is this loop. The model is given the goal, the conversation so far and the list of tools. It produces either a final answer or a request to call a tool. The code executes the tool, appends the result and calls the model again. It stops when the model answers, when a step or spend budget is exhausted, or when a check fails.
The quality of an agent is decided far more by what surrounds the loop than by the model inside it: the tools, the stopping rules, the permissions and the trace.
Tool design decides everything
A tool is a function the model can call, described in words. The description is the model's only documentation, so write it for a capable new colleague: what it does, when to use it, what it returns and what it must not be used for.
- Narrow beats general.
get_order_status(order_id)is called correctly;query_database(sql)is called creatively. - Return only what the next step needs. Large results flood the context window and bury the useful part.
- Make errors recoverable. "No order with that id; the customer may have used a reference number" lets the model try again sensibly.
- Separate reads from writes. Reads can be free; writes need permission, confirmation or both.
- Standardise the plumbing. If more than one assistant needs the same tools, serve them through MCP, as described in MCP explained.
A useful test: could a careful human do the task with only these tools and these descriptions? If not, the agent cannot either. More on this in tool use.
Stopping conditions and budgets
The model should never be the only thing deciding when to stop. Set three limits in code: a maximum number of steps per run, a maximum token or spend budget per run, and a daily cap per user or tenant. Add a wall-clock timeout. When any limit trips, the agent returns what it has, with a clear statement that it stopped early, and the run is flagged for review.
Also define what "done" means before you start. "Reply to the customer" is not a stopping condition; "a draft reply exists, cites the relevant policy and has been queued for approval" is. Vague goals are the single biggest cause of agents that wander.
Where the human sits
Autonomy is a dial, not a switch. The patterns below are listed in order of increasing independence; most production agents live in the middle.
| Pattern | Who acts | Use when |
|---|---|---|
| Suggest | Agent drafts, human does everything | Consequential or customer-facing output; early in a rollout |
| Approve | Agent acts after a human approves each write | Writes to systems of record, payments, external communication |
| Notify | Agent acts, human is informed and can reverse | Reversible actions with a clear audit trail |
| Autonomous within bounds | Agent acts; only exceptions reach a human | Low-risk, high-volume, well-measured tasks |
Move one step along the dial only when the evaluation numbers say the previous step is reliable. This is the approach behind our customer support AI and sales copilot solutions, which both start at "suggest".
When an agent beats a pipeline
Agents are worth their unpredictability when the path to the goal genuinely varies case by case and the tools to discover it exist. They are not worth it when the path is known.
| Situation | Pipeline | Agent |
|---|---|---|
| Same steps every time (invoice extraction, nightly report) | Yes | Overkill and less predictable |
| Steps depend on what is found (investigate a failed payment) | Branches explode | Yes |
| Needs to combine several systems ad hoc (prepare for a client meeting) | Rigid | Yes, with read-only tools |
| High-stakes, irreversible action (send payment) | Yes, with model-assisted steps | Only with approval pattern |
| Strict latency or cost per request | Yes | Loops are slow and variable |
A useful compromise is a pipeline whose steps are small agents: a fixed outer structure, bounded autonomy inside each step. It gives you predictability where you need it and flexibility where it pays.
Failure modes to design out
Runaway loops. The model keeps calling the same tool with slightly different inputs. Fix: step budgets and a check for repeated calls.
Cost blow-ups. Each step carries the whole history; long runs get expensive fast. Fix: spend budgets, summarising context, smaller models for routine steps.
Wrong tool, confidently. Overlapping or vaguely described tools. Fix: fewer, narrower tools with precise descriptions.
Instructions in the data. A fetched web page or email tells the agent to do something else. This is prompt injection; fix with treating tool results as data, least privilege and approvals.
Silent partial success. Three of five updates applied, then a limit hit, and nobody told. Fix: transactional patterns or explicit reporting of what was and was not done.
Every one of these should be a test case. Our AI red teaming service builds adversarial suites for exactly these behaviours.
Evaluating an agent
You cannot evaluate an agent by reading a few transcripts. Build a set of tasks with known good outcomes, run the agent against them repeatedly, and measure task success, steps taken, cost per run and the rate of unsafe actions attempted. Record the full trace of every run in production and sample them for review. Treat a drop in task success or a rise in steps as a regression, exactly as you would a failing unit test. The method is laid out in evaluating LLM outputs; the guardrails entry covers the runtime side.
A sensible first agent
Pick an internal, read-mostly task that people find tedious and that touches two or three systems: preparing a customer summary before a call, triaging an inbox, investigating a failed job. Give it three or four narrow tools, a step budget of a dozen, and the "suggest" pattern. Run it on a hundred real cases, review the traces, fix the tools. Only then consider a write tool with approval. This is the path our AI agents and automation engagements follow, and it rarely takes more than a few weeks to reach something people use daily.
Key takeaways
- Pipeline, workflow and agent are different shapes; choose by how much the path varies.
- The loop is simple; tools, stopping rules, permissions and traces decide the outcome.
- Write narrow tools with descriptions a new colleague could follow.
- Enforce step, spend and time budgets in code, never in the prompt.
- Start at "suggest" and move along the autonomy dial only when the numbers justify it.
- Treat tool results as untrusted; a web page can instruct your agent.
- Evaluate on repeated task runs and keep every trace.
Related services
AI agents & automation
Agents that do real work inside bounds you set, built in weeks and measured from the first run.
ExploreMCP server development
Standard, permission-aware tools over your systems that any agent or assistant can use.
ExploreAI red teaming
Adversarial testing of tool-using systems before an attacker, or a stray email, does it for you.
Explore