La grammatica GBNF enumera i valori ammessi, quindi un output non valido è
strutturalmente impossibile: 100% di JSON validi su 200 richieste misurate.
Nessun prompt di sistema. Il modello riceve solo la query dell'utente. La
tassonomia sta nei pesi, non nel contesto — sono 158 token in meno per
richiesta, contro una query media di 10,8 token.
Risultati
Test set: 2.805 query italiane da MASSIVE, split per seed_id.
modello
accuratezza
macro-F1
Qwen3-1.7B zero-shot (stesso modello, non addestrato)
0,5077
0,4160
embedding congelati + regressione logistica
0,9002
0,8335
SetFit (encoder fine-tunato)
0,9519
0,8600
questo modello (bf16)
0,9615
0,9555
questo modello (GGUF Q4_K_M)
0,9576
0,9423
Il modello consigliato è la variante con aumento, che regge molto meglio
fuori distribuzione al costo di 0,4 punti in-distribution:
test
gold (scritto a mano)
bf16
0,9572
0,9139
GGUF Q4_K_M
0,9569
0,9139
Latenza a richiesta singola, Q4_K_M su RTX 3080 con clock bloccati:
p50 66,4 ms · p95 75,4 ms · p99 141,6 ms, 100% di JSON validi.
Regressione generalista (lm-eval, 300 esempi/task): delta medio
−0,33 punti su arc_easy / hellaswag / piqa. Il catastrophic forgetting è
assente.
Consigliato: aggiungi il cancello OOD. Il modello da solo non riconosce il
fuori dominio. Con una soglia sul max-softmax tarata al 90° percentile del
traffico in-domain, blocca il 73,6% di un dominio estraneo, al costo del 5,5%
di query corrette mandate a fallback.
🚨 Limitazioni — leggere prima di usarlo
1. Fuori distribuzione il vantaggio sparisce. Su 151 query italiane scritte
a mano, che non derivano da nessun benchmark:
modello
accuratezza
macro-F1
richiamo su fallback
embedding congelati + LogReg
0,8344
0,8129
0,417
questo modello (bf16)
0,8278
0,7884
0,167
questo modello (Q4_K_M)
0,8477
0,8029
0,167
Il 96% diventa 85%, e un baseline lineare banale è alla pari. Il 96,15%
misura la generalizzazione dentro MASSIVE, non la robustezza a query reali.
1-bis. Non riconosce il fuori dominio. Su 1.200 query bancarie — un dominio
adiacente e coerente — il richiamo su fallback è 0,0%. Le instrada con
sicurezza a info e comms. Se lo metti davanti a traffico che esce dal
dominio assistente-vocale, non se ne accorge.
E la confidenza non ti salva: su quel set la confidenza media è 0,80 contro
un'accuratezza di 0,21 (ECE 0,59). Il modello sbaglia con sicurezza. Una
soglia serve a graduare la fiducia dentro il dominio — dove funziona bene, ECE
0,015 — non a stabilirne il confine. Serve un rilevatore OOD separato.
2. confidence varia, ma non misura l'affidabilità. Dopo l'aumento il campo
non è più costante: emette "medium" sul 7,3% del gold set. Ma su quei casi
l'accuratezza è 1,000 — il campo segnala «questa è multi-intento o
degenere», non «sono meno sicuro». Trattarlo come misura di affidabilità
sarebbe esattamente sbagliato, e a 93-100% di "high" non serve comunque come
soglia. Per una confidenza vera leggi la softmax sui logit dei sei nomi di
agente: in-distribution è ben calibrata (ECE 0,015) e a soglia 0,99 copre
l'81% del traffico con il 99,4% di accuratezza.
3. fallback non è affidabile. Il richiamo crolla a 0,167 fuori
distribuzione: multi-intento («mandami la mail e metti la sveglia») e query
degeneri non vengono riconosciuti, perché nel training non esistono in quella
forma. Una soglia di confidenza aiuta ma non basta (vedi 1-bis): dentro il
dominio intercetta l'88% degli errori, fuori no.
4. Il vantaggio si manifesta solo con abbastanza dati. Sotto ~1.500 esempi
di training SetFit è migliore, costa 8× meno in latenza e 8× meno in tempo di
addestramento. Questo modello ha senso oltre quella soglia.
5. Dominio di validità. Assistente vocale / smart home / produttività
personale, il dominio di MASSIVE (traffico Alexa). Fuori da lì — dominio
bancario, medico, legale, supporto tecnico — non è stato valutato e non c'è
ragione di aspettarsi che funzioni.
6. Italiano. Addestrato sul solo italiano. Esiste anche una variante
addestrata sul solo inglese: valutata in italiano fa 0,9455, cioè il transfer
cross-linguale costa 1,60 punti.
7. Non c'è estrazione di slot. L'output è solo l'agente di destinazione.
Parametri ed entità sono lavoro dell'agente a valle.
Dati di addestramento
10.959 esempi italiani da MASSIVE (Apache 2.0), rietichettati su 6 agenti
tramite una mappatura versionata: i 18 scenario collassati meccanicamente, più
cinque override motivati a livello di intent.
Due sorgenti sono state escluse dal training perché la loro etichetta è
contesa, e sono conservate come holdout valutati a parte:
general_quirky di MASSIVE — non è out-of-domain, è un cassetto della
spazzatura: contiene query che appartengono ad altri agenti. Concorda con
l'etichetta nominale fallback solo nel 17,4% dei casi.
l'out-of-scope di CLINC150 — «fuori dominio» lì significa fuori dai 150
intent di CLINC, non fuori dai nostri 6 agenti. «quanto è 1 quota di aapl»
è una query info. Concordanza con fallback: 1,8%.
Lo split è per seed_id, mai per riga, e il seed_id non contiene la lingua:
MASSIVE è un corpus parallelo, quindi le versioni italiana e inglese della
stessa frase non possono finire in split diversi.
Nessun dato personale o proprietario. Solo benchmark pubblici, più 151 query
scritte a mano per il test set fuori distribuzione.
Riproduzione
Codice, config e comandi: github.com/charlie128233/router-rtx3080. Ogni figura si
riproduce con un comando singolo, e il paper legge i numeri da results/ invece
di averli scritti a mano. Il repo non distribuisce llama.cpp: usa la tua
installazione.
Licenza
Apache 2.0, come il modello base Qwen3-1.7B e come MASSIVE.