🎁 Novità Registrati gratis, 10 chiamate le offriamo noi. Fino a $1, senza carta.
Provider Drift: come il routing di default fa lievitare i costi degli LLM

Provider Drift: come il routing di default fa lievitare i costi degli LLM

Indice
  1. Le due condizioni che lo scatenano
  2. Come si presentano 20 richieste identiche
  3. Conclusione A: il costo che ti aspettavi vs il costo che hai pagato
  4. Conclusione B: niente cache significa anche niente vantaggio sulla latenza
  5. Verifica il tuo setup in cinque minuti
  6. Cosa cercare
  7. Chiusura
  8. FAQ

Hai attivato il prompt caching, il contatore degli hit scatta ogni tanto, ma il conto è rimasto praticamente uguale. Prima di prendertela con la struttura del tuo prompt, guarda una cosa che la dashboard nasconde: quale upstream ha davvero servito ciascuna richiesta.

I gateway multi-provider distribuiscono un singolo modello su più provider upstream e ne scelgono uno per ogni richiesta. Le prompt cache sono per provider (spesso per nodo all’interno di un provider). Così, quando la tua seconda richiesta identica finisce su un upstream diverso dalla prima, è un cache miss, anche se il tuo prompt non è cambiato di un byte. Questo è il provider drift, e su un modello pay-per-token moltiplica i tuoi costi in silenzio.

TL;DR

  • Con il routing predefinito di fabbrica, un gateway multi-provider ha distribuito 20 chiamate identiche su 9 upstream e ha raggiunto la cache del prompt 4 volte su 20.
  • Un gateway con backend singolo ha raggiunto 19/20 sullo stesso carico di lavoro; la deriva ha reso l’esecuzione circa 3.9x più costosa ($0.0102 vs $0.0026).
  • Un cache miss è costato circa 4x un hit sul modello della famiglia DeepSeek misurato ($0.00062 vs $0.00015 mediana per chiamata).
  • La deriva è per-modello: lo stesso gateway ha instradato un modello di classe GPT verso un unico upstream per tutte le 20 chiamate, raggiungendo 19/20.

Le due condizioni che lo scatenano

Non è una configurazione sbagliata che hai scelto tu. È quello che ottieni di default:

  1. Auto routing di default. La richiesta viene inviata al modello senza fissare un upstream, quindi il gateway ne sceglie uno a ogni chiamata.
  2. Ordinamento dei provider di default = “default (balanced)”. Il gateway bilancia il carico tra gli upstream idonei invece di restare fedele a uno solo.

Entrambe sono le impostazioni di fabbrica. Non devi toccare niente per avere il drift; devi toccare le impostazioni per evitarlo.

Come si presentano 20 richieste identiche

Abbiamo inviato lo stesso prefisso di ~8K token 20 volte di fila a un noto gateway multi-provider, con i default di cui sopra, chiedendo ogni volta i campi provider e cache riportati dall’upstream stesso. Per un modello con cache su disco della famiglia DeepSeek:

  • 9 upstream distinti hanno servito le 20 chiamate: N***a, S***w, M***h, D***a, A***L, P***l, S***e, V***e, A***d.
  • Cache hit rate: 4/20 (20%). Fai hit solo sulle chiamate che per caso finiscono su un upstream che aveva già in cache il tuo prefisso.

Fai le stesse 20 chiamate contro un gateway a backend singolo (un modello, un upstream, nessun bilanciamento) e l’hit rate è 19/20 (95%) sullo stesso identico carico. Stesso modello, stesso prompt, stesso numero di chiamate. L’unica variabile è se il routing va in drift o no.

Per contrasto, sullo stesso identico gateway multi-provider un modello di classe GPT è stato instradato su un solo upstream (A***e) per tutte le 20 chiamate e ha fatto hit 19/20. Il drift non è uniforme; colpisce il modello che il gateway per caso distribuisce, e in questa prova era il modello della famiglia DeepSeek.

Conclusione A: il costo che ti aspettavi vs il costo che hai pagato

Il costo per chiamata sul modello soggetto a drift si divide nettamente in base all’esito della cache:

tipo di chiamatacosto mediano / chiamata
cache hit~$0.00015
cache miss~$0.00062

Un miss costa circa 4x un hit su questo modello (sui token di input grezzi il divario pubblicato è ancora più ampio, circa 50x). Ora fai il totale sulle 20 chiamate:

scenariohit ratecosto per 20 chiamate identiche
atteso (cache raggiungibile)95%$0.0026
reale (drift di default)20%$0.0102

Stesso modello, stesso prompt, stesse 20 richieste. Il provider drift ha reso il run ~3.9x più costoso. Il caching è rimasto “attivo” per tutto il tempo; è il livello di routing che ha semplicemente fatturato la maggior parte dei tuoi token al prezzo del miss. Porta tutto questo su un endpoint di produzione che rigioca un prefisso grande e stabile tutto il giorno e il divario diventa il grosso della tua spesa di input.

Conclusione B: niente cache significa anche niente vantaggio sulla latenza

La cache non è solo una leva sui costi. Un prefill caldo restituisce prima il primo token. Quando la deriva ti nega la cache, perdi anche quel guadagno di velocità. Abbiamo misurato il time-to-first-token (TTFT) su chiamate identiche ripetute:

