Custom Tools

Create customized tools for your Seekrflow Agents

What are Custom Tools?

Custom Tools are developer-defined Python functions that extend the capabilities of Seekrflow Agents at runtime. They allow you to define custom functionality that the agent can potentially leverage to complete the task at hand.

Once created, a Custom Tool becomes part of the agent’s available toolset. The agent’s reasoning model will dynamically determine when and how to invoke the tool based on its instructions, context, and user input, just like it does with built-in tools such as File Search or Web Search.

With Custom Tools, you can extend the set of tools available to Seekrflow Agents to address use-case-specific needs, all within a single, unified agent configuration.

Custom Tool Functionality

A Custom Tool is simply Python code that runs within the Seekrflow Agent environment—meaning it can perform virtually any task you can implement in Python (subject to runtime compatibility requirements).

While the possibilities are broad, customers most often use Custom Tools to:

  • Connect to external systems and APIs — e.g., Slack, Outlook, or databases
  • Leverage internal knowledge stores — access proprietary data sources or repositories unique to the business
  • Transform or enrich data — clean, format, or augment text, numerical, or structured data
  • Execute specialized business logic — tailor operations to specific organizational needs

By embedding these capabilities directly into an agent’s available toolset, Custom Tools enable you to build Seekrflow Agents tailored to your localized use-case—addressing the specific requirements, data, and context of the problem you’re solving.

Quickstart

The following guide walks you through creating your first Custom Tool in Seekrflow.

Define your Python File

Each Custom Tool must be implemented in its own .py file. In this example, we’ll create a simple tool that adds two integers together:

def add(a: int, b: int) -> int:
    """Add two numbers together.

    This function takes two integers and returns their sum.
    Use this function when you need to perform a simple addition
    operation on exactly two integer inputs.

    Args:
        a (int): First number.
        b (int): Second number.

    Returns:
        int: The total of a and b.
    """
    return a + b

While not required, Seekr strongly recommends using Google-style docstrings for each Custom Tool. As explain below, the inclusion of robust docstrings aids in the performance of custom tools on multiple dimensions.

Create a Custom Tool

Next, you must invoke the create() function in order to

client = SeekrFlow()

add_tool = client.agents.custom_functions.create(
    description="A tool that takes two integers and adds them together, returning the result",
    file_path ="relative-path-to/add.py"
    )
)
print("add_tool id: " + add_tool.id)
print("add_tool id: " + add_tool.description)
print("add_tool id: " + add_tool.code)
  • description: A clear, concise description of what the Custom Tool does and when it should be used. This description serves as context for the agent's reasoning model to determine when to invoke the tool.
  • file_path: The relative or absolute path to the Python file containing your Custom Tool function. The path should be relative to your current working directory or an absolute path to the .py file.

Attach a Custom Tool to an Agent

from seekrai.types import RunPython, RunPythonEnv

addition_agent = client.agents.create(
    CreateAgentRequest(
        name="addition-agent",
        instructions="Agent that performs basic addition and returns the answer",
        model_id"meta-llama/Meta-Llama-3.3-70B-Instruct", # a model with long context for summarizing
        tools=[RunPython(
            tool_env=RunPythonEnv(
                function_ids=[add_tool.id] #pass in the id of the tool created in the previous step
            ),
				reasoning_effort=ReasoningEffort.SPEED_OPTIMIZED
		)]
))

Run the Agent

Now simply run the agent as you would for any other tool configuration. You can find Seekr's QuickStart documentation explaining how to create and run an Agent located here.

Update a Custom Tool

If you want to iterate on your custom tool, you can use the following function:

client = SeekrFlow()
tool_id =  add_tool.id #previously created custom tool 

add_tool = client.agents.custom_functions.update(
  description="A tool that takes two integers and adds them together, returning the result",
	function_id=tool_id
  file_path ="relative-path-to/add.py" #updated 
    )
)

A Seekrflow agent that is currently Active will need to be demoted and re-promoted in order to have the updated function executed by the agent.

import time

from seekrai import SeekrFlow
from seekrai.types import AgentStatus

#Demote an agent
agent = client.agents.demote(agent.id)

while True:
    agent = client.agents.retrieve(agent.id)
    if agent.status == AgentStatus.INACTIVE:
        break
    time.sleep(5)
    
print(f"Agent demoted. Agent ID: {agent.id}")
print(f"Agent status: {agent.status}")

#re-promote the agent
agent = client.agents.promote(agent.id)

while True:
    agent = client.agents.retrieve(agent.id)
    if agent.status == AgentStatus.ACTIVE:
        break
    time.sleep(5)

print(f"Agent promoted. Agent ID: {agent.id}")

After successful re-promotion, the logic reflected in the updated custom tool should be reflected.

Delete Custom Tools

To delete a custom function, follow the below code:

tool_id = add_tool.id
deleted_tool = client.agents.custom_functions.delete(function_id=add_tool.id)

if is_deleted.deleted == True:
  print("the custom tool was successfully deleted")

List Custom Tools

