Skip to main content

Overview

DynamicToolLoader keeps tools deferred: registered and executable, but absent from the schema list sent to the model. One extra tool is always present — tool_search — which matches the catalog by name and description and loads what it finds. Loaded tools stay loaded for the rest of the run and become callable on the next request. Tool definitions live in the prompt’s cached prefix, so a large tool set is paid for on every call. Selection accuracy also degrades as the list grows: a model choosing among 80 tools chooses worse than one choosing among 8.

Import

DynamicToolLoader is not re-exported from swarms or swarms.tools. Use the full module path shown above — from swarms.tools import DynamicToolLoader raises ImportError.
Most users never construct one directly. Agent(dynamic_tools=True) builds it and exposes it as agent.tool_loader. See Dynamic Tool Loading for the agent-level guide.

Constructor

Iterable[Callable]
default:"()"
Callables to defer. Each is converted to an OpenAI function schema once, at registration.
Iterable[Dict[str, Any]]
default:"()"
Pre-built schemas to defer, for tools that have no local callable — MCP tools, for instance.
Iterable[Dict[str, Any]]
default:"()"
Schemas that are never deferred. Control-flow tools belong here: an agent that has to search for its own complete_task cannot finish.

Module Constants

str
default:"tool_search"
The reserved name of the search tool. Registering a tool under this name is refused with a warning.
Dict[str, Any]
The OpenAI function schema for tool_search. Takes a required query string and an optional max_results integer. Its description instructs the model to load everything it expects to need in a single call.
str
The system-prompt block appended once when deferral activates, headed ## MOST TOOLS ARE NOT LOADED. Tells the model that its visible tool list describes what exists, not what it can call right now.

Methods

register

Defer one or more Python callables. Chainable; None entries are filtered out.
Callable
required
One or more callables. Each is converted to an OpenAI function schema at registration time.
DynamicToolLoader
The same loader, for chaining.

register_schema

Defer a pre-built OpenAI function schema, optionally binding a local callable to it.
Dict[str, Any]
required
An OpenAI function schema. A schema with no function.name is ignored.
Optional[Callable]
default:"None"
The callable that executes this tool. Leave as None for remotely-dispatched tools such as MCP.
DynamicToolLoader
The same loader, for chaining.
A schema named tool_search is dropped with a warning — that name is reserved, and both entries would appear in the tool list with the model unable to tell them apart.
Rank catalog entries against a query. Does not load anything.
str
required
Keywords, or select:name1,name2 for exact names.
int
default:"5"
Maximum results returned.
float
default:"0.0"
Drop results scoring below this fraction of the best score. 0.0 keeps every match, which suits an explicit search where the model said what it wanted. Speculative callers should raise it — a long query contains enough common words to give weak matches a nonzero score.
List[DeferredTool]
Matching catalog entries, best first. Empty when nothing matches.

load

Mark tools as loaded by name.
Iterable[str]
required
Catalog names to load. Unknown names are ignored.
List[DeferredTool]
Only the tools that were newly loaded by this call.
The tool_search handler: search, load, and report. This is what the model’s tool call invokes.
str
required
Keywords, or select:name1,name2 for exact names.
int
default:"5"
Maximum tools to load. A falsy value (0 or None) silently becomes 5.
float
default:"0.0"
Relative score cutoff, as in search.
str
A compact listing — one name: description line per match, then a blank line, then either Loaded N: a, b. They are callable from your next turn. or All already loaded - call them directly. On a miss, the available tool names plus a hint to retry with select:.
The result deliberately returns summaries rather than full schemas. The schemas are already going out in the request’s tool array — repeating them here would pay for them twice.

schemas

The tool list to send with the next request.
List[Dict[str, Any]]
always_loaded first, then SEARCH_TOOL_SCHEMA, then every loaded tool sorted by name.
The ordering is load-bearing. Loading changes the tool list, which invalidates the provider’s cached prompt prefix; a stable, name-sorted order means two runs that load the same tools produce an identical prefix.

handlers

Name-to-callable mapping for dispatch.
Dict[str, Callable]
Every loaded tool that has a local callable. Schema-only entries such as MCP tools are excluded by design — they are dispatched through the MCP manager.

catalog_listing

Every deferred tool, one per line. Useful for prompts and debugging.
str
Name-sorted name: first line of description lines for the whole catalog.

Properties

List[str]
Sorted names of tools that have been loaded.
List[str]
Sorted names of tools still deferred.
List[Dict[str, Any]]
The never-deferred schemas passed to the constructor. A public mutable list.

Dunder Methods

The Search Algorithm

Matching is deliberately simple: token overlap, with a name match worth more than a description match. That is enough for the catalog sizes this targets, has no dependencies, and is deterministic — so it can be tested. Swap in embeddings only when this measurably fails.
1

Handle select:

A query starting with select: splits the remainder on commas and returns those exact catalog entries immediately — unranked, ignoring both limit and min_score_ratio. If none of the names match, the loader falls through to a keyword search over the guessed names rather than returning nothing.
2

Tokenize

Non-alphanumeric characters become spaces, so get_weather yields get and weather. Everything is lowercased, then single characters and stopwords are dropped.
3

Score

Each catalog entry scores 3 points for a name-token match and 1 point for a description or parameter-name match, summed across the query’s terms. Entries scoring zero are dropped.
4

Sort and cut

Sort by descending score, then by name for stability. If min_score_ratio > 0, drop anything below best_score * min_score_ratio. Return the first limit results.

Searchable Surface

An entry matches on its name, its description, and its parameter property names. Searching "recipient subject" finds a send_email(recipient, subject, body) tool even if neither word appears in its description.

Stopwords

Common words and single characters are filtered before matching:
Without this, a query like "weather in a city" would match every tool whose description contains "a" — loading the whole catalog and defeating the point.

DeferredTool

One catalog entry: what it is, how to call it, and how to run it.
str
Property. "name: first line of description", or just the name when the description is empty. This is the line shown in search results.
List[str]
Property. The lowercased tokens this entry can be matched on — drawn from its name, description, and parameter property names.

Usage Example

Wiring It to a Custom Loop

Two steps: pass loader.schemas() as the tool list, and re-read it after each tool_search call so newly loaded tools are sent with the next request.
Forgetting to re-read schemas() is the most common integration bug. The tool loads successfully, the search result says it is callable, and the model still cannot call it — because the request never carried its schema.

Source

swarms/tools/dynamic_tool_loader.py on GitHub