Salta ai contenuti

Contesto degli strumenti e cache dei prompt

Due cose valgono per ogni richiesta che l’harness integrato effettua: le definizioni degli strumenti ne sono il costo fisso più grande e quasi nessuna di esse verrà usata. Questa pagina spiega che cosa fa Control Center in proposito e perché la risposta non è semplicemente «inviare meno strumenti».

Control Center registra circa 126 strumenti. Inviati per intero, le loro definizioni costano all’incirca 23.000 token a ogni richiesta — un costo che nessuna compattazione può scalfire, perché le definizioni degli strumenti viaggiano in una parte della richiesta separata dalla conversazione.

Il conto dei token è il lamento ovvio e, con la cache dei prompt, è anche il minore. Il costo reale è la precisione nella selezione. Le valutazioni pubblicate sulle chiamate agli strumenti concordano sul fatto che i modelli scelgono lo strumento giusto in modo affidabile fino a circa 30–50 strumenti nel contesto, e peggiorano progressivamente oltre quella soglia. La causa indicata non è il numero di token ma la sovrapposizione semantica: quando un catalogo contiene diversi strumenti le cui descrizioni si somigliano, il modello sceglie tra quasi identici invece di richiamare alla mente una capacità.

Con 126 strumenti, un agente è ben oltre quella fascia a ogni singolo turno — compresi i molti turni in cui doveva soltanto leggere un file.

A un’esecuzione vengono quindi mostrate due cose:

  • un insieme residente — circa due dozzine di strumenti, inviati con gli schemi completi a ogni richiesta;
  • un indice dei nomi di tutto il resto, raggruppato sotto intestazioni come «Tickets and projects» o «Memory and knowledge», che costa qualche centinaio di token per l’intero catalogo.

Misurato sul catalogo attuale, tutto ciò porta il blocco degli strumenti da ~23,1k token a ~5,0k, circa il 78% in meno, e colloca l’insieme sempre visibile dentro la fascia in cui la selezione è affidabile.

L’insieme residente è formato dagli strumenti che un’esecuzione usa nella maggior parte delle esecuzioni: il vocabolario di file e shell (read, write, edit, search, bash, …), gli strumenti di scoperta, la checklist delle attività, la ricerca nella memoria e qualunque verbo debba invocare la modalità corrente per produrre il proprio output. Il verbo di output di una modalità è sempre residente: un’esecuzione non deve mai doversi mettere a cercare l’unica chiamata che produce il suo deliverable.

Questa è la parte che rende il progetto sicuro e non solo economico. Uno strumento differito è invocabile fin dal primo turno. L’unica cosa che viene trattenuta è il suo schema.

L’agente vede il nome nel proprio prompt. Se chiama direttamente quel nome, l’harness carica lo schema ed esegue lo strumento nello stesso passo: nessun errore, nessun andata e ritorno. Il modello non ha bisogno di sapere che lo strumento è mai stato «scaricato».

Quando l’agente conosce il compito ma non il nome, search_tools accetta una descrizione in linguaggio naturale («assegna un ticket a qualcuno»), classifica l’intera superficie dell’esecuzione e restituisce le corrispondenze con i loro schemi già caricati, così che il turno immediatamente successivo possa chiamarne una. Se una ricerca non trova nulla, lo dice chiaramente e suggerisce altre parole o una ricerca più ampia — e lo fa di proposito, perché un agente che interpreta una ricerca vuota come «questa capacità non esiste» inventerà un sostituto invece di guardare di nuovo.

search_tools esiste solo nell’harness integrato. I client MCP esterni hanno invece search_tool_bm25, che classifica lo stesso indice ma descrive soltanto le corrispondenze: quei client hanno già ricevuto tutti gli schemi da tools/list, quindi non c’è nulla da caricare.

Il differimento viene applicato dopo il filtro degli strumenti della modalità, mai al suo posto. Nasconde uno schema; non può rivelare uno strumento che la modalità ha negato. Uno strumento attivato passa comunque dalla richiesta di approvazione e dai guardrail delle azioni esattamente come farebbe uno residente, e uno strumento non può caricare un nome che non fosse già sulla superficie dell’esecuzione in partenza.

La superficie MCP che vedono i client esterni non è interessata. tools/list continua a restituire il catalogo completo. Un tentativo precedente di ridurlo ha rotto gli agenti di netto: i client MCP convalidano i nomi degli strumenti rispetto alla propria lista in cache e rifiutano qualunque cosa non sia in elenco senza mai chiedere al server, quindi uno strumento «nascosto ma invocabile» era semplicemente irraggiungibile. Il differimento vive nell’harness, dove caricare uno strumento a metà esecuzione è qualcosa che l’harness può effettivamente fare.

