La domanda vera non è "quale modello è più bravo", ma quale modello fa il lavoro del village a parità di risultato, e a che costo. È una domanda con una risposta misurabile, e cambia nel tempo: i modelli vengono aggiornati, i prezzi si muovono, i task si spostano.
Quindi il valore non sta nel singolo confronto, ma nell'avere una procedura che si può rieseguire fra tre mesi e ottenere numeri paragonabili a quelli di oggi. Senza protocollo, ogni confronto è un aneddoto e non si può portare a una decisione di budget.
Cosa questo confronto non è: non è una classifica assoluta fra modelli. Vale per i task del village, con i prompt del village. Un modello che perde qui può vincere altrove.
Un brain non genera testo: legge file, scrive file, esegue comandi. Se un modello apre la chiamata a uno strumento ma non trasmette gli argomenti, l'agente riceve una chiamata vuota e fallisce a raffica. È già successo su questa installazione: per settimane alcuni modelli sembravano vivi (rispondevano) ma erano incapaci di fare qualunque cosa.
Un modello che fallisce questo test è fuori dal confronto a qualsiasi prezzo, e il prezzo non va nemmeno calcolato. Il controllo va rifatto a ogni tornata di benchmark e dopo ogni aggiornamento del gateway: è un comportamento che si rompe e si ripara da solo, fuori dal nostro controllo.
Il controllo è una singola richiesta in streaming con uno strumento dichiarato: nel flusso di risposta devono comparire gli eventi che trasportano gli argomenti (input_json_delta), non solo l'apertura della chiamata.
curl -s $GATEWAY/v1/messages \
-H "Authorization: Bearer $KEY" -H "content-type: application/json" \
-d '{"model":"MODELLO","max_tokens":300,"stream":true,
"tools":[{"name":"Read","description":"Read a file",
"input_schema":{"type":"object",
"properties":{"file_path":{"type":"string"}},
"required":["file_path"]}}],
"messages":[{"role":"user",
"content":"Leggi /etc/hostname con il tool Read."}]}' \
| grep -o 'partial_json.\{0,60\}'
Esito atteso: una riga che contiene gli argomenti veri, per esempio {"file_path": "/etc/hostname"}. Nessuna riga significa modello non utilizzabile come agente.
I task sono presi dal lavoro reale, non inventati per il test. Servono input fissi: la stessa mail, lo stesso transcript, lo stesso brain di partenza per tutte le esecuzioni e per tutti i modelli.
| # | Task | Cosa mette alla prova |
|---|---|---|
| 1 | Riassunto di una call da transcript lungo | Tenuta sul contesto lungo, fedeltà ai fatti |
| 2 | Estrazione entità da una mail (persone, aziende, scadenze) | Precisione strutturata, niente invenzioni |
| 3 | Generazione di una pagina HTML da dati forniti | Output lungo e formattato, accentate, nessun numero inventato |
| 4 | Ricerca nel brain che richiede di aprire più file | Uso degli strumenti in catena, numero di turni |
| 5 | Modifica mirata di un file esistente | Precisione dell'edit, capacità di non riscrivere tutto |
Task 3 e 5 sono i più discriminanti: il primo perché è dove i modelli riempiono i vuoti con dati plausibili, il secondo perché distingue chi sa fare una modifica chirurgica da chi rigenera il file intero.
- Sessione nuova a ogni esecuzione. Mai riprendere una conversazione: il contesto precedente cambia il comportamento e falsa il confronto.
- Tre ripetizioni per task e per modello. La variabilità fra due esecuzioni identiche è alta: un solo giro non misura niente. Si registrano tutte e tre, si riporta la mediana.
- Ordine alternato. Non tutte le prove di un modello e poi l'altro: si alternano, per non far coincidere un modello con una fascia oraria (il carico dei provider cambia durante il giorno).
- Stesso stato di partenza. Se un task scrive nel brain, si ripristina lo stato prima della prova successiva.
- Prompt identici, senza nominare il modello. Un prompt che dice "sei Gemini" o "sei Claude" cambia la risposta.
| Metrica | Come si legge | Perché conta |
|---|---|---|
| Token in / out | Campo usage nel flusso di risposta | È la base del costo: l'unica cifra non opinabile |
| Tempo totale | Cronometro sull'esecuzione | Percepito dall'utente; pesa sull'adozione |
| Numero di turni | Conteggio dei passaggi fino alla risposta finale | Un modello che gira a vuoto costa il doppio a parità di esito |
| Esito | Giudizio umano: 0 sbagliato, 1 parziale, 2 buono, 3 pronto da consegnare | Un output veloce ed economico ma da rifare non vale niente |
| Dati inventati | Conteggio secco dei numeri o nomi non presenti negli input | Per pagine e report è il difetto che squalifica |
Il giudizio umano lo dà sempre la stessa persona, e prima di sapere quale modello ha prodotto l'output. Altrimenti si misura l'aspettativa, non il risultato.
Il costo non si stima: si calcola dai token misurati, moltiplicati per il prezzo di listino alla data della prova. Il listino va riportato qui sotto al momento dell'esecuzione, con la data — cambia, e un confronto con prezzi vecchi non è difendibile.
| Modello | Prezzo input / 1M token | Prezzo output / 1M token | Data listino |
|---|---|---|---|
| Gemini | da compilare | da compilare | da compilare |
| Claude | da compilare | da compilare | da compilare |
Va dichiarata anche la via di accesso, perché non è neutra: lo stesso modello usato via interfaccia grafica, via abbonamento o via chiave a consumo può pescare da capienze diverse, e una di queste non compare come consumo di token. Un confronto che mescola le vie di accesso non misura niente.
- Sessione ripresa invece che nuova
- Brain in stato diverso fra una prova e l'altra
- Prompt ritoccato fra un modello e l'altro
- Una sola esecuzione per task
- Limite di contesto raggiunto: la sessione si tronca e il confronto salta
- Aggiornamento del gateway a metà tornata
- Fasce orarie diverse fra i due modelli
- Cache del prompt attiva su un solo lato
Una riga per esecuzione. Si compila mentre si esegue, non a memoria dopo.
| Task | Modello | Giro | Token in | Token out | Secondi | Turni | Esito 0-3 | Inventati |
|---|---|---|---|---|---|---|---|---|
| 1 | — | — | — | — | — | — | — | — |
| 2 | — | — | — | — | — | — | — | — |
| 3 | — | — | — | — | — | — | — | — |
| 4 | — | — | — | — | — | — | — | — |
| 5 | — | — | — | — | — | — | — | — |
Il risultato da portare a una decisione è una riga sola per modello: costo medio per task completato con esito 2 o 3. Non il costo per token, non il costo per chiamata: il costo del lavoro fatto bene. Un modello che costa metà ma serve due giri per arrivare allo stesso punto non è più economico.
Accanto va la parte che i numeri non dicono: dove ciascun modello ha sbagliato, e se il tipo di errore è tollerabile per il lavoro del village. Un errore di forma si corregge; un dato inventato in una pagina che finisce a un terzo, no.