Primi passi con la Grok 4 API
Prima di inviare la nostra prima richiesta, ci serve una chiave API e un ambiente Python in grado di connettersi all’API di Grok.
Creare la tua chiave API
Per creare una chiave API da usare per autenticare il client con l’API, segui questi passaggi:
- Visita il sito ufficiale della documentazione xAI.
- Accedi con il tuo account X, xAI o Google. Se non hai ancora un account, puoi registrarti a xAI.
- Trova l’opzione “Create an API key”. Inserisci un nome per la tua chiave e fai clic su “save”.
- Quando compare la chiave, copiala subito. Non potrai più visualizzarla in seguito, ma puoi sempre generarne una nuova se necessario.
- Nel tuo progetto, crea un file chiamato .env. Incolla la tua chiave API all’interno, usando questo formato:
XAI_API_KEY=<your_api_key_here>
Prezzi della Grok 4 API
Usare l’API può essere più conveniente rispetto a un abbonamento premium, ma non è gratuito. Diversamente dal piano SuperGrok, che parte da 30 $ al mese a tariffa fissa, i costi dell’API dipendono interamente dall’utilizzo. Tuttavia, se vuoi accedere a Grok 4 Heavy, la situazione cambia: ti serve un abbonamento attivo a SuperGrok Heavy (300 $ al mese), anche quando usi l’API.
Per un’analisi dettagliata delle possibili spese, consulta la pagina dei prezzi su xAI.

Fonte: xAI
Il prezzo dell’API di Grok si basa sull’uso, misurato per milione di token. A titolo di riferimento, un milione di token equivale all’incirca a 750.000 parole in inglese, in input o in output. Sebbene la finestra di contesto sia quasi raddoppiata rispetto al predecessore, Grok 4 ha lo stesso prezzo del modello Grok 3 standard: pagherai 3 $ per ogni milione di token in input e 15 $ per ogni milione di token in output.
Per accedere all’API devi acquistare dei crediti. All’inizio è saggio usare crediti prepagati invece della fatturazione automatica: così eviti addebiti a sorpresa. Puoi acquistare token e monitorare l’utilizzo dalla console xAI, in Invoices > Credits.
Configurazione dell’ambiente Python
Una volta pronta la chiave API e i crediti, il passo successivo è preparare l’ambiente Python. Ti servono due pacchetti per un’integrazione fluida con l’API:
python-dotenvper caricare la chiave API dal file.envcome variabile d’ambiente.- Il client
openaiper interagire con la Grok 4 API.
Per mantenere pulite le dipendenze del progetto, è una buona idea usare Anaconda. Dopo aver installato Anaconda, crea un nuovo ambiente chiamato grok4 con Python 3.10 eseguendo:
conda create -n grok4 python=3.10
conda activate grok4
Con l’ambiente attivo, installa i pacchetti richiesti:
pip install python-dotenv openai
Preparativi finali
Iniziamo scrivendo il primo script. Importa le funzioni necessarie dai pacchetti installati, insieme a os per accedere alla chiave API:
import os
from dotenv import load_dotenv
from openai import OpenAI
Poi usa load_dotenv() del pacchetto dotenv per caricare le variabili d’ambiente, rendendo disponibile al tuo script la chiave API:
# Load environment variables
load_dotenv()
Ora inizializza il client API passando la chiave (dal file .env) e l’URL del server Grok alla classe OpenAI (in questo tutorial useremo l’SDK di OpenAI, ma Grok 4 ha anche un SDK Python nativo di xAI, ed è compatibile anche con l’SDK di Antrhopic). Assegna il tutto alla variabile client:
client = OpenAI(
api_key=os.getenv("XAI_API_KEY"),
base_url="https://api.x.ai/v1",
)
Con questi passaggi, il tuo script è pronto a inviare richieste a Grok 4.
Riconoscimento immagini con Grok 4
Ora che abbiamo impostato l’ambiente, testiamo il riconoscimento immagini, una delle novità di Grok 4. Lo dimostriamo caricando la foto qui sotto di una lasagna vegetariana e chiedendo a Grok di identificare gli ingredienti visibili.

