CrewAI Tools Integration: Let Agents Search, Read, and Actually Do Work

2 min read

An agent without tools is like an engineer with plenty of theory but no keyboard.
Can talk a lot, but cannot ship.

Common built-in tools

Frequently used CrewAI tools include:

  • SerperDevTool: web search
  • FileReadTool: read files
  • FileWriterTool: write files
  • ScrapeWebsiteTool: scrape webpage content

Attach tools to an agent

from crewai import Agent
from crewai_tools import SerperDevTool
 
search_tool = SerperDevTool()
 
researcher = Agent(
    role="Researcher",
    goal="Find trustworthy sources about the topic",
    backstory="You validate facts before writing.",
    tools=[search_tool],
    allow_delegation=False,
    verbose=True,
)

💡 You can reuse the same search_tool across agents. No need to recreate it every time (DRY).

Minimal custom tool template

from crewai.tools import BaseTool
from pydantic import BaseModel, Field
 
class QueryInput(BaseModel):
    keyword: str = Field(description="Search keyword")
 
class KeywordTool(BaseTool):
    name: str = "Keyword Tool"
    description: str = "Return a short explanation for a keyword."
    args_schema: type[BaseModel] = QueryInput
 
    def _run(self, keyword: str) -> str:
        return f"Result for: {keyword}"

Four tool design rules

  1. Do one thing only: if it searches, do not also write files
  2. Be explicit: description should clearly state purpose and input
  3. Validate parameters: use Pydantic schema
  4. Return stable format: easier for downstream tasks to parse

Common errors

Symptom Cause Fix
Tool never called Task prompt does not explicitly require it Add explicit "use tool first" instruction in task
Bad parameter values args schema is unclear Add Field(description=...)
Hard-to-use output Free-form text too scattered Return fixed sections or JSON string

Next step

After tools, the next focus is output consistency.
Next post shows how to lock format with Pydantic:
👉 Structured Output with Pydantic