Strategie di Caching per Agenti AI: Ridurre i Costi Senza Compromessi
Strategie di Caching per Agenti AI: Ridurre i Costi Senza Compromessi
Il tuo agente di ricerca esegue 50 attività al giorno. Ogni attività inizia con lo stesso system prompt da 3.000 token, le stesse definizioni di tool da 2.500 token e la stessa knowledge base da 5.000 token. Sono 10.500 token ripetuti 50 volte — 525.000 token al giorno che il modello legge in modo identico ogni volta. Con i prezzi standard, stai pagando per elaborare lo stesso contenuto ancora e ancora.
Il caching è l’ottimizzazione con il minimo sforzo e il massimo impatto per gli agenti in produzione. Il solo prompt caching può ridurre i costi dei token di input del 90% per i contenuti memorizzati nella cache. Combinato con il caching dei risultati dei tool, è spesso possibile dimezzare i costi totali dell’agente — senza sacrificare qualità, accuratezza o flessibilità.
In questo articolo imparerai tre livelli di caching per gli agenti — prompt caching, tool result caching e response memoization — con pattern di implementazione usando l’API di Claude e un’analisi dei costi chiara per guidare le tue decisioni.
Sezione 1: Anatomia dei Costi di un Agente
Prima di ottimizzare, devi capire dove vanno effettivamente i tuoi token. Analizziamo un tipico flusso di lavoro agente.
Ripartizione dei Token per Turno
In un’architettura agente standard, ogni chiamata API al modello include:
| Componente | Token approssimativi | Ripetuto? |
|---|---|---|
| System prompt | ~1.500 | Ogni turno |
| Definizioni dei tool | ~2.000 | Ogni turno |
| Knowledge base / contesto | ~3.000 | Ogni turno |
| Cronologia della conversazione | In crescita | Si accumula |
| Risultati dei tool | ~500 in media | Per ogni chiamata al tool |
L’overhead statico — system prompt, definizioni dei tool e knowledge base — totalizza circa 6.500 token per turno, ed è identico ogni singola volta.
Il Problema del Costo Composto
Gli agenti non effettuano una sola chiamata API. Eseguono cicli. Un tipico ciclo di esecuzione di un agente in 15 step si presenta così:
Senza caching:
Ciascuno dei 15 step invia il contesto completo. Assumendo che la cronologia della conversazione cresca di circa 300 token per step in media:
- Token statici per step: 6.500
- Token statici totali su 15 step: 97.500
- Token della cronologia della conversazione (cumulativi): ~33.750
- Token dei risultati dei tool: ~7.500
- Token di input totali: ~138.750
Al prezzo di input di Claude Sonnet di $3 per milione di token, sono circa $0,42 per attività. Eseguendo 50 attività al giorno, si arriva a $21/giorno — solo sui token di input.
Con il prompt caching:
I token memorizzati nella cache vengono addebitati a $0,30 per milione per le letture dalla cache (sconto del 90%). Se memorizzi nella cache i 6.500 token statici:
- Letture di token dalla cache su 15 step: 97.500 token × $0,30/M = $0,029
- I token non memorizzati nella cache rimangono al prezzo standard: ~41.250 × $3/M = $0,124
- Scrittura nella cache (primo step): 6.500 × $3,75/M = $0,024
- Costo totale di input: ~$0,18 per attività
Si tratta di una riduzione del 57% dal solo caching. Con 50 attività al giorno, risparmi oltre $12/giorno — circa $360/mese — con modifiche minime al codice.
Sezione 2: Prompt Caching con Claude
L’API di prompt caching di Claude è l’ottimizzazione con il singolo maggiore impatto che puoi applicare ai flussi di lavoro agente. Ti permette di dire all’API “questa parte del mio prompt non è cambiata — riutilizza il calcolo memorizzato nella cache.”
Come Funziona il Prompt Caching
Quando invii una richiesta con il caching abilitato, l’infrastruttura di Anthropic:
- Verifica se esiste una versione memorizzata nella cache del prefisso contrassegnato
- In caso di cache miss: Elabora il prompt completo, memorizza il prefisso nella cache e addebita una tariffa di cache write (premio del 25% rispetto al prezzo di input standard)
- In caso di cache hit: Riutilizza il calcolo memorizzato nella cache, addebitando solo la tariffa di cache read (sconto del 90% rispetto al prezzo di input standard)
La cache ha un TTL di 5 minuti (Time to Live — la durata prima che i dati memorizzati nella cache scadano). Ogni cache hit reimposta il TTL, quindi gli agenti attivi mantengono naturalmente la loro cache attiva. I job batch con intervalli superiori a 5 minuti tra le chiamate comporteranno costi di cache write più frequenti.
Cosa Memorizzare nella Cache
Non tutto può o deve essere memorizzato nella cache. Memorizza nella cache prefissi stabili e ripetuti:
- System prompt — Quasi sempre identici tra le esecuzioni. Memorizzali nella cache per primi.
- Definizioni dei tool — I tuoi schemi di tool raramente cambiano tra le chiamate.
- Knowledge base statiche — Documenti di riferimento, linee guida, policy.
- Prefissi delle conversazioni — Per conversazioni multi-turno, memorizza nella cache i turni precedenti che non cambieranno.
Vincoli importanti:
- Il caching è basato sui prefissi — puoi memorizzare nella cache solo il contenuto dall’inizio del prompt, in ordine. Non puoi memorizzare nella cache una sezione nel mezzo lasciando le sezioni precedenti non memorizzate.
- C’è una lunghezza minima memorizzabile di 1.024 token per Claude Sonnet e Haiku (2.048 per Opus).
- Puoi impostare fino a 4 breakpoint di cache in una singola richiesta.
Implementazione
Ecco un esempio completo che mostra la configurazione di un agente con prompt caching:
Prima (senza caching):
import anthropic
client = anthropic.Anthropic()
SYSTEM_PROMPT = """You are a research assistant specializing in market analysis.You have access to tools for searching databases, reading files, and performingcalculations. Always cite your sources and provide confidence levels for yourfindings. [... detailed instructions totaling ~1,500 tokens ...]"""
TOOLS = [ { "name": "search_database", "description": "Search the company database for market data, competitor info, or financial records.", "input_schema": { "type": "object", "properties": { "query": {"type": "string", "description": "Search query"}, "database": {"type": "string", "enum": ["market", "competitors", "financial"]}, "limit": {"type": "integer", "description": "Max results", "default": 10} }, "required": ["query", "database"] } }, { "name": "read_file", "description": "Read the contents of a research file.", "input_schema": { "type": "object", "properties": { "file_path": {"type": "string", "description": "Path to the file"} }, "required": ["file_path"] } }, # ... more tools totaling ~2,000 tokens in definitions]
KNOWLEDGE_BASE = """## Company Policies and Guidelines[... reference material totaling ~3,000 tokens ...]"""
def run_agent(user_query: str): messages = [{"role": "user", "content": user_query}]
response = client.messages.create( model="claude-sonnet-4-20250514", max_tokens=4096, system=f"{SYSTEM_PROMPT}\n\n{KNOWLEDGE_BASE}", tools=TOOLS, messages=messages, ) # Log token usage print(f"Input tokens: {response.usage.input_tokens}") return responseDopo (con prompt caching):
import anthropic
client = anthropic.Anthropic()
SYSTEM_PROMPT = """You are a research assistant specializing in market analysis.You have access to tools for searching databases, reading files, and performingcalculations. Always cite your sources and provide confidence levels for yourfindings. [... detailed instructions totaling ~1,500 tokens ...]"""
KNOWLEDGE_BASE = """## Company Policies and Guidelines[... reference material totaling ~3,000 tokens ...]"""
TOOLS = [ { "name": "search_database", "description": "Search the company database for market data, competitor info, or financial records.", "input_schema": { "type": "object", "properties": { "query": {"type": "string", "description": "Search query"}, "database": {"type": "string", "enum": ["market", "competitors", "financial"]}, "limit": {"type": "integer", "description": "Max results", "default": 10} }, "required": ["query", "database"] } }, { "name": "read_file", "description": "Read the contents of a research file.", "input_schema": { "type": "object", "properties": { "file_path": {"type": "string", "description": "Path to the file"} }, "required": ["file_path"] }, "cache_control": {"type": "ephemeral"} # Cache breakpoint after tools },]
def run_agent_cached(user_query: str): messages = [{"role": "user", "content": user_query}]
response = client.messages.create( model="claude-sonnet-4-20250514", max_tokens=4096, system=[ { "type": "text", "text": SYSTEM_PROMPT, }, { "type": "text", "text": KNOWLEDGE_BASE, "cache_control": {"type": "ephemeral"}, # Cache breakpoint }, ], tools=TOOLS, messages=messages, ) # Log token usage — now includes cache metrics usage = response.usage print(f"Input tokens: {usage.input_tokens}") print(f"Cache read tokens: {usage.cache_read_input_tokens}") print(f"Cache creation tokens: {usage.cache_creation_input_tokens}") return responseLe modifiche chiave:
- Il parametro
systemdiventa un elenco di blocchi di contenuto (invece di una stringa semplice) in modo da poter allegarecache_controla blocchi specifici. - Aggiungi
"cache_control": {"type": "ephemeral"}nei breakpoint desiderati. - L’ultima definizione di tool riceve un blocco
cache_controlper memorizzare nella cache anche tutte le definizioni dei tool. - Monitora i nuovi campi
cache_read_input_tokensecache_creation_input_tokensnella risposta.
Considerazioni sulla Durata della Cache
Il TTL di 5
Articoli Correlati
- Ottimizzazione dei costi degli agenti: una guida pratica per ridurre la spesa API
- Recupero Errori degli Agenti: 5 Pattern per l’Affidabilità in Produzione
- Pattern di Utilizzo degli Strumenti: Interfacce Agente-Strumento Affidabili