Per analizzare un’immagine con la Grok 4 API, dobbiamo inviare una richiesta che includa sia un’immagine sia un prompt. Il modo consigliato è usare un client Python compatibile con OpenAI, specificando il modello grok-4 e includendo l’URL dell’immagine e la tua domanda nell’array messages. L’API restituirà una risposta dettagliata che descrive il contenuto dell’immagine, accessibile nell’oggetto di risposta.
Prima di inviare la richiesta, assicuriamoci che l’immagine rispetti i requisiti dell’API. Sono supportati solo i formati JPEG e PNG, e la dimensione del file non deve superare i 20 MB. L’immagine deve essere accessibile tramite link diretto e il server deve inviare l’header Content-Type corretto (image/jpeg o image/png).
Dopo aver importato i pacchetti necessari, caricato le variabili d’ambiente e configurato il client, possiamo inviare la nostra query così:
# Sending the query
response = client.chat.completions.create(
model="grok-4",
messages=[
{
"role": "user",
"content": [
{
"type": "image_url",
"image_url": {
"url": "https://shorturl.at/mVDEh",
"detail": "high"
}
},
{
"type": "text",
"text": "Which ingredients do you notice on the picture?"
}
]
}
],
max_tokens=2000,
temperature=0.2, # lower temperature for more deterministic answers
)
# Print the response
print(response.choices[0].message.content)
Based on the picture, it looks like a delicious slice of vegetarian lasagna! Here's what I can clearly see in terms of ingredients (I'm basing this purely on visual cues, so it's not a full recipe—just what's noticeable):
### Main Visible Ingredients:
- **Pasta sheets/lasagna noodles**: The flat, layered pasta that's the base structure of the dish.
- **Tomato sauce**: A red, chunky sauce (likely marinara or similar) that's spread between layers and on top.
- **Cheese**:
- Melted, bubbly cheese on top (probably mozzarella or Parmesan, given the golden-brown spots).
- White, creamy cheese in the filling layers (looks like ricotta or cottage cheese).
- **Spinach (or similar greens)**: Dark green leaves mixed into the layers, giving it a veggie-packed look (this seems like a spinach lasagna variant).
- **Basil leaf**: A fresh green leaf garnishing the top for decoration and flavor.
It doesn't appear to have any meat (like ground beef or sausage), so it's likely a vegetarian version. If this is from a specific recipe or if you have more context, I could refine my observations! What do you think it is? 😊
In questo caso, Grok ha persino riconosciuto che si tratta di una versione vegetariana solo dall’immagine: niente male!
Ragionamento con Grok 4
Grok 4 è progettato per il ragionamento avanzato e può risolvere problemi complessi passo dopo passo. Tuttavia, a differenza di alcuni modelli precedenti, Grok 4 non espone le tracce interne del suo ragionamento, quindi non puoi estrarre un dettagliato "processo di pensiero" o chain-of-thought come campo separato dalla risposta dell’API. L’output che ricevi è la risposta finale, non i passaggi intermedi o il ragionamento grezzo del modello.
Inoltre, Grok 4 non supporta il parametro reasoning_effort usato, ad esempio, in Grok 3 mini (per imparare a usare quel parametro, vedi questo tutorial sulla Grok 3 API). Questo significa che non puoi regolare quanto “pensi” il modello prima di arrivare a una conclusione finale. Pertanto, qualsiasi query di ragionamento si costruisce esattamente come una query normale.
Mettiamo alla prova Grok con un altro compito di ragionamento legato alla lasagna e chiediamogli di mostrare il ragionamento nell’output.
# Send a basic reasoning query
response = client.chat.completions.create(
model="grok-4",
messages=[
{"role": "user", "content": (
"You want to cook lasagna for a dinner party, but several guests have dietary restrictions. One is vegetarian, one is lactose-intolerant, and another cannot eat gluten. You have six different lasagna recipes (classic, vegetarian, vegan, gluten-free, cheese-heavy, and meat-based). Which recipe or combination of recipes would best satisfy everyone, and what specific ingredient substitutions would you need to make? Explain your reasoning step by step."
)}
],
max_tokens=5000,
temperature=0.2, # lower randomness
)
# Print the final answer
print(response.choices[0].message.content)
Below, I'll explain my reasoning step by step for selecting the best recipe (or combination of recipes) to satisfy all guests at your dinner party, including the vegetarian, the lactose-intolerant person, the gluten-intolerant person, and everyone else (who presumably have no restrictions). I'll base this on logical inferences about what each recipe likely contains, since the problem doesn't provide exact ingredient lists. Then, I'll recommend specific ingredient substitutions and why this approach works.
(...)
### Step 3: Selecting the Best Recipe or Combination
- **Recommended approach**: Use a **combination of the vegan and gluten-free recipes** to create a single modified lasagna that everyone can eat. Start with the vegan recipe as your base (it already handles no meat and no lactose/dairy), then incorporate elements from the gluten-free recipe (e.g., ingredient swaps to eliminate gluten). This results in a **vegan, gluten-free lasagna**.
- Why not multiple lasagnas? Preparing separate dishes (e.g., one vegetarian, one gluten-free) could work but might not fully satisfy everyone in a shared meal—e.g., the lactose-intolerant guest couldn't eat a dairy-based vegetarian version. A single inclusive dish promotes unity at the party and simplifies cooking/serving. If you have time and oven space, you could make a small "classic" version on the side for unrestricted guests who prefer meat and cheese, but the modified vegan/gluten-free one would still be the core option.
- Why this combination over others? Vegan + gluten-free covers all restrictions without needing to add meat or dairy (which would violate rules). Starting with gluten-free and making it vegan would require more substitutions (e.g., removing meat and cheese), while vegan is already "80% there." Other combos (e.g., vegetarian + gluten-free) would still need dairy removals for lactose intolerance, making them less efficient.
This approach ensures:
- The vegetarian can eat it (no meat).
- The lactose-intolerant can eat it (no dairy/lactose).
- The gluten-intolerant can eat it (no gluten).
- Others can eat it (it's still a flavorful lasagna, though it won't have "real" meat or cheese—unrestricted guests might find it less indulgent, but it's a fair compromise).
(...)
Ho accorciato la risposta di Grok per evidenziare i punti chiave, ma anche in questa versione ridotta è chiaro che il modello ha lavorato bene. Grok ha proceduto passo dopo passo per
- Comprendere le restrizioni alimentari
- Valutare le ricette disponibili
- Selezionare la combinazione di ricette migliore
- Suggerire sostituzioni specifiche degli ingredienti
- Fornire uno schema completo della ricetta modificata
- Ricollegarsi al perché soddisfa tutti
- Discutere potenziali svantaggi e alternative
Function calling con Grok 4
Come il suo predecessore, Grok 4 supporta il function calling. Consente al modello di interagire direttamente con strumenti e servizi esterni. Questo significa che Grok non si limita a generare testo: può anche eseguire azioni come recuperare aggiornamenti meteo, controllare orari di eventi, analizzare record di database o persino gestire dispositivi smart home.
Quando invii una richiesta, Grok può determinare se gli servono dati aggiuntivi e chiederà di chiamare una funzione specifica con i parametri corretti. Il client Python si occupa di eseguire localmente questa funzione, passa il risultato a Grok e poi ricevi una risposta completa e ben argomentata.
Preparazione
Per lavorare con il function calling, dobbiamo importare il pacchetto json, che ci permette di accedere alla struttura degli argomenti di qualunque funzione chiamata da Grok. Poi definiamo una funzione di callback che Grok invocherà quando richiederà dati specifici.
In questo esempio, la funzione suggest_lasagna_recipe è una semplice funzione Python che restituisce un suggerimento di ricetta fisso. Questo approccio hard-coded mantiene la demo semplice ed evita dipendenze da servizi esterni.
import json
# Define the callback function
def suggest_lasagna_recipe(ingredients: list) -> dict:
# Very simplified logic for demo purposes
if "zucchini" in ingredients:
return {"recipe": "Vegetarian Zucchini Lasagna"}
if "beef" in ingredients:
return {"recipe": "Classic Beef Lasagna"}
if "tofu" in ingredients:
return {"recipe": "Vegan Tofu Lasagna"}
return {"recipe": "Basic Cheese Lasagna"}
Dobbiamo anche definire lo strumento che Grok può chiamare. Questo implica specificarne nome, scopo e parametri richiesti in uno schema JSON. Lo schema viene inviato a Grok con la richiesta, informandolo che può chiamare questo tool quando ha bisogno di informazioni extra a supporto del suo ragionamento.
# Define the JSON schema for the tool
tools = [
{
"type": "function",
"function": {
"name": "suggest_lasagna_recipe",
"description": "Suggests a lasagna recipe based on available ingredients.",
"parameters": {
"type": "object",
"properties": {
"ingredients": {
"type": "array",
"items": {"type": "string"},
"description": "List of available ingredients"
}
},
"required": ["ingredients"]
}
}
}
]
Infine, il dizionario tools_map collega i nomi delle funzioni usati da Grok alle effettive funzioni Python nel tuo codice. Questo mapping consente al client di eseguire correttamente le chiamate richieste.
# link the function names to the functions
tools_map = {
"suggest_lasagna_recipe": suggest_lasagna_recipe
}
Definire manualmente gli schemi degli strumenti funziona bene per progetti semplici, ma man mano che il progetto cresce è altamente consigliato usare una libreria di validazione dei dati come Pydantic. Pydantic offre validazione automatica degli input delle funzioni, migliore gestione degli errori e produce codice più pulito e manutenibile.
Esecuzione
Verifichiamo se Grok usa la nostra funzione quando gli chiediamo una ricetta di lasagna. Ecco come si svolge il flusso di function calling:
- Per prima cosa inviamo a Grok una domanda dell’utente — “Quale lasagna posso preparare con i miei ingredienti?” — insieme ai
toolsdisponibili. - Grok esamina la richiesta e, se determina che serve una chiamata di funzione, chiede la ricetta attivando la nostra funzione locale. Se non viene effettuata alcuna chiamata a tool, usiamo semplicemente la risposta iniziale di Grok.
- Quando è richiesta una chiamata a tool, eseguiamo la funzione locale corrispondente e aggiungiamo il risultato alla cronologia dei messaggi in corso.
- Questa cronologia aggiornata viene poi rimandata a Grok, permettendogli di completare il ragionamento e fornire una risposta finale contestualizzata.
# Step 1: Send the initial user request
messages = [
{"role": "user", "content": "I have beef, ricotta, and tomato sauce. Which lasagna can I make?"}
]
response = client.chat.completions.create(
model="grok-4",
messages=messages,
tools=tools,
tool_choice="auto",
)
# Step 2: Check if a tool call was requested
tool_calls = getattr(response.choices[0].message, "tool_calls", [])
if tool_calls:
for tool_call in tool_calls:
function_name = tool_call.function.name
print(f"{function_name} successfully called")
function_args = json.loads(tool_call.function.arguments)
# Find and call the matching local function
if function_name in tools_map:
function_result = tools_map[function_name](**function_args)
# Step 3: Add the function result back to the message history
messages.append(response.choices[0].message) # Assistant's tool call message
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": json.dumps(function_result)
})
# Step 4: Send a new request including the tool response
final_response = client.chat.completions.create(
model="grok-4",
messages=messages,
tools=tools,
tool_choice="auto"
)
# Print the final answer
print("\nFinal Answer:")
print(final_response.choices[0].message.content)
else:
# No tool call: respond directly
print("\nNo tool call was requested. Final Answer:")
print(response.choices[0].message.content)
suggest_lasagna_recipe successfully called
Final Answer:
Based on your available ingredients (beef, ricotta, and tomato sauce), you can make a **Classic Beef Lasagna**! (...)
Come si vede, Grok ha chiamato la nostra funzione e suggerito la ricetta corrispondente.
Avrai notato anche l’argomento tool_choice nella richiesta iniziale. Per impostazione predefinita, “auto” lascia a Grok la decisione se e quale funzione chiamare. Se vuoi più controllo, puoi forzare la chiamata di una funzione specifica, indicare esattamente quale usare o disattivare del tutto il function calling modificando questo parametro.
Output strutturati con Grok 4
Analogamente al function calling, gli output strutturati sono una funzione introdotta con Grok 3. Consentono a Grok di fornire risposte in un formato rigoroso come JSON invece che in testo libero. Questo approccio facilita molto il parsing, la validazione e l’uso delle risposte del modello nelle tue applicazioni o nei tuoi workflow.
Impostando in anticipo uno schema, puoi assicurarti che gli output di Grok siano sempre coerenti, leggibili dalle macchine e pronti per ulteriori elaborazioni. È particolarmente utile quando devi estrarre dati strutturati da documenti o inviare contenuti generati dall’AI direttamente in database, dashboard o strumenti di automazione, senza preoccuparti di un parsing del testo poco affidabile.
Per definire lo schema di output, usiamo Pydantic, che rende più semplice e leggibile strutturare dati complessi (questo tutorial su Pydantic ti aiuterà ad approfondire). Per questo, devi importare sia BaseModel sia Field da pydantic. Poiché il nostro output contiene un elenco di ingredienti, importiamo anche List dal modulo typing di Python per specificare chiaramente il tipo di ogni elemento della lista.
Pur potendo definire lo schema con semplice JSON, a volte Grok restituisce output che non corrispondono esattamente alla struttura attesa. Il significato può essere lo stesso, ma lo schema può differire, causando problemi se alla tua applicazione serve un formato specifico. Ciò è particolarmente vero per elementi annidati come le liste. Per questo consiglio di usare Pydantic: aiuta a garantire che l’output strutturato venga validato e analizzato in modo affidabile ogni volta.
Nel nostro esempio, lo schema — chiamato Recipe — include il nome, il numero di porzioni e un elenco di ingredienti. Ogni Ingredient è definito dal nome, dalla quantità necessaria per la ricetta, dalla disponibilità in casa, dal prezzo al chilo e dalle informazioni su vegetariano, vegano o senza glutine. È utile impostare valori predefiniti nello schema stesso, come stiamo facendo per il numero di porzioni.
# import additionally needed packages
from pydantic import BaseModel, Field
from typing import List
# Define the schema for the structured output
class Ingredient(BaseModel):
name: str = Field(description="Name of the ingredient")
amount: int = Field(description="Amount in g needed for recipe")
is_at_home: bool = Field(description="Is the item already at home?")
price: float = Field(description="Price of the ingredient in USD per kg")
is_vegetarian: bool = Field(description="Is the ingredient vegetarian?")
is_vegan: bool = Field(description="Is the ingredient vegan?")
is_gluten_free: bool = Field(description="Is the ingredient gluten-free?")
class Recipe(BaseModel):
name: str = Field(description="The name of the recipe")
portions: int = Field(default=4, description="Amount of portions")
ingredients: List[Ingredient] = Field(description="List of ingredients for the recipe")
Ci sono alcuni dettagli da tenere a mente al momento della richiesta. Invece di usare client.chat.completions.create(), vogliamo chiamare client.beta.chat.completions.parse(). Questo segnala a Grok che ci aspettiamo un output in un formato specifico, e lo schema Recipe viene passato come argomento response_format.
È utile anche inserire tutte le istruzioni chiave per il task nel prompt di sistema. Questo mantiene Grok 4 focalizzato e coerente durante tutta la conversazione. Poiché lo schema è definito separatamente, il prompt dell’utente può concentrarsi sul compito in sé, senza dover elencare i campi richiesti per il JSON di output.
Per esempio, potresti impostare Grok nel ruolo di uno chef italiano, assicurandoti che tutte le ricette proposte siano autenticamente italiane, così l’ananas non finirà mai sulla tua pizza!
# Send a prompt and request structured output
completion = client.beta.chat.completions.parse(
model="grok-4",
messages=[
{"role": "system", "content": (
"You are a master chef specialized in italian cuisine."
"When asked about recipes, return the output in structured JSON format following the provided schema, without any extra text."
)},
{"role": "user", "content": (
"I have beef, ricotta, and tomato sauce, and want to cook for 4 persons. Which lasagna can I make?"
)}
],
response_format=Recipe,
)
Una volta analizzato l’output strutturato di Grok 4, i suoi vantaggi rispetto al testo libero diventano evidenti. Possiamo riorganizzare e personalizzare facilmente le informazioni in base alle nostre esigenze, o persino inviare punti dati specifici direttamente in workflow automatizzati. Nel nostro esempio, questo significa che possiamo moltiplicare rapidamente i prezzi degli ingredienti al chilo per le quantità richieste, sommare i costi in base a ciò che abbiamo già in dispensa e calcolare il prezzo finale a porzione in pochi passaggi.
# Access the parsed result
recipe = completion.choices[0].message.parsed
price = 0 # initialize price variable
print(f"Recipe: {recipe.name}")
print("Ingredients:")
for i in recipe.ingredients:
print("- " + i.name + " " + str(i.amount) + " g")
if not i.is_at_home:
price += (i.price * i.amount / 1000)
print(f"Price per portion: USD {round((price/recipe.portions), 2)}")
Recipe: Classic Beef Lasagna
Ingredients:
- Ground beef 500 g
- Ricotta cheese 400 g
- Tomato sauce 800 g
- Lasagna noodles 300 g
- Mozzarella cheese 300 g
- Parmesan cheese 100 g
- Onion 200 g
- Garlic 20 g
- Olive oil 30 g
- Egg 50 g
Price per portion: USD 1.7625
Conclusione
Grok 4 porta novità come una finestra di contesto più ampia e migliori capacità di ragionamento. Il riconoscimento immagini e il function calling aprono possibilità interessanti per combinare l’AI con dati e azioni del mondo reale, mentre gli output strutturati garantiscono risposte affidabili e leggibili dalle macchine. Il setup dell’API è semplice e consente un’integrazione rapida nei tuoi progetti Python con poche dipendenze.
E se tutti questi esempi a base di lasagna ti hanno messo fame, non sei il solo: potrei proprio andare a prendermene una fetta!


