Session 5· 14· 20 min
Tool-Call Loop with Generic Router
What you'll learn
- ▸Build a while-loop that keeps calling the model until it stops requesting tools
- ▸Route tool calls dynamically by function name
- ▸Handle multi-round conversations that need several tools
Real agents loop. The model may need the weather AND an exchange rate AND a calendar lookup before it can answer. You build a while-loop: as long as the response contains tool_calls, run them, return the results, and call the API again. Exit when the model stops requesting tools.
Send messages
tool_calls?
yes
Run router
Append tool msgs
...repeat...
No tool_calls
Final answer
14_tool_call_loop_generic_router.py
def call_tool(name: str, args: dict) -> dict: ①
if name == "get_mock_weather":
return get_mock_weather(**args)
if name == "convert_currency":
return convert_currency(**args)
return {"error": f"Unknown tool: {name}"}
messages = [{"role": "user", "content": "Weather in Delhi and convert 15 USD to INR."}]
while True: ②
response = client.chat.completions.create(
model=model, messages=messages, tools=tools
)
msg = response.choices[0].message
messages.append(msg)
if not msg.tool_calls: ③
print(msg.content)
break
for call in msg.tool_calls: ④
args = json.loads(call.function.arguments)
result = call_tool(call.function.name, args)
messages.append({
"role": "tool",
"tool_call_id": call.id,
"content": json.dumps(result),
})①A generic router — a dict/if-chain that maps tool name to Python function.
②Loop forever until the model stops requesting tools.
③Exit condition: no tool_calls on the latest message.
④Process EVERY tool_call in the list (parallel case is free here).
$ python 14_tool_call_loop_generic_router.py
Always cap iterations
A bug in your tool could make the model keep retrying forever. In production, add "max_iterations = 5" and break out if the count is exceeded.
Code Check
What is the loop exit condition?
Recap — what you just learned
- ✓Agents loop: while the model wants tools, run them and feed results back
- ✓A router function maps tool name to Python function
- ✓Process EVERY tool_call per round (handles parallel calls for free)
- ✓Always cap iterations in production