You can retrieve your custom tools in one of two ways.

Retrieve All

To retrieve all custom tools for your account, follow the below code:

client = SeekrFlow()

custom_tool_list = client.agents.custom_functions.list_functions(limit=20, order="desc", offset=0)

for tool in custom_tool_list:  
  print(f"Tool ID: {tool.id}, Description: {tool.description}")

Note that all parameters are **optional **

  • limit: The maximum number of tools to return in the results.
  • order: The sorting direction ("asc" or "desc") based on the tool’s created_at timestamp.
  • offset: The number of records to skip before starting to return results.

Retrieve an individual tool

To retrieve an individual tool, observe follow the below code:

tool_id = add_tool.id

tool = client.agents.custom_functions.retrieve(function_id=tool_id)

print(f"ID: {tool.id}, Description: {tool.description}")
  • function_id: The previously created function unique identifier

Custom Tools Best Practices

Seekr purposely puts limited restrictions on the usage of custom tools. That said, our team does recommend the following best practices:

Write clear, purposeful docstrings

Seekr's reasoning model relies heavily on function docstrings to understand when and how to invoke your Custom Tools. Well-crafted docstrings directly impact tool performance and reliability.

  • Function description: Include both a short description and a long description. Ideally the short description should describe when to invoke the function, and the long description should specify the conditions or scenarios when the agent should use this tool versus other available options.
  • Parameter documentation: Provide clear, specific descriptions for each parameter that help the reasoning model understand what information from the conversation context should be mapped to each argument. Avoid generic descriptions like "input value" and instead use contextual descriptions like "user's email address from the conversation" or "the product ID mentioned in the request."
  • Return value documentation: Clearly describe what the function returns and how the agent should interpret or use that information in its response to the user.

Example of effective docstring:

def get_user_order_history(user_email: str, days_back: int = 30) -> List[Dict]:
    """Retrieve a user's recent order history from the e-commerce database.
    
    Use this function when a user asks about their past orders, purchase history,
    or needs information about previous transactions. Only invoke when you have
    confirmed the user's email address.
    
    Args:
        user_email (str): The customer's email address as provided in the conversation
        days_back (int): Number of days to look back for orders (default: 30)
        
    Returns:
        List[Dict]: List of order dictionaries containing order_id, date, items, and total
    """

Example of an ineffective docstring:

def get_user_order_history(user_email: str, days_back: int = 30) -> List[Dict]:
    """Gets orders.
    
    This function gets user orders from the database. Use it for orders.
    
    Args:
        user_email (str): Email
        days_back (int): Days
        
    Returns:
        List[Dict]: Orders
    """

Test functions locally before deployment

Seekr does not validate Python syntax or runtime behavior when you inoke create - the Custom Tool will be created successfully even if your code contains errors. However, when the agent attempts to invoke a faulty function during a conversation, it will fail and potentially disrupt the user experience.

Before calling create(), always:

  • Verify your function runs without syntax errors
  • Test with representative input data
  • Handle expected edge cases (null values, empty strings, invalid inputs)

Leverage External Services for Complex Logic

Custom Tools support single function definitions only - helper functions and nested functions within the same file are not supported. For sophisticated workflows requiring multiple functions or complex business logic, we recommend creating an external service that your Custom Tool can call.

External Integrations

Custom Tools can integrate with external systems including APIs, databases, knowledge stores, and MCP servers. We encourage these integrations as they significantly expand your agent's capabilities.

  • Current consideration: Seekr does not currently provide built-in secret management for storing API keys, database credentials, or other sensitive information. You'll need to manage these secrets through your own secure methods (environment variables, external secret managers, etc.).
  • Coming soon: We're actively developing native secret management capabilities and expect to release this feature in the coming weeks. This will provide a secure, streamlined way to store and access credentials directly within the Seekr platform.
  • For now: Feel free to build external integrations using your preferred secret management approach. Just ensure you follow your organization's security best practices for handling sensitive credentials.

A note on Imports and Package Support

Seekr uses Pyodide to execute Custom Tools in a secure sandboxed environment. Understanding Pyodide's package ecosystem will help ensure your Custom Tools run reliably.

  • Natively supported packages: Pyodide includes many popular Python packages out of the box. You can find the complete list of pre-installed packages here.
  • External packages: For packages not natively supported, Pyodide will automatically attempt to install them at runtime using micropip. This works for "pure Python" packages - those that don't require compiled extensions or system-level dependencies.

Best practices

When it comes to imports, we recommend the following best practices:

  • Leverage natively supported packages when possible for faster execution and guaranteed compatibility
  • Verify pure Python compatibility for external packages - check that they have wheels available on PyPI and don't depend on C extensions
  • Test thoroughly when using external packages, as installation failures will cause your Custom Tool to fail at runtime
  • Consider alternatives if a package doesn't work - often there are pure Python alternatives that provide similar functionality
  • Use external services for incompatible packages - if a required package won't compile in Pyodide, create an external service that uses the package and call it from your Custom Tool via API