La settimana scorsa, xAI ha rilasciato l’aggiornamento molto atteso di Grok. Come nelle versioni precedenti, il modello principale è facilmente accessibile tramite API.
In questo tutorial ti spiego cosa offre Grok 4 e come iniziare con la Grok 4 API. Sfrutteremo al massimo le sue funzioni avanzate come l’elaborazione di immagini, il function calling e gli output strutturati.
Teniamo i lettori aggiornati sulle ultime novità dell’AI con The Median, la nostra newsletter gratuita del venerdì che riassume le notizie più importanti della settimana. Iscriviti e rimani sul pezzo in pochi minuti a settimana:
Cosa c’è di nuovo in Grok 4?
Grok 4 è l’ultimo LLM sviluppato da xAI, pensato per il ragionamento avanzato e la risoluzione di problemi. A differenza del suo predecessore, Grok 4 funziona esclusivamente come modello di ragionamento: non è disponibile una modalità non di ragionamento. Il parametro
reasoning_effort, che in passato permetteva di regolare quanto “pensasse” il modello prima di rispondere, è stato rimosso.Esistono due varianti principali: Grok 4 e Grok 4 Heavy. Grok 4 Heavy è la variante ad alte prestazioni e multi-agent, che esegue più agenti AI in parallelo per aumentare l’accuratezza e ridurre le allucinazioni, risultando particolarmente potente per compiti analitici complessi e applicazioni critiche. L’accesso a Grok 4 Heavy è limitato: serve un abbonamento attivo SuperGrok Heavy per usarlo, anche via API.
La finestra di contesto è quasi raddoppiata, da 131.072 token in Grok 3 a 256.000, consentendo di elaborare e ricordare documenti e conversazioni molto più lunghi rispetto a prima, il che lo rende adatto ad applicazioni impegnative.
Se vuoi approfondire funzionalità e benchmark, ti consiglio questo blog su Grok 4 e le ultime novità su Grok 4.1. Se preferisci una panoramica in video, dai un’occhiata a questo video: