Claude, la famiglia di modelli di Anthropic, e' tra le piu' usate per assistenti, analisi di documenti e agenti software. Se hai gia' provato ChatGPT o Gemini da codice, questa guida ti mostra come fare lo stesso con Claude in Python: dalla chiave API al primo messaggio, fino allo streaming, all'uso degli strumenti (tool use) e all'output strutturato in JSON. Tutti gli esempi sono pronti da copiare.

A chi serve e cosa otterrai

La guida e' pensata per chi sa muovere i primi passi in Python e vuole integrare Claude in uno script o in un'applicazione. Alla fine saprai fare una chiamata di base, gestire una conversazione, mostrare le risposte in tempo reale, far usare al modello i tuoi strumenti e ottenere risposte in formato strutturato. Non servono conoscenze di machine learning: si tratta di chiamare un'API.

Prerequisiti

  • Python 3.8 o superiore.
  • Un account su console.anthropic.com con una chiave API e un metodo di pagamento (le chiamate sono a consumo; ci sono di solito crediti iniziali per provare).
  • Nozioni di base di riga di comando.

Passo 1: chiave API e installazione

Dalla Console di Anthropic, crea una chiave API dalla sezione API Keys e copiala (la vedrai una sola volta). Non inserirla mai nel codice: impostala come variabile d'ambiente.

# macOS/Linux
export ANTHROPIC_API_KEY="la-tua-chiave"
# Windows (PowerShell)
setx ANTHROPIC_API_KEY "la-tua-chiave"

Poi installa l'SDK ufficiale:

pip install anthropic

Passo 2: il primo messaggio

Ecco la chiamata minima. L'SDK legge automaticamente la chiave dalla variabile d'ambiente.

import anthropic

client = anthropic.Anthropic()

response = client.messages.create(
    model="claude-opus-5",
    max_tokens=1024,
    messages=[
        {"role": "user", "content": "Spiega in 3 punti cos'e' un'API, per un principiante."}
    ],
)

for blocco in response.content:
    if blocco.type == "text":
        print(blocco.text)

