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
Next up: 15 — Parallel Tool Calls