Tool registry pattern in Python
You want your agent to pick between multiple tools at run time; a tool registry is a clean way to do this.
At its core, a tool registry is just a mapping from a tool name the model uses in text (like "search_web") to a callable function plus metadata your code understands.
Basic structure
Use a dict where keys are tool names (strings) and values are objects holding:
- The Python function to call
- A human-readable description
- Optional metadata: argument schema, risk level, etc.
from typing import Callable, Dict, Any
class Tool:
def __init__(self, func: Callable, description: str, risky: bool = False):
self.func = func
self.description = description
self.risky = risky
# Example tool functions
def add_numbers(a: float, b: float) -> float:
return a + b
def reverse_text(text: str) -> str:
return text[::-1]
# Registry
TOOLS: Dict[str, Tool] = {
"add_numbers": Tool(
func=add_numbers,
description="Add two numbers and return the sum"
),
"reverse_text": Tool(
func=reverse_text,
description="Reverse the given text"
),
}
The model chooses between tools by name. Your prompt tells it:
- What tools exist
- What each tool does
- How to call them (the format you expect)
Example tool section in the prompt:
textYou can use these tools:
1. add_numbers(a, b)
Use this to add two numbers.
2. reverse_text(text)
Use this to reverse a piece of text.
When you want to use a tool, answer in this exact JSON:
{"tool": "tool_name", "args": { ... }}
At run time:
- The model responds with a JSON specifying
"tool": "add_numbers"or"reverse_text". - Your code looks up that name in
TOOLS. - You call the appropriate function with the provided arguments.
import json
def run_tool_from_model_output(raw_output: str) -> Any:
data = json.loads(raw_output)
tool_name = data["tool"]
args = data.get("args", {})
if tool_name not in TOOLS:
raise ValueError(f"Unknown tool {tool_name}")
tool = TOOLS[tool_name]
return tool.func(**args)
This design supports at least two tools and scales easily: new tool → new function + new Tool entry, without changing the core loop.
Keep tool names short, unambiguous, and stable; changing names later breaks older prompts or logs.
1 / 5