Ask most people what an agent is and you’ll hear some version of “a model in a loop with tools, told to be helpful.” That’s a fine description of a demo and a terrible description of anything you’d run in production. A real agent is a declared workflow — a state machine — not a model improvising against an open-ended instruction. The difference isn’t pedantic. Four properties separate the two, and a while-loop can give you none of them.

Tools held as a capability object

The tool set an agent can use is passed in when the run is constructed — held as a capability object — so a prompt cannot name a function the agent doesn’t hold. This is the crucial inversion. The safety property is not “the prompt says don’t do X.” It’s that X isn’t reachable: there is no path from this run to that capability, no matter what the prompt, the model, or an attacker puts into the input. Every tool also declares whether it’s readOnly or sideEffecting, so the runtime knows which calls can change the world and which can’t. “Instructed not to” is a hope. “Not in the capability set” is a guarantee.

Runs and steps are rows

A run that’s paused at a human gate for three days is a database row, not a suspended process. This sounds like an implementation detail and it’s actually what makes human-in-the-loop gates real rather than aspirational. If a paused agent is an in-memory coroutine waiting on a callback, your gate evaporates the moment the process restarts. If it’s a row in a table with an explicit state, the gate survives deploys, crashes, and three-day weekends, and you can query every run currently waiting on a human. Durable state is the difference between a gate you can rely on and a gate that works until it doesn’t.

Hard budgets

Every run carries hard budgets — tool calls, tokens, wall-clock time, cost — and exhaustion halts and escalates. It never retries indefinitely, and it never silently truncates and reports success. That last one matters more than it seems, because silent truncation reporting success is the most common way agents fail invisibly: the run hit a wall, gave up on half the work, and returned a cheerful “done.” A budget that halts-and-escalates converts that invisible failure into a visible one — a run that stopped and asked for help, instead of a run that lied. Bounding the blast radius of a stuck agent is not optional; unbounded loops are how a single bad input becomes a runaway bill.

Replay

Store the inputs, the model version, the prompt version, and the retrieval set for every step, and any output becomes reconstructible. Replay is three things at once: a support tool (why did this run do that?), a sales and trust artifact (here is exactly what happened, reproducibly), and an audit requirement (show your work). A system you can replay is a system you can debug, defend, and sell. A system you can’t is a black box that happens to be yours.

Two disciplines that hold it together

Two more rules make the whole thing sturdy. First, every model call returns structured output validated against a schema, with typed retry — free text never enters a decision path. If the model returns something the schema rejects, you retry against the schema; you don’t hand a loose string to code that then has to guess. Second, every model call goes through one gateway that pins versions, routes by region, redacts sensitive data, caches, and attributes cost. Nothing else in the codebase imports a provider SDK directly. One chokepoint means one place to change models, enforce policy, and see the bill — instead of provider calls scattered across forty files, each with its own quiet assumptions.

None of these four properties — capability scoping, durable rows, hard budgets, replay — is something you bolt onto a loop later. They’re the reason to model the agent as a declared state machine from the start. The loop is what you write to pass a demo. The state machine is what you run when being wrong is expensive.


Cheap to Be Wrong — a six-part series on agent architecture

  1. Put the Model Where Being Wrong Is Cheap
  2. Use the Model to Write the Parser, Not to Be the Parser
  3. Where the Model Is Genuinely Load-Bearing
  4. An Agent Is a State Machine, Not a Loop — you are here
  5. The Model Upgrade That Quietly Breaks You
  6. The Model Is the Least Defensible Part of Your Agent

Related: A Longer Leash: What Autonomous Coding Agents Change.


Discover more from Digital Reflections

Subscribe to get the latest posts sent to your email.

Leave a Reply

The Blog

At the intersection of data, AI, and imagination lies the path to transformation. Our greatest evolutions occur when we use technology not just to improve what is, but to reimagine what could be.

Discover more from Digital Reflections

Subscribe now to keep reading and get access to the full archive.

Continue reading

Discover more from Digital Reflections

Subscribe now to keep reading and get access to the full archive.

Continue reading