Il tuo primo agente AI con tool use

Chiedi a un modello di linguaggio che ore sono e succede una cosa istruttiva: risponde con sicurezza un orario a caso. Non sta mentendo per cattiveria, semplicemente non ha modo di guardare l'orologio. Un LLM da solo sa solo prevedere la parola successiva sulla base di ciò che ha letto in addestramento; non può leggere un file, interrogare un database, mandare un'email o controllare il meteo di oggi. È un cervello geniale chiuso in una stanza senza finestre.

Un agente è quel cervello a cui hai dato delle mani. Il meccanismo tecnico che gliele dà si chiama tool use (o function calling): la capacità del modello di decidere, da solo, quando chiamare uno strumento esterno che gli fornisci, con quali argomenti, e poi di usare il risultato per proseguire. Questo articolo ti mostra cos'è davvero un agente, come è fatto uno strumento e come costruire il tuo primo loop agentico funzionante in poche righe di Python.

Cos'è un agente (e cosa non lo è)

Attorno alla parola "agente" c'è molto fumo. La definizione operativa, quella che ti serve per costruire, è sorprendentemente sobria: un agente è un LLM che gira dentro un loop, in cui a ogni giro può scegliere di usare uno strumento, osservare il risultato e decidere il passo successivo, finché il compito non è finito.

Questo schema ha un nome storico, ReAct (Reasoning + Acting), da un lavoro di ricerca del 2022 che ha retto meglio di quasi ogni altra idea di quell'epoca. L'intuizione è semplice: invece di far ragionare il modello a vuoto, gli si permette di alternare un pensiero ("mi serve sapere il meteo di Cagliari") a un'azione ("chiamo lo strumento meteo con città = Cagliari") e a un'osservazione ("24°C, sereno"). Ogni azione àncora il ragionamento a un fatto reale, e questo riduce drasticamente le allucinazioni: il modello non deve più indovinare un dato, lo va a prendere.

Attenzione a non confondere l'agente con la sua controparte più semplice, il workflow. In un workflow sei tu a decidere in anticipo la sequenza dei passi (prima cerca, poi riassumi, poi traduci). In un agente è il modello a decidere quali strumenti usare e in che ordine, adattandosi a ciò che osserva. La guida di riferimento di Anthropic sul tema è netta su questo punto: parti sempre dalla soluzione più semplice possibile e aggiungi complessità — cioè autonomia all'agente — solo quando serve davvero. Molti problemi che sembrano richiedere un agente si risolvono benissimo con una singola chiamata o un workflow rigido.

L'anatomia di uno strumento

Uno strumento, dal punto di vista del modello, non è codice: è una descrizione. Tu esegui il codice; al modello passi solo un biglietto da visita che dice tre cose:

La qualità di queste tre cose determina la qualità dell'agente più di qualsiasi altra scelta. Una descrizione vaga ("gestisce i dati") porta il modello a usare lo strumento a sproposito o a non usarlo mai; un nome ambiguo lo confonde quando ne ha dieci tra cui scegliere. La regola pratica: scrivi la descrizione di un tool come la scriveresti per un collega nuovo che non ha mai visto il tuo sistema. Se un umano capisce quando usarlo, il modello anche.

Il loop, in quattro passi

Il cuore di ogni agente è sempre lo stesso ciclo, indipendentemente dal linguaggio o dalla libreria:

  1. Chiedi al modello, passandogli il messaggio dell'utente e l'elenco degli strumenti disponibili.
  2. Guarda la risposta. Se il modello ha prodotto direttamente un testo, hai finito. Se invece ha chiesto di usare uno o più strumenti, procedi.
  3. Esegui gli strumenti che ha richiesto, con gli argomenti che ha indicato, e raccogli i risultati.
  4. Rimanda i risultati al modello e torna al passo 1.

Il loop si chiude quando il modello smette di chiedere strumenti e produce la risposta finale. Questa è l'intera magia: non c'è nient'altro. Framework come l'Agent SDK o LangGraph automatizzano questo ciclo e aggiungono comodità (memoria, gestione degli errori, più agenti che collaborano), ma sotto il cofano fanno esattamente questi quattro passi. Costruirlo a mano una volta ti serve proprio a demistificarli.

Un agente minimo in Python

Ecco il loop completo con l'API di Claude. È volutamente essenziale: un solo strumento, finto, per concentrarsi sulla meccanica. Se non hai mai fatto una chiamata API, parti prima dalla guida alla prima chiamata in Python.

import anthropic

client = anthropic.Anthropic()  # legge la chiave da ANTHROPIC_API_KEY

