Python & AI Tutorials Logo
LangChain & LangGraph

1. Configurazione e primo successo

Benvenuto nel tuo percorso per costruire agenti(agent) di IA con Python! Entro la fine di questo capitolo, avrai effettuato la tua prima chiamata riuscita a un Large Language Model (LLM) e capito esattamente cosa è successo dietro le quinte. Questa è la tua base per tutto ciò che segue.

Prerequisiti

Pubblico e assunzioni

Questo libro è scritto per sviluppatori Python che vogliono costruire agenti di IA ma non hanno esperienza precedente con gli LLM o con framework di IA. Presupponiamo che tu sia a tuo agio con:

  • Fondamenti di Python: funzioni, classi, import, strutture dati di base
  • Python 3.10+: dovresti avere Python 3.10 o superiore installato sul tuo sistema
  • Ambienti virtuali: creazione e attivazione di venv con python -m venv
  • Gestione dei pacchetti: installazione di pacchetti con pip
  • Variabili d'ambiente: impostazione e lettura di variabili d'ambiente nella tua shell
  • Chiavi API: capire cosa sono le chiavi API e come ottenerle dai provider di servizio

Se uno qualsiasi di questi concetti non ti è familiare, consigliamo di ripassarli separatamente prima di continuare. La documentazione Python e i tutorial sugli ambienti virtuali e su pip sono ottimi punti di partenza.

Cosa NON diamo per scontato: non hai bisogno di alcuna base in machine learning, reti neurali, transformer o teoria dell’IA. Spiegheremo i concetti specifici degli LLM man mano che li incontriamo, collegandoli sempre a pattern di programmazione familiari.

Convenzione del modello

In tutto questo libro, useremo GPT-5-mini come modello predefinito per gli esempi. Ecco perché:

  • Ampia disponibilità: l’API di OpenAI è accessibile a livello globale con una registrazione semplice
  • Velocità ragionevole: con uno sforzo di ragionamento minimo, le risposte arrivano abbastanza rapidamente per uno sviluppo iterativo
  • Conveniente: a $0.25 per milione di token in input e $2.00 per milione di token in output (a partire dal 2026), è economico per apprendimento e sperimentazione
  • Capacità sufficienti: gestisce bene la stragrande maggioranza dei compiti pratici per agenti di IA

Quando vedi esempi di codice senza un modello esplicitamente specificato, presumi che stiamo usando GPT-5-mini. Nel Capitolo 2, esploreremo l’intero panorama dei modelli disponibili (Claude, Gemini e altre varianti GPT) e discuteremo quando potresti scegliere alternative in base alla dimensione della finestra di contesto, al costo o a capacità specializzate.

1.1) Cos'è un LLM?

Prima di scrivere qualsiasi codice, stabiliamo con cosa stiamo effettivamente lavorando. Un Large Language Model (LLM) è una rete neurale addestrata su enormi quantità di dati testuali per predire quale testo dovrebbe arrivare dopo in una sequenza.

Pensa a un sistema di completamento automatico estremamente sofisticato. Quando digiti sul telefono e lui suggerisce la parola successiva, quella è una versione semplice di ciò che fanno gli LLM. Ma gli LLM operano su una scala e con una sofisticazione che consentono loro di:

  • Generare risposte coerenti e contestualmente appropriate alle domande
  • Scrivere codice, saggi, email e altri contenuti strutturati
  • Tradurre tra lingue
  • Riassumere documenti lunghi
  • Estrarre informazioni da testo non strutturato
  • E molto altro

In cosa gli LLM differiscono dal software tradizionale

Il software tradizionale segue regole esplicite che programmi:

python
def calculate_discount(price, customer_type):
    if customer_type == "premium":
        return price * 0.8  # sconto del 20%
    elif customer_type == "regular":
        return price * 0.95  # sconto del 5%
    else:
        return price

Questa funzione produce sempre lo stesso output a parità di input. La logica è deterministica e trasparente.

