Skip to main content
Use the UI or Python SDK to compare healthy runs with agents that get stuck. Scripted agents make detection easy to reproduce; the ReAct scenarios use a real model to choose tool calls. Controlled scenarios fix the tool responses, not the model’s decisions. The four visual examples below connect what you see to actual Python SDK usage: exact repetition, semantic repetition, a healthy calculation, and an impossible search goal. The UI displays the SDK’s events, signals, decisions, and final verdict; you can inspect those messages directly in Python without starting the UI server. Start with local setup. Then choose a scenario in the UI, or run python main.py SCENARIO from the repository root.

Run the visual examples through the SDK

Use LoopGuard.stream() to inspect the same events, signals, and decisions shown in the UI. get_scenario() supplies a demo agent, detectors, and initial input. In your application, pass your own agent and input or use the callback integration. Run these snippets from the source checkout after installing the demo dependencies. They load the root .env just like the demo entry points. The exact example needs no credentials; check the requirements below before running the other three.

What each run needs

exact runs offline after dependency installation. Every other scenario can make provider calls. calc and trap include semantic detection, so model credentials alone are not enough when chat and embedding providers differ.

Exact loop

What happens: a scripted agent repeatedly searches for the weather in Paris; the tool always returns no results. Why it matters: repeated calls become suspicious when the results never change. Expected behavior: exact repetition accumulates, followed by stagnant-result evidence. The policy reaches STOP, and the graph turns red in the UI. This scenario uses LoopDetector and StallDetector, so its stop timing differs from the default callback example, which also includes ProgressDetector. Python SDK: run the same agent and detector mix, then inspect the evidence and policy decisions that the UI displays.
The repeated calls first produce warning evidence. Stagnant output then combines with repetition to reach a stop decision; the final done message has interrupted: True.
LoopGuard UI showing repeated weather searches, no-results observations, a red graph, and an interrupted verdict

A LoopGuard demo run showing identical searches and empty results ending in interruption.

Semantic loop

What happens: a scripted agent changes the search wording while pursuing the same intent. Every search still comes back empty. Why it matters: exact signatures differ even though the approach hasn’t changed. Expected behavior: semantic similarity and stagnant results provide evidence for stopping. The embedding provider affects similarity scores and timing. Python SDK: select the paraphrasing agent and its embedding-backed detector. The signal messages expose the similarity evidence behind the screenshot’s alert.
LoopGuard UI displaying a semantic-loop alert, stagnant results, and a stopped paraphrasing search agent

Semantic evidence catches repeated intent across different search phrases.

Controlled progress

What happens: the real agent checks a job while the controlled tool returns pending, processing, then completed with useful status details. Why it matters: the same status tool is useful when its output advances. Expected behavior: let the run finish. This scenario uses a looser exact-repeat threshold of four so three changing status calls don’t create an unnecessary warning.

Controlled 503 recovery

What happens: the tool returns 503 temporarily unavailable twice and then returns a success message. Why it matters: repetition alone is not a reason to stop. Allowing short retries lets the agent recover from a temporary failure. Expected behavior: retryable-failure evidence can warn, but should allow this short recovery sequence. The model still decides whether to issue the next call.

Controlled 401 failure

What happens: the controlled tool returns 401 unauthorized: token expired. Why it matters: repeating this request cannot repair the credential. Expected behavior: stop for the permanent failure. This demo deliberately sets the repeated-failure threshold to one, so the first observed auth failure can stop the run. The default live detector uses a threshold of two.

Controlled empty results

What happens: a real model keeps checking a tool that returns no results. Why it matters: the agent can change its wording without finding useful information. Expected behavior: repeated or similar actions combined with no progress should reach STOP. This scenario includes an embedding-backed detector, even though the tool responses are controlled.

Healthy calculation

What happens: a real agent uses the calculator for 4801 * 379 + 1234 and returns an answer. Why it matters: a normal successful tool call should finish without interruption. Expected behavior: useful output lets the run finish without a fatal loop alert. This is the healthy comparison for the stuck search runs. Python SDK: the real agent gets a useful result and finishes. Inspect the decision stream and expect interrupted: False in the final done message when the task succeeds. Check for error messages separately.
LoopGuard UI showing a calculator result, the agent's final answer, and a successful completion verdict

A calculation finishes with a useful tool result and no fatal loop alert.

Impossible goal

What happens: a real search agent is asked to find a reputable source confirming the false claim that the Great Wall is visible from the Moon with the unaided eye. Its goal encourages it to keep refining its search. Why it matters: an impossible goal can keep an agent searching after the evidence stops helping. Expected behavior: the run can build repeated-intent and no-progress evidence and be interrupted. Real search output and model choices vary; do not treat the recorded demo as a fixed step-count guarantee. Python SDK: the same stream lets your application inspect why the search becomes suspicious. A policy stop produces action: "stop" followed by a done message with interrupted: True and a reason.
A real search agent caught in a semantic loop while pursuing an impossible goal

A LoopGuard demo run showing repeated intent while searching for an impossible confirmation.

Troubleshoot a demo run · Understand the policy