Low Code Custom Tools

Step-by-step guide for creating and implementing custom tools in PraisonAI, including examples and configuration instructions

python
from praisonaiagents import Agent, tool

@tool
def weather(city: str) -> str:
    """Return a short weather summary for a city."""
    return f"Sunny in {city}"

agent = Agent(name="Assistant", tools=[weather])
agent.start("What is the weather in London?")

The user asks in plain language; custom tools extend what the agent can do beyond built-ins.

Diagram

Input

Agent

Tool

Output

Diagram
Low Code Custom ToolsAgentUserLow Code Custom ToolsAgentUserRequestProcess requestResultResponse

Create Custom Tools

Quick Start

  1. Install
    bash
    pip install praisonaiagents
  2. Create a custom tool
    python
    from praisonaiagents import Agent
    
    def get_weather(city: str) -> str:
        return f'Weather in {city}: Sunny, 22 degrees'
    
    agent = Agent(
        name="WeatherAgent",
        instructions="Provide weather information using the weather tool.",
        tools=[get_weather],
    )
    
    agent.start("What is the weather in London?")

Step 1: Install the praisonai Package

First, you need to install the praisonai package. Open your terminal and run the following command:

bash
pip install praisonai

Step 2: Create the InternetSearchTool

Next, create a file named tools.py and add the following code to define the InternetSearchTool:

python
from duckduckgo_search import DDGS
from praisonai_tools import BaseTool

class InternetSearchTool(BaseTool):
    name: str = "Internet Search Tool"
    description: str = "Search Internet for relevant information based on a query or latest news"

    def _run(self, query: str):
        ddgs = DDGS()
        results = ddgs.text(keywords=query, region='wt-wt', safesearch='moderate', max_results=5)
        return results

Step 3: Define the Agent Configuration

Create a file named agents.yaml and add the following content to configure the agent:

yaml
framework: crewai
topic: research about the causes of lung disease
agents:  # Canonical: use 'agents' instead of 'roles'
  research_analyst:
    instructions:  # Canonical: use 'instructions' instead of 'backstory' Experienced in analyzing scientific data related to respiratory health.
    goal: Analyze data on lung diseases
    role: Research Analyst
    tasks:
      data_analysis:
        description: Gather and analyze data on the causes and risk factors of lung diseases.
        expected_output: Report detailing key findings on lung disease causes.
    tools:
    - InternetSearchTool

Step 4: Run the PraisonAI Tool

To run the PraisonAI tool, simply type the following command in your terminal:

bash
praisonai

If you want to run the AG2 framework (Formerly AutoGen), use:

bash
praisonai --framework autogen

Prerequisites

Ensure you have the duckduckgo_search package installed. If not, you can install it using:

bash
pip install duckduckgo_search

That’s it! You should now have the PraisonAI tool installed and configured.

Other information

TL;DR to Create a Custom Tool

bash
pip install praisonai duckduckgo-search
export OPENAI_API_KEY="Enter your API key"
praisonai --init research about the latest AI News and prepare a detailed report
  • Add - InternetSearchTool in the agents.yaml file in the tools section.
  • Create a file called tools.py and add this code tools.py
bash
praisonai

Pre-requisite to Create a Custom Tool

agents.yaml file should be present in the current directory.

If it doesn’t exist, create it by running the command praisonai --init research about the latest AI News and prepare a detailed report.

Step 1 to Create a Custom Tool

Create a file called tools.py in the same directory as the agents.yaml file.

python
# example tools.py
from duckduckgo_search import DDGS
from praisonai_tools import BaseTool

class InternetSearchTool(BaseTool):
    name: str = "InternetSearchTool"
    description: str = "Search Internet for relevant information based on a query or latest news"

    def _run(self, query: str):
        ddgs = DDGS()
        results = ddgs.text(keywords=query, region='wt-wt', safesearch='moderate', max_results=5)
        return results

Step 2 to Create a Custom Tool

Add the tool to the agents.yaml file as show below under the tools section - InternetSearchTool.

