CrewAICrewAI 1.15 · Python 3.10 to 3.13
Dashboard
0%
1
Curious builder0 XP earned · 300 to level 2
0 daysFinish a lesson to begin
Badge collection0 of 6 unlocked
35 small wins to finish your pathNext lesson →

Tools: functions an agent can use

A tool is a Python function an agent can call, described by its name, docstring and argument schema; the model asks for it and CrewAI runs it.

Last updated: 28 Sep, 2026 · CrewAI 1.15

The plain-Python lesson's clerk looked orders up in a dictionary. That lookup becomes a tool, so an agent can use it from the tool-calls lesson on.

Turning a function into a tool

python
from crewai.tools import tool

ORDERS = {"A17": "shipped on 3 March", "C40": "waiting for stock"}


@tool
def lookup_order(order_id: str) -> str:
    """Look up an order's shipping status by its id, such as A17."""
    status = ORDERS.get(order_id)
    return f"{order_id} {status}." if status else f"{order_id} is not an order we have."

@tool from crewai.tools turns the function into a tool object. It takes the name from the function, the description from the docstring, and the argument types from the type hints.

What the model is told about a tool

Example
from tools import lookup_order

print(lookup_order.name)
print(lookup_order.description)
print(lookup_order.args_schema.model_json_schema()["properties"])

This is everything a model learns about the tool. The docstring is how it decides when to use it, so it says what the tool does and what an order id looks like. The schema says to send one string called order_id.

Running a tool yourself

Example
from tools import lookup_order

print(lookup_order.run(order_id="A17"))
print(lookup_order.run(order_id="B22"))

run calls the function with keyword arguments, the way CrewAI will. B22 is not in the dictionary, so the tool says so in words a model can pass on.

A tool without a docstring

Example
from crewai.tools import tool


@tool
def lookup_order(order_id: str) -> str:
    return "unknown"

A tool with no description is refused when it is defined. Without one, a model would have nothing to decide with.

Save tools.py. The tool-calls lesson gives the tool to an agent, and the tool-hooks lesson adds a second tool to the file.

Reading what a tool exposes

  • Name, description and schema are all the model gets; it never sees the function body.
  • run calls the function with keyword arguments, the way CrewAI will call it.
  • A tool with no docstring is refused at definition, not at run time.

Where each part of a tool comes from

PartSource
namethe function name
descriptionthe docstring
argument schemathe type hints

When an agent needs a tool

  • It has to look something up that is not in the prompt, such as an order status.
  • It has to take an action with an effect, such as sending a refund.
  • It has to call an API or a database the model cannot reach on its own.
Watch out
The docstring is the model's only guide to when a tool applies. A vague one gets the tool called at the wrong time, or not at all.
Try it yourself
  • Pass a name, @tool("Order lookup"), and print lookup_order.name.
  • Add a second argument, customer: str, and print the schema again.
  • Remove the type hint from order_id and print the schema.

Slow is fine. Stopping is the only problem.