Modello di classe GPT (instradato verso un unico upstream costante, cache raggiungibile):

chiamataTTFT
1ª (fredda, miss)~1760 ms
successive (calda, hit)~1130 ms

La cache regala circa un 36% in meno sul primo token, e in modo stabile: ogni chiamata calda cade in una fascia stretta.

Modello della famiglia DeepSeek (deriva di default, cache raramente raggiungibile):

  • Cache hit su un ciclo di 10 chiamate: 0.
  • Il TTFT oscillava da ~1000 ms a ~4500 ms tra una chiamata e l’altra, con qualche risposta vuota.

Dato che quasi ogni richiesta finisce su un upstream nuovo, resti alla latenza del prefill freddo e ti prendi la varianza del provider che ha risposto. Il modello GPT ha guadagnato un 36% di TTFT grazie a una cache raggiungibile; il modello soggetto a deriva non ha guadagnato niente, con in più uno scarto di 4,5x tra la chiamata più veloce e la più lenta.

Verifica il tuo setup in cinque minuti

Non fidarti di questi numeri, né di quelli di nessun altro. Manda lo stesso prefisso lungo più volte e guarda due campi. Nessun dominio hardcoded; puntalo al tuo gateway con delle variabili d’ambiente.

import os, uuid
from openai import OpenAI

client = OpenAI(api_key=os.environ["GW_KEY"], base_url=os.environ["GW_BASE"])
SYS = f"[probe {uuid.uuid4().hex}]\n\n" + ("You are a support assistant. " * 300)

seen, hits = {}, 0
for i in range(20):
    r = client.chat.completions.create(
        model=os.environ["GW_MODEL"], max_tokens=16,
        messages=[{"role": "system", "content": SYS},
                  {"role": "user", "content": f"q{i}"}],
        extra_body={"usage": {"include": True}})
    d = r.model_dump()
    det = r.usage.prompt_tokens_details
    cached = (getattr(det, "cached_tokens", 0) or 0) if det else 0
    seen[d.get("provider")] = seen.get(d.get("provider"), 0) + 1   # populated when exposed
    hits += 1 if cached else 0

print(f"hit rate {hits}/20; upstreams seen: {len(seen)}")

Più di un upstream per lo stesso modello significa deriva. Un hit rate ben al di sotto della stabilità del tuo prompt significa che ti sta costando. Il metodo più completo è in Il tuo LLM Gateway mente sulla cache?.

Cosa cercare

Il rimedio alla deriva è strutturale: instrada un dato modello verso un backend costante, così che alla richiesta successiva una cache calda sia davvero raggiungibile, invece di bilanciare ogni chiamata su un upstream nuovo che non ha mai visto il tuo prefisso. Quando valuti un gateway, manda lo stesso prefisso 20 volte e conta gli upstream. Uno è quello che vuoi. Nove sono una tassa.

Una precisazione doverosa: il prompt caching è best-effort ovunque, e sui modelli con cache su disco l’hit rate cala comunque dopo lunghi periodi di inattività, anche con un singolo backend. Eliminare la deriva non ti dà una cache infinita. Rimuove la fonte di miss più grande e più sprecona, quella che non hai mai accettato e che non riesci a vedere.

Chiusura

“Supporta il prompt caching” e “la tua cache è raggiungibile” sono affermazioni diverse. Un gateway che sparpaglia un modello su un insieme rotante di upstream può dichiarare il supporto alla cache dicendo il vero, e nel frattempo consegnarti un hit rate del 20%, un conto ~4x e una latenza sul primo token che oscilla di 4,5x. Il numero da guardare non è se la cache viene pubblicizzata. È il tuo hit rate misurato e quanti upstream toccano le tue richieste identiche. Lancia la probe e lascia decidere ai dati.

Per il metodo di audit completo vedi Il tuo LLM Gateway mente sulla cache?; per capire perché le cache esistono, vedi Come funzionano KV Cache e TTL.

FAQ

È un errore di configurazione dalla mia parte? No. Succede con le impostazioni di fabbrica: routing automatico con l’ordinamento dei provider lasciato su “default (bilanciato)”. Per evitare il drift bisogna fissare attivamente un upstream, non il contrario.

Fissare un solo upstream risolve il problema? Elimina il drift tra provider, ma un singolo upstream spesso gira su più repliche senza affinità di prefisso, quindi gli hit possono continuare a oscillare. Misura dopo aver fissato l’upstream, non darlo per scontato.

Perché il modello di classe GPT non ha subito drift? In questa esecuzione il gateway lo ha indirizzato verso un unico upstream. Il drift è specifico per modello e dipende da quanti upstream idonei il gateway usa per il bilanciamento; non è uniforme.

La differenza di costo è davvero ~4x? Sui totali per chiamata che abbiamo misurato, un miss costava ~4x rispetto a un hit; sul prezzo grezzo degli input token per questa classe di modelli, la differenza pubblicata tra hit e miss è più vicina a 50x. In ogni caso, trasformare hit attesi in miss è la parte costosa.

Quale singola metrica dovrei monitorare? Il cache hit rate per modello nel tempo, insieme al numero di upstream distinti per modello. Se l’hit rate cala o il numero di upstream sale, il tuo costo effettivo per token è appena aumentato.

← Torna al blog