Provider Drift: Como o Roteamento Padrão Infla o Custo de LLM
Conteúdo
Você ativou o prompt caching, o contador de acertos avança de vez em quando, mas sua conta mal se mexeu. Antes de culpar a estrutura do seu prompt, observe algo que o dashboard esconde: qual upstream de fato atendeu cada requisição.
Gateways multiprovedor distribuem um único modelo entre vários provedores upstream e escolhem um por requisição. Os prompt caches são por provedor (muitas vezes por nó dentro de um provedor). Então, quando sua segunda requisição idêntica cai em um upstream diferente do primeiro, é um cache miss, mesmo que seu prompt não tenha mudado um único byte. Isso é o provider drift, e em um modelo de pagamento por token ele silenciosamente multiplica seu custo.
As duas condições que o disparam
Isso não é uma má configuração que você escolheu. É o que você recebe de fábrica:
- Roteamento automático padrão. A requisição é enviada ao modelo sem fixar um upstream, então o gateway escolhe um a cada chamada.
- Ordenação de provedor padrão = “default (balanced)”. O gateway faz balanceamento de carga entre os upstreams elegíveis em vez de manter um só.
Ambos são os padrões de fábrica. Você não precisa tocar em nada para ter drift; você precisa mexer nas configurações para evitá-lo.
Como ficam 20 requisições idênticas
Enviamos o mesmo prefixo de ~8K tokens 20 vezes seguidas para um popular gateway multiprovedor, com os padrões acima, solicitando a cada vez os campos de provedor e cache reportados pelo próprio upstream. Para um modelo com cache em disco da família DeepSeek:
- 9 upstreams distintos atenderam as 20 chamadas:
N***a,S***w,M***h,D***a,A***L,P***l,S***e,V***e,A***d. - Taxa de acerto de cache: 4/20 (20%). Você só acertava nas chamadas que por acaso caíam em um upstream que já havia cacheado seu prefixo.
Execute as mesmas 20 chamadas contra um gateway de backend único (um modelo, um upstream, sem balanceamento) e a taxa de acerto é 19/20 (95%) na carga de trabalho idêntica. Mesmo modelo, mesmo prompt, mesmo número de chamadas. A única variável é se o roteamento sofre drift.
Para contraste, no mesmo gateway multiprovedor um modelo da classe GPT foi roteado para um upstream (A***e) em todas as 20 chamadas e acertou 19/20. O drift não é uniforme; ele afeta qualquer modelo que o gateway acabe espalhando, e nesta execução foi o modelo da família DeepSeek.
Conclusão A: o custo que você esperava vs o custo que você pagou
O custo por chamada no modelo com drift se dividiu claramente conforme o resultado do cache:
| tipo de chamada | custo mediano / chamada |
|---|---|
| cache hit | ~$0.00015 |
| cache miss | ~$0.00062 |
Um miss custa cerca de 4x um hit neste modelo (em tokens de entrada brutos, a diferença publicada é ainda maior, cerca de 50x). Agora some isso entre as 20 chamadas:
| cenário | taxa de acerto | custo para 20 chamadas idênticas |
|---|---|---|
| esperado (cache acessível) | 95% | $0.0026 |
| real (drift padrão) | 20% | $0.0102 |
Mesmo modelo, mesmo prompt, mesmas 20 requisições. O provider drift fez a execução custar ~3,9x mais. O caching esteve “ligado” o tempo todo; a camada de roteamento simplesmente cobrou a maioria dos seus tokens à taxa de miss. Escale isso para um endpoint de produção reproduzindo um grande prefixo estável o dia inteiro e a diferença é a maior parte do seu gasto com entrada.
Conclusão B: sem cache também significa sem ganho de latência
O caching não é apenas uma alavanca de custo. Um prefill quente retorna o primeiro token mais cedo. Quando o drift te nega o cache, você abre mão desse ganho também. Medimos o time-to-first-token (TTFT) em chamadas idênticas repetidas:
Modelo da classe GPT (roteado para um upstream consistente, cache acessível):
| chamada | TTFT |
|---|---|
| 1ª (fria, miss) | ~1760 ms |
| subsequentes (quentes, hit) | ~1130 ms |
O caching compra um primeiro token cerca de 36% mais rápido, e é estável: toda chamada quente cai em uma faixa estreita.
Modelo da família DeepSeek (drift padrão, cache raramente acessível):
- Cache hits ao longo de 10 chamadas repetidas: 0.
- O TTFT oscilou de ~1000 ms a ~4500 ms de chamada para chamada, com respostas vazias ocasionais.
Como quase toda requisição cai em um upstream novo, você permanece na latência de prefill frio e herda a variância do provedor que respondeu. O modelo GPT teve uma melhora de 36% no TTFT por causa de um cache acessível; o modelo com drift não teve nenhuma, além de uma diferença de 4,5x entre sua chamada mais rápida e a mais lenta.
Audite sua própria configuração em cinco minutos
Não confie nesses números, nem nos de ninguém. Envie o mesmo prefixo longo várias vezes e observe dois campos. Nenhum domínio hardcoded; aponte para o seu próprio gateway com variáveis de 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)}")
Mais de um upstream para o mesmo modelo significa drift. Uma taxa de acerto bem abaixo da estabilidade do seu prompt significa que ele está te tributando. O método mais completo está em Será que Seu LLM Gateway Mente Sobre o Cache?.
O que procurar
A cura para o drift é estrutural: roteie um dado modelo para um backend consistente para que um cache quente seja de fato acessível na próxima requisição, em vez de balancear cada chamada em um upstream novo que nunca viu seu prefixo. Quando você avaliar um gateway, envie o mesmo prefixo 20 vezes e conte os upstreams. Um é o que você quer. Nove é um imposto.
Uma ressalva justa: o prompt caching é best-effort em todo lugar, e em modelos com cache em disco a taxa de acerto ainda enfraquece ao longo de longos intervalos ociosos mesmo com um único backend. Eliminar o drift não te entrega um cache infinito. Ele remove a maior e mais desperdiçadora fonte de misses, aquela que você nunca concordou e não consegue ver.
Encerramento
“Suporta prompt caching” e “seu cache é acessível” são afirmações diferentes. Um gateway que espalha um modelo por um elenco rotativo de upstreams pode reportar suporte a cache de forma verdadeira enquanto entrega uma taxa de acerto de 20%, uma conta ~4x maior e uma latência de primeiro token que oscila 4,5x. O número a observar não é se o caching é anunciado. É sua taxa de acerto medida e quantos upstreams suas requisições idênticas tocam. Execute a sonda e deixe os dados resolverem.
Para o método de auditoria mais amplo veja Será que Seu LLM Gateway Mente Sobre o Cache?; para entender por que os caches existem, veja Como Funcionam o KV Cache e o TTL.
FAQ
Isso é uma má configuração do meu lado? Não. Acontece com os padrões de fábrica: roteamento automático com a ordenação de provedor mantida em “default (balanced).” Evitar o drift exige fixar ativamente um upstream, não o contrário.
Fixar um upstream resolve? Remove o drift entre provedores, mas um único upstream muitas vezes roda várias réplicas sem afinidade de prefixo, então os hits ainda podem oscilar. Meça após fixar em vez de presumir.
Por que o modelo da classe GPT não sofreu drift? Nesta execução o gateway por acaso o roteou para um único upstream. O drift é por modelo e depende de quantos upstreams elegíveis o gateway balanceia; não é uniforme.
A diferença de custo é realmente ~4x? Nos totais por chamada que medimos, um miss foi ~4x um hit; no preço bruto de tokens de entrada para essa classe de modelo, a diferença publicada entre hit e miss chega perto de 50x. De qualquer forma, transformar hits esperados em misses é a parte cara.
Qual métrica única devo monitorar? A taxa de acerto de cache por modelo ao longo do tempo, junto com a contagem de upstreams distintos por modelo. Se a taxa de acerto cair ou a contagem de upstreams subir, seu custo efetivo por token acabou de aumentar.