CrewAI Tutorial (Python): building custom tools for beginners
This tutorial shows you how to build a custom CrewAI tool in Python, wire it into an agent, and verify that the agent can call it correctly. You need this when the built-in tools are not enough and your agent has to reach into your own systems, APIs, or business logic.
What You'll Need
- •Python 3.10 or newer
- •
crewai - •
crewai-tools - •
python-dotenv - •An OpenAI API key set as
OPENAI_API_KEY - •A working virtual environment
- •Basic familiarity with CrewAI agents, tasks, and crews
Step-by-Step
- •Start by installing the packages and setting up your environment. Keep this isolated so you can test tools without polluting a shared Python install.
python -m venv .venv
source .venv/bin/activate
pip install crewai crewai-tools python-dotenv
- •Create a small custom tool by subclassing
BaseTool. The key thing here is defining thename,description, and_runmethod clearly so the model knows when to use it.
from typing import Type
from pydantic import BaseModel, Field
from crewai_tools import BaseTool
class PolicyLookupInput(BaseModel):
policy_id: str = Field(..., description="The policy ID to look up")
class PolicyLookupTool(BaseTool):
name: str = "policy_lookup"
description: str = "Look up a policy by policy ID and return its status."
args_schema: Type[BaseModel] = PolicyLookupInput
def _run(self, policy_id: str) -> str:
mock_db = {
"POL-1001": "Policy POL-1001 is active and premium is up to date.",
"POL-1002": "Policy POL-1002 is lapsed due to missed payment.",
}
return mock_db.get(policy_id, f"No policy found for {policy_id}.")
- •Load your API key and create an agent that can use the tool. For beginners, keep the goal narrow so you can see exactly when the tool gets called.
import os
from dotenv import load_dotenv
from crewai import Agent
load_dotenv()
policy_tool = PolicyLookupTool()
agent = Agent(
role="Insurance support assistant",
goal="Answer policy questions using available tools.",
backstory="You help customer service teams check policy status quickly.",
tools=[policy_tool],
verbose=True,
)
- •Add a task that forces the agent to use the tool instead of guessing. This is where most beginner setups go wrong: if the task is too vague, the model may answer from memory instead of calling your tool.
from crewai import Task
task = Task(
description="Check the status of policy POL-1001 and explain it in one sentence.",
expected_output="A short customer-friendly policy status response.",
agent=agent,
)
- •Run the crew and print the result. If everything is wired correctly, CrewAI will call your custom tool during execution and return a response based on its output.
from crewai import Crew, Process
crew = Crew(
agents=[agent],
tasks=[task],
process=Process.sequential,
verbose=True,
)
result = crew.kickoff()
print(result)
- •If you want a more realistic pattern, move the lookup logic behind a function that talks to your own service later. The tool interface stays the same, so you can swap mock data for an internal API without changing your agent setup.
def lookup_policy_from_service(policy_id: str) -> str:
# Replace this with requests.get(...) or your internal SDK call.
return f"Policy {policy_id} is active."
class LivePolicyLookupTool(BaseTool):
name: str = "live_policy_lookup"
description: str = "Fetch live policy details from the internal policy system."
args_schema: Type[BaseModel] = PolicyLookupInput
def _run(self, policy_id: str) -> str:
return lookup_policy_from_service(policy_id)
Testing It
Run the script from your terminal and watch the verbose output. You should see the agent deciding whether to use policy_lookup, then returning a response based on the tool output rather than inventing one.
Test at least two inputs: one known ID like POL-1001 and one unknown ID like POL-9999. That confirms both the happy path and fallback behavior work.
If you are not seeing tool calls, tighten the task wording so it explicitly requires using the tool. Also confirm verbose=True is set on both the agent and crew so you can inspect execution.
Next Steps
- •Add input validation rules to your
args_schemafor stricter production behavior - •Replace mock data with real API calls using
requestsor your internal SDK - •Learn how to chain multiple tools in one agent for claims, billing, and customer support workflows
Keep learning
- •The complete AI Agents Roadmap — my full 8-step breakdown
- •Free: The AI Agent Starter Kit — PDF checklist + starter code
- •Work with me — I build AI for banks and insurance companies
By Cyprian Aarons, AI Consultant at Topiax.
Want the complete 8-step roadmap?
Grab the free AI Agent Starter Kit — architecture templates, compliance checklists, and a 7-email deep-dive course.
Get the Starter Kit