Skip to content

Running tools

Watch it run · 1 of 3

From name to function

1def add(a, b):
2 return a + b
3
4def shout(text):
5 return text.upper() + "!"
6
7TOOLS = {"add": add, "shout": shout}
8
9call = {"name": "shout", "input": {"text": "agents"}}
10fn = TOOLS[call["name"]]
11result = fn(**call["input"])
12print(result)

Output

(nothing yet)

line 7A dict from tool names to the Python functions that do the work.

step 1 of 5
Read this lesson as text

A dispatch table turns a tool name into a function call. Errors become results, not crashes.

From name to function

def add(a, b):
    return a + b

def shout(text):
    return text.upper() + "!"

TOOLS = {"add": add, "shout": shout}

call = {"name": "shout", "input": {"text": "agents"}}
fn = TOOLS[call["name"]]
result = fn(**call["input"])
print(result)
  1. Line 7: A dict from tool names to the Python functions that do the work.
  2. Line 9: What a tool_use block asks for: a name and its arguments.
  3. Line 10: Look the function up by name.
  4. Line 11: `**` spreads the input dict into keyword arguments: `shout(text="agents")`.
  5. Line 12: That result is what goes back to the model.

Tools fail. Agents shouldn't.

The model can ask for a tool that doesn't exist, or pass arguments that make it crash (dividing by zero, a missing file).

Never let that crash your agent. Catch the error and send it back as the tool's result, marked as an error. The model reads division by zero and tries something else, the way a person would.

Exercise: A dispatcher that never crashes

Tools: add(a, b), divide(a, b) and shout(text) (upper-case plus !).

Input: n, then n tool calls, one JSON object per line: {"id": ..., "name": ..., "input": {...}}.

For each call print id: result. If the tool doesn't exist print id: ERROR unknown tool <name>; if it raises, print id: ERROR <the error message>.