RAG Tool Curator docs v0.1.0
Hybrid RAG tool selection for LLM agents

Give your agent the right 15 tools, not all 3,000.

Two small, independent plug-ins for agentic systems: a hybrid retrieval engine that narrows a large tool registry down to the handful relevant to one query, and a provider-agnostic normalizer that keeps non-English queries from breaking that retrieval. Copy them in or pip install them — no framework lock-in.

The problem

LLM tool-calling accuracy degrades measurably once the available tool count passes roughly 20–30, and drops sharply beyond a few hundred. Independent of accuracy, every tool declaration in a prompt costs tokens — a registry of 3,000 tools at ~200 tokens each is 600,000 tokens per request, more than the context window of essentially any production model. Both plug-ins here exist to fix a version of this problem: tool_curator narrows the tool registry per query before it reaches the model; multilingual_normalizer keeps that narrowing from silently breaking the moment a query isn’t in English.

83%
token reduction · 87-tool pool
92%
token reduction · 191-tool pool
99.3%
token reduction · 3,000-tool pool
94.8%
accuracy score · reference eval

How tool_curator works

Two independent retrieval passes run per query and get fused:

  • Dense retrievalBAAI/bge-small-en-v1.5 encodes the query and every tool description into 384-dimensional vectors; FAISS IndexFlatIP does exact cosine-similarity search. This is what matches “raise a formal complaint” to a tool named submit_grievance with zero shared words.
  • Sparse retrievalBM25Okapi scores tools by keyword overlap, catching exact-terminology queries (“CGPA” → get_cgpa) that embeddings alone can dilute.
  • Fusion — Reciprocal Rank Fusion (RRF, k=60) merges both rankings using rank position only, so no manual score-weighting between two incompatible scales is needed.

Layered on top: a name-token anchor that force-includes a tool whenever its own name closely matches the query, compound-query splitting for multi-intent queries, adaptive expansion when retrieval confidence is low, and a disk-cached index keyed by a content hash so tool or vocabulary edits invalidate the cache automatically. See Tool Curator Architecture for the full mechanics.

How multilingual_normalizer works

tool_curator’s dense retrieval is trained on English text — a non-English query embeds nowhere near its English-described tools, and retrieval degrades to noise. multilingual_normalizer sits one stage earlier and translates non-English queries to English before they reach the curator, restoring retrieval accuracy without changing anything about how the curator itself works. English queries take a zero-cost local fast-path — no network call, no added latency — and the fast-path is a majority-vocabulary check, not a bare ASCII check, so it correctly catches romanized non-English text that would otherwise slip through untranslated. See Multilingual Normalizer.

Two plug-ins, one repo

Both packages are independent — installing or using one never requires the other:

pip install rag-tool-curator                # tool_curator only
pip install "rag-tool-curator[normalizer]"   # + multilingual_normalizer's Gemini backend
from tool_curator import get_curator
from multilingual_normalizer import get_normalizer

Neither package knows anything about MCP, a specific LLM SDK, or a transport protocol — both operate on plain strings and (name, description) pairs. The bundled example/ is a full reference deployment (a simulated university system, 191 tools across 8 MCP servers) used to validate the curator against a 281-case hand-labeled evaluation suite — it’s a proof point and a template to copy from, not a dependency of either plug-in.