# 1. Il "biglietto da visita" dello strumento: nome, descrizione, schema
tools = [
    {
        "name": "get_meteo",
        "description": "Restituisce il meteo attuale di una città italiana. "
                       "Usalo quando l'utente chiede che tempo fa.",
        "input_schema": {
            "type": "object",
            "properties": {
                "citta": {
                    "type": "string",
                    "description": "Nome della città, es. 'Cagliari'"
                }
            },
            "required": ["citta"],
        },
    }
]

# 2. La funzione vera che fa il lavoro (qui finta, per l'esempio)
def get_meteo(citta):
    return f"A {citta} ci sono 24°C e cielo sereno."

messaggi = [{"role": "user", "content": "Che tempo fa a Cagliari?"}]

# 3. Il loop: chiedi, esegui i tool richiesti, ripeti
while True:
    risposta = client.messages.create(
        model="claude-sonnet-5",
        max_tokens=1024,
        tools=tools,
        messages=messaggi,
    )

    if risposta.stop_reason != "tool_use":
        # nessun altro strumento richiesto: è la risposta finale
        print(risposta.content[0].text)
        break

    # il modello ha chiesto uno o più strumenti: eseguili
    messaggi.append({"role": "assistant", "content": risposta.content})
    risultati = []
    for blocco in risposta.content:
        if blocco.type == "tool_use":
            output = get_meteo(**blocco.input)
            risultati.append({
                "type": "tool_result",
                "tool_use_id": blocco.id,
                "content": output,
            })
    messaggi.append({"role": "user", "content": risultati})

Segui il flusso: alla prima chiamata il modello non risponde col meteo (non lo sa), ma chiede di usare get_meteo con citta="Cagliari". Il tuo codice esegue la funzione, rimanda il risultato, e alla seconda chiamata il modello formula la risposta in linguaggio naturale. Hai appena costruito un agente. Il passo successivo — un agente utile — consiste solo nel sostituire la funzione finta con una vera (una chiamata a un servizio meteo, una query al tuo database, la lettura di un file) e nell'aggiungere altri strumenti.

Gli errori da principiante

Chi costruisce il primo agente inciampa quasi sempre negli stessi punti, e conoscerli in anticipo ti risparmia ore.

Troppi strumenti tutti insieme

La tentazione è dare all'agente venti strumenti "così se la cava". Il risultato è l'opposto: più strumenti simili tra loro, più il modello fa scelte sbagliate. Parti con due o tre strumenti ben distinti e aggiungine solo quando un compito reale lo richiede.

Descrizioni pigre

Una descrizione come "strumento per gli ordini" non dice al modello quando usarlo. Scrivi invece "Cerca un ordine dato il suo codice; usalo quando l'utente menziona un numero d'ordine". La differenza tra un agente che funziona e uno che sbrocca sta quasi sempre qui, non nel modello.

Nessuna gestione degli errori

Nell'esempio la funzione va sempre a buon fine. Nel mondo reale il database va giù, il codice città non esiste, l'API risponde con un errore. Restituisci al modello un tool_result che descrive il problema ("città non trovata") invece di far crashare il programma: spesso il modello si corregge da solo e riprova con argomenti diversi.

Nessun freno al loop

Un agente che può chiamare strumenti all'infinito, prima o poi, lo fa — e ti brucia budget e tempo. Metti sempre un tetto al numero di giri (ad esempio dieci) e interrompi con un messaggio chiaro se lo superi. La libertà dell'agente va sempre accompagnata da un guinzaglio.

Prova subito

Prendi l'esempio qui sopra e fallo evolvere in tre mosse, una alla volta:

  1. Rendi vero il singolo strumento. Sostituisci il return finto di get_meteo con una chiamata reale a un'API meteo gratuita (ce ne sono diverse senza chiave). Verifica che l'agente ora risponda con dati reali.
  2. Aggiungi un secondo strumento diverso, per esempio calcola che valuta un'espressione matematica. Poi fai una domanda che li usi entrambi ("Che tempo fa a Cagliari e quanto fa 18 per 7?") e osserva il modello scegliere lo strumento giusto per ogni pezzo.
  3. Metti il guinzaglio. Aggiungi un contatore che interrompe il loop dopo dieci giri e stampa un messaggio di errore. Prova a scrivere una descrizione volutamente ambigua e guarda cosa cambia nel comportamento.

Quando questi tre passi ti risultano naturali, hai capito il 90% di come funziona qualsiasi agente in circolazione — dai copiloti di codice agli assistenti che prenotano viaggi. Il resto è la stessa idea, ripetuta con strumenti migliori.