Why does my LangChain agent keep calling the same tool?
Rius shows a repeated tool call as consecutive tool spans with identical arguments inside one trace, and its Tool Loop alert fires on three or more identical calls in a row. Open the trace, find the collapsed row of repeated calls, and read the input and output of each attempt to see why the agent never stops. The spans tell you what the tool returned each time. Your own prompt and tool code decide why the model asks again.
How it works
The LangChain integration records one span per step. Tool invocations arrive as tool spans, model calls as LLM spans with model, tokens and messages, and the nesting follows your chain or graph. A loop therefore appears as the same tool span repeated under the same parent, with an LLM span between the repeats.
The pre-defined Tool Loop alert reads those spans. It fires when the same tool is called with identical parameters at least the configured number of times in a row inside a single trace. The defaults are:
- Identical calls: at least 3, and 3 is also the minimum.
- Time window: 10 minutes.
- Renotify: off, so the notification is sent once.
Calls count as identical when the tool name and normalized arguments match. At most one other tool call may sit between neighboring repeats, so a tool the agent returns to after other work is not a loop. It fires once per trace and tool.
The alert’s documented causes are an agent repeating the same search because no result satisfies its stop condition, a broken tool schema where the model retries the identical call expecting a different outcome, and a planner and executor cycling on the same lookup. Use these as your first hypotheses.
Set it up
- Make sure the LangChain integration is on. It hooks LangChain’s callback system, so chains, agents and LangGraph nodes are traced. The LangChain integration page has the full setup, and Integrations covers how integrations are enabled.
pip install "glassflow-rius[langchain]" langchainimport rius
rius.init(api_key="ri_...", service_name="my-agent")
# build and run your chains exactly as before-
Find the run. In Traces, open the run that looped. Or open the Spans tab, use the All kinds menu to pick Tool, and sort by Time or Duration to see the same tool name over and over.
-
Find the repeats. If the calls ran back to back, they collapse into one row with an attempt count, such as
fetch_article · 3 attempts. Expand it to see each attempt. When an LLM call sits between them, they stay separate rows, so filter the Spans tab to Tool. -
Compare the attempts. Select each tool span and read the Input / Output tab. Identical arguments with identical results mean the agent got nothing new and asked again. Look at what the tool returned: an error, an empty result, or output the model cannot use are the usual reasons it tries again.
-
Read what the model saw in between. Select the LLM span after each tool span and switch Since previous llm call on. It marks what was added to the prompt, so you can check whether the tool result was added at all and whether the system prompt changed. The context growth strip above the tree plots input tokens per call, and a loop shows up as steady growth.
-
Check the alert. Open Tool Loop under pre-defined alerts and confirm it is not disabled. Attach a channel (webhook, email or Slack) so the next loop reaches you. See Pre-defined alerts for the knobs.
Tool Loop only counts calls whose arguments were captured. With content capture off, arguments are not recorded and those calls are never counted as identical, so the alert stays quiet.
What you get
- A trace that shows the loop as one row of repeated attempts, with each call’s arguments and result a click away.
- The prompt changes between calls, through the input comparison on each LLM span, so you can tell a stuck stop condition from a tool result that never reached the model.
- Token and cost totals for the run, so you can see what the loop spent. Costs are list-price estimates in US dollars.
- Compare runs, which sets the looping trace against another run of the same agent so you can see which steps were added or dropped.
- A Tool Loop firing, with its history, the next time an agent repeats identical calls. For the wider workflow around traces and alerts, see Monitor AI agents in production, and for the trace views used above see Exploring traces.
When something else fits
- If the repeated calls have slightly different arguments each time, or two or more other tool calls sit between them, Tool Loop does not fire. Read the trace directly in the Spans tab and the retry rows instead.
- If the tool fails with the same error across many runs, the Consistent Error Pattern alert is the better catch.
- If you want a bar on cost, tokens or LLM calls per run, a custom alert covers that.