Ending a Run on Purpose
Until It Is Done Is the Most Common Bug
The single most frequent defect in first-generation agents is a termination condition that exists only in the prompt. The instruction says to continue until the task is complete, and completion is left to the model's judgement, evaluated against a context that no longer contains the original requirements clearly. What follows is familiar: the agent declares victory on partial work, or it keeps going because there is always another thing that could be checked, or it enters a polite loop of re-verifying what it already verified. None of these are model failures in an interesting sense. They are the predictable result of putting a control-flow decision inside a probabilistic system. Termination is a property of the runtime. The model can propose that it is finished; only your code can decide that the loop ends.
- A prompt-level stop condition is a control decision delegated to a sampler
- Three standard outcomes: stops early, never stops, or loops re-verifying
- The model may propose completion; the runtime decides it
- Every run needs at least one termination condition your code evaluates
Make Stopping an Explicit Action
The cleanest mechanism is a terminal tool: the model finishes by calling something like submit or hand_back with a structured result, and the loop ends when that call is made. This is better than parsing prose for finality for several reasons. It gives you a schema, so completion carries the artefact — the answer, the identifiers touched, the confidence, the caveats — rather than a paragraph you then have to interpret. It separates finishing successfully from giving up, if you provide both a success terminal and an escalation terminal, which turns "I could not do this" from a failure into a legitimate outcome. And it makes the end of a run a discrete, loggable event rather than an inference. Anything the caller needs at the end should be a required field on that schema.
- A terminal tool ends the loop; prose finality detection is guesswork
- The terminal schema carries the artefact, not just the fact of stopping
- Provide a separate escalation terminal so giving up is a first-class outcome
- Required fields on the terminal schema are how you stop empty successes
Conditions Your Code Can Actually Check
Wherever the definition of done is mechanically checkable, check it mechanically and do not ask the model. The tests pass. The record exists with the expected field values. The file parses. The invoice total matches the sum of lines. A deterministic completion predicate is cheap, never drifts and cannot be talked out of its answer, and where one exists the model's opinion about completion is at best a hint. Where no such predicate exists, degrade in order: a cheap validator over the produced artefact, then a separate model call with a specific rubric rather than the working model's self-assessment, then a human. The asymmetry worth internalising is that the model that did the work is the worst available judge of whether the work is finished, because it is grading its own understanding of the goal.
- Prefer a deterministic completion predicate wherever one can be written
- Degrade in order: validator, separate judged check, human — never self-assessment first
- The working model is the weakest judge of its own completion
- Checkable definitions of done should shape how you scope agent tasks in the first place
Premature Stop Deserves Equal Attention
Runaway loops get the attention because they cost money visibly, but stopping too early is more common and much quieter. An agent asked to fix a failing build fixes the first error and reports success. An agent asked to reconcile a list processes the first page. The output looks plausible, the run is cheap, nothing alerts. Two habits catch most of it. Require evidence in the terminal call — which items were processed, which checks were run, what the final verification returned — so an empty success becomes structurally visible rather than rhetorically hidden. And measure work done per run alongside success rate: a sudden drop in steps or tool calls per successful run, with success rate flat, usually means the agent has learned to declare victory sooner rather than to work more efficiently.
- Premature stop is quieter than runaway looping and at least as common
- Require evidence fields in the terminal call so empty success is visible
- Watch steps and tool calls per success — a sudden drop is rarely efficiency
- A cheap run with a plausible report is the failure that survives review longest
Prefer slides, quizzes, and saved progress? Read this lesson in the library — free, no sign-up.