yaml
framework: crewai
topic: research about the latest AI News and prepare a detailed report
agents:  # Canonical: use 'agents' instead of 'roles'
  research_analyst:
    instructions:  # Canonical: use 'instructions' instead of 'backstory' Experienced in gathering and analyzing data related to AI news trends.
    goal: Analyze AI News trends
    role: Research Analyst
    tasks:
      gather_data:
        description: Conduct in-depth research on the latest AI News trends from reputable
          sources.
        expected_output: Comprehensive report on current AI News trends.
    tools:
    - InternetSearchTool

Python Code Custom Tools

For praisonaiagents package users, you can create custom tools using the @tool decorator or BaseTool class.

Using @tool Decorator

python
from praisonaiagents import Agent, tool

@tool
def search(query: str) -> str:
    """Search the web for information."""
    return f"Results for: {query}"

@tool
def add(a: float, b: float) -> float:
    """Add two numbers (safe — no eval)."""
    return a + b

agent = Agent(
    instructions="You are a helpful assistant",
    tools=[search, add]
)
agent.start("Search for AI news and add 15 and 4")

Using BaseTool Class

python
from praisonaiagents import Agent, BaseTool

class WeatherTool(BaseTool):
    name = "weather"
    description = "Get current weather for a location"

    def run(self, location: str) -> str:
        return f"Weather in {location}: 72°F, Sunny"

agent = Agent(
    instructions="You are a weather assistant",
    tools=[WeatherTool()]
)
agent.start("What's the weather in Paris?")

Expressive Parameter Types

Create tools with rich type annotations for better schema generation:

python
from typing import Optional, Literal
from praisonaiagents import Agent, tool

@tool
def configure_service(
    name: str,
    port: Optional[int] = None,
    mode: Literal["production", "development"] = "development"
) -> str:
    """Configure a service with optional port and mode."""
    config = f"Service '{name}' configured in {mode} mode"
    if port:
        config += f" on port {port}"
    return config

agent = Agent(
    instructions="You configure services",
    tools=[configure_service]
)
agent.start("Configure webapp in production mode with port 8080")

See the Tool Parameter Types page for complete guide.

Creating a Pip-Installable Tool Package

Create tools that auto-register when installed:

pyproject.toml

toml
[project]
name = "my-praisonai-tools"
version = "1.0.0"
dependencies = ["praisonaiagents"]

[project.entry-points."praisonaiagents.tools"]
my_tool = "my_package:MyTool"

my_package/__init__.py

python
from praisonaiagents import BaseTool

class MyTool(BaseTool):
    name = "my_tool"
    description = "My custom tool"

    def run(self, param: str) -> str:
        return f"Result: {param}"

Usage

After pip install, tools are auto-discovered:

python
from praisonaiagents import Agent

agent = Agent(tools=["my_tool"])  # Works automatically!

What Happens During Validation

The @tool decorator and BaseTool instances now validate schemas automatically to ensure OpenAI compatibility.

Automatic validation when using @tool:

python
@tool
def search(query: str) -> str:
    """Search the web for information."""
    return f"Results for: {query}"
# Validation runs here - check logs for warnings

Important notes:

  • The @tool decorator validates at creation time and logs warnings (doesn’t raise)
  • parameters (if set manually) must include properties for OpenAI compatibility
  • Validation failures are logged – scan your logs for Tool validation warning for ...

Example that will raise ToolValidationError at agent creation:

python
# This will raise ToolValidationError at agent creation:
class BadTool(BaseTool):
    name = "bad"
    description = "..."
    parameters = {"type": "object"}  # missing 'properties'
    def run(self, q: str) -> str: return q

For comprehensive validation details and error fixes, see Tool Schema Validation.

Best Practices

Use simple function signatures

Define tools as plain Python functions with clear type hints – def my_tool(query: str) -> str.

Write descriptive docstrings

The agent reads tool docstrings to decide when to call them – be specific about what the tool does.

Always return strings

Return a string from tool functions – even for errors – so the agent can process the result.

Test tools independently

Call your tool function directly with test inputs before adding it to an agent.

Related