--tool-deferral=off (o CC_SERVER_TOOL_DEFERRAL=off) rende di nuovo residenti tutti gli strumenti ammessi, producendo esattamente le richieste che il server effettuava prima che il differimento esistesse. Vedi il riferimento alla CLI di cc_server.

I carichi di lavoro degli agenti sono sbilanciati: inviano prompt enormi e ricevono risposte piccole, turno dopo turno, sempre con lo stesso prefisso. I provider mettono in cache quel prefisso, e una lettura dalla cache costa circa un decimo di una nuova. Il tasso di successo della cache è quindi una proprietà di primo ordine dell’harness, non un’ottimizzazione — e su Anthropic regala anche throughput, perché i token in cache non contano ai fini del limite di input al minuto.

La cache funziona su una corrispondenza esatta del prefisso, da cui deriva un’unica regola dominante.

Qualunque byte che cambi invalida la cache da quel punto in poi. Perciò l’harness accoda soltanto: nuovi messaggi in fondo, e gli schemi degli strumenti appena attivati dopo il blocco di strumenti in cache anziché fusi al suo interno. È quest’ordine a rendere economica l’attivazione: il prefisso in cache resta identico e l’esecuzione paga solo gli schemi che ha appena caricato.

Il ciclo inoltre ritaglia l’output obsoleto degli strumenti dei turni più vecchi per recuperare contesto. Aspetta che ci sia abbastanza da recuperare perché la riscrittura valga la pena, quindi un ritaglio è una riscrittura profonda e rara invece di un continuo mancato successo della cache.

Un provider concede un numero limitato di marcatori di cache, e Control Center li spende con criterio:

Marcatore Copre Durata
Ultimo strumento residente Il blocco degli strumenti 1 ora
Ultimo blocco di sistema Strumenti + prompt di sistema 1 ora
Coda del turno precedente Cronologia fino all’ultima richiesta 5 min
Coda del turno attuale La cronologia completa 5 min

Gli ultimi due formano una coppia mobile, e la ragione di quella coppia è sottile: una ricerca nella cache va a ritroso per un numero limitato di blocchi a cercare qualcosa che una richiesta precedente ha memorizzato. Un singolo turno che esegue molti strumenti in parallelo può emettere più blocchi di quella finestra, e a quel punto uno dei marcatori di coda manca il bersaglio in silenzio e la richiesta paga il prezzo pieno senza che nulla nella risposta lo dica. Contrassegnare il punto esatto in cui si è fermata la richiesta precedente rende il successo strutturale invece che una corsa.

Il prefisso strumenti-e-sistema riceve la durata lunga perché è costante per tutta l’esecuzione, è condiviso da ogni esecuzione e subagent con la stessa forma, e perché il cronometro parte quando una richiesta inizia: un turno che fa streaming per diversi minuti ha già consumato gran parte di una finestra breve prima che si formi la richiesta successiva.

I subagent dello stesso tipo producono prefissi di prompt identici byte per byte, quindi dovrebbero leggere un’unica voce di cache anziché scriverne ciascuno la propria. Ma una voce diventa leggibile solo quando la richiesta che l’ha scritta inizia a rispondere, perciò in un fan-out avviato tutto in una volta ogni figlio paga il sovrapprezzo per un prefisso che condividono tutti.

L’harness lascia partire il primo figlio di una data forma, poi libera i suoi fratelli non appena inizia a fare streaming. L’attesa è limitata: un primo figlio lento costa un successo di cache, mai il fan-out in sé. Per lo stesso motivo, ogni subagent riceve lo stesso insieme di strumenti residenti a prescindere dal proprio profilo: variarlo per profilo frammenterebbe il prefisso condiviso senza alcun vantaggio, dato che il profilo ha già deciso che cosa può chiamare il figlio.

Entrambe le metà sono osservabili anziché date per scontate:

  • L’esploratore del contesto di una conversazione riporta gli strumenti residenti, l’indice differito e quanto costerebbe ogni schema trattenuto, ed è costruito con lo stesso percorso di codice che usa un’esecuzione reale.
  • Ogni esecuzione registra quali strumenti differiti ha caricato e che cosa l’ha innescato, così una ricerca che non trova nulla è visibile come un recupero mancato invece di sparire in un agente che, in silenzio, fa qualcosa di adiacente.
  • Osservabilità riporta il Tasso di cache come letture dalla cache su tutti i token di prompt elaborati, scritture incluse: un’esecuzione che continua a ricostruire il proprio prefisso ottiene un punteggio basso, invece di ottenere lo stesso punteggio di una che non ha mai avuto bisogno di una cache.