Skip to main content
Cap how many tool-use steps an agent may take before wrapping up with its best final answer. max_steps is the unified outer-loop step budget honoured identically by both tool-execution loops (OpenAI-native and LiteLLM). On the final permitted step the model is asked to wrap up, so you get a coherent answer instead of a hard cut.

Quick Start

1

Raise the budget with a scalar

2

Detect truncation with last_stop_reason


How It Works

On the final permitted step both loops inject an internal user-role message so the model produces a coherent final answer:
“You are approaching the maximum number of tool-use steps for this task. Stop calling tools now and provide your best final answer, summarising the work completed so far and clearly noting anything left incomplete.”
The wrap-up message works on a local copy of the conversation, so it never leaks into the caller’s history.

Choosing a Value


Configuration Options

Full list of options, types, and defaults — ExecutionConfig
Two helpers resolve the effective values:

How it relates to max_tool_calls_per_turn

max_steps bounds outer-loop iterations — one LLM round-trip each. max_tool_calls_per_turn caps how many tool calls the model can fire inside one response. They are independent on purpose: if they were coupled, a single parallel-tool response could exhaust the whole step budget (e.g. max_steps=5 truncating after one round of 5 parallel calls). Set them separately when you need both a long overall budget and a small per-turn burst.
Safe to read on any agent, including LiteLLM-only ones — reading agent.last_stop_reason never lazily creates the OpenAI client. Returns "completed" by default when no run has finished yet.

Common Patterns

Pattern 1 — Raise the budget for long runs

Pattern 2 — Detect and continue after truncation

Pattern 3 — Independent per-turn guardrail


Best Practices

The default (20, via max_iter) is fine for short tasks but truncates deep refactors and multi-step research. Raise max_steps to 50–100 for those.
Check agent.last_stop_reason == "max_steps" instead of parsing the answer text. The old magic "Tool call limit reached" string is now suppressed when a genuine final answer exists.
max_steps and max_tool_calls_per_turn govern different things — a per-turn cap of 5 does not halve your step budget. Coupling them would let one parallel-tool response exhaust the whole budget.
max_steps must be >= 1 when set, otherwise ExecutionConfig raises ValueError. Catch it in config-driven setups.

Execution

Iteration limits, retries, rate limiting, and code execution

Error Handling

Catch and recover from agent, tool, and LLM errors