Il risultato atteso e' una spiegazione in tre punti. Nota due cose: max_tokens e' il tetto massimo della risposta (se e' troppo basso la risposta viene troncata), e response.content e' una lista di blocchi: si controlla sempre blocco.type prima di leggerne il testo.

Bastano poche righe di Python per fare la prima chiamata alle API di Claude.

Passo 3: scegliere il modello giusto

Anthropic offre modelli con diversi equilibri tra intelligenza, velocita' e costo. I principali al momento:

ModelloIdentificativoQuando usarlo
Claude Opus 5claude-opus-5Compiti complessi, ragionamento, codice, agenti
Claude Sonnet 5claude-sonnet-5Ottimo equilibrio per la maggior parte delle applicazioni
Claude Haiku 4.5claude-haiku-4-5Compiti semplici, alto volume, latenza minima

Come regola pratica: parti da Opus 5 per la qualita', passa a Sonnet 5 quando devi gestire molti volumi a costo piu' basso, e usa Haiku 4.5 per classificazioni o estrazioni semplici dove conta la velocita'.

Passo 4: prompt di sistema e conversazione

Il "system prompt" definisce il comportamento dell'assistente. L'API e' senza stato: per una conversazione bisogna rimandare tutta la cronologia a ogni chiamata.

messaggi = [{"role": "user", "content": "Mi chiamo Andrea."}]

r1 = client.messages.create(
    model="claude-sonnet-5",
    max_tokens=512,
    system="Sei un assistente conciso che risponde in italiano.",
    messages=messaggi,
)
risposta1 = next(b.text for b in r1.content if b.type == "text")
messaggi.append({"role": "assistant", "content": risposta1})
messaggi.append({"role": "user", "content": "Come mi chiamo?"})

r2 = client.messages.create(
    model="claude-sonnet-5", max_tokens=512,
    system="Sei un assistente conciso che risponde in italiano.",
    messages=messaggi,
)
print(next(b.text for b in r2.content if b.type == "text"))

Alla seconda domanda Claude risponde "Andrea" perche' gli abbiamo passato la cronologia. Il primo messaggio deve sempre essere dell'utente (user).

Passo 5: streaming, per risposte in tempo reale

Per mostrare il testo mentre viene generato — utile in una chat — si usa lo streaming. E' anche la scelta consigliata quando max_tokens e' alto, per evitare timeout.

with client.messages.stream(
    model="claude-sonnet-5",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Scrivi una breve favola sulla volpe e l'uva."}],
) as stream:
    for testo in stream.text_stream:
        print(testo, end="", flush=True)

Vedrai la favola comparire parola per parola. Con stream.get_final_message() puoi comunque recuperare il messaggio completo alla fine.

Passo 6: far usare a Claude i tuoi strumenti (tool use)

Il "tool use" permette a Claude di chiamare funzioni che scrivi tu: cercare in un database, interrogare un'API meteo, fare un calcolo. Tu definisci lo strumento; Claude decide quando usarlo e con quali argomenti; il tuo codice lo esegue e restituisce il risultato.

tools = [{
    "name": "meteo",
    "description": "Restituisce il meteo attuale per una citta'.",
    "input_schema": {
        "type": "object",
        "properties": {"citta": {"type": "string", "description": "Nome della citta'"}},
        "required": ["citta"],
    },
}]

r = client.messages.create(
    model="claude-opus-5", max_tokens=1024,
    tools=tools,
    messages=[{"role": "user", "content": "Che tempo fa a Milano?"}],
)

# Claude risponde con un blocco tool_use: eseguiamo la funzione e restituiamo il risultato
if r.stop_reason == "tool_use":
    blocco = next(b for b in r.content if b.type == "tool_use")
    risultato = "18 gradi, sereno"  # qui chiameresti la tua vera API meteo
    finale = client.messages.create(
        model="claude-opus-5", max_tokens=1024, tools=tools,
        messages=[
            {"role": "user", "content": "Che tempo fa a Milano?"},
            {"role": "assistant", "content": r.content},
            {"role": "user", "content": [
                {"type": "tool_result", "tool_use_id": blocco.id, "content": risultato}
            ]},
        ],
    )
    print(next(b.text for b in finale.content if b.type == "text"))

Il risultato atteso e' una frase come "A Milano ci sono 18 gradi con cielo sereno". Il tool use e' il mattone su cui si costruiscono gli agenti: si concatenano piu' strumenti in un ciclo finche' il modello non ha finito.

Passo 7: analizzare immagini e PDF

Claude e' multimodale: puo' leggere immagini e documenti. Per inviare un'immagine si aggiunge un blocco image al messaggio. Ecco un esempio che chiede di descrivere una foto passata come URL:

r = client.messages.create(
    model="claude-sonnet-5", max_tokens=512,
    messages=[{
        "role": "user",
        "content": [
            {"type": "image", "source": {"type": "url", "url": "https://esempio.it/foto.jpg"}},
            {"type": "text", "text": "Cosa c'e' in questa immagine? Rispondi in italiano."},
        ],
    }],
)
print(next(b.text for b in r.content if b.type == "text"))

Allo stesso modo si possono inviare PDF con un blocco document, utile per riassumere contratti o estrarre dati da fatture. E' una delle funzioni piu' pratiche per automatizzare il lavoro d'ufficio.

Passo 8: far ragionare Claude sui problemi difficili

Sui compiti che richiedono ragionamento — matematica, logica, analisi complesse — si puo' attivare il "pensiero adattivo", che lascia al modello decidere quanto ragionare prima di rispondere:

r = client.messages.create(
    model="claude-opus-5", max_tokens=4096,
    thinking={"type": "adaptive"},
    messages=[{"role": "user", "content": "Un treno parte alle 9:15 e viaggia a 120 km/h. Quando avra' percorso 300 km?"}],
)
for b in r.content:
    if b.type == "text":
        print(b.text)

Con il pensiero adattivo attivo, il modello dedica piu' "riflessione" ai problemi che lo richiedono e risponde direttamente a quelli semplici. Per bilanciare qualita' e costo si puo' regolare il livello di "sforzo" tramite il parametro output_config, indicando valori come low, medium o high a seconda di quanto e' impegnativo il compito.

Passo 9: output strutturato in JSON

Quando ti serve una risposta in un formato preciso — per esempio da salvare in un database — puoi vincolare l'output a uno schema JSON. Un modo semplice e' usare uno strumento con schema stretto, oppure chiedere direttamente il formato nel prompt e validare il risultato. Per estrazioni affidabili conviene definire con chiarezza i campi desiderati (nome, email, categoria) e istruire il modello a restituire solo JSON valido, poi caricarlo con json.loads() gestendo eventuali errori.

Controllare i costi

Le API si pagano a token (all'incirca, pezzi di parola) in ingresso e in uscita. Indicativamente Opus 5 costa 5 dollari per milione di token in ingresso e 25 in uscita; Sonnet 5 3 e 15; Haiku 4.5 1 e 5. Consigli pratici: scegli il modello piu' piccolo che svolge bene il compito; imposta max_tokens al minimo necessario; e per contesti lunghi e ripetuti usa la memorizzazione della cache dei prompt, che riduce sensibilmente il costo delle parti fisse riutilizzate. Puoi anche stimare i token prima di inviare con client.messages.count_tokens(...).

Errori comuni e soluzioni

  • 401 authentication_error: chiave mancante o errata. Verifica la variabile ANTHROPIC_API_KEY.
  • 404 not_found: identificativo del modello sbagliato. Usa esattamente le stringhe indicate (es. claude-opus-5), senza inventare suffissi.
  • Risposta troncata: stop_reason vale max_tokens. Aumenta max_tokens o usa lo streaming.
  • 429 rate_limit: troppe richieste. L'SDK riprova in automatico con backoff; per volumi alti valuta la Batch API.

Come proseguire

Da qui puoi costruire un agente completo concatenando piu' strumenti, aggiungere l'analisi di PDF e immagini (Claude e' multimodale), o passare alla Batch API per elaborare grandi quantita' di richieste a meta' prezzo. La documentazione ufficiale di Anthropic e l'SDK Python su GitHub contengono esempi per ognuno di questi scenari. Il modello mentale, pero', resta quello visto qui: costruisci l'elenco dei messaggi, scegli il modello, chiama messages.create e gestisci la risposta a blocchi.