The one-sentence definition is a model in a loop with tools and a stopping
condition. People spend their design time on the middle two. The loop is
interesting, the tools are concrete, and both produce visible progress. The
stopping condition gets whatever attention is left, usually in the form of
max_iterations = 10.
That is backwards. In every agent that has caused a real problem, the failure was not that it could not do the work. It was that it did not know when to quit.
Three stops, not one
An iteration cap is one stopping condition doing the job of three. Separate them and each gets easier to reason about.
Done. The agent has a verifiable result. Not "the model believes it is finished" — a check that some other piece of code can run. The file parses. The test passes. The row count matches. If you cannot write that check, you do not have a done condition, you have a vibe, and the agent will hit it early and confidently.
Can't. The task is outside what this agent can accomplish: a missing credential, an ambiguous instruction, a source that does not have the data. This is the stop that gets skipped, and skipping it is expensive, because a model asked to produce output will produce output. Deny it the ability to say "I could not do this" and it will invent something that looks like success. Every fabricated citation and every plausible-but-wrong summary you have seen is a missing can't branch.
Too expensive. Wall-clock, tokens, or tool calls past the point where the answer is worth having. This is the one people actually implement, and on its own it is the weakest of the three — it fires long after the run went wrong, and it tells you nothing about why.
Make the stop legible
Whatever stops the loop should say which of the three fired, and the caller
should be able to branch on it. {status: "done", result} versus
{status: "blocked", reason} versus {status: "exhausted", attempts} is a
different product from a function that returns a string either way.
This is what makes an agent sellable. A client can live with "I could not process 12 of these 400 invoices, here they are." No client can live with 400 processed invoices where 12 are quietly wrong and there is no way to tell which.
The stopping condition is not error handling bolted onto the end. It is the interface — the only part of the agent your buyer actually experiences on the day it does not work.