Gli LLM funzionano diversamente. Invece di regole esplicite, usano pattern appresi dai dati di addestramento per generare risposte. Fornisci un testo di input (chiamato prompt(prompt)), e il modello genera un testo di output (chiamato completion o response).

python
# Esempio concettuale - presto scriveremo codice reale
response = llm.generate("Qual è un buono sconto per i clienti premium?")
# Esempio di output: "I clienti premium ricevono tipicamente sconti del 15-25%..."

L’LLM non ha una percentuale di sconto codificata in modo rigido. Genera una risposta in base ai pattern appresi durante l’addestramento. Questo significa:

  1. Le risposte possono variare: lo stesso prompt potrebbe produrre risposte leggermente diverse ogni volta
  2. Il comportamento è appreso, non programmato: guidi il modello con i prompt invece di scrivere logica esplicita
  3. Le capacità emergono dalla scala: il modello può gestire compiti per cui non è stato addestrato esplicitamente

Terminologia chiave

Definiamo alcuni termini che incontrerai continuamente:

  • Prompt(prompt): il testo di input che invii al modello. Consideralo come la "domanda" o "istruzione"
  • Completion/Response: il testo che il modello genera in risposta al tuo prompt
  • Token(token): l’unità di base con cui lavorano gli LLM. Approssimativamente, 1 token ≈ 4 caratteri o ¾ di una parola. "Hello world" è circa 2 token
  • Finestra di contesto(context window): la quantità massima di testo (in token) che il modello può elaborare in una volta. GPT-5-mini ha una finestra di contesto da 400K token
  • Temperatura(temperature): un parametro che controlla la casualità. Più bassa (0.0-0.3) = più focalizzato e deterministico. Più alta (0.7-1.0) = più creativo e vario

Cosa gli LLM possono e non possono fare

Capire cosa gli LLM fanno in modo affidabile—e cosa sembra soltanto che facciano—è essenziale per costruire agenti di IA robusti.

Gli LLM sono eccellenti nel:

  • Comprendere e generare linguaggio naturale: possono interpretare l’intento, generare risposte coerenti e gestire formulazioni complesse
"Voglio un rimborso" → Riconosce l’intento: refund_request
"Riassumi questo documento" → Produce un riassunto conciso
  • Seguire istruzioni nei prompt: quando ricevono indicazioni chiare, possono produrre output strutturati come JSON o testo formattato
"Converti in JSON: John Smith, 32, vive a Boston"
→ {"name": "John Smith", "age": 32, "city": "Boston"}
  • Riconoscere pattern nel testo: analisi del sentiment, categorizzazione ed estrazione di informazioni funzionano in modo affidabile

  • Generare codice e contenuti strutturati: possono scrivere Python valido, SQL o altri output formattati se correttamente istruiti

  • Ragionamento passo dopo passo: quando viene esplicitamente richiesto di "pensare passo per passo", scompongono i problemi in modo metodico

Limiti degli LLM:

  • Non sono un database: non recuperano fatti—generano testo statisticamente plausibile. Possono affermare con sicurezza informazioni errate che suonano autorevoli.
"Quando è stato rilasciato Python 4.0?" 
→ Potrebbe generare "Python 4.0 è stato rilasciato nel 2023" (falso, ma plausibile)
  • Non sono una calcolatrice: predicono come dovrebbe apparire una risposta invece di calcolarla. L’aritmetica semplice spesso funziona; la matematica complessa fallisce in modo imprevedibile.
"Quanto fa 8,247 × 6,839?" → Potrebbe produrre un risultato errato che sembra ragionevole
  • Non sono deterministici: lo stesso prompt può produrre output diversi ogni volta. Questa variabilità è controllata dal parametro temperatura.

  • Non sono sempre accurati: generano testo plausibile indipendentemente dalla correttezza fattuale. Le "allucinazioni"—informazioni dettagliate, sicure, ma completamente inventate—si verificano frequentemente.

