Jump to content

Connect Leeroopedia MCP: Equip your AI agents to search best practices, build plans, verify code, diagnose failures, and look up hyperparameter defaults.

Implementation:Anthropics Anthropic sdk python Beta Tool Decorator

From Leeroopedia
Knowledge Sources
Domains Tool_Use, LLM, Function_Calling
Last Updated 2026-02-15 00:00 GMT

Overview

The beta_tool decorator converts a Python function into a BetaFunctionTool with automatic JSON Schema inference from type annotations, docstring extraction, and Pydantic-based input validation. It supports both bare (@beta_tool) and parameterized (@beta_tool(name=...)) usage patterns.

API Signature

def beta_tool(
    func: FunctionT | None = None,
    *,
    name: str | None = None,
    description: str | None = None,
    input_schema: InputSchema | type[BaseModel] | None = None,
    defer_loading: bool | None = None,
) -> BetaFunctionTool[FunctionT] | Callable[[FunctionT], BetaFunctionTool[FunctionT]]

Source Location

File: src/anthropic/lib/tools/_beta_functions.py, lines 205-265

Import

from anthropic import beta_tool

Parameters

Parameter Type Default Description
func None None The function to wrap. Provided implicitly when using bare @beta_tool syntax.
name None None Override the tool name. Defaults to func.__name__.
description None None Override the tool description. Defaults to the docstring's short + long description.
input_schema type[BaseModel] | None None Override the input schema. Can be a JSON Schema dict or a Pydantic BaseModel class. Defaults to auto-inference from type hints.
defer_loading None None When set, adds defer_loading to the tool definition sent to the API.

Return Value

Returns a BetaFunctionTool[FunctionT] instance (when func is provided) or a Callable[[FunctionT], BetaFunctionTool[FunctionT]] decorator (when called with keyword arguments only).

The BetaFunctionTool class provides:

Method/Property Type Description
.to_dict() BetaToolParam Produces the API-ready tool definition dict with name, description, and input_schema
.call(input) BetaFunctionToolResultType Executes the wrapped function with validated input
.name str The tool's name
.description str The tool's description
.input_schema InputSchema The JSON Schema dict for the tool's parameters
.func FunctionT Reference to the original wrapped function

Overload Variants

The function uses three @overload signatures (lines 205-226):

# Bare decorator: @beta_tool
@overload
def beta_tool(func: FunctionT) -> BetaFunctionTool[FunctionT]: ...

# Direct call with func: beta_tool(my_func, name="custom")
@overload
def beta_tool(
    func: FunctionT,
    *,
    name: str | None = None,
    description: str | None = None,
    input_schema: InputSchema | type[BaseModel] | None = None,
) -> BetaFunctionTool[FunctionT]: ...

# Parameterized decorator: @beta_tool(name="custom")
@overload
def beta_tool(
    *,
    name: str | None = None,
    description: str | None = None,
    input_schema: InputSchema | type[BaseModel] | None = None,
    defer_loading: bool | None = None,
) -> Callable[[FunctionT], BetaFunctionTool[FunctionT]]: ...

Auto-Inference Pipeline

When defaults are used, the tool metadata is inferred as follows:

Name: From func.__name__ (line 88):

self.name = name or func.__name__

Description: From the docstring via docstring_parser (lines 119-126):

def _get_description_from_docstring(self) -> str:
    if self._parsed_docstring.short_description:
        description = self._parsed_docstring.short_description
        if self._parsed_docstring.long_description:
            description += f"\n\n{self._parsed_docstring.long_description}"
        return description
    return ""

Schema: Via Pydantic TypeAdapter with a custom GenerateJsonSchema subclass that enriches property descriptions from docstring Args: sections (lines 128-170).

Usage Examples

Bare decorator (all metadata inferred):

from anthropic import beta_tool

@beta_tool
def get_weather(city: str, unit: str = "celsius") -> str:
    """Get the current weather for a city.

    Args:
        city: The city name
        unit: Temperature unit (celsius or fahrenheit)
    """
    return f"The weather in {city} is 22 degrees {unit}"

Parameterized decorator:

@beta_tool(name="weather_lookup", description="Fetch current weather data")
def get_weather(city: str) -> str:
    return f"The weather in {city} is 22 degrees"

Using the tool object:

# Get the API-ready dict
tool_dict = get_weather.to_dict()
# {'name': 'get_weather', 'description': 'Get the current weather...', 'input_schema': {...}}

# Pass to messages.create
message = client.messages.create(
    model="claude-sonnet-4-20250514",
    max_tokens=1024,
    tools=[get_weather.to_dict()],
    messages=[{"role": "user", "content": "What's the weather in London?"}]
)

Async Variant

For asynchronous functions, use beta_async_tool (lines 268-337):

from anthropic import beta_async_tool

@beta_async_tool
async def get_weather(city: str) -> str:
    """Get the current weather for a city."""
    async with httpx.AsyncClient() as client:
        resp = await client.get(f"https://weather.example.com/{city}")
        return resp.text

This returns a BetaAsyncFunctionTool whose .call() method is a coroutine.

Dependencies

  • pydantic (v2 required): validate_call, TypeAdapter, BaseModel, GenerateJsonSchema
  • docstring_parser: Parses Google/NumPy/reStructuredText docstring formats to extract parameter descriptions
  • typing_extensions: For TypeAlias, override

Error Conditions

Error Condition
RuntimeError("Tool functions are only supported with Pydantic v2") Raised at decoration time if Pydantic v1 is installed
ValueError("Invalid arguments for function {name}") Raised by .call() when input fails Pydantic validation
TypeError("Input must be a dictionary, got {type}") Raised by .call() when input is not a dict
RuntimeError("Cannot call a coroutine function synchronously...") Raised by BetaFunctionTool.call() when the wrapped function is async

Related Pages

Implements Principle

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment