Take an ordinary case. A supplier invoice arrives for 1,200 units. The purchase order says 1,200. The goods receipt shows 1,180 delivered and 20 on back-order. Someone has to decide whether to pay in full, pay short or query the supplier, and in most companies that someone is a person with three browser tabs open.
Hand that case to a language model on its own and it will explain three-way matching to you, fluently, and leave the invoice exactly where it was. Hand it to a model with a harness and the purchase order gets fetched, the receipt checked, the tolerance policy applied, a query drafted to the supplier and the payment held until a person signs off. Same model. The difference is everything built around it.
That surrounding build is the harness: everything put around a model so that it can act, and be trusted to have acted. In practice it comes down to four things: the tools the model can call, the context it is shown, the limits on what it may do, and the checks that prove the work happened. When people say “agent”, they usually mean this pair, a model and the harness it runs in. Most of the engineering, and most of the reliability, lives in the second half.
The model is a component
A language model takes text in and produces text out. It cannot open a database, it does not remember last week, and it cannot press a button. On its own it is a strong reader and writer with nothing to read and no way to act.
Everything else is harness work. The model reasons; the harness sees, acts, remembers and checks.
This is also why we are model-agnostic. When a system’s behaviour lives in its harness, swapping the model underneath is a configuration change plus an evaluation run, not a rebuild. Put the behaviour in the prompt instead and the opposite holds: a clever prompt on a bare model rarely survives the next model release.
Tools: what the model can reach
A tool is a function the harness exposes to the model, with a name, a description and a typed input. Fetch a purchase order by number. Look up the goods receipt for a delivery. Draft an email. Submit a payment. The model does not run any of these. It asks for one, the harness executes it, and the result comes back as text for the model to read.
That ask-and-return exchange is the loop, and the harness runs it. One case might go round a dozen times. The person who asked sees a single result; the log shows every step, each small enough to inspect.
Tool design decides more about an agent’s quality than most people expect. Tools that hold up in production are:
- Narrow. One job each, with a name that says what it does.
- Honest about failure. A tool that returns “not found” or “timed out” lets the model recover. One that returns an empty string teaches it to guess.
- Structured. Fields, not prose, so the next step can rely on them.
- Split by risk. A read tool and a write tool with different permissions, rather than one tool that does both.
Context: what the model is shown
Every call to a model starts from nothing. Whatever it knows about your company, this case and the last five steps arrived on this turn, placed there by the harness: instructions, the relevant policy, the records for this invoice, the results so far. All of it has to be assembled, and there is a hard limit on how much fits.
So the harness has to choose. The full record of the case lives outside the model, in storage the harness controls. On each turn it selects the pieces this step depends on, compresses what it does not, and fetches a document only when the step calls for one. Done well, the model sees exactly what matters and nothing that distracts. Done badly, a detail from step two is gone by step nine, and the agent confidently applies the wrong tolerance.
This is where data foundations come in. If purchase orders, receipts and supplier terms live in three systems with three definitions of “delivered”, no prompt fixes that. The harness can only show the model what the business can actually surface, which is why the data work comes first in our engagements and the agents come after.
Guardrails: what the model may do
There is a difference between telling a model not to do something and making it impossible. “Never pay above the tolerance without approval” is a sentence in a prompt. A payment tool that refuses to run unless an approval record is attached is a rule. A prompt asks. Code decides. A dependable system has both and relies on the second.
Guardrails are mostly ordinary engineering:
- Credentials scoped to the task, so a tool cannot reach systems it has no reason to touch.
- An allowlist of the actions that are permitted at all.
- Approval gates in front of anything with consequences: money, customer-facing messages, deletions.
- Budgets for steps, time and spend, so a loop that is not converging stops instead of burning the afternoon.
- A clean exit. When the agent is stuck it stops, and a person gets the case together with the log, not a blank slate.
None of this is exotic, and none of it ships with the model. Calling something an agent makes it no safer. Whether it is safe gets decided in the harness, one gate at a time.
Evaluation: proof the job got done
An agent will happily report success it did not achieve. Payment submissions fail. Emails bounce. The model misreads a contract term and pays short on a supplier who had it right. If the only evidence the harness collects is the model’s own account, every run looks fine.
Checks belong at two levels. Inside the loop, the harness confirms outcomes against something other than the model: the payment shows as posted, the message has a sent timestamp, the record changed. If the confirmation is missing, the agent says so instead of closing the case.
Outside the loop sits the evaluation set: a bench of past cases from your own records, each with a known-correct outcome, run every time a prompt, a tool, a policy or the model changes. Every step is logged, so a failure can be replayed and fixed rather than reconstructed from memory. This is what turns an agent from a demo nobody dares touch into a system you can change on a Tuesday.
Where the work actually is
In a typical engagement, a small share of the engineering time goes to the model. The rest is harness: wiring tools, cleaning the data they read, deciding what the model sees, building the gates and writing the evals.
It also decides what you own. Models are rented and replaced. The harness, built on your systems, around your policies and tested against your cases, is the asset that carries over. It should be yours: in your repositories, readable by your engineers, deployable without us.
Back to the invoice. The model read a mismatch and proposed a resolution. The harness fetched the records, held the policy in view, refused to pay without a signature, confirmed the query went out and logged the whole run. The model did the reading. The harness did the job.