L’intuizione chiave: costruisci agenti che combinano gli LLM (per comprensione e decision-making) con strumenti tradizionali (per calcolo, recupero dati e operazioni fattuali). Implementeremo questo pattern a partire dal Capitolo 13, dove l’LLM decide quando usare una calcolatrice invece di tentare la matematica da solo.

Cosa imparerai

In questo libro, imparerai a costruire agenti di IA - sistemi in cui l’LLM decide autonomamente quali azioni intraprendere per raggiungere obiettivi, invece di seguire una logica predeterminata. Esploreremo questo paradigma in profondità nel Capitolo 2.

1.2) Installare le dipendenze

Impostiamo il tuo ambiente di sviluppo. Creeremo una struttura di progetto pulita e installeremo LangChain, il framework che useremo per costruire agenti di IA.

Verificare l'installazione di Python

Per prima cosa, assicurati che Python sia installato sul tuo sistema. Consigliamo Python 3.10 o superiore (a partire dal 2026, Python 3.13 o 3.14 sono buone scelte).

Controlla la tua versione di Python:

bash
python --version
# or
python3 --version

Dovresti vedere un output come Python 3.13.x o Python 3.14.x.

Se Python non è installato:

  • macOS:

    • Scarica da python.org
    • Oppure usa Homebrew: brew install python@3.14
  • Windows:

    • Scarica da python.org
    • Seleziona "Add Python to PATH" durante l’installazione
  • Linux:

    • Ubuntu/Debian: sudo apt update && sudo apt install python3.14
    • Fedora: sudo dnf install python3.14

Dopo l’installazione, verifica di nuovo con python --version.

Nota: su alcuni sistemi, potrebbe essere necessario usare python3 invece di python. In tutto questo libro, se python non funziona, prova python3.

Crea il tuo progetto

Apri il terminale e crea una nuova directory per il tuo progetto:

bash
mkdir agentic-ai-project
cd agentic-ai-project

Crea un ambiente virtuale per isolare le dipendenze:

bash
python -m venv venv

Attiva l’ambiente virtuale:

bash
# On macOS/Linux:
source venv/bin/activate
 
# On Windows:
venv\Scripts\activate

Dovresti vedere (venv) apparire nel prompt del terminale, a indicare che l’ambiente virtuale è attivo.

Installa LangChain e OpenAI

Installeremo l’integrazione OpenAI di LangChain, che include tutto ciò che serve per lavorare con i modelli di OpenAI:

bash
pip install langchain-openai

Questo installa langchain-openai insieme alle sue dipendenze, incluse langchain-core (le astrazioni core di LangChain) e il client Python di OpenAI. Dovresti vedere un output che conferma l’installazione di più pacchetti.

Verifica l’installazione:

bash
pip show langchain-openai

Dovresti vedere i dettagli del pacchetto installato, inclusi il numero di versione e la posizione. Questo conferma che l’installazione è andata a buon fine.

Ottieni la tua chiave API OpenAI

Per chiamare i modelli di OpenAI, ti serve una chiave API:

  1. Vai su platform.openai.com
  2. Registrati o accedi
  3. Vai a API Keys nelle impostazioni del tuo account
  4. Clicca "Create new secret key"
  5. Copia la chiave (inizia con sk-)

⚠️ Avviso di sicurezza: tratta questa chiave come una password. Non inserirla mai nel controllo versione e non condividerla pubblicamente. Chiunque abbia la tua chiave può fare chiamate API che verranno addebitate al tuo account.

Imposta la tua chiave API come variabile d'ambiente

Il modo consigliato per fornire la tua chiave API è tramite una variabile d’ambiente:

bash
# On macOS/Linux:
export OPENAI_API_KEY='sk-your-actual-key-here'
 
# On Windows (Command Prompt):
set OPENAI_API_KEY=sk-your-actual-key-here
 
# On Windows (PowerShell):
$env:OPENAI_API_KEY='sk-your-actual-key-here'

