1
Curious builder0 XP earned · 300 to level 2
0 daysFinish a lesson to begin
Badge collection0 of 6 unlocked
28 small wins to finish your pathNext lesson →
When the loop will not stop
A model that keeps asking for tools would go round forever. ADK counts the model calls, and you decide the limit.
An agent with nothing to stop it
def ping() -> dict:
"""Ping."""
return {"status": "success"}
agent = LlmAgent(
name="looper",
model=PretendModel(replies=[call("ping")]),
instruction="Keep going.",
tools=[ping],
)One scripted reply, which the stand-in repeats once the list runs out. That is exactly what a confused model does: ask for the same tool again and again.
Running it with a limit
from google.adk.agents.run_config import RunConfig
from google.adk.agents.invocation_context import LlmCallsLimitExceededError
runner = InMemoryRunner(agent=agent, app_name="demo")
session = await runner.session_service.create_session(app_name="demo", user_id="u1")
message = types.Content(role="user", parts=[types.Part(text="go")])RunConfig carries the settings for one run. The one that matters on day one is max_llm_calls.
steps = 0
try:
async for event in runner.run_async(user_id="u1", session_id=session.id,
new_message=message,
run_config=RunConfig(max_llm_calls=3)):
steps += 1
except LlmCallsLimitExceededError as error:
print("stopped:", error)
print("events before it stopped:", steps)Three calls in, the run was abandoned with an error that names the limit rather than going quiet or spending your money.
What to do when you see it
Raising the number is almost never the fix. The error says the agent cannot make progress, and a bigger limit only delays the same ending.
- Read the events. Which tool did it keep calling, and what did that tool keep returning?
- Look at the tool result. A tool that answers the wrong question makes the model try again.
- Look at the instruction. An agent told to keep checking until it is sure will keep checking.
| Setting on RunConfig | What it does |
|---|---|
max_llm_calls | How many model calls one run may make |
streaming_mode | Whether partial responses arrive as they are generated |
| Speech settings | For voice agents, which this course does not cover |
Especially when nobody is watching
Set a limit in anything that runs unattended. The default is generous enough to let a broken loop cost real money before anybody notices.
Try it yourself
- Give the model a second reply that answers in words and watch the run finish normally.
- Set the limit to 1 and read the error again.
Every expert started right here.