Implementation:Microsoft Agent framework Tool Decorator
Template:Microsoft Agent framework Sidebar
Overview
The Tool Decorator (@tool) is the primary mechanism in the Microsoft Agent Framework for converting a plain Python function into a FunctionTool instance that an LLM agent can invoke. It handles JSON schema generation from type annotations, argument deserialization, and supports both synchronous and asynchronous functions.
| Property | Value |
|---|---|
| Source | python/packages/core/agent_framework/_tools.py (lines L903-1049)
|
| Import | from agent_framework import tool
|
| Inputs | A Python function (sync or async) with type-annotated parameters; optional name, description, schema overrides; approval_mode |
| Outputs | FunctionTool instance callable by LLM agent
|
| Related Principle | Function Tool Definition |
Code Reference
Full Signature
def tool(
func: Callable[..., ReturnT | Awaitable[ReturnT]] | None = None,
*,
name: str | None = None,
description: str | None = None,
schema: type[BaseModel] | Mapping[str, Any] | None = None,
approval_mode: Literal["always_require", "never_require"] | None = None,
max_invocations: int | None = None,
max_invocation_exceptions: int | None = None,
additional_properties: dict[str, Any] | None = None,
) -> FunctionTool[Any, ReturnT] | Callable[...]:
Source Location
python/packages/core/agent_framework/_tools.py, lines L903-1049. The decorator is defined as a top-level function that supports both @tool (no parentheses) and @tool(...) (with keyword arguments) usage patterns.
I/O Contract
Inputs
| Parameter | Type | Default | Description |
|---|---|---|---|
func |
Awaitable[ReturnT]] | None | None |
The Python function to wrap. When using @tool without parentheses, this is populated automatically.
|
name |
None | None |
Custom name for the tool. Defaults to the function's __name__.
|
description |
None | None |
Custom description. Defaults to the function's docstring. |
schema |
Mapping[str, Any] | None | None |
Explicit parameter schema. When None, the schema is generated automatically from the function's type annotations.
|
approval_mode |
None | None |
Controls whether tool execution requires human-in-the-loop approval. |
max_invocations |
None | None |
Maximum number of times the tool can be called in a single agent run. |
max_invocation_exceptions |
None | None |
Maximum number of exceptions allowed before the framework stops retrying. |
additional_properties |
None | None |
Arbitrary extra metadata attached to the tool definition. |
Outputs
The decorator returns a FunctionTool instance with the following key attributes:
| Field | Type | Description |
|---|---|---|
name |
str |
The tool name exposed to the LLM. |
description |
str |
The tool description shown to the LLM. |
params_json_schema |
dict[str, Any] |
The JSON schema for the tool's parameters, derived from type annotations. |
on_invoke |
Callable |
The callable that executes the tool given deserialized arguments. |
approval_mode |
None | Whether approval is required before execution. |
Description
The @tool decorator works through the following internal steps:
- Schema generation: Inspects the function's signature, type annotations, and docstring. Uses Pydantic to synthesize a JSON schema from the parameter types.
Annotated[type, Field(description=...)]metadata is extracted and included in the schema. - Invocation wrapper creation: Builds a callable that:
- Parses the JSON input string from the LLM into a dictionary.
- Validates the dictionary against the generated or provided schema.
- Converts validated data into positional and keyword arguments.
- Calls the original function (using
awaitfor async functions).
- FunctionTool construction: Assembles and returns a
FunctionToolinstance with all computed fields, including the JSON schema, tool name, description, and invocation handler.
The decorator supports a dual calling convention. When used as @tool (without parentheses), the func parameter receives the decorated function directly and the FunctionTool is returned immediately. When used as @tool(...) (with keyword arguments), it returns an intermediate decorator function that subsequently wraps the target function.
Examples
Basic Usage
from agent_framework import tool
from typing import Annotated
@tool
def get_weather(
location: Annotated[str, "The city and state"],
unit: Annotated[str, "celsius or fahrenheit"] = "celsius",
) -> str:
"""Get weather for a location."""
return f"Weather in {location}: 22 {unit}"
With Explicit Name and Description
from agent_framework import tool
@tool(name="custom_weather", description="Get weather data")
def another_func(location: str) -> str:
return f"Weather in {location}"
Async Function
from agent_framework import tool
@tool
async def async_get_weather(location: str) -> str:
"""Get weather asynchronously."""
return f"Weather in {location}"
Related Pages
- Principle:Microsoft_Agent_framework_Function_Tool_Definition
- Principle: Function Tool Definition -- the theoretical basis for function tool wrapping
- Heuristic:Microsoft_Agent_framework_Tool_Approval_Mode_Production
- Heuristic:Microsoft_Agent_framework_Function_Invocation_Defaults
- Heuristic:Microsoft_Agent_framework_Declaration_Only_Tools_Pattern