Nota: questa impostazione è temporanea e verrà persa quando chiuderai il terminale. Per una soluzione permanente, puoi:

  • Aggiungere il comando export al file di configurazione della shell (.bashrc, .zshrc, ecc.)
  • Usare un file .env (lo imposteremo nel Capitolo 3 per una migliore organizzazione del progetto)

Per ora, l’impostazione temporanea è sufficiente per continuare.

Verifica che sia impostata:

bash
# On macOS/Linux:
echo $OPENAI_API_KEY
 
# On Windows (Command Prompt):
echo %OPENAI_API_KEY%
 
# On Windows (PowerShell):
echo $env:OPENAI_API_KEY

Dovresti vedere stampata la tua chiave API. In caso contrario, ripeti il comando export/set e assicurati che non ci siano refusi.

1.3) La tua prima chiamata a un LLM

Ora la parte entusiasmante: facciamo la tua prima chiamata a un LLM. Crea un file chiamato first_call.py:

python
# first_call.py
from langchain_openai import ChatOpenAI
 
# Inizializza l'LLM
llm = ChatOpenAI(model="gpt-5-mini")
 
# Invia un prompt e ottieni una risposta
response = llm.invoke("Cos'è LangChain?")
 
# Stampa la risposta
print(response.content)

Eseguilo:

bash
python first_call.py

Dovresti vedere un output simile a questo (la formulazione esatta può variare):

LangChain è un framework progettato per semplificare lo sviluppo di applicazioni basate su Large Language Model (LLM). Fornisce strumenti e astrazioni per costruire catene di chiamate agli LLM, integrare fonti dati esterne, gestire i prompt e creare agenti in grado di interagire con varie API e database. LangChain rende più semplice creare applicazioni di IA complesse fornendo componenti e pattern riutilizzabili.

Congratulazioni! Hai appena effettuato la tua prima chiamata a un LLM. Vediamo nel dettaglio cosa è successo in questo codice.

Risoluzione dei problemi: se vedi un errore:

  • AuthenticationError: la chiave API non è valida o non è impostata → controlla la variabile d’ambiente OPENAI_API_KEY (vedi sezione 1.2)
  • RateLimitError: richieste troppo rapide o limite di utilizzo superato → aspetta qualche secondo e riprova, oppure controlla l’uso su platform.openai.com/usage
  • APIConnectionError: problema di connettività di rete → controlla la tua connessione Internet

Comprendere il codice

Importa il wrapper dell’LLM:

python
from langchain_openai import ChatOpenAI

ChatOpenAI è il wrapper di LangChain attorno ai modelli chat di OpenAI. Gestisce per te l’autenticazione API, la formattazione delle richieste e il parsing delle risposte.

Inizializza il modello:

python
llm = ChatOpenAI(model="gpt-5-mini")

Questo crea un’istanza configurata per usare GPT-5-mini. Dietro le quinte, LangChain legge la variabile d’ambiente OPENAI_API_KEY per l’autenticazione. Potresti anche passare la chiave in modo esplicito:

python
llm = ChatOpenAI(model="gpt-5-mini", api_key="sk-your-key")

Ma usare variabili d’ambiente è più sicuro e flessibile.

Invoca il modello:

python
response = llm.invoke("Cos'è LangChain?")

Il metodo invoke() invia il tuo prompt all’API di OpenAI e attende la risposta completa. Questa è una chiamata sincrona - il tuo programma si ferma finché non arriva la risposta.

Accedi al contenuto della risposta:

python
print(response.content)

L’oggetto risposta contiene diversi campi. Il campo .content contiene il testo effettivo generato dal modello. Esploreremo altri campi nella prossima sezione.

Prova prompt diversi

Modifica il prompt per vedere come il modello risponde a input diversi:

python
# first_call.py
from langchain_openai import ChatOpenAI
 
llm = ChatOpenAI(model="gpt-5-mini")
 
