Torna alla home
5 min di lettura
#mklang#LLM#Production#Evals#Cost

Il prototipo LLM funziona. Quattro domande prima della produzione

Stato, recovery, eval, costi: quattro domande da porsi prima di portare in produzione un prototipo LLM, con esempi reali e i limiti dichiarati.

Il prototipo risponde bene in demo. Il team è contento, il cliente interno anche. Poi arriva la domanda che nessuno ha messo in roadmap: cosa succede quando lo lasciamo girare da solo, con traffico vero, per tre mesi?

In quel passaggio i problemi raramente stanno nel modello. Stanno nel sistema attorno al modello. Io li riduco a quattro domande: dove si perde lo stato, come si recupera dai fallimenti, come si misura la qualità degli output e quanto costa ogni richiesta. Per ciascuna, qui sotto, c'è un esempio reale preso dal mio codice open source. Ogni esempio mostra come la risposta facile si è rivelata sbagliata, o almeno incompleta.

1. Dove si perde lo stato?

Un prototipo tiene lo stato in memoria: la conversazione, i risultati intermedi, il punto del flusso in cui si trova. Finché il processo non si riavvia, va tutto bene. In produzione il processo si riavvia: un deploy, un timeout, un budget esaurito a metà lavoro.

La prima risposta è «salviamo lo stato». È giusta, ma apre una seconda domanda: cosa stai salvando, e chi può leggerlo?

In mklang, il linguaggio per macchine a stati LLM che sviluppo in open source, le run si possono sospendere e riprendere da un checkpoint (ADR 0007, docs/adr/0007-resumable-checkpoints.md). Il progetto stesso scrive che quel checkpoint contiene l'intera blackboard (lo stato condiviso della run) in JSON in chiaro: testo dei clienti, dati personali, policy interne. E aggiunge che i casi che restano sospesi più a lungo, le escalation verso un umano, sono proprio i più sensibili (ADR 0032, docs/adr/0032-pluggable-checkpoint-store.md).

Nel tuo sistema la domanda pratica è doppia. Se il processo muore a metà, riparti dal punto giusto o ricominci da capo? E i file o le righe di database che rendono possibile la ripartenza sono trattati come dati sensibili, con cifratura e scadenza?

Lo stesso tema compare quando più componenti scrivono sullo stesso stato. L'ho raccontato per LangGraph in «Lo stato come API: LangGraph dopo tre riscritture» (gianlucamazza.it/it/blog/langgraph-workflow-orchestration): un flag scritto da un nodo e sovrascritto da quello dopo, perché il campo non dichiarava come andavano unite le scritture.

2. Come si recupera dai fallimenti?

Un LLM sbaglia in modi che il codice classico non conosce: un output troncato, un JSON non valido, una risposta che ignora un vincolo. La reazione naturale è riprovare, magari dicendo al modello cosa ha sbagliato.

Sembra ovvio che il secondo tentativo, con il feedback, vada meglio del primo. In mklang il costrutto repair fa esattamente questo, ma fino al 20 agosto 2026 non era mai stato misurato. Quel giorno (DeepSeek, 30 run) il tasso di successo è stato 0,57 al primo tentativo e 0,15 al secondo. Fonte: docs/experiments/repair-convergence.md nel repo mklang.

Non è una confutazione. Al secondo tentativo arrivano solo i casi che il primo ha fallito, cioè i più difficili, e il campione è piccolo: 13 run su 30 sono arrivate al secondo tentativo. Ma basta a togliere la certezza. Oggi non posso dire che il feedback funzioni meglio di un semplice nuovo campione, che costerebbe uguale.

La domanda per il tuo sistema: i tuoi retry migliorano davvero il risultato, o pagano due volte la stessa probabilità? E quando i retry finiscono, dove va la richiesta: a un umano, a un errore esplicito, o a un «ok» che nasconde il fallimento?

3. Come si misura la qualità degli output?

Quasi ogni team ha qualche forma di valutazione: un set di esempi, un confronto tra modelli, a volte un secondo LLM che fa da giudice. Il rischio è avere un numero che sembra buono e non misura niente.

In mklang misuro se modelli diversi prendono la stessa decisione sugli stessi input. Il 27 luglio 2026 quel numero era 1,0 su quattro macchine a stati di test, cioè accordo perfetto. Il progetto stesso, nella pagina dell'esperimento (docs/experiments/gate-divergence.md), scrive che quel numero «non aveva potere discriminante», per tre motivi. I casi erano facili. Due modelli possono essere d'accordo sulla risposta sbagliata. E il dato mescolava due domande diverse: un modello è coerente con sé stesso? Due modelli sono d'accordo tra loro?

La correzione è stata aggiungere casi di confine, dove la risposta giusta è difendibile ma non ovvia, e misurare l'accuratezza contro una risposta di riferimento, non solo l'accordo.

La domanda per il tuo sistema: i tuoi test possono fallire? Se un cambio di modello o di prompt peggiora le risposte, quale numero se ne accorge, e prima o dopo il rilascio?

4. Quanto costa ogni richiesta?

Il costo di un sistema LLM sembra semplice: token in entrata più token in uscita, per il prezzo del provider. Il problema sono le richieste che non finiscono bene.

Fino alla versione 1.3.7 di mklang (29 settembre 2026), una risposta troncata o un JSON non valido fermavano la run senza registrare i token di quella chiamata, che però il provider aveva già fatturato. Il conteggio dei costi della run sottostimava proprio i fallimenti, cioè la parte di costo che serve vedere. La correzione è nel CHANGELOG 1.3.7 ed è coperta da test di regressione (PR #111).

La domanda per il tuo sistema: il costo che misuri include le risposte scartate, i retry e le chiamate fallite? E conosci il costo per richiesta, non solo il totale del mese?

Prima della produzione

Le quattro domande non richiedono un framework particolare. Servono risposte scritte, con un riferimento al codice o a un run per ciascuna. Dove la risposta è «non lo sappiamo», di solito lì sta il primo intervento.

Se hai un prototipo LLM funzionante e vuoi queste risposte sul tuo repository, è il lavoro della review di production readiness: una valutazione scritta per ciascuna delle quattro domande, senza modifiche al codice. I dettagli sono su /it/servizi.

Condividi questo articolo

Articoli correlati

  • Una risposta rifiutata deve comunque addebitare i token

    Se il runtime rifiuta la risposta, conservo i token della chiamata produce già fatturata. Onestà del ledger per agenti governabili, da mklang 1.3.7 / pull 111.

    4 ott 20268 min di lettura
    #mklang#LLM#Cost#Agents#Production
  • Proof of work e inference: il costo come segnale, non come identità

    L'inference non è proof of work. Distinguo due spese di compute: una regola per il consenso scarso, e un modello più un prompt per l'utilità.

    2 ott 202610 min di lettura
    #Inference#Cost#Eval#LLM#Production
  • RAG: chunking e re-ranking prima degli embedding

    Quando il retrieval è debole, cambiare gli embedding raramente lo sistema. Diagnostico prima chunking e re-ranking.

    20 dic 202414 min di lettura
    #RAG#Retrieval#LLM#Production