f in x
Claude API con Python: integrazione completa e prompt caching per risparmiare costi e latenza
> cd .. / HUB_EDITORIALE > Visualizza in Inglese
Analisi dei dati e metriche

Claude API con Python: integrazione completa e prompt caching per risparmiare costi e latenza

[2026-06-11] Author: Ing. Calogero Bono

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 anthropic

Ottieni 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 minuti

Ovviamente, 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, messages

Nota: 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

  1. Identifica i prompt statici nel tuo progetto: system prompt, documenti di riferimento, istruzioni fisse.
  2. Implementa il caching con cache_control come mostrato sopra, partendo da un test isolato con un solo contenuto.
  3. Monitora gli header di cache nella risposta per verificare l’effettivo riutilizzo.
  4. Valuta se scaldare la cache con un timer se le richieste sono sporadiche ma frequenti.
  5. 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.

Ing. Calogero Bono

> AUTHOR_EXTRACTED

Ing. Calogero Bono

Ingegnere Informatico, co-fondatore di Meteora Web. Esperto in architetture software, sicurezza informatica e sviluppo sistemi scalabili.
[ Read Full Dossier ]

> METEORA_WEB // WEB AGENCY

Costruiamo la presenza digitale che la tua azienda merita.

Siti web, social, pubblicità online, e-commerce e hosting performante: ingegnerizzati con metodo da ingegneri informatici a Sciacca, per tutta Italia.

> MW_JOURNAL

> READ_ALL()