Programma
La corsa ai modelli open si è riaperta il 16 luglio 2026, quando Moonshot AI ha rilasciato Kimi K3, un modello da 2,8 trilioni di parametri con una finestra di contesto da 1 milione di token e visione nativa. È il modello open più grande mai distribuito da Moonshot, ben oltre Kimi K2 per dimensioni, e il primo che descrivono come appartenente alla classe dei 3 trilioni di parametri.
Se vuoi la storia del lancio, l’approfondimento sull’architettura, i grafici dei benchmark, i confronti con Claude, GPT e gli altri laboratori cinesi, e l’elenco dei limiti pubblicato da Moonshot, il nostro post sul blog Kimi K3 copre tutto questo. Questo tutorial è la parte pratica: come accedervi e come si comporta quando lo usi. Ti guiderò in cinque piccoli esempi, quattro tramite API, dove mostro l’uso reale dei token e i costi, e due nella web app kimi.com. Insieme, mostrano come K3 gestisce:
- Chiamata di strumenti e restituzione di JSON rigoroso
- Caricamento al volo della definizione di uno strumento
- Riduzione dei costi per contesti lunghi con caching automatico
- Lettura di uno screenshot e correzione del layout
- Creazione di una dashboard interattiva da un unico prompt
I quattro esempi API sono stati eseguiti il 17 luglio 2026 sul modello kimi-k3 e sono costati circa 11 centesimi al primo giro, o pochi centesimi una volta attivata la cache.
Come accedere a Kimi K3
Il modo più rapido per provare il modello è kimi.com, dove la web app e le app mobile eseguono Kimi K3 per attività agent generali senza configurazione.
Per lavori più pesanti come report e dashboard, c’è Kimi Work, un’app desktop.
Se vivi nel terminale, Kimi Code è un agente per il coding che installi da npm come @moonshot-ai/kimi-code e scegli il modello con il comando /model. Usare K3 in Kimi Code richiede un abbonamento a pagamento, e per l’intera finestra da 1 milione di token serve un livello superiore.
Questo tutorial si concentra sull’API grezza e sulla web app, ma l’agente da terminale è lì se ti serve.
K3 non sostituisce però i suoi “fratelli”. La tabella qui sotto mostra come si suddivide l’attuale lineup.
|
Modello |
Finestra di contesto |
Ideale per |
|
|
1.048.576 token |
Lavori di punta: coding lungo, visione, attività di conoscenza |
|
|
262.144 token |
Coding dedicato, con un’opzione ad alta velocità |
|
|
262.144 token |
Chat generica su testo, immagini e video |
In breve, K3 è il modello da cui partire quando un lavoro mescola codice, strumenti, documenti e immagini, o quando serve davvero la finestra da 1 milione di token. Per la generazione di codice pura dove la velocità conta più del contesto, kimi-k2.7-code resta la scelta più sensata: non dare per scontato che il modello più nuovo sia sempre quello giusto.
Configurare l’API di Kimi K3
L’API è compatibile con l’SDK di OpenAI, quindi se lo hai già usato, qui non c’è quasi nulla di nuovo. Ti servono Python 3.9 o successivi e una chiave API.
Passo 1: Generare una chiave API
Per prima cosa, accedi alla piattaforma Kimi e apri la pagina delle API Keys nella console. Crea una chiave, copiala una volta e conservala in un luogo sicuro, perché non la rivedrai più. Ti serve anche un piccolo credito sull’account per effettuare chiamate, e per l’intero tutorial bastano pochi dollari.

Creazione di una chiave API Kimi K3. Immagine dell’autore.
Passo 2: Installare l’SDK
Poi, installa l’SDK di OpenAI nel tuo ambiente. Un solo comando basta.
python -m pip install --upgrade "openai>=1.0"
Questo scarica la libreria client usata nel resto degli esempi, e non c’è nulla di specifico per Kimi da installare.
Passo 3: Salvare la chiave e inizializzare il client
È meglio leggere la chiave da una variabile d’ambiente che incollarla nel codice. Imposta MOONSHOT_API_KEY nella tua shell o in un file .env , quindi punta il client alla base URL di Moonshot.
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["MOONSHOT_API_KEY"],
base_url="https://api.moonshot.ai/v1",
)
Le uniche due cose che differiscono da una configurazione OpenAI standard sono il base_url e il nome del modello, che è kimi-k3. Con questo a posto, sei pronto a fare una chiamata.
Passo 4: Effettuare la prima chiamata
E ora una prima richiesta. Ho chiesto al modello di presentarsi in una frase, e ne è uscito un piccolo momento di onestà.
completion = client.chat.completions.create(
model="kimi-k3",
messages=[{"role": "user", "content": "Introduce Kimi K3 in one sentence."}],
max_completion_tokens=800,
)
print(completion.choices[0].message.content)
La risposta è stata un rifiuto garbato di indovinare: il modello ha detto di non avere informazioni affidabili su Kimi K3, poiché è stato addestrato prima del suo stesso rilascio, e mi ha rimandato agli annunci di Moonshot. È un promemoria utile che un modello non conosce se stesso. La chiamata API appena fatta costa circa sette decimi di centesimo. Nota il limite max_completion_tokens che ho impostato in ogni chiamata di questo tutorial per evitare che un output prolisso faccia salire il conto.

