Stopping Conditions: How an Agent Knows When It's Done
An agent loop without a stop rule is a cost and reliability hazard. The model will keep proposing next steps as long as the host asks it to.
Search across all documentation pages
An agent loop without a stop rule is a cost and reliability hazard. The model will keep proposing next steps as long as the host asks it to.
Stopping conditions are the explicit rules that end a run: success, failure, budget exhaustion, timeout, or human cancel. They are not optional polish. They are part of the agent definition.
The agent loop has a natural "happy path" stop: the model emits a final answer instead of another tool call. That signal is necessary but not sufficient.
You also need host-enforced stops the model cannot override:
Think of elevator doors: the "open" button is a request, but mechanical limits and fire overrides still exist. The model's "I am done" is a request to stop; your runtime must also enforce limits.
loop:
reason → act? → observe → ...
stop if:
- final answer accepted
- max turns hit
- timeout hit
- budget hit
- error budget hit
- human cancel / deny
- goal verifier says success (optional)The model returns assistant text with no pending tool calls. Your runtime should treat that as a candidate stop.
Optionally validate: does the answer actually address the user goal, or is it empty / "I will continue later"? Weak models sometimes "finish" with a plan instead of a result.
Count host-controlled units:
MAX_MODEL_TURNS = 8
MAX_TOOL_CALLS = 12
# increment after each LLM call / each successful tool dispatch
# if either exceeds, stop with reason max_turns or max_tool_callsPick limits from task shape, not superstition. A two-lookup support bot may need 4 turns. A research agent may need dozens, with higher cost tolerance.
Separate:
A tool timeout should usually become an observation error, not always a full run stop. A run timeout always stops.
Agents re-send growing context. Token spend can explode even with moderate turn counts.
Budget stop example policy:
Beyond "model says done," add a verifier:
Goal checks prevent early exit. They do not replace max-turn hard caps.
If the last N tool calls all failed with the same error, stop or escalate. Blind retries are a common runaway pattern.
Some "stops" are pauses: wait for approval before a refund tool. The loop is suspended, not finished.
Distinguish:
| Signal | Meaning |
|---|---|
completed | Final answer delivered |
awaiting_human | Paused for input/approval |
failed | Stopped with error |
cancelled | User/operator aborted |
budget_exhausted | Cap hit |
Product UX and metrics need these distinctions.
When you stop for budget reasons, you may still ask the model once for a partial summary of what was learned. That is a deliberate final turn under a "must finalize" system instruction, not an open-ended continue.
Production agents usually combine stops:
| Layer | Example | Overrideable by model? |
|---|---|---|
| Success | Final answer + schema ok | Soft |
| Safety | Disallowed tool blocked | No |
| Resource | Max turns / $ / seconds | No |
| Quality | Goal verifier fails → continue or escalate | Partial |
| Human | Cancel button | No |
In graphs, each node may have local timeouts while the graph has a global deadline. Handoffs should carry the remaining budget so specialists cannot reset caps to infinity.
Overnight monitors need different stops: per-cycle caps plus schedule boundaries ("end of business day"), not a single max-turns from boot.
See Single-Turn vs Multi-Turn vs Long-Running Agents.
Always return a machine-readable stop_reason plus user-safe message.
{"stop_reason": "max_turns", "content": "I hit my step limit before finishing. Partial findings: ..."}Operators can alert on unexpected reason distributions (spike in max_turns means prompt/tool design is wrong).
| Stop style | Strength | Weakness | Best fit |
|---|---|---|---|
| Final-answer only | Simple | Runaways if model never finishes | Demos only |
| Hard caps only | Safe cost bound | May cut off success late | All production agents (as floor) |
| Caps + goal verifier | Better completeness | More engineering | Business-critical tasks |
| Caps + human gates | Safe side effects | Higher latency | Money, delete, send external |
A rule that ends or pauses the agent loop and yields control with a clear reason, such as final answer, max turns, timeout, or cancel.
At least: accept final answers, max model turns or tool calls, per-run timeout, and user cancel. Add cost caps for paid model usage.
Start from the shortest successful golden trajectories in evals, then add a small buffer. Raise caps only when metrics show real incomplete successes.
Count host-controlled model and tool steps. User messages are usually out of band for budget protection.
Hard caps must fire, then optionally force a summarization turn with tools disabled.
Detect repeated identical tool calls and results, convert to an error observation, then stop after N repeats. See runaway debugging.
No. Limits must be enforced in host code outside the model's control.
Pause waits for external input and may resume the same run. Stop finalizes the run and needs a new run to continue.
Streaming changes presentation, not the need for caps. You can stop mid-stream if cancel or timeout fires.
Sometimes as a soft check. Prefer deterministic checks (schema, tests, DB state) when stakes are high.
Track distribution of stop_reason, average turns per success, and rate of budget stops on tasks that should succeed.
Use a dedicated reason like budget_exhausted or max_turns with partial content, not final_answer, so dashboards stay honest.
Cap both planning and execution phases. A perfect plan with infinite execute steps is still a runaway risk.
Product success is user outcome. Runtime success is meeting stop criteria with a valid result. Measure both.
max_turns in a minimal loopStack versions: Pins from the category manifest (verify at build): OpenRouter (~315+ models, July 2026 pricing/fees); LangGraph 1.0+; CrewAI 1.14+; Microsoft Agent Framework 1.0; Vercel AI SDK 6; Pydantic AI (latest); LlamaIndex (latest); OpenAI Agents SDK (latest + MCP); MCP (Linux Foundation governance); A2A (HTTP+SSE+JSON-RPC 2.0); Solana
@solana/web3.js+@solana/spl-token.
Reviewed by Chris St. John·Last updated Jul 16, 2026