Home
VA.
Back to Projects

SIFT

Two meta-tools instead of a 30k-token catalogue: hierarchical, search-first tool discovery for LLM agents, with hybrid retrieval and response filtering.

3 min read

Stack

  • Python
  • fastembed
  • BM25
  • MCP
  • OpenAPI

The problem

The standard way to give an agent tools is injecting every schema on every request. That works with ten tools. With two hundred, you're paying for the whole catalogue each turn, even when the agent will use exactly one:

CatalogueCost per turn
30 tools~2.4k tokens
250 tools~24k tokens

And it isn't only cost. The bigger the catalogue, the more often the model picks the wrong tool.

The idea

SIFT doesn't show the catalogue. It shows two meta-tools: search_tools and execute_tool. The surface visible to the model stays constant at about 430 tokens, no matter whether 30 or 3,000 tools sit behind it.

The agent discovers what it needs by walking a hierarchical taxonomy — category, service, function. Discovery returns results in TOON format, one line per tool, so the payload doesn't grow along with the catalogue.

from sift import Sift
 
sift = Sift()
 
@sift.tool("google_workspace.gmail.read",
           description="Read emails from the inbox",
           params={"q": "string:o:is:unread:search query", "m": "number:o:10:max"},
           returns=["id", "subject", "from", "snippet", "date"])
def gmail_read(q="is:unread", m=10):
    return {...}
 
sift.build_index()
sift.search_tools("read my last email")
sift.execute_tool("google_workspace.gmail.read", {"m": 1})

How discovery works

Hybrid retrieval

Local embeddings and BM25 run in parallel, and the two rankings merge through Reciprocal Rank Fusion. Embeddings alone stumble on proper nouns and acronyms; BM25 alone stumbles on paraphrase. Together they cover each other's gap.

Embeddings run locally through fastembed with bge-small — 63 ms on CPU, no API key and no network call during discovery.

Active requests

Beyond free-text search, the agent can issue an active request, separating domain — the platform or permission area — from action, the operation itself. It's more structured than a loose query, and the difference shows up in the numbers.

Results

On an independent dataset of 2,797 MCP tools:

MethodTop-1 accuracy
Query search96.2%
Active request99.5%

And in agent-level tests, against a flat catalogue as the baseline:

CatalogueToken efficiency
100 tools4.1×
250 tools8.4×

With zero wrong-tool calls across every size tested.

Beyond discovery

The catalogue problem has a sibling on the other side: the response. A tool returning a huge JSON blob fills the context just as the schemas used to.

Hence per-tool response whitelisting, filtering sensitive or irrelevant fields before they reach the model, a global result cap — 100k characters by default — and transformation hooks.

Code mode lets the agent orchestrate several tools in a single turn through an executable snippet, instead of one call at a time. And session memory promotes frequently-used tools, so the search doesn't repeat every turn.

Where it runs

Adapters for OpenAI-compatible APIs — OpenAI, DeepSeek, Ollama — plus native Anthropic, LangChain and MCP clients. For models without function calling there's a prompted mode using a text JSON protocol. Importers pull catalogues from OpenAPI and the MCP ecosystem.

pip install sift-tools
pip install "sift-tools[langchain]"
pip install "sift-tools[mcp]"

Published on PyPI under the MIT license. It's the tool-calling engine behind AI Workspace.

Tags

  • LLM
  • Agents
  • RAG
  • Python