Output della prima chiamata API a Kimi K3. Immagine dell’autore.
Esempio 1: Reasoning in streaming e risposta finale
K3 ragiona sempre, e l’API restituisce quel ragionamento su un canale separato rispetto alla risposta. In streaming, ogni chunk può contenere reasoning_content, la content finale o entrambi, così puoi collocare separatamente il “pensiero” e la risposta.
stream = client.chat.completions.create(
model="kimi-k3",
messages=[{"role": "user", "content": "A bat and a ball cost $1.10 together. The bat costs $1.00 more than the ball. How much is the ball?"}],
max_completion_tokens=1200,
stream=True,
stream_options={"include_usage": True},
)
for chunk in stream:
if not chunk.choices:
continue
delta = chunk.choices[0].delta
reasoning = getattr(delta, "reasoning_content", None)
if reasoning:
print(reasoning, end="", flush=True)
if delta.content:
print(delta.content, end="", flush=True)
Il modello ha prima trasmesso il suo ragionamento: ha riconosciuto la domanda di mazza e palla come il classico Cognitive Reflection Test, ha segnalato l’intuitiva risposta sbagliata di $0,10, poi ha svolto l’algebra fino a $0,05 per la palla e ha verificato che $1,05 più $0,05 fa $1,10. La divisione è la parte utile: in un’app reale mostri content agli utenti e tieni reasoning_content per i log, perché mostrare il ragionamento grezzo in produzione raramente è ciò che vuoi. Questa chiamata ha usato 488 token di output e ha costato meno di un centesimo.

Reasoning in streaming e poi risposta finale. Immagine dell’autore.
Esempio 2: Tool calling con output strutturato
Kimi K3 è il modello della lineup che supporta tool_choice="required", che impone almeno una chiamata a uno strumento in un turno. È utile quando vuoi che il modello recuperi dati prima di rispondere, invece di tirare a indovinare. Qui gli ho dato due strumenti fittizi, una ricerca prezzo e un controllo stock, ho forzato una chiamata a strumento, ho eseguito gli strumenti in locale e poi ho chiesto il risultato come JSON rigoroso usando response_format.
first = client.chat.completions.create(
model="kimi-k3",
messages=messages,
tools=TOOLS,
tool_choice="required",
max_completion_tokens=2500,
)
assistant_message = first.choices[0].message
messages.append(assistant_message)
for tool_call in assistant_message.tool_calls or []:
args = json.loads(tool_call.function.arguments)
messages.append({"role": "tool", "tool_call_id": tool_call.id, "content": run_tool(tool_call.function.name, args)})
Il modello ha chiamato entrambi gli strumenti con il giusto codice prodotto, poi ha restituito un pulito riepilogo d’ordine in JSON: cinque tastiere meccaniche a $89 l’una, totale $445, e un flag di stock impostato su true. Due dettagli lo rendono affidabile in pratica. Devi aggiungere di nuovo alla conversazione l’intero messaggio dell’assistente prima di aggiungere i risultati degli strumenti, e dovresti analizzare solo content per il JSON, mai il campo di reasoning. La coppia di chiamate è costata insieme meno di un centesimo.

Chiamate a strumenti e output JSON strutturato. Immagine dell’autore.
Esempio 3: Caricare strumenti in modo dinamico
Se hai decine di strumenti, inviare tutte le loro definizioni a ogni richiesta spreca token e appesantisce il prompt. Kimi K3 ti consente di inserire una definizione di strumento a conversazione avviata con un messaggio system che contiene il campo tools e nessun content. Da quel momento lo strumento è disponibile, così i grandi cataloghi di strumenti restano fuori dal tuo prefisso in cache finché uno strumento non serve davvero.
messages = [
{"role": "user", "content": "Convert 100 US dollars to euros at a rate of 0.92."},
{"role": "system", "tools": [{
"type": "function",
"function": {
"name": "convert_currency",
"description": "Convert an amount from one currency to another",
"parameters": {
"type": "object",
"properties": {"amount": {"type": "number"}, "rate": {"type": "number"}},
"required": ["amount", "rate"],
},
},
}]},
]
completion = client.chat.completions.create(model="kimi-k3", messages=messages)
print(completion.choices[0].message.tool_calls)
K3 ha rilevato lo strumento appena caricato e ha chiamato convert_currency con amount 100 e rate 0,92, esattamente come previsto. Ricorda che il server non conserva questa definizione per te, quindi reinvia il messaggio di sistema nelle richieste successive se vuoi che lo strumento resti disponibile. Questa è stata la chiamata più economica del set, circa due decimi di centesimo.