# Prova prompt diversi
prompts = [
    "Spiega i decorator di Python in una frase.",
    "Quanto fa 15 * 23?",
    "Elenca tre vantaggi dell'uso dei type hint in Python.",
]
 
for prompt in prompts:
    response = llm.invoke(prompt)
    print(f"Prompt: {prompt}")
    print(f"Response: {response.content}\n")

Il modello gestisce diversi tipi di richieste - spiegazioni, calcoli ed elenchi strutturati. Noterai che le risposte possono variare leggermente se esegui lo stesso prompt più volte. Questo è un comportamento normale - esploreremo perché succede e come controllarlo nel Capitolo 2.

1.4) Cosa è appena successo? (Flusso richiesta → modello → risposta)

Esaminiamo esattamente cosa è successo quando hai chiamato llm.invoke(). Capire questo flusso è fondamentale per costruire agenti di IA affidabili.

Il ciclo completo richiesta-risposta

GPT-5-miniAPI di OpenAILibreria LangChainIl tuo codiceGPT-5-miniAPI di OpenAILibreria LangChainIl tuo codicellm.invoke("Cos'è LangChain?")Formatta la richiesta con la chiave APIPOST /v1/chat/completionsElabora il promptGenera la rispostaRestituisce la risposta JSONEsegue il parsing della rispostaRestituisce un oggetto AIMessage

Ripercorriamo ciascun passaggio:

Passaggio 1: Il tuo codice chiama invoke()

python
response = llm.invoke("Cos'è LangChain?")

Il metodo invoke() è la tua interfaccia principale verso l’LLM. Passi una stringa di prompt e lui restituisce un oggetto risposta contenente la risposta del modello. Dietro questa semplice chiamata, avvengono automaticamente diversi passaggi.

Passaggio 2: LangChain formatta la richiesta

LangChain trasforma la tua stringa in una richiesta API strutturata. Dietro le quinte, crea un payload JSON come questo:

json
{
  "model": "gpt-5-mini",
  "messages": [
    {
      "role": "user",
      "content": "Cos'è LangChain?"
    }
  ],
  "temperature": 1.0
}

L’array messages è il modo in cui i modelli chat ricevono input. Ogni messaggio ha un role (user, assistant o system) e un content (il testo). Esploreremo i ruoli dei messaggi nel Capitolo 4.

Passaggio 3: Chiamata API verso OpenAI

LangChain invia una richiesta HTTPS POST all’endpoint API di OpenAI:

POST https://api.openai.com/v1/chat/completions
Authorization: Bearer sk-your-api-key
Content-Type: application/json
 
{request payload}

La tua chiave API autentica la richiesta. I server di OpenAI ricevono la richiesta e la instradano al modello specificato.

Passaggio 4: Il modello elabora il prompt

GPT-5-mini riceve il tuo prompt e genera una risposta token per token. Il modello:

  1. Converte il tuo testo in token (rappresentazioni numeriche)
  2. Elabora i token attraverso i suoi livelli di rete neurale
  3. Predice il token successivo più probabile
  4. Ripete finché non genera una risposta completa o raggiunge una condizione di arresto

Questo avviene sui server di OpenAI - il tuo codice aspetta soltanto il risultato.

Passaggio 5: L’API restituisce la risposta

L’API di OpenAI rimanda una risposta JSON:

json
{
  "id": "chatcmpl-8x7y9z",
  "object": "chat.completion",
  "created": 1704067200,
  "model": "gpt-5-mini",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "LangChain è un framework progettato per semplificare..."
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 12,
    "completion_tokens": 58,
    "total_tokens": 70
  }
}

Campi chiave:

  • message.content: il testo generato
  • usage: conteggi token per fatturazione e monitoraggio
  • finish_reason: perché la generazione si è fermata ("stop" = completamento naturale, "length" = raggiunto il limite di token)

Passaggio 6: LangChain esegue il parsing della risposta

LangChain converte il JSON in un oggetto Python con cui puoi lavorare:

python
from langchain_openai import ChatOpenAI
 
