All resources

Designing agent loops

An agent is a loop with a job. The trick is knowing where the loop ends.

The first time you wire up an LLM to call its own tools, two things happen: it feels like magic, and you find yourself watching it spin in a corner doing the wrong thing for six minutes. The first is real. The second is fixable.

An agent is four parts

  • An input — what the world hands it.
  • An action — what it does in response.
  • A check — how it knows the action worked.
  • A decision — whether to keep going, or stop.

Most failing agents skip the check or the decision. They run actions until they run out of budget. The result feels intelligent but it isn't.

Halt conditions are a deliverable

Before you let an agent loop in production, write its halt conditions like specs:

  • "Stop when the support ticket is tagged."
  • "Stop when the JSON schema validates."
  • "Stop after three retries on the same step."

Declarative, measurable, finite. If you can't write the halt condition, you don't have an agent yet — you have an open chat.

Reflection without action is debt

A lot of "agentic" systems are really chains of LLM calls that critique each other. That's not an agent — that's a council. Useful sometimes, but it doesn't replace the loop. The loop has consequences; the council just has opinions.

A real example

We run an email-triage agent for a portfolio client. Input: every unread email. Action: assign one of six labels. Check: schema-validate the label and confidence. Decision: if confidence is below 0.7, escalate to a human queue; otherwise apply the label and move on. Runs forty thousand times a month. Has produced zero meltdowns because the halt condition is unambiguous.

Every agent should know how to quit. A good loop is built around the moment it admits it's done.

Design that moment first. The rest is plumbing.