---
title: "Adding Tools"
description: "Give your agents the ability to interact with the outside world through automatic schema generation, parameter validation, and concurrent execution"
---

## Basic Usage

Add tools to agents as functions or `Tool` objects:

```python
def get_weather(location: str) -> str:
    """Get weather for a location."""
    return f"Weather in {location}: 22°C"

agent = Agent(
    name="weather_agent",
    model="openai/gpt-4o-mini",
    tools=[get_weather]  # Function automatically becomes a tool
)
```

## Tool Configuration

Use `Tool` for custom descriptions and parameter control:

```python
from timbal import Tool

# Custom description - helpful when function name isn't clear enough
Tool(
    handler=get_weather,
    description="Get current weather information for any location"
)
```

When a tool has many parameters, use `schema_params_mode="required"` to reduce tokens and avoid overwhelming the LLM with unnecessary options:

```python
Tool(
    handler=search,
    schema_params_mode="required"  # Only show required params (default: "all")
)
```

You can also include or exclude specific parameters to fine-tune what the LLM sees:

```python
# Include extra parameters even in "required" mode
Tool(
    handler=search_function,
    schema_params_mode="required",
    schema_include_params=["model"]  # Include this optional param
)

# Exclude sensitive or internal parameters
Tool(
    handler=api_function,
    schema_exclude_params=["api_key", "debug_mode"]  # Hide from LLM
)
```

Set default values that are automatically applied when the tool is called:

```python
Tool(
    handler=database_query,
    default_params={
        "timeout": 30
    }  # These values are used when not specified by the LLM
)
```

You can also use functions or environment variables as default parameters:

```python
def get_current_timestamp():
    return datetime.now().isoformat()

def process_data(data: str, timestamp: str | None = None, user_id: str = "default"):
    return f"Processed {data} at {timestamp} by {user_id}"

# Tool with dynamic default parameters
tool = Tool(
    name="data_processor",
    handler=process_data,
    default_params={
        "timestamp": get_current_timestamp,
        "user_id": "system_user"
    }
)
```

## Agent as a Tool

You can use an Agent as a tool within another Agent, enabling hierarchical agent compositions where specialized agents handle specific tasks.

Since `Agent` instances can be treated as `Tool` objects, they inherit the same parameter control configurations available to regular tools.

```python
from timbal import Agent

def calculate_cost(days: int, hotel_rate: float, flights: float = 0) -> float:
    """Calculate total trip cost."""
    return (days * hotel_rate) + flights

# Pricing specialist agent
pricing_agent = Agent(
    name="pricing_calculator",
    description="Calculate travel costs",  # Tool description for other agents
    model="openai/gpt-4o-mini",
    system_prompt="Answer only with the price. Any text",
    tools=[calculate_cost]
)

# Main travel agent
travel_agent = Agent(
    name="travel_assistant", 
    model="openai/gpt-4o",
    system_prompt="Help plan trips and provide travel advice.",
    tools=[pricing_agent]
)
```

## Summary

- **Automatic Introspection**: Function signatures become tool schemas automatically
- **Enhanced Validation**: Pydantic-based parameter validation
- **Execution Flexibility**: Support for all Python callable types
- **Better Configuration**: Fine-grained parameter control
- **Performance**: Concurrent execution and optimized patterns
- **Robustness**: Improved error handling and tracing

For more advanced patterns, see the [Integrations](/integrations) and explore the built-in tools in the Timbal library!