llm = ChatOpenAI(model="gpt-5-mini")
response = llm.invoke("What is LangChain?")
 
# Esplora l'oggetto response
print(f"Content: {response.content}")
print(f"Type: {type(response)}")
print(f"Response metadata: {response.response_metadata}")

Output:

Content: LangChain è un framework progettato per semplificare...
Type: <class 'langchain_core.messages.ai.AIMessage'>
Response metadata: {'token_usage': {'completion_tokens': 58, 'prompt_tokens': 12, 'total_tokens': 70}, 'model_name': 'gpt-5-mini', 'finish_reason': 'stop'}

La risposta è un oggetto AIMessage con diversi attributi utili:

  • content: il testo generato (quello che di solito ti serve)
  • response_metadata: uso dei token, nome del modello, motivo di stop
  • id: identificatore univoco per questa risposta
  • usage_metadata: dettaglio dei token

Comprendere l’uso dei token

Prima di guardare i conteggi dei token, una nota veloce: i token sono le unità di base elaborate dagli LLM. In inglese, il testo usa tipicamente poco più di 1 token per parola (ad es. "explain quantum computing" = 3 parole, 4-5 token), ma lingue non inglesi come coreano o cinese richiedono significativamente più token per rappresentare lo stesso testo. Esploreremo i token in modo più approfondito nel Capitolo 2.

Esaminiamo più da vicino il consumo di token:

python
from langchain_openai import ChatOpenAI
 
llm = ChatOpenAI(model="gpt-5-mini")
response = llm.invoke("Spiega il quantum computing in termini semplici.")
 
usage = response.response_metadata['token_usage']
print(f"Input tokens: {usage['prompt_tokens']}")
print(f"Output tokens: {usage['completion_tokens']}")
print(f"Total tokens: {usage['total_tokens']}")

Output:

Input tokens: 11
Output tokens: 95
Total tokens: 106

Nota: prompt_tokens = token di input (il tuo prompt), completion_tokens = token di output (la risposta del modello), total_tokens = somma di entrambi.

Il consumo di token varia in base a:

  • Lunghezza del prompt: prompt più lunghi usano più token in input
  • Dettaglio della risposta: risposte dettagliate generano più token in output
  • Complessità della lingua: termini tecnici e codice possono tokenizzarsi in modo diverso

Ad esempio, un prompt breve come "Quanto fa 2+2?" potrebbe usare solo 5-6 token in input e 8-10 token in output, mentre "Scrivi un saggio dettagliato sulla storia del linguaggio di programmazione Python" potrebbe usare 15-20 token in input e 500+ token in output.

Calcolo del costo per l’esempio sopra:

Con i prezzi di GPT-5-mini ($0.25 per milione di token in input, $2.00 per milione di token in output):

  • Input: 11 token × $0.25 / 1,000,000 = $0.00000275
  • Output: 95 token × $2.00 / 1,000,000 = $0.00019
  • Totale: ~$0.0002 (due centesimi di centesimo)

Paghi sia i token in input sia quelli in output, ma i token in output costano di più (8× in questo caso).

Cosa hai imparato

Ora comprendi il ciclo di vita completo di una chiamata a un LLM:

  1. Il tuo codice fornisce una stringa di prompt
  2. LangChain la formatta in una richiesta API con autenticazione
  3. L’API di OpenAI instrada la richiesta al modello
  4. Il modello genera una risposta token per token
  5. L’API restituisce JSON strutturato con risposta e metadati
  6. LangChain esegue il parsing in un oggetto Python
  7. Il tuo codice accede al contenuto e ai metadati

Hai anche imparato:

  • Come ispezionare gli oggetti risposta ed estrarre i metadati
  • Come l’uso dei token influisce sui costi

Questa base ti prepara per il Capitolo 2, dove esploreremo come funzionano davvero gli LLM sotto il cofano, confronteremo modelli diversi e impareremo tecniche di prompt engineering per ottenere risultati migliori.