SIFT
Duas meta-ferramentas no lugar de um catálogo de 30 mil tokens: descoberta hierárquica de ferramentas para agentes de LLM, com busca híbrida e filtro de resposta.
3 min de leitura
Stack
- Python
- fastembed
- BM25
- MCP
- OpenAPI
O problema
A forma padrão de dar ferramentas a um agente é injetar o schema de todas elas em toda requisição. Funciona com dez ferramentas. Com duzentas, você está pagando por um catálogo inteiro a cada turno, mesmo quando o agente vai usar uma só:
| Catálogo | Custo por turno |
|---|---|
| 30 ferramentas | ~2,4 mil tokens |
| 250 ferramentas | ~24 mil tokens |
E não é só custo. Quanto maior o catálogo, mais o modelo erra qual ferramenta chamar.
A ideia
O SIFT não mostra o catálogo. Mostra duas meta-ferramentas: search_tools e
execute_tool. A superfície visível ao modelo fica constante em cerca de 430 tokens,
não importa se atrás dela existem 30 ou 3 mil ferramentas.
O agente descobre o que precisa navegando uma taxonomia hierárquica — categoria, serviço, função. A descoberta devolve os resultados em formato TOON, uma linha por ferramenta, para o payload não crescer junto.
from sift import Sift
sift = Sift()
@sift.tool("google_workspace.gmail.read",
description="Lê e-mails da caixa de entrada",
params={"q": "string:o:is:unread:busca", "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("ler meu último e-mail")
sift.execute_tool("google_workspace.gmail.read", {"m": 1})Como a descoberta funciona
Busca híbrida
Embeddings locais e BM25 rodam em paralelo, e os dois rankings se fundem por Reciprocal Rank Fusion. Embedding sozinho erra em nome próprio e sigla; BM25 sozinho erra em paráfrase. Juntos, cobrem o buraco um do outro.
Os embeddings rodam localmente via fastembed com o bge-small — 63 ms de CPU, sem
chave de API e sem chamada de rede na descoberta.
Pedido ativo
Além da busca por texto livre, o agente pode fazer um pedido ativo, separando
domain — a plataforma ou área de permissão — de action, a operação em si. É mais
estruturado que uma query solta, e a diferença aparece nos números.
Resultados
Num conjunto independente de 2.797 ferramentas MCP:
| Método | Acerto no top-1 |
|---|---|
| Busca por query | 96,2% |
| Pedido ativo | 99,5% |
E em teste de agente, contra o catálogo achatado como baseline:
| Catálogo | Eficiência de tokens |
|---|---|
| 100 ferramentas | 4,1× |
| 250 ferramentas | 8,4× |
Com zero chamadas à ferramenta errada em todos os tamanhos testados.
Além da descoberta
O problema do catálogo tem um irmão do outro lado: a resposta. Uma ferramenta que devolve um JSON gigante enche o contexto tanto quanto o schema enchia.
Por isso existe whitelist de resposta por ferramenta, para filtrar campos sensíveis ou irrelevantes antes de chegar ao modelo, um teto global de resultado — 100 mil caracteres por padrão — e hooks de transformação.
O code mode deixa o agente orquestrar várias ferramentas num turno só, através de um trecho executável, em vez de fazer uma chamada por vez. E a memória de sessão promove as ferramentas mais usadas, para não repetir a busca a cada turno.
Onde roda
Adaptadores para APIs compatíveis com OpenAI — OpenAI, DeepSeek, Ollama —, Anthropic
nativo, LangChain e clientes MCP. Para modelos sem function calling, há um modo prompted
com protocolo JSON em texto. Os importadores trazem catálogos de OpenAPI e do ecossistema
MCP.
pip install sift-tools
pip install "sift-tools[langchain]"
pip install "sift-tools[mcp]"Publicado no PyPI, sob licença MIT. É o motor de tool-calling do AI Workspace.