Chiamare uno strumento valutario caricato dinamicamente. Immagine dell’autore.
Esempio 4: Ridurre i costi del contesto lungo con la cache
Questo è l’esempio in cui la finestra da 1 milione di token diventa pratica. Il caching del contesto è automatico, senza ID della cache e senza durata da gestire. Invi un prefisso ampio, lo mantieni identico byte per byte nelle richieste successive e la parte ripetuta viene fatturata alla tariffa di cache-hit invece che a quella di cache-miss. Per rendere visibile la differenza ho usato una base di conoscenza di circa 33.000 token e ho fatto una domanda al riguardo.
knowledge = Path("knowledge_base.md").read_text(encoding="utf-8")
completion = client.chat.completions.create(
model="kimi-k3",
messages=[
{"role": "system", "content": knowledge},
{"role": "user", "content": "What is the rated payload of the Atlas robot?"},
],
max_completion_tokens=600,
)
La prima volta che ho inviato quel prefisso, nulla era in cache e la richiesta è costata circa 9,9 centesimi per circa 33.000 token in input. Dopo che il prefisso è stato visto, la stessa richiesta ha colpito la cache su tutti i 32.512 token del prefisso ed è costata circa 1,1 centesimi, vicino a un calo di nove volte. Il motivo è il divario di prezzo: l’input in cache costa $0,30 per milione di token contro i $3,00 per l’input non in cache. Un aspetto che ho notato è che le scritture in cache sono asincrone, quindi l’hit non appare su una chiamata immediatamente successiva. Arriva su una richiesta più avanti, quindi eseguire lo script due volte a distanza di un minuto mostra prima il miss e poi l’hit.

Costo cache miss contro cache hit. Immagine dell’autore.
Esempio 5: Individuare bug di layout in uno screenshot
La visione è nativa in K3, e l’API è un modo pulito per usarla, anche se non accetta URL pubblici di immagini. Invi l’immagine come data URL base64 e rendi il content del messaggio un array di oggetti, una parte per l’immagine e una per il testo. Ho renderizzato una piccola dashboard con alcuni bug di layout intenzionali, salvato uno screenshot e chiesto a K3 cosa non andava.

La dashboard con bug di layout intenzionali. Immagine dell’autore.
import base64
from pathlib import Path
image_data = base64.b64encode(Path("broken_dashboard.png").read_bytes()).decode()
completion = client.chat.completions.create(
model="kimi-k3",
messages=[{
"role": "user",
"content": [
{"type": "image_url", "image_url": {"url": f"data:image/png;base64,{image_data}"}},
{"type": "text", "text": "List the layout and alignment problems you can see, and give a short CSS fix for each."},
],
}],
max_completion_tokens=3500,
)
print(completion.choices[0].message.content)
K3 ha letto bene l’immagine. Ha individuato la card più bassa della riga che si sovrappone alla vicina, il badge parcheggiato sopra un numero (ha persino letto erroneamente il 3.910 coperto come 5.910, che è il bug che si auto-dimostra), lo spazio irregolare prima dell’ultima card, la barra che “sanguina” nella card sopra e la tooltip che si sovrappone alle barre, e ha fornito una breve correzione CSS per ciascuno, come spostare le card in una sola griglia. Tuttavia, ha saltato il sottotitolo a basso contrasto quasi invisibile: la visione cattura ciò che colpisce l’occhio più dei dettagli tenui. La chiamata è costata circa due centesimi.
Limitazioni di Kimi K3
Gli esempi API sono andati bene, ma vale la pena citare alcune asperità per non sorprenderti. Mi sono imbattuto direttamente nella maggior parte di queste.
-
Per ora è disponibile solo
reasoning_effort="max", quindi non puoi ancora ridurre il “pensiero” per risparmiare. -
Le impostazioni di campionamento sono fisse. Valori come
temperature,top_pe le penalità sono bloccati, quindi omettili dalle richieste invece di provare a ottimizzarli. -
L’output può diventare lungo e costoso. Imposta un limite a
max_completion_tokens, come negli esempi, e valida qualsiasi loop di agent. -
Gli URL pubblici delle immagini non sono supportati via API, quindi prevedi base64 o file caricati per la visione lì.
Nessuna di queste è un blocco totale, ma influenzano come usare il modello. Il costo dell’output è quello che monitorerei di più.
Conclusione
Nei miei test, due cose hanno spiccato. Le chiamate a strumenti e l’output strutturato non hanno richiesto retry, e la cache ha contato più del previsto, perché riutilizzare lo stesso prefisso lungo ha reso economico reinviare una richiesta grande. Quindi, per analisi a livello di repository, chiamate ripetute con contesto lungo o ingegneria multimodale, K3 è una scelta ragionevole; per chat rapide a basso costo o controllo preciso del campionamento, un modello più piccolo è la scelta più semplice. I dettagli su pesi open e licenza, che ho segnalato prima, dovrebbero essere più chiari dopo il rilascio del 27 luglio.
Per maggiori informazioni sui pattern usati in questi esempi, il nostro corso Sviluppare sistemi di AI con l’API di OpenAI copre il function calling e il collegamento dei modelli a strumenti esterni in Python.
Sono un data engineer e community builder: lavoro su pipeline dati, cloud e strumenti di AI, e scrivo tutorial pratici e ad alto impatto per DataCamp e per sviluppatori alle prime armi.
