On this page
- What an AI agent actually is
- Who it is for, and who it is not for
- What we actually build
- How it works technically
- The Reversibility Ladder, and why it decides everything
- The build process, stage by stage
- What you get at handover
- Where these projects go wrong
- What it costs to run once live
- How to tell whether you need one
- How to start
What an AI agent actually is
An AI agent is a program that receives a goal, decides its own sequence of steps, calls tools to carry them out, inspects what came back, and stops when the goal is met or a preset limit is reached. The model supplies the decisions. Everything around it, the tools, the limits, the verification pass and the escalation route, is ordinary software somebody has to write and maintain.
The only structural difference between an agent and an automation is where the control flow lives. In a workflow you fix the order while building. In an agent the order is chosen during the run, by a model reading the state in front of it. That is what makes agents useful for varied work, and harder to test, price and explain.
- RuntimeAn agent picks its control flow while running. A workflow has its control flow written down beforehand.
- One jobEvery agent gets a one sentence job statement that fits both the prompt and the evaluation set.
- 5 rungsTools are classified by what undoing them costs, and the control at each rung differs.
- Agent
- A program given a goal rather than a procedure. It chooses which tools to call and in what order, and decides when it has finished, inside limits set by the developer.
- Agent loop
- Read the state, choose one action, execute it, observe the result, decide whether to continue. Every agent is this cycle plus the rules that stop it.
- Tool
- A function the agent may call, described with a name, typed arguments and what it returns. If the description omits when to call it, the model will call it at the wrong moment.
- Trace
- The stored record of one run: every prompt, tool call, argument and result, joined by a run identifier. Without it a production incident cannot be explained.
- Escalation
- The route an agent takes when it cannot finish or reaches an action it may not perform. A named queue, a named human and a deadline.
The longer treatment is in agent or workflow. The short version: pick the workflow unless the input varies in ways nobody can enumerate.
Who it is for, and who it is not for
Agents pay off inside a narrow band: reasonable volume, inputs that vary in ways you cannot list, a definition of done a machine can check, and systems reachable through an API. Outside it, an agent loses to a workflow or to a person.
| The work looks like | What to build | Why |
|---|---|---|
| Same five fields, same three systems, every time | A workflow | The control flow is already known. Paying a model to rediscover it buys variance and cost, nothing else. |
| Inputs arrive in forty formats and the next step depends on what is inside | An agent | Enumerating branches is the expensive part, and reading unstructured input to pick one is what a model does well. |
| High volume, varied, reversible actions, output already sampled | An agent | This is the band. Volume pays for the build, reversibility caps the damage, sampling catches drift. |
| Judgement with legal, clinical or safety consequences | A person, with software support | Nobody can be held to account for a decision no person made. |
| Fewer than about twenty runs a week | Neither | Build and maintenance will exceed the cost of the work itself, for years. |
| A process nobody has written down | Write it down first | An agent built on folklore automates the folklore, including the parts three people disagree about. |
Draw the process as a flowchart. If every diamond holds a rule you can state in one line, you want a workflow. Agents earn their keep only at the diamonds you cannot write down.
- You want one agent that runs the company. What reaches production is a narrow agent with six tools and a queue somebody reads.
- Nobody can name who will own the escalation queue in six months. An unowned queue fills, gets ignored, then becomes evidence the project failed.
- The upstream data is wrong and the agent is expected to paper over it. Automation makes bad data faster, not better.
- You need the identical answer to the identical question every time. That is a query, not an agent.
- The process is your competitive edge and it changes weekly. You will spend the build chasing the specification.
What we actually build
The deliverable is a running service with an operator interface, not a prompt in a text file. Most of the code has nothing to do with the model.
The tool layer
Every system the agent touches is wrapped in a typed function with a narrow scope, an idempotency key and error strings written for a model to read. A tool returning five hundred lines of JSON buries the fields that matter and decides worse than one returning eight fields and a reference id. A tool whose error is a stack trace teaches nothing. One whose error says the period is closed and the next action is to escalate teaches exactly what to do.
The policy layer
Rules that must never bend live in code around every tool call, not in sentences inside the prompt. A rule in a prompt is a strong suggestion. A rule in code is a rule. Spend caps, allowlists, rate limits and approval thresholds belong here. When an auditor asks how you know the agent could not have refunded above a limit, the answer has to be a function with a test.
The verification layer
Self verification is not the model marking its own homework in the same call. It is a deterministic check where one exists, or a separate call with a different prompt comparing the output against the evidence gathered in the run. Amounts get recomputed, identifiers looked up again, and any claim not tied to a tool result gets flagged. That pass catches the confident wrong answer.
- A typed tool per system, with a scope, an idempotency key and model readable errors.
- A policy module holding every rule that must not bend, enforced around each tool call.
- The loop, with budgets for steps, tokens, spend and wall clock time, plus a repeat detector.
- An escalation queue with a schema: what it was doing, what it could not resolve, what it recommends.
- A trace store queryable by business record and by run, plus a cost dashboard split by outcome.
- An operator interface showing the run, the reason, the evidence and two buttons.
- The evaluation harness, runnable with one command, results committed beside the prompt.
How it works technically
One run is a loop with a budget. It reads the state, asks the model for one next action, executes it inside your code, appends a trimmed result, and repeats until a stop condition fires. The engineering sits in the stop conditions and the error paths.
- A trigger arrives as a webhook, queue message or schedule. The run record gets an id and an idempotency key from the source event, so a duplicate delivery cannot cause a duplicate action.
- Context is assembled: job statement, policy summary, tool catalogue, the input, and reference material retrieved up front. Retrieval before the loop is cheaper and more predictable than inside it.
- The model returns a tool call or a final answer. Anything else is a parse failure, retried once, then escalated. The call is validated against its schema first, so malformed arguments go back as a typed error naming the offending field.
- The tool executes inside your service, with your credentials, at the scope policy allows, behind a timeout and a rate limit.
- The result is trimmed and appended. Raw payloads eat the token budget and bury what matters.
- Stop conditions: goal met, step or token budget spent, wall clock exceeded, a rung above the agent's authority reached, or the same tool called twice with identical arguments.
- Verification runs, then the agent commits or escalates. Both paths write a complete trace before the run closes.
Repetition is the most common live failure and the cheapest to defend against. An agent calling search three times with the same query is stuck and keeps paying for it. Hash the tool name with its normalised arguments and break on the second exact repeat.
ROLE
You process exactly one supplier invoice per run. You handle no other task.
If the input is not a supplier invoice, call escalate(reason="wrong_input") and stop.
DEFINITION OF DONE
1. The invoice is matched to exactly one purchase order, or marked unmatched with
a reason drawn from unmatched_reasons.json.
2. Every amount you report was read from a tool result in this run. Never infer an
amount from a similar invoice and never do arithmetic in your head.
3. The result validates against invoice_result.schema.json.
TOOLS AND AUTHORITY
Call only the tools provided. Never describe an action you did not take.
Reversibility classes:
R0 read R1 draft R2 internal write R3 external send R4 irreversible
You may act on your own initiative up to R2. For R3 and R4, call
request_approval() with the exact payload, then stop.
LIMITS
Maximum 12 tool calls per run.
Never call the same tool twice with identical arguments. If you are about to,
your plan is wrong: call escalate(reason="loop") instead.
If a tool errors twice, stop and escalate. Do not invent a workaround and do not
reach for another tool to get around a permission error.
UNCERTAINTY
If a required field is missing, unreadable or ambiguous, do not guess.
Call escalate(reason="missing_field", field="<field_name>") and stop.
A missing supplier tax number is an escalation, not an empty string.
OUTPUT
Return only JSON matching invoice_result.schema.json. No prose outside the JSON.
Populate "evidence" with the tool_call_id that produced each field you report.
The prompt is half the contract. The tool definition is the other half, and putting the reversibility class inside it means the rule travels with the code.
{
"name": "post_invoice_to_ledger",
"description": "Post a matched invoice to the ledger. Call ONLY after match_purchase_order returned status='matched' and the variance is inside the tolerance from get_tolerance. Finance sees this entry immediately and this agent cannot reverse it.",
"reversibility": "R3",
"requires_approval": true,
"idempotency_key": "invoice_id",
"timeout_seconds": 20,
"input_schema": {
"type": "object",
"additionalProperties": false,
"properties": {
"invoice_id": {"type": "string", "description": "Exact id from fetch_invoice. Never construct it."},
"purchase_order_id": {"type": "string", "description": "Exact id from match_purchase_order."},
"amount_minor_units": {"type": "integer", "description": "Smallest currency unit. 1250 means 12.50."},
"currency": {"type": "string", "enum": ["GBP", "EUR", "USD", "INR"]},
"variance_reason": {"type": "string", "description": "Required when the amount differs."}
},
"required": ["invoice_id", "purchase_order_id", "amount_minor_units", "currency"]
},
"returns": {
"ok": {"ledger_entry_id": "string", "posted_at": "ISO-8601"},
"error": {"error_code": "not_matched | duplicate_entry | period_closed | insufficient_permission",
"hint": "A sentence written for the model saying what to do next. Never a stack trace."}
}
}Two details do most of the work. The description says when not to call the tool, which is more useful than saying what it does. And the failure branch returns named error codes with a plain hint, so a model hitting a closed period escalates rather than retrying eleven times.
The Reversibility Ladder, and why it decides everything
Most arguments about agent safety are really arguments about undo. Sort actions by what reversing them costs and the autonomy question stops being philosophical.
The ChatGPTalker Reversibility Ladder
Every tool sits on one of five rungs, defined by what undoing the action costs. The rung sets the control. Not the tool's importance, and not how confident anyone feels on launch day.
Queries, lookups, searches, retrieval. Nothing changes. The agent calls these freely under a rate limit and a spend cap. Most of a healthy agent's calls sit here. If yours do not, the tool design is pushing state changes somewhere they do not belong.
Drafts, scratch records, staged files, a message composed but not sent. An undo exists and the system performs it without a human deciding anything. The agent acts without approval, and a scheduled job clears stale drafts so staging never becomes the system of record.
Internal state others can see: a ticket assigned, a deal stage moved, a record updated. The agent acts, writes before and after values into the trace, and a human can revert inside the audit window. This is the highest rung we let an agent occupy unsupervised.
An email to a customer, a webhook to a partner, anything published. You cannot unsend it. Either a person approves each one, or the agent is confined to a fixed template with a recipient allowlist and a hard daily cap. What we never ship is free text to an address the agent chose.
Payments, refunds, deletions, signatures, anything with a statutory trail. The agent assembles the payload and explains it with evidence attached. A named person commits it. We have yet to see a case where removing that one click survives a single bad payment.
Autonomy is set by the highest rung on the tool list, not the average. One R4 tool on a five tool agent does not make it slightly riskier. It makes the whole thing an R4 system with a gate on every path. The fix is to split it so the irreversible action sits in its own gated component.
Put the class in the tool definition rather than a policy document. Documents drift, definitions get reviewed with the code. Re-read the list quarterly, because a system that was R2 in March is often R3 by September without anyone deciding.
The build process, stage by stage
Six stages, four to eight weeks for a first agent in an unfamiliar stack. The first two produce documents rather than code, and they decide whether the rest works.
- Baseline and job statement
We time the work as done today: cases per week, handling time, how often it goes wrong, who catches it and how late. Measured before anything is built, because after launch nobody remembers what it used to be like and every claim of improvement becomes an argument.
- Tool and policy design
Every system the agent must touch, and how it gets in. Each becomes a typed tool with a class, a scope and an idempotency key. This stage regularly kills a feature. If the only way in is a screen with no API, the honest answer is to change the process.
- Evaluation set from real history
Forty to a hundred real past cases with known outcomes, weighted towards the ugly ones, each with a recorded good answer. Demonstrations built on clean cases are how a pilot passes and a production system fails.
- Build and instrument
The loop, the tools, the policy checks, verification, escalation and the trace, in that order. Instrumentation goes in on day one, because the first live incident cannot be explained without it.
- Shadow run
The agent runs on live traffic and commits nothing. Its proposed action sits beside the human decision and the two are compared daily. Every disagreement is either a defect or a rule nobody wrote down. Clients want to skip this stage. It is the one that prevents rollbacks.
- Cutover behind a sample gate
The agent starts committing on one team, category or region. A percentage of runs is sampled daily, and that rate falls as disagreement falls. It never reaches zero. A named person owns the queue and gets the weekly report.
What you get at handover
You get the running system plus everything needed to change it without us. The handover test runs with your engineer before the final invoice: find the prompt, change one line, run the evaluation set, read the result, deploy. If they cannot do all five, handover is not finished.
Credentials stay in your vault and the system runs in your cloud account unless you ask otherwise. Provider accounts are yours and billed to you, so you see token spend directly. An agent you cannot modify becomes one you cannot maintain.
Where these projects go wrong
Agent projects rarely fail because the model was not clever enough. They fail on plumbing, on scope, and on having no way to tell whether anything improved.
The job statement quietly grew a paragraph
It starts as invoice matching. Then credit notes, then supplier onboarding, then the monthly accrual. Each addition is reasonable and the sum is untestable. The tell is an evaluation set that stops being representative, because fifty cases cannot cover four jobs. Split it and accept two agents with two owners.
Tools designed for humans rather than models
An endpoint returning the whole customer object with two hundred fields is fine for a developer with a debugger and terrible for an agent with a token budget. So are tools with overlapping purposes and three calls to answer what a person asks once. Full treatment in designing tools an agent can use.
No evaluation set, so every change is a guess
Without stored cases and expected outcomes, prompt changes become superstition. Somebody adds a sentence, the demo looks better, and nobody knows what broke. Six months on, the prompt is nine hundred words of defensive scar tissue nobody dares delete. This is why evaluation and guardrails is part of the build.
Retries that are not idempotent
A timeout is not a failure, it is an unknown. The request may have succeeded with the response lost. If the retry path is not keyed on something stable, the agent will cheerfully send the second email or post the second ledger entry. Where the receiving system cannot honour a key, read before you write.
No trace, so the incident cannot be explained
The first serious question from the business is never technical. It is what the agent did to this record on this date, and why. If answering needs application logs and guesswork, the system loses its licence to operate however well it performs. Traces must be queryable by business identifier, a day one decision and the subject of agent observability.
A crashing agent gets fixed on Tuesday. An agent that handles nine cases correctly and the tenth wrongly, in the same confident tone, is found during an audit six months later. Sampling and verification exist for that tenth case, and they are the first things cut when a budget tightens.
What it costs to run once live
Token cost is real, easy to model, and usually not the largest line. Run the arithmetic on your own numbers at today's prices, because pricing moves often enough that any figure printed on a web page is stale by the time you read it.
Defaults are illustrative, not quoted prices. Replace the price fields from your provider's page today and the token fields from your own traces.
Three multipliers catch people out. Failed runs cost full price, so a run that burns eleven calls then escalates is dearer than a successful one. Input grows through the run as results are appended, so twelve calls cost closer to a rising series than twelve times the first. And verification re-reads the evidence, roughly doubling input where it fires.
| Cost line | Shape | What drives it |
|---|---|---|
| Model tokens | Per run, highly variable | Call count, context growth, retries, the verification pass |
| Compute and queueing | Flat until concurrency spikes | Container hosting, the queue, the scheduler, cold starts |
| Vector or search index | Per document plus per query | Corpus size, refresh rate, replicas, re-embedding |
| Trace and log storage | Grows daily unless capped | Retention period, payload size, full capture sampling rate |
| Human review | Per sampled run | Sample rate, escalation rate, how long a review honestly takes |
| Maintenance | Monthly, and unavoidable | API changes, model deprecations, prompt drift, new edge cases |
A model gets deprecated, a supplier renames a field, a new document format arrives, and the agent has to be re-evaluated. Budget engineering time monthly from launch, not from the first outage. Unowned, the system decays quietly and AI gets the blame.
How to tell whether you need one
Most teams asking for an agent need a workflow. The comparison below is deliberately unflattering to agents, because the wrong shape is expensive and slow to discover.
- Can you write the job in one sentence and the definition of done in three bullets?
- Can you find forty real past cases with known outcomes without a data project?
- Does every system have an API, or must a model drive a screen built for a person?
- Is there a named human who reads the escalation queue on a Monday morning?
- If the agent gets a case wrong tomorrow, can you undo it, and who finds out?
Four clear yeses and a soft fifth is a project worth starting. Two yeses is a workflow, and we will say so on the call rather than after the deposit. If the work is several genuinely different jobs rather than one varied job, the shape you want is multi-agent systems.
How to start
Start with one process and a conversation, not a platform decision. The first agent teaches you how your process really behaves, and that lesson is cheapest on a narrow job.
- A scoping call
You describe the process. We ask what breaks it, who fixes it now, and what happens when it goes wrong at four on a Friday. If an agent is the wrong shape here, that is the outcome of the call and it costs nothing.
- A scoping document
The job statement, the tools with their reversibility classes, whether an evaluation set can realistically be assembled, the baseline we would measure, and a price range with every assumption beside it.
- Baseline week
Volume, handling time, current error rate, current rework. Every later claim is checked against this, and it cannot be reconstructed afterwards.
- Build, shadow, cut over on a slice
The six stages above, ending with the agent committing work on one team or category behind a daily human sample.
- The thirty day review
Disagreement rate, escalation rate, cost per run and handling time, all against the baseline. If the numbers do not justify the system, that is a finding rather than an embarrassment, and better found at thirty days than thirty months.