Dare a un agente tutti i tool che possiede l’organizzazione è la scelta di default e quasi sempre quella sbagliata. La distribuzione dei tool fra agenti e la configurazione di tool_choice sono due leve distinte: la prima decide che cosa il modello vede, la seconda quanta libertà ha nel momento in cui decide.

Oltre i 30-50 tool la selezione degrada

Il numero non è un dettaglio implementativo. La documentazione del tool search tool lo dichiara: «Claude’s ability to pick the right tool degrades once you exceed 30–50 available tools». E il costo è doppio, perché lo stesso testo stima che un setup multiserver tipico, con GitHub, Slack, Sentry, Grafana e Splunk, bruci circa 55.000 token di sole definizioni prima che l’agente faccia qualsiasi cosa.

Il tool search sposta le definizioni fuori dal contesto finché non servono: «Tool search typically reduces this by over 85 percent, loading only the 3–5 tools Claude needs for a given request». La soglia consigliata per introdurlo è bassa, dieci tool o definizioni oltre i 10.000 token, mentre il calcolo si ribalta quando i tool sono pochi: «Standard tool calling, without tool search, is a better fit when you have fewer than 10 tools, every tool is used in every request, or your tool definitions are small (less than 100 tokens total)». Il prezzo è un turno in più per la ricerca, quindi latenza.

Un sottoagente è un tool set con un contesto proprio

La seconda strategia di ripartizione è delegare. Un sottoagente riceve il proprio elenco di tool, e la differenza rispetto a un semplice divieto è sostanziale: «A tool you leave out isn’t in the subagent’s session at all: Claude works without it, with no permission prompt or error». Un revisore di documentazione con soli Read e Grep analizza senza poter toccare nulla, «ensuring it can analyze but never accidentally modify your documentation files».

Le combinazioni ricorrenti sono tre: sola lettura con Read, Grep e Glob; esecuzione di test con Bash, Read e Grep; modifica del codice con Read, Edit, Write, Grep e Glob. Nei file di definizione l’elenco funziona da allowlist e ne esiste uno speculare di esclusione, con una precedenza da ricordare: «If both are set, disallowedTools is applied first, then tools is resolved against the remaining pool. A tool listed in both is removed». Entrambi accettano pattern a livello di server MCP, quindi puoi togliere di colpo tutti i tool di un server.

Il vincolo architetturale che sorprende chi delega la prima volta riguarda il contesto: «The only content you pass from parent to subagent is the Agent tool’s prompt string, so include any file paths, error messages, or decisions the subagent needs directly in that prompt».

Disponibilità e permesso sono due leve diverse

Nell’SDK le due dimensioni non coincidono. L’elenco dei tool e i divieti scritti col nome nudo agiscono sulla disponibilità, cioè tolgono il tool dal contesto; le liste di autorizzazione e le regole con argomento agiscono sul permesso, cioè lasciano il tool visibile e bloccano solo le chiamate che corrispondono. La conseguenza pratica è una perdita netta: «A scoped disallowedTools rule blocks matching calls but leaves the tool visible, so Claude may waste a turn trying it».

Sul lato API il connettore MCP offre la stessa scelta in forma dichiarativa: si disabilita tutto per default e si riabilitano i singoli tool, oppure si abilita tutto e si spegne il sottoinsieme pericoloso. La documentazione raccomanda esplicitamente la seconda forma quando serve un assistente in sola lettura o un passaggio di conferma umana prima di una modifica di stato.

tool_choice: quattro valori e un prefill

Quando il tool set è deciso, resta chi sceglie. I quattro valori sono definiti così: auto «allows Claude to decide whether to call any provided tools or not», ed è il default quando i tool ci sono; any «tells Claude that it must use one of the provided tools, but doesn’t force a particular tool»; tool «forces Claude to always use a particular tool»; none «prevents Claude from using any tools», default quando non passi tool.

Forzare ha tre costi concreti. Il primo è espressivo: con any o tool «the API prefills the assistant message to force a tool to be used», e di conseguenza «the models will not emit a natural language response or explanation before tool_use content blocks, even if explicitly asked to do so». Il secondo è di token: sul modello Opus 5 il system prompt del tool use pesa 286 token con auto o none e 406 con any o tool. Il terzo è la cache: «changes to the tool_choice parameter will invalidate cached message blocks», e la guida di troubleshooting indica come sintomo un cache miss a ogni richiesta, con la cura di tenere il valore stabile.

Sullo stesso parametro vive disable_parallel_tool_use, che chiede al massimo una chiamata per turno. Va impostato sulla richiesta che produce il tool_use: «Setting it on a later request has no effect on earlier tool calls».

Quello che paghi per delegare

Ogni sottoagente fa richieste proprie che confluiscono nel costo totale della query e può a sua volta generarne altri, quindi un solo prompt diventa un albero. I limiti esistono e hanno default noti: tre livelli di annidamento, venti sottoagenti concorrenti, nessun tetto di spesa finché non lo imposti. Vale la pena guardarli perché «Claude Opus 5 delegates to subagents more readily than earlier models».

Prima di ripartire, però, conviene ridurre. La regola di progetto è consolidare le operazioni affini in un tool solo con un parametro di azione, invece di moltiplicare i verbi, e usare prefissi per servizio, come github_ o slack_, così che una sola ricerca peschi l’intero gruppo. La sintesi del post sui sistemi in produzione con MCP è la stessa: «Fewer, well-described tools consistently outperform exhaustive API mirrors».