The AI Learning Hub Journal

Ending a Run on Purpose

Termination is a property of the runtimethe model may propose that it is finished; only your code can decide that the loop endsSTOP CONDITION IN THE PROMPT"continue until the task is complete"completion left to the model's judgement, against acontext that no longer states the requirements clearlyDECLARES VICTORY EARLYpartial work, a plausible report, nothing alertsNEVER STOPSthere is always one more thing it could checkTHE POLITE LOOPre-verifying what it has already verifieda control-flow decision delegated to a samplernone of these are interesting model failuresFINISH BY CALLING A TERMINAL TOOLsubmit({ … }) — completion carries the artefactthe answer or artefact producedidentifiers touched, checks runconfidence and caveatsrequired fields stop empty successesSUCCESS TERMINALdone, with the resultand the evidenceattachedESCALATION TERMINAL"I could not do this"as a legitimateoutcome, not a failurethe end of a run becomes a discrete, loggable eventnot an inference from proseTHE MODEL PROPOSES COMPLETION — THE RUNTIME DECIDES ITWhere done is mechanically checkable, check it in code — the model that did the work is the weakest judge of it
The model may propose completion; only a termination condition your runtime evaluates can end the run

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.