Hai appena integrato l'API di Claude nel tuo progetto Python, tutto funziona. Poi arriva la bolletta: ogni richiesta ti costa perché mandi sempre lo stesso contesto di 40mila token – system prompt, documentazione interna, storico conversazione – anche se la risposta è un semplice "si". A 15 centesimi per milione di token in input, può sembrare poco, ma moltiplicalo per migliaia di chiamate al giorno: il conto sale veloce. E la latenza aumenta perché ogni volta il modello deve rileggere tutto.
Noi, di Meteora Web, abbiamo incontrato questo problema su piattaforme che gestiscono clienti con documenti tecnici fissi (manuali, policy, cataloghi). La soluzione si chiama prompt caching, una funzionalità nativa dell’API di Claude (modelli Sonnet 4, Opus 4) che permette di mantenere in cache porzioni di prompt — paghi la scrittura una volta sola e riutilizzi la cache per le richieste successive. In questa guida vediamo come integrarla correttamente, con codice Python funzionante, e come evitare gli errori più comuni.
Perché il prompt caching cambia le regole
Immagina di dover caricare ogni volta un file PDF di 200 pagine come contesto per un assistente clienti. Senza caching, ogni chiamata invia quei token, li paghi e aspetti che l’elaborazione li processi. Con il caching, invii il contenuto una volta, ottieni un identificatore di cache, e poi fai riferimento a quello. Il risparmio è secco: fino al 90% sul costo di input e una riduzione della latenza di 2-3 secondi per richiesta, perché il modello salta la fase di encoding.
Noi lo abbiamo applicato a un sistema di FAQ aziendale: prima ogni risposta costava $0,12 di input, dopo il caching siamo scesi a $0,015. Su 10.000 richieste al mese, il risparmio è stato di oltre 1.000 dollari. E la latenza percepita dall’utente è passata da 5 a 2 secondi.
Quando usarlo (e quando no)
Il caching è utile quando:
Sponsored Protocol
- Hai un system prompt lungo e statico (regole, tono, esempi fissi).
- Includi documenti di riferimento (manuali, PDF, interi database testuali).
- Gestisci conversazioni multi-turn dove la cronologia rimane stabile per molti scambi.
Non serve se:
- Il prompt cambia radicalmente a ogni richiesta (es. traduzioni di frasi singole).
- I token di input sono già pochi (sotto 1.000) – il caching ha un overhead di gestione minimo ma non necessario.
Configurazione base dell’API Claude con Python
Prima di tutto: installa il client ufficiale Anthropic. Noi usiamo sempre l’ultima versione stabile, in questo caso la anthropic SDK per Python.
pip install anthropicOttieni la tua API key da console.anthropic.com e impostala come variabile d’ambiente. Mai hardcodata nel codice.
import os
from anthropic import Anthropic
client = Anthropic(api_key=os.environ.get("ANTHROPIC_API_KEY"))
response = client.messages.create(
model="claude-sonnet-4-20250514", # modello che supporta caching
max_tokens=1024,
messages=[
{"role": "user", "content": "Ciao, chi sei?"}
]
)
print(response.content[0].text)Attenzione: non tutti i modelli supportano il caching. Al momento della scrittura, claude-sonnet-4 e claude-opus-4 lo supportano (verifica sempre la documentazione ufficiale).
Implementare il prompt caching passo passo
Il meccanismo è semplice: devi contrassegnare una parte del prompt come cacheable usando un header speciale o un campo nel content. Con l’SDK Python, usiamo il campo metadata all’interno del content block di tipo text. Ecco come:
from anthropic.types.message import Message
# Contenuto di sistema statico (da cache)
system_prompt = """Sei un assistente esperto di meccanica automobilistica.
Rispondi in modo preciso e conciso. Usa sempre la terminologia tecnica corretta.
Non inventare mai specifiche. Se non sai, ammettilo."""
# Chiamata con caching attivato sul system prompt
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
system=[
{
"type": "text",
"text": system_prompt,
"cache_control": {"type": "ephemeral"}
}
],
messages=[
{"role": "user", "content": "Qual è la differenza tra cambio manuale e automatico?"}
]
)
# Leggi l'header di cache dalla risposta
print("Cache hit:", response.cache_read_input_tokens)
print("Cache creation:", response.cache_creation_input_tokens)Il parametro cache_control: {"type": "ephemeral"} dice ad Anthropic di mettere in cache quel contenuto. La cache è ephemeral: dura circa 5 minuti di inattività, poi scade. Se continui a fare richieste con lo stesso identico blocco di sistema, la cache rimane attiva.
Sponsored Protocol
Leggere lo stato della cache
Nella risposta, due campi sono fondamentali:
cache_read_input_tokens: token letti dalla cache (zero se la cache era fredda).cache_creation_input_tokens: token scritti in cache (solo alla prima richiesta).
Monitorali per verificare il risparmio. A ogni richiesta successiva con lo stesso system prompt, cache_read_input_tokens dovrebbe essere positivo, mentre cache_creation_input_tokens sarà zero.
Prompt caching su messaggi utente: documenti e contesto lungo
Spesso il contesto statico non è solo il system prompt, ma anche documenti allegati (PDF, articoli). Puoi applicare il caching anche a blocchi di messaggi. Esempio: in una chat di supporto, il manuale utente rimane uguale per tutta la sessione.
# Simuliamo un documento lungo (es. estratto di manuale)
manuale = """
CAPITOLO 1: INSTALLAZIONE
1.1 Aprire l'imballaggio e verificare il contenuto...
... (1000 token di testo) ...
"""
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
system=[
{
"type": "text",
"text": "Sei un assistente tecnico per il prodotto X.",
"cache_control": {"type": "ephemeral"}
}
],
messages=[
{
"role": "user",
"content": [
{
"type": "text",
"text": maniale,
"cache_control": {"type": "ephemeral"}
},
{
"type": "text",
"text": "Come si installa il prodotto?"
}
]
}
]
)Attenzione: la cache è per blocco di testo esatto. Se modifichi anche un solo carattere, il contenuto viene ricreato. Assicurati che il testo da cache sia perfettamente stabile.
Sponsored Protocol
Errori comuni e debugging
Abbiamo visto clienti che non riescono a ottenere il cache hit. Ecco i controlli che facciamo noi:
- Modello non supportato: usa solo Sonnet 4 o Opus 4. I modelli più vecchi (Claude 3) non supportano il caching.
- Cache troppo breve: se fai richieste distanziate di più di 5 minuti, la cache scade. Per sessioni lunghe, devi mantenere il flusso attivo o ricreare la cache periodicamente.
- Stesso contenuto, ma formattazione diversa: spazi, newline, caratteri Unicode – la corrispondenza è esatta. Usa sempre la stessa stringa.
- Dimenticare di leggere gli header: se non controlli
cache_read_input_tokens, non sai se il caching sta funzionando. Noi lo loggiamo sempre in produzione.
Strategy di fallback
In produzione, gestiamo il caso in cui la cache non sia ancora stata creata (prima richiesta) o sia scaduta. Il codice potrebbe riscaldare la cache ogni 4 minuti con una richiesta fittizia se il carico è basso.
import time
def warm_cache(client, system_text, model="claude-sonnet-4-20250514"):
"""Mantiene la cache attiva inviando una richiesta minimal ogni 4 minuti."""
client.messages.create(
model=model,
max_tokens=1,
system=[{"type": "text", "text": system_text, "cache_control": {"type": "ephemeral"}}],
messages=[{"role": "user", "content": "ping"}]
)
# In un thread separato
while True:
warm_cache(client, system_prompt)
time.sleep(240) # 4 minutiOvviamente, valuta se il costo della richiesta di mantenimento è inferiore al risparmio. Di solito sì, perché una richiesta di 1 token è quasi gratis.
Sponsored Protocol
Integrazione completa: template per assistente conversazionale
Mettiamo tutto insieme: un assistente che mantiene la cache sul system prompt e su un documento di riferimento, e gestisce la cronologia utente.
import os
from anthropic import Anthropic
client = Anthropic(api_key=os.environ["ANTHROPIC_KEY"])
SYSTEM = """Sei un esperto di normativa GDPR per PMI.
Rispondi in italiano, chiaro, con riferimenti agli articoli del regolamento.
"""
CONTESTO = """Estratto del Regolamento UE 2016/679:
Articolo 5: Principi...
Articolo 17: Diritto alla cancellazione...
"""
cache_created = False
def ask(question: str, history: list = None) -> str:
global cache_created
messages = history or []
messages.append({"role": "user", "content": question})
# Costruiamo i content blocks
user_content = [
{"type": "text", "text": CONTESTO, "cache_control": {"type": "ephemeral"}},
{"type": "text", "text": question}
]
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=2048,
system=[{"type": "text", "text": SYSTEM, "cache_control": {"type": "ephemeral"}}],
messages=[
*messages[:-1], # storia precedente
{"role": "user", "content": user_content}
]
)
# Log per debug
print(f"Cache creation: {response.cache_creation_input_tokens}, Cache read: {response.cache_read_input_tokens}")
reply = response.content[0].text
messages.append({"role": "assistant", "content": reply})
return reply, messagesNota: non mettiamo il caching sulla cronologia delle conversazioni perché cambia a ogni turno. Solo i blocchi statici vanno in cache.
Sponsored Protocol
Misurare il risparmio reale
Anthropic fattura i token di cache a una tariffa ridotta (circa 1/10 del prezzo normale). Per claude-sonnet-4, i prezzi indicativi sono:
- Input normale: $3.00 / milione di token
- Input da cache: $0.30 / milione di token
- Scrittura cache: $3.75 / milione di token (paghi solo la prima volta)
Quindi, se il tuo prompt contiene 10.000 token fissi, e fai 100 richieste:
- Senza cache: 100 × 10.000 = 1.000.000 token input → $3,00
- Con cache: prima richiesta 10.000 token scrittura ($0,0375) + 99 richieste da cache: 99 × 10.000 = 990.000 token a $0,30/milione → $0,297 + $0,0375 = $0,3345
Risparmio: dal $3,00 a $0,33 – circa il 90%.
Cosa fare adesso
- Identifica i prompt statici nel tuo progetto: system prompt, documenti di riferimento, istruzioni fisse.
- Implementa il caching con
cache_controlcome mostrato sopra, partendo da un test isolato con un solo contenuto. - Monitora gli header di cache nella risposta per verificare l’effettivo riutilizzo.
- Valuta se scaldare la cache con un timer se le richieste sono sporadiche ma frequenti.
- Controlla la documentazione ufficiale per aggiornamenti sui modelli e tariffe: Anthropic Prompt Caching Guide.
Noi, di Meteora Web, applichiamo queste tecniche ogni giorno nei progetti dei nostri clienti. Se vuoi approfondire, guarda anche il nostro articolo sul benchmark ALE che mostra i limiti reali dell’AI – un altro tassello per non farsi illusioni sui numeri di marketing: ALE Benchmark.