Skip to main content
Version: 2.26-unstable

SearchableToolset

Enable agents to dynamically discover tools from large catalogs using keyword-based search.

Mandatory init variablescatalog: A list of Tools and/or Toolsets, or a single Toolset
API referenceSearchableToolset
GitHub linkhttps://github.com/deepset-ai/haystack/blob/main/haystack/tools/searchable_toolset.py

Overview

SearchableToolset is designed for working with large tool catalogs. Instead of exposing all tools at once, which can overwhelm the LLM context, it provides a single search_tools bootstrap tool. The agent uses this tool to find and load specific tools from the catalog using BM25 keyword search.

Once the agent calls search_tools, the matching tools become immediately available and the agent can invoke them in subsequent iterations.

Modes of operation

SearchableToolset operates in one of two modes depending on catalog size:

  • Search mode (default for large catalogs): The agent starts with only the search_tools bootstrap tool and discovers other tools on demand. This is activated when the catalog size meets or exceeds search_threshold.
  • Passthrough mode (small catalogs): All tools are exposed directly, with no discovery step needed. This is activated automatically when the catalog has fewer tools than search_threshold.

Parameters

  • catalog (required): The source of tools — a list of Tool and/or Toolset instances, or a single Toolset. This includes MCPTool and MCPToolset instances.
  • top_k (optional): The default number of tools returned by each search_tools call. Default is 3.
  • search_threshold (optional): Minimum catalog size to activate search mode. Catalogs smaller than this value use passthrough mode instead. Default is 8.
info

SearchableToolset does not support adding new tools after initialization or merging with other toolsets. Use catalog to provide all tools upfront.

Usage

Basic usage with an Agent

python
from typing import Annotated
from haystack.components.agents import Agent
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.dataclasses import ChatMessage
from haystack.tools import create_tool_from_function, SearchableToolset


def get_weather(city: Annotated[str, "The city to get the weather for"]) -> str:
"""Get current weather for a city."""
return f"Sunny, 22°C in {city}"


def search_web(query: Annotated[str, "The search query"]) -> str:
"""Search the web for information."""
return f"Results for: {query}"


# Build a catalog from tools
catalog = [
create_tool_from_function(get_weather),
create_tool_from_function(search_web),
# ... many more tools
]

toolset = SearchableToolset(catalog=catalog)

agent = Agent(
chat_generator=OpenAIChatGenerator(),
tools=toolset,
)

# The agent initially sees only `search_tools`. It will call it to find relevant tools,
# then use the discovered tools to answer the question.
result = agent.run(messages=[ChatMessage.from_user("What's the weather in Milan?")])
print(result["messages"][-1].text)

Reusing the toolset across multiple agent runs

When reusing the same SearchableToolset instance across multiple agent runs, you can call clear() to reset any tools discovered in the previous run:

python
agent = Agent(
chat_generator=OpenAIChatGenerator(),
tools=toolset,
)

result1 = agent.run(messages=[ChatMessage.from_user("What's the weather in Milan?")])

# Reset discovered tools before the next run
toolset.clear()

result2 = agent.run(messages=[ChatMessage.from_user("Search for news about AI.")])