Implementation:CrewAIInc CrewAI Tool Decorator And Classes
Overview
Concrete decorator, class, and factory methods for creating agent tools provided by the CrewAI framework.
Source Reference
- Repository: crewAIInc/crewAI
- Files:
lib/crewai/src/crewai/tools/base_tool.py-- Lines L476-555 (@tooldecorator), Lines L313-388 (Toolclass)lib/crewai/src/crewai/tools/structured_tool.py-- Lines L24-80 (CrewStructuredTool)
Signatures
@tool Decorator
@tool(*args, result_as_answer=False, max_usage_count=None) -> Tool
Transforms a plain Python function into a Tool instance. The function's name becomes the tool name, its docstring becomes the description, and its type annotations are used to generate the args schema automatically.
Tool Class
class Tool(BaseTool):
# Concrete tool produced by the @tool decorator
# Stores the decorated function and delegates _run() to it
...
CrewStructuredTool
CrewStructuredTool(
name: str,
description: str,
args_schema: type[BaseModel],
func: Callable,
result_as_answer: bool = False,
max_usage_count: int | None = None,
)
CrewStructuredTool.from_function Factory
CrewStructuredTool.from_function(
func: Callable,
name: str | None = None,
description: str | None = None,
args_schema: type[BaseModel] | None = None,
infer_schema: bool = True,
) -> CrewStructuredTool
Import
from crewai.tools import tool, BaseTool
from crewai.tools.structured_tool import CrewStructuredTool
How It Works
Approach 1: @tool Decorator
The @tool decorator inspects the decorated function to extract:
- Name from the function's
__name__attribute - Description from the function's
__doc__(docstring) - Args schema from the function's type annotations via
inspect.signature()
It then constructs a Tool instance (a concrete subclass of BaseTool) with these values. The _run() method of the resulting Tool delegates to the original function.
Approach 2: BaseTool Subclass
Developers create a class that inherits from BaseTool and explicitly set name, description, and args_schema as class attributes. The _run() abstract method must be implemented with the tool's logic. This approach supports tool-level state stored as additional Pydantic fields.
Approach 3: CrewStructuredTool.from_function Factory
The from_function() class method creates a CrewStructuredTool instance by combining:
- An explicit or inferred name (defaults to
func.__name__) - An explicit or inferred description (defaults to
func.__doc__) - An explicit or inferred args schema (inferred from type annotations when
infer_schema=True) - The function itself, stored and called during execution
Example
Using the @tool Decorator
from crewai.tools import tool
@tool
def search_web(query: str, max_results: int = 5) -> str:
"""Search the web for current information about a topic.
Use this when the agent needs up-to-date data."""
results = perform_search(query, max_results)
return "\n".join(results)
# search_web is now a Tool instance with:
# name = "search_web"
# description = "Search the web for current information..."
# args_schema = auto-generated from (query: str, max_results: int)
Using a BaseTool Subclass
from pydantic import BaseModel, Field
from crewai.tools import BaseTool
class FileReadArgs(BaseModel):
"""Arguments for reading a file."""
file_path: str = Field(description="Absolute path to the file to read")
encoding: str = Field(default="utf-8", description="File encoding")
class FileReadTool(BaseTool):
name: str = "read_file"
description: str = "Read the contents of a file from the local filesystem."
args_schema: type[BaseModel] = FileReadArgs
def _run(self, file_path: str, encoding: str = "utf-8") -> str:
with open(file_path, "r", encoding=encoding) as f:
return f.read()
file_reader = FileReadTool()
Using CrewStructuredTool.from_function
from crewai.tools.structured_tool import CrewStructuredTool
def calculate_price(base_price: float, tax_rate: float = 0.1) -> str:
"""Calculate the total price including tax."""
total = base_price * (1 + tax_rate)
return f"Total price: ${total:.2f}"
price_tool = CrewStructuredTool.from_function(
func=calculate_price,
name="calculate_price",
description="Calculate the total price of an item including tax.",
infer_schema=True,
)
Comparison
| Feature | @tool Decorator | BaseTool Subclass | from_function Factory |
|---|---|---|---|
| Lines of code | Fewest | Most | Medium |
| Auto-generated schema | Yes | No (explicit) | Yes (when infer_schema=True) |
| Custom state | No | Yes (Pydantic fields) | No |
| Dynamic creation | No | No | Yes |
| Description source | Docstring | Class attribute | Docstring or explicit |
Principle Link
Principle:CrewAIInc_CrewAI_Tool_Implementation
See Also
- Implementation:CrewAIInc_CrewAI_BaseTool_Schema -- The base class all tools inherit from
- Implementation:CrewAIInc_CrewAI_Tool_Assignment_Config -- How created tools are assigned to agents and tasks
- Implementation:CrewAIInc_CrewAI_CrewAI_Tools_Library -- Pre-built tools created using these patterns