Cominciamo dalla conclusione: quando un chatbot di assistenza clienti brucia soldi, nell'80% dei casi non è perché il prezzo unitario del modello è alto, ma perché c'è qualcosa che non va nel modo in cui viene chiamato. Un nostro chatbot interno di Q&A post-vendita, con qualche migliaio di utenti attivi al giorno, nel primo mese online ha fatto schizzare la fattura direttamente al triplo del budget. Dopo l'analisi, il prezzo unitario del modello non era cambiato di un centesimo: erano tutti costi nascosti nella struttura delle chiamate. Questo articolo documenta il processo di retrospettiva; se vi occupate di ottimizzazione dei costi delle API dei grandi modelli, potete verificarlo riga per riga sulla vostra fattura.
Come si presenta una fattura anomala
La caratteristica dell'anomalia non è "un totale alto", ma "una struttura strana". Abbiamo estratto il dettaglio delle chiamate per giorno e trovato tre cose che non tornavano: nei giorni con il volume di chiamate più alto, il numero medio di token per singola richiesta tendeva a salire; la percentuale di tentativi ripetuti si avvicinava al 20%; per la stessa domanda dell'utente, si andava da poche centinaia di token fino a decine di migliaia, con una varianza enorme. Questi tre elementi messi insieme bastano praticamente a localizzare il problema: non è lato modello, è nella nostra catena di chiamate.
Quattro costi nascosti, uno più subdolo dell'altro
Primo, il modello di punta usato per i lavori grossolani. All'inizio, per comodità, facevamo passare tutte le richieste dal modello di punta. Ma nel scenario dell'assistenza clienti, oltre il 70% è riconoscimento di intenti e risposte con frasi fisse del tipo "dov'è il mio ordine" o "come faccio il reso": per questi compiti un modello leggero è più che sufficiente, con un costo di un ordine di grandezza inferiore. Far rispondere al modello di punta "a che ora aprite" equivale a usare un camion per consegnare una pizza.
Secondo, espansione sfrenata del contesto. Nei dialoghi multi-turno rimettevamo dentro tutti i messaggi storici; quando l'utente arrivava al decimo turno, solo la cronologia occupava la maggior parte dei token. Il problema peggiore è che molta cronologia non aveva nulla a che fare con la domanda corrente: puro passeggero. Il contesto non è più intelligente se è più lungo; oltre una certa lunghezza, il miglioramento dell'accuratezza è limitato, ma il costo cresce in modo lineare.
Terzo, tempesta di tentativi ripetuti. Avevamo impostato un semplice retry in caso di fallimento, ma senza backoff né circuit breaker. Quando l'upstream andava in timeout occasionalmente, lo stesso lotto di richieste veniva rispedito più volte: un fallimento, un retry; il retry falliva, e si riprovava. Sulla fattura queste chiamate erano tutte spese a vuoto, e lato utente si vedeva comunque un errore.
Quarto, doppia fatturazione tra streaming e non-streaming. Questo è il più facile da trascurare. Alcune nostre catene, per ottenere il risultato completo e fare post-processing, chiamavano in modalità non-streaming; il frontend, per l'effetto macchina da scrivere, chiamava di nuovo in streaming. Stessa domanda, due addebiti. Poi abbiamo unificato tutto in ricezione streaming con assemblaggio locale, e solo allora questo costo duplicato è sparito.
Come implementare il routing a livelli
L'idea non è complicata: smistare in base alla difficoltà del compito. Riconoscimento di intenti, estrazione di slot, frasi fisse vanno su modelli leggeri; solo le conversazioni complesse che richiedono davvero ragionamento, giudizi multi-passo e gestione emotiva vengono affidate al modello di punta. In mezzo si aggiunge un livello di gateway dei modelli che fa da smistatore: la richiesta entra, passa prima dal classificatore, viene etichettata con il tipo di compito e poi si decide verso quale modello instradarla.
Noi usiamo la logica di selezione automatica del modello ottimale in base al compito; l'abbiamo testata per un ciclo sul routing multi-modello di SiCore TokenWorks e, dopo aver spostato i compiti semplici sui modelli leggeri, il costo complessivo è sceso in modo evidente e anche la risposta è diventata più rapida. La chiave qui non è "quale modello usare", ma la tabella di mappatura "quale compito con quale modello", che va messa a punto di continuo. All'inizio l'avevamo configurata a esperienza; dopo due settimane di esecuzione l'abbiamo ricalibrata in base al tasso di successo reale, con risultati molto migliori rispetto a una configurazione a intuito. È anche in questo momento che emergono i vantaggi dell'accesso unificato multi-modello: cambiare la strategia di routing non richiede modifiche al codice di business, basta regolare il livello gateway.
Confronto della fattura prima e dopo l'ottimizzazione
Non riporto numeri assoluti, riporto le proporzioni. Il volume totale di chiamate non è cambiato, perché il numero di utenti non è cambiato. Il costo totale è sceso di circa il 60%; di questo, la quota di chiamate al modello di punta è passata da quasi il 100% a circa il 30%, e il resto è stato dirottato sui modelli leggeri. Le chiamate legate ai retry sono scese da quasi il 20% a una percentuale a una cifra. Il numero medio di token per singola richiesta è calato di circa il 40%, soprattutto grazie al taglio del contesto. La voce della doppia fatturazione streaming è andata direttamente a zero. Tirando le somme, dal triplo del budget siamo tornati dentro il budget con del margine.
Come configurare monitoraggio e alert
I soldi risparmiati vanno difesi con il monitoraggio, non con la buona volontà. Abbiamo configurato quattro alert: scatto quando il numero di token per singola richiesta supera la soglia, per prevenire il contesto fuori controllo; scatto quando il tasso di retry supera la proporzione impostata, per prevenire la tempesta di retry; scatto quando la quota di chiamate al modello di punta sale in modo anomalo, segno che il routing potrebbe essere inefficace; scatto quando l'aumento del costo giornaliero su base comparativa supera la soglia. Questi quattro non serve renderli complicati: aggregazione giornaliera e alert al superamento della soglia bastano. Nel modello di fatturazione a Token, il costo si accumula in tempo reale; aspettare la fine del mese per guardare la fattura e ottimizzare significa che i soldi sono già stati spesi.
In una frase: la voce principale del costo di un chatbot di assistenza clienti sta nella struttura delle chiamate, non nel prezzo unitario del modello. Facendo bene queste quattro cose — routing a livelli, taglio del contesto, controllo dei retry, unificazione dello streaming — la fattura scende da sola. Come estensione, se nel vostro scenario c'è anche il retrieval RAG, vale la pena verificare con la stessa logica anche il numero di documenti recuperati dal vector store.