Loop Lifecycle

  1. Init — Load system prompt, tools, memory, and config
  2. Observe — Receive user input or previous tool result
  3. Think — LLM generates a Thought and decides next action
  4. Act — Execute the selected tool (or produce a final answer)
  5. Check — Test termination conditions (done? max_steps? budget?)
  6. Repeat — Return to Observe with the tool result as new input

Step and Budget Limits

agent:
  max_steps: 20                          # Hard stop after 20 steps
  max_tokens_total: 100000               # Stop if total tokens exceed 100k
  max_wall_time_seconds: 120             # Stop after 2 minutes
  max_cost_usd: 0.50                     # Stop if estimated cost exceeds $0.50
  on_limit_reached: "return_partial"     # return_partial | raise | retry

Loop Detection

An agent can get stuck in a loop — calling the same tool with the same args repeatedly. OpenClaw uses a hash-based similarity check to detect and break loops automatically.

agent:
  loop_detection:
    enabled: true
    window: 4             # Check last 4 steps for repetition
    similarity: 0.95      # Trigger if similarity > 95%
    action: "inject_hint" # inject_hint | abort | ask_user

Pause and Resume

For long-running agents or human-in-the-loop workflows, you can pause execution and resume later:

from openclaw import Agent

agent = Agent(model="gpt-4o", tools=["web_search", "code_exec"])
session = agent.start("Analyse the top 10 open-source LLM frameworks")

# Pause mid-run and serialise state
checkpoint = session.pause()
checkpoint.save(".openclaw/checkpoint.json")

# Later: restore from checkpoint
from openclaw import AgentSession
restored = AgentSession.load(".openclaw/checkpoint.json")
result = restored.resume()

Streaming Intermediate Steps

agent = Agent(model="gpt-4o", tools=["web_search"])

for step in agent.stream("Compare React and Vue in 2025"):
    if step.type == "thought":
        print(f"[Thinking] {step.content}")
    elif step.type == "tool_call":
        print(f"[Tool] {step.tool_name}({step.args})")
    elif step.type == "observation":
        print(f"[Result] {step.content[:200]}...")
    elif step.type == "final":
        print(f"\n[Done]\n{step.content}")

Lifecycle Hooks

from openclaw import Agent

def on_step_start(step_num, thought):
    print(f"Step {step_num} starting: {thought[:80]}")

def on_step_end(step_num, tool_name, result):
    print(f"Step {step_num} done: {tool_name} returned {len(result)} chars")

def on_complete(result):
    print(f"Agent finished in {result.steps_taken} steps, "
          f"cost ${result.usage.estimated_cost_usd:.4f}")

agent = Agent(
    model="gpt-4o",
    tools=["web_search"],
    hooks={
        "on_step_start": on_step_start,
        "on_step_end": on_step_end,
        "on_complete": on_complete,
    },
)

Debugging a Stuck Loop

If an agent keeps repeating the same step, check:

  • The tool is returning an error the agent doesn't understand
  • The system prompt doesn't tell the agent when to stop
  • The model is not recognising the final answer state

Enable verbose mode and inspect the trace: Agent(verbose=True, return_trace=True). The trace shows every thought and tool call in sequence.

Key takeaways:
  • Every agent run is a loop: observe → think → act → check → repeat.
  • Always set max_steps and max_cost_usd to cap runaway agents.
  • Use agent.stream() to show real-time progress in production UIs.
  • Lifecycle hooks let you log, audit, or modify behaviour at each step boundary.
  • Enable loop_detection to automatically catch agents stuck in repetition.

Advanced Loop Patterns

Beyond the basic Thought → Action → Observation cycle, OpenClaw supports several extended loop patterns for complex workflows:

  • Nested loops. An outer orchestrator agent spawns sub-agents for specific tasks. Each sub-agent runs its own loop and returns a result to the parent. Use agent.spawn_subagent() to create a nested execution context.
  • Parallel step execution. When a planning step identifies independent tasks (e.g., "fetch from API A" and "fetch from API B"), OpenClaw can execute them concurrently using asyncio.gather under the hood, reducing total latency.
  • Reflective loops. After task completion, a reflection step reviews the output for errors or missed requirements before returning to the caller. Enable with enable_reflection=True in the agent config.
from openclaw import Agent

agent = Agent(
    model="gpt-4o",
    max_steps=20,
    loop_detection=True,
    loop_detection_window=5,   # flag if same action repeats 5x
    enable_reflection=True,
    reflection_prompt="Review your answer. Is it complete and correct?",
)