Skip to content

Python Tools

There are two approaches to defining python-based tools in Strands:

  • Python functions with the @tool decorator: Transform regular Python functions into tools by adding a simple decorator. This approach leverages Python's docstrings and type hints to automatically generate tool specifications.

  • Python modules following a specific format: Define tools by creating Python modules that contain a tool specification and a matching function. This approach gives you more control over the tool's definition and is useful for dependency-free implementations of tools.

Python Tool Decorators

The @tool decorator provides a straightforward way to transform regular Python functions into tools that agents can use.

Basic Example

Here's a simple example of a function decorated as a tool:

from strands import tool

@tool
def weather_forecast(city: str, days: int = 3) -> str:
    """Get weather forecast for a city.

    Args:
        city: The name of the city
        days: Number of days for the forecast
    """
    return f"Weather forecast for {city} for the next {days} days..."

The decorator extracts information from your function's docstring to create the tool specification. The first paragraph becomes the tool's description, and the "Args" section provides parameter descriptions. These are combined with the function's type hints to create a complete tool specification.

Loading Function-Decorated tools

To use function based tool, simply pass the function to the agent:

agent = Agent(
    tools=[weather_forecast]
)

Overriding Tool Name and Description

You can also optionally override the tool name or description by providing them as arguments to the decorator:

@tool(name="get_weather", description="Retrieves weather forecast for a specified location")
def weather_forecast(city: str, days: int = 3) -> str:
    """Implementation function for weather forecasting.

    Args:
        city: The name of the city
        days: Number of days for the forecast
    """
    # Implementation
    return f"Weather forecast for {city} for the next {days} days..."

Dictionary Return Type

By default, your function's return value is automatically formatted as a text response. However, if you need more control over the response format, you can return a dictionary with a specific structure:

@tool
def fetch_data(source_id: str) -> dict:
    """Fetch data from a specified source.

    Args:
        source_id: Identifier for the data source
    """
    try:
        data = some_other_function(source_id)
        return {
            "status": "success",
            "content": [ {
                "json": data,
            }]
        }
    except Exception as e:
        return {
            "status": "error",
             "content": [
                {"text": f"Error:{e}"}
            ]
        }

For more details, see the Tool Response Format section below.

Python Modules as Tools

An alternative approach is to define a tool as a Python module with a specific structure. This enables creating tools that don't depend on the SDK directly.

A Python module tool requires two key components:

  1. A TOOL_SPEC variable that defines the tool's name, description, and input schema
  2. A function with the same name as specified in the tool spec that implements the tool's functionality

Basic Example

Here's how you would implement the same weather forecast tool as a module:

# weather_forecast.py

# 1. Tool Specification
TOOL_SPEC = {
    "name": "weather_forecast",
    "description": "Get weather forecast for a city.",
    "inputSchema": {
        "json": {
            "type": "object",
            "properties": {
                "city": {
                    "type": "string",
                    "description": "The name of the city"
                },
                "days": {
                    "type": "integer",
                    "description": "Number of days for the forecast",
                    "default": 3
                }
            },
            "required": ["city"]
        }
    }
}

# 2. Tool Function
def weather_forecast(tool, **kwargs: Any):
    # Extract tool parameters
    tool_use_id = tool["toolUseId"]
    tool_input = tool["input"]

    # Get parameter values
    city = tool_input.get("city", "")
    days = tool_input.get("days", 3)

    # Tool implementation
    result = f"Weather forecast for {city} for the next {days} days..."

    # Return structured response
    return {
        "toolUseId": tool_use_id,
        "status": "success",
        "content": [{"text": result}]
    }

Loading Module Tools

To use a module-based tool, import the module and pass it to the agent:

from strands import Agent
import weather_forecast

agent = Agent(
    tools=[weather_forecast]
)

Alternatively, you can load a tool by passing in a path:

from strands import Agent

agent = Agent(
    tools=["./weather_forecast.py"]
)

Tool Response Format

Tools can return responses in various formats using the ToolResult structure. This structure provides flexibility for returning different types of content while maintaining a consistent interface.

ToolResult Structure

The ToolResult dictionary has the following structure:

{
    "toolUseId": str,       # The ID of the tool use request (should match the incoming request).  Optional
    "status": str,          # Either "success" or "error"
    "content": List[dict]   # A list of content items with different possible formats
}

Content Types

The content field is a list of dictionaries, where each dictionary can contain one of the following keys:

  • text: A string containing text output
  • json: Any JSON-serializable data structure
  • image: An image object with format and source
  • document: A document object with format, name, and source

Success Response Example

{
    "toolUseId": "tool-123",
    "status": "success",
    "content": [
        {"text": "Operation completed successfully"},
        {"json": {"results": [1, 2, 3], "total": 3}}
    ]
}

Error Response Example

{
    "toolUseId": "tool-123",
    "status": "error",
    "content": [
        {"text": "Error: Unable to process request due to invalid parameters"}
    ]
}

Automatic Conversion

When using the @tool decorator, your function's return value is automatically converted to a proper ToolResult:

  1. If you return a string or other simple value, it's wrapped as {"text": str(result)}
  2. If you return a dictionary with the proper ToolResult structure, it's used directly
  3. If an exception occurs, it's converted to an error response