A Savings Layer faz parte da plataforma BiVelio
Banco público · reproduzível

O nosso banco A/B, em aberto. Meça-nos.

Publicamos cada execução: quatro baterias com conjuntos de dados públicos, 10 modelos, e os dois braços medidos com o contador de uso do próprio fornecedor. Cada valor traz o seu n, o seu intervalo e a sua data. O que não economiza também está aqui.

baterias
4
modelos testados
10
modelos com alguma medição
10
relatórios em tempo real
15
última execução
29 de set. de 2026

O que é medido, e como

  • Dois braços, o mesmo pedido. A vai direto ao fornecedor, sem a camada; B passa pela camada com a sua configuração predefinida. Mesmo prompt, mesma amostragem, mesmo limite de saída.
  • O custo é contado pelo fornecedor. Cada braço é avaliado a partir do usage que a API devolve em cada chamada, ao preço de tabela. A economia é 1 − custo(B) / custo(A) da mesma execução, não o que a camada diz de si mesma.
  • Intervalos ao 95%. Cada harness calcula-os (reamostragem por famílias de perguntas, Wilson para as taxas de recusa). Um intervalo que atravessa o zero significa «indistinguível de zero», e é isso que dizemos.
  • O pacote que se instala. O braço B executa a fonte da tag 0.4.31; o seu dist/index.js é idêntico byte a byte ao do tarball do npm (sha256 b52f99cacf9804ecd3153e56f26ec3adcdc2510d52a8446a369ecf914e0b5731).
  • Sem atalhos. Cada harness vigia os hosts com que fala e traz um limite de gasto por modelo escrito no código. Um modelo que não pôde ser medido aparece como «não medido», com o motivo.

Quatro baterias, conjuntos de dados públicos, fixados

BateriaO que verificaConjunto de dadosArquivos fixadosLicença
GSM8KProblemas matemáticos em texto com repetições e paráfrases: quanto a cache economiza e se a precisão cai.openai/grade-school-mathcommit 3101c7d5072418e28b9008a6636bde82a006892cgsm8k-test
sha256 3730d312f6e3440559ace48831e51066acaca737f6eabec99bccb9e4b3c39d14
gsm8k-train
sha256 17f347dc51477c50d4efb83959dbb7c56297aba886e5544ee2aaed3024813465
MIT
BFCLChamadas a ferramentas: a camada não pode mudar nenhuma, e o catálogo inteiro tem de chegar.ShishirPatil/gorillacommit f7cf7359b7ac615a0b294831c5ba2bc95ee4a000fixado por commitApache-2.0
XSTestRecusas: a camada não pode mudar quando o modelo recusa, nem servir uma recusa da cache.paul-rottger/exaggerated-safetycommit d7bb5bd738c1fcbc36edd83d5e7d1b71a3e2d84dxstest_prompts.csv
sha256 11783fb294ed017473ee53c207d71f2161c7672c8d0b037501e78387f801cb5a
CC-BY-4.0
MT-BenchChat de dois turnos sem repetições: a camada não pode piorar o custo, a latência nem a qualidade.lm-sys/FastChatcommit 587d5cfa1609a43d192cedb8441cac3c17db105dquestion.jsonl
sha256 119565adbab82227089cefdb44c8d7e2cf04dc0a0ec233634c82e7d4e2a944f7
gpt-4.jsonl
sha256 f957a5bc977badb66885ec970e6cd08527845780313f0995764260e5777b9b3f
judge_prompts.jsonl
sha256 fd283293406d024f44c174b094ef48031d0687a4682fd3a56b29b138f80281b6
Apache-2.0

Economia medida por modelo

GSM8K, com um fluxo de requisições em que 30% são repetições exatas e 20% paráfrases. É a bateria com tráfego repetido: a sua economia depende de quanto o seu tráfego se repete. Sem repetições, veja «O que não economiza».

ModelonEconomia medida [IC]Do cache exatoNas chamadas (prefixo)Precisão A → BVersão · data
openai/gpt-4o-mini200 requisições · 100 únicas31,5% [25,7% – 36,7%]US$ 0,0124US$ 0,000695,0% → 96,1%Δ +1,1 pp [0,0, +2,8]0.4.31 · 28 de set. de 2026
openai/gpt-5.4-mini176 requisições · 88 únicas31,7% [25,6% – 37,6%]US$ 0,0734US$ 0,000395,6% → 93,7%Δ -1,9 pp [-5,0, 0,0]0.4.31 · 28 de set. de 2026
openai/gpt-5.522 requisições · 11 únicas33,4% [6,8% – 53,8%]US$ 0,0790-US$ 0,0023100,0% → 100,0%Δ 0,0 pp [0,0, 0,0]0.4.31 · 28 de set. de 2026
openai/gpt-5.6-sol32 requisições · 16 únicas29,2% [9,5% – 46,8%]US$ 0,0252-US$ 0,0003100,0% → 100,0%Δ 0,0 pp [0,0, 0,0]0.4.31 · 28 de set. de 2026
anthropic/claude-haiku-4-5116 requisições · 58 únicas32,2% [23,6% – 40,2%]US$ 0,0773US$ 0,000299,0% → 99,0%Δ 0,0 pp [0,0, 0,0]0.4.31 · 28 de set. de 2026
anthropic/claude-opus-5-532 requisições · 16 únicas77,2% [67,1% – 83,9%]US$ 0,0974US$ 0,1391100,0% → 100,0%Δ 0,0 pp [0,0, 0,0]0.4.31 · 28 de set. de 2026
anthropic/claude-sonnet-562 requisições · 31 únicas75,1% [69,3% – 79,6%]US$ 0,1054US$ 0,1313100,0% → 100,0%Δ 0,0 pp [0,0, 0,0]0.4.31 · 28 de set. de 2026
anthropic/claude-sonnet-5-562 requisições · 31 únicas77,5% [72,0% – 81,7%]US$ 0,0924US$ 0,1289100,0% → 100,0%Δ 0,0 pp [0,0, 0,0]0.4.31 · 28 de set. de 2026
google/gemini-3.1-pro-previewa camada falhou: as requisições não passaram pela camada0.4.31 · 28 de set. de 2026
google/gemini-3.8-flasha camada falhou: as requisições não passaram pela camada0.4.31 · 28 de set. de 2026

De onde vem a economia, posição por posição: «do cache exato» é o que A pagou nas requisições que a camada serviu sem chamar o fornecedor; «nas chamadas» é a diferença nas que realmente o alcançaram, sobretudo o cache de prefixo do fornecedor (mais alguma variação na saída). As duas somadas dão a economia total.

A precisão é medida sobre as perguntas com resposta publicada; as variantes com um número alterado servem apenas para verificar que a camada nunca entrega a resposta de outra pergunta.

Garantias, contadas

A camada nunca alterou uma chamada a ferramentas

0 chamadas alteradas em 1.325 comparações do BFCL, 6 modelos, desde 0.4.31. Se a camada falhar (um erro em B que A não tinha), isso não é contado aqui: está em «Bugs que o banco encontrou».

Nenhuma resposta de outra pergunta desde 0.4.31

0 de 198 variantes (a mesma pergunta com outro número, logo outra resposta) servidas com a resposta de outra pergunta, em 8 modelos ao vivo e em todas as configurações de cache medidas.

Repetição offline de todo o split de teste do GSM8K: 0 em 5.813 requisições, em cada uma das 5 configurações de cache.

A mesma taxa de recusa, com e sem a camada

XSTest, 10 modelos medidos: nenhuma diferença A/B abaixo de p = 0,05 (McNemar, prompts pareados). A camada entregou sem alteração o texto de 4.668 respostas (0 alteradas).

Taxa de recusa por modelo, sem a camada (A) e com ela (B), sobre os mesmos prompts.
ModeloPromptsRecusas, prompts seguros (A → B)Recusas, prompts inseguros (A → B)Versão · data
openai/gpt-4o-mini4505,2% → 5,2% (n = 250, p = 1,00)81,5% → 81,5% (n = 200, p = 1,00)0.4.31 · 28 de set. de 2026
openai/gpt-5.4-mini44111,0% → 9,8% (n = 245, p = 0,63)87,2% → 86,7% (n = 196, p = 1,00)0.4.31 · 28 de set. de 2026
openai/gpt-5.51206,3% → 4,7% (n = 64, p = 1,00)80,0% → 80,0% (n = 55, p = 1,00)0.4.31 · 29 de set. de 2026
openai/gpt-5.6-sol1992,7% → 2,7% (n = 111, p = 1,00)75,6% → 76,7% (n = 86, p = 1,00)0.4.31 · 29 de set. de 2026
anthropic/claude-haiku-4-54501,6% → 2,0% (n = 250, p = 1,00)42,5% → 42,5% (n = 200, p = 1,00)0.4.31 · 29 de set. de 2026
anthropic/claude-opus-5-581—67,1% → 67,1% (n = 79, p = 1,00)0.4.31 · 29 de set. de 2026
anthropic/claude-sonnet-52642,7% → 2,0% (n = 147, p = 1,00)68,4% → 71,8% (n = 117, p = 0,34)0.4.31 · 29 de set. de 2026
anthropic/claude-sonnet-5-53111,5% → 0,0% (n = 135, p = 0,50)64,3% → 65,3% (n = 98, p = 1,00)0.4.31 · 29 de set. de 2026
google/gemini-3.1-pro-preview580,0% → 0,0% (n = 32, p = 1,00)80,8% → 84,6% (n = 26, p = 1,00)0.4.31 · 29 de set. de 2026
google/gemini-3.8-flash4500,4% → 0,4% (n = 249, p = 1,00)67,8% → 66,8% (n = 199, p = 0,73)0.4.31 · 29 de set. de 2026

O que não economiza

Sem repetições, a economia é ≈ 0%. Publicamos mesmo assim, porque é o que você vai ver se o seu tráfego não se repetir.

O MT-Bench é um chat de dois turnos com uma camada nova a cada pergunta: não há nada que o cache possa reutilizar, e o prompt quase nunca atinge o mínimo que o fornecedor exige para fazer cache de um prefixo. No BFCL, cada chamada a ferramentas é diferente. O que estas duas baterias medem é que a camada não piora nada; a diferença de custo que sobra é ruído na saída do modelo, não a camada.

BateriaModelonEconomia medida [IC]LeituraVersão · data
BFCLopenai/gpt-4o-mini400 itens0,1% [0,0% – 0,3%]indistinguível de zero0.4.31 · 28 de set. de 2026
BFCLopenai/gpt-5.4-mini400 itens-0,2% [-1,0% – 0,5%]indistinguível de zero0.4.31 · 28 de set. de 2026
BFCLanthropic/claude-haiku-4-548 itens0,1% [0,0% – 0,2%]indistinguível de zero0.4.31 · 29 de set. de 2026
BFCLanthropic/claude-sonnet-548 itens1,5% [-1,6% – 5,8%]indistinguível de zero0.4.31 · 29 de set. de 2026
BFCLgoogle/gemini-3.1-pro-preview97 itens4,8% [-6,6% – 15,6%]indistinguível de zero0.4.31 · 29 de set. de 2026
BFCLgoogle/gemini-3.8-flash324 itens-10,7% [-27,8% – 3,2%]indistinguível de zero0.4.31 · 29 de set. de 2026
MT-Benchopenai/gpt-4o-mini80 perguntas3,3% [0,8% – 6,0%]economia · não atribuível à camada0.4.31 · 28 de set. de 2026
MT-Benchopenai/gpt-5.4-mini80 perguntas-3,5% [-8,6% – 1,6%]indistinguível de zero · não atribuível à camada0.4.31 · 28 de set. de 2026
MT-Benchopenai/gpt-5.58 perguntas2,1% [-4,4% – 9,7%]indistinguível de zero0.4.31 · 29 de set. de 2026
MT-Benchopenai/gpt-5.6-sol13 perguntas-0,4% [-21,2% – 13,5%]indistinguível de zero · não atribuível à camada0.4.31 · 29 de set. de 2026
MT-Benchanthropic/claude-haiku-4-580 perguntas-2,6% [-4,6% – -0,9%]custo extra · não atribuível à camada0.4.31 · 28 de set. de 2026
MT-Benchanthropic/claude-opus-5-518 perguntas1,1% [-2,0% – 4,9%]indistinguível de zero0.4.31 · 29 de set. de 2026
MT-Benchanthropic/claude-sonnet-523 perguntas1,7% [-8,9% – 12,7%]indistinguível de zero0.4.31 · 28 de set. de 2026
MT-Benchanthropic/claude-sonnet-5-537 perguntas-0,8% [-2,5% – 0,9%]indistinguível de zero0.4.31 · 29 de set. de 2026

Estado por modelo e bateria

Cada célula mostra a execução na versão mais alta da camada. Se um modelo não pôde ser medido, dizemos por quê, em vez de deixar o espaço em branco.

ModeloGSM8KBFCLXSTestMT-Bench
openai/gpt-4o-minimedido · n = 200
0.4.31 · 28 de set. de 2026
medido · n = 400
0.4.31 · 28 de set. de 2026
medido · n = 450
0.4.31 · 28 de set. de 2026
medido · n = 80
0.4.31 · 28 de set. de 2026
openai/gpt-5.4-minimedido · n = 176
0.4.31 · 28 de set. de 2026
medido · n = 400
0.4.31 · 28 de set. de 2026
medido · n = 441
0.4.31 · 28 de set. de 2026
medido · n = 80
0.4.31 · 28 de set. de 2026
openai/gpt-5.5medido · n = 22
0.4.31 · 28 de set. de 2026
não medido: limite de gasto esgotado
0.4.31 · 29 de set. de 2026
medido · n = 120
0.4.31 · 29 de set. de 2026
medido · n = 8
0.4.31 · 29 de set. de 2026
openai/gpt-5.6-solmedido · n = 32
0.4.31 · 28 de set. de 2026
não medido: o fornecedor rejeitou a requisição em ambos os braços
0.4.31 · 29 de set. de 2026
medido · n = 199
0.4.31 · 29 de set. de 2026
medido · n = 13
0.4.31 · 29 de set. de 2026
anthropic/claude-haiku-4-5medido · n = 116
0.4.31 · 28 de set. de 2026
medido · n = 48
0.4.31 · 29 de set. de 2026
medido · n = 450
0.4.31 · 29 de set. de 2026
medido · n = 80
0.4.31 · 28 de set. de 2026
anthropic/claude-opus-5-5medido · n = 32
0.4.31 · 28 de set. de 2026
não medido: limite de gasto esgotado
0.4.31 · 29 de set. de 2026
medido · n = 81
0.4.31 · 29 de set. de 2026
medido · n = 18
0.4.31 · 29 de set. de 2026
anthropic/claude-sonnet-5medido · n = 62
0.4.31 · 28 de set. de 2026
medido · n = 48
0.4.31 · 29 de set. de 2026
medido · n = 264
0.4.31 · 29 de set. de 2026
medido · n = 23
0.4.31 · 28 de set. de 2026
anthropic/claude-sonnet-5-5medido · n = 62
0.4.31 · 28 de set. de 2026
não medido: limite de gasto esgotado
0.4.31 · 29 de set. de 2026
medido · n = 311
0.4.31 · 29 de set. de 2026
medido · n = 37
0.4.31 · 29 de set. de 2026
google/gemini-3.1-pro-previewa camada falhou: as requisições não passaram pela camada
0.4.31 · 28 de set. de 2026
medido · n = 97
0.4.31 · 29 de set. de 2026
medido · n = 58
0.4.31 · 29 de set. de 2026
não medido: cota do fornecedor esgotada
0.4.31 · 29 de set. de 2026
google/gemini-3.8-flasha camada falhou: as requisições não passaram pela camada
0.4.31 · 28 de set. de 2026
medido · n = 324
0.4.31 · 29 de set. de 2026
medido · n = 450
0.4.31 · 29 de set. de 2026
a camada falhou: as requisições não passaram pela camada
0.4.31 · 29 de set. de 2026

Bugs que o banco encontrou

O banco não está aqui para ficar bem na fotografia: está aqui para encontrar os bugs antes de você. Encontrou estes, com a versão em que apareceram e a que os corrige.

  1. O cache semântico sem calibração servia a resposta de outra pergunta 0.4.30 → 0.4.31

    Com o cache semântico sem calibração, uma variante com outro número («three baskets» versus «two baskets») podia receber a resposta da pergunta original. Contado sobre as variantes do GSM8K.

    • Encontrado na 0.4.30: 15 de 111. gsm8k.json
    • Corrigido na 0.4.31 (#383).
    • Verificado ao vivo na 0.4.31: 0 de 198.
  2. A camada cortava o catálogo de ferramentas sem nenhum sinal para isso 0.4.30 → 0.4.31

    Em conversas de vários turnos, o braço B enviava menos ferramentas do que o A, mesmo sem nada indicar quais eram desnecessárias. Contado sobre as conversas multi-turno do BFCL.

    • Encontrado na 0.4.30: 20 de 20. bfcl.json
    • Corrigido na 0.4.31 (#382).
    • Verificado ao vivo na 0.4.31: 0 de 83.
  3. Algumas recusas escritas como texto eram guardadas em cache 0.4.31 → 0.4.32

    Uma recusa que o modelo escreve como texto (sem o sinal da API) podia ser guardada em cache, repetida e creditada como economia. Contado em prompts do XSTest.

  4. Um filtro de conteúdo do Gemini era guardado em cache como resposta 0.4.31 → 0.4.32

    O Gemini sinaliza o seu filtro com um motivo de parada próprio, que a camada não reconhecia como recusa, e por isso podia guardá-lo em cache e repeti-lo. Contado em prompts do XSTest.

  5. O Gemini não passava pela camada 0.4.31 → 0.4.32

    A camada enviava um campo próprio da API da OpenAI para qualquer endpoint compatível, e o Gemini o rejeita: todas as requisições do braço B falhavam. Contado em requisições do GSM8K.

    • Encontrado na 0.4.31: 504 de 504. gsm8k-0431-gama-alta.json
    • Corrigido na 0.4.32 (#402).
    • Aguardando nova medição ao vivo na 0.4.32.
  6. Com o Gemini 3, o segundo turno com ferramentas falhava 0.4.31 → 0.4.32

    A camada não devolvia a assinatura de pensamento que o Gemini 3 exige em cada chamada a ferramentas, e por isso o turno seguinte era rejeitado. Contado em continuações multi-turno do BFCL.

    • Encontrado na 0.4.31: 50 de 50. bfcl-0431-gama-alta.json
    • Corrigido na 0.4.32 (#402).
    • Aguardando nova medição ao vivo na 0.4.32.

Como reproduzir

O código do banco ainda não é público; o método é, e cabe em cinco passos. Com as suas próprias chaves de fornecedor pode repeti-lo e comparar número a número com os nossos relatórios.

  1. O dataset. Descarregue cada dataset público no commit da tabela acima e verifique o sha256 de cada ficheiro antes de o usar. Se não bater certo, não é o mesmo dataset.
  2. A camada. Instale @bivelio/savings-layer a partir do npm na versão indicada pelo relatório e verifique o sha256 de dist/index.js: cada relatório traz o seu.
  3. Dois braços por prompt. A vai direto ao fornecedor; B envia o mesmo prompt, ao mesmo modelo e com o mesmo limite de saída, através da camada com a configuração padrão. Uma parte dos prompts repete-se ou é parafraseada, como no tráfego real, e a ordem A/B é sorteada.
  4. O custo é o fornecedor que o diz. Some o que cada braço é faturado segundo o usage devolvido pelo fornecedor, à sua tarifa publicada. A poupança é 1 − custo B / custo A, com o seu intervalo.
  5. A qualidade, na mesma execução. Pontue da mesma forma as respostas dos dois braços (resposta exata no GSM8K, chamada de ferramenta no BFCL, recusa ou não no XSTest, um juiz no MT-Bench) e compare-as com o relatório JSON da mesma bateria e versão.

Os relatórios

Cada execução deixa um relatório JSON com o seu desenho, as suas limitações e cada chamada medida: usage, custo por braço e classificação da resposta. São servidos a partir deste site.

Os relatórios são servidos tal como o banco os escreveu, com uma exceção: retiram-se os dados do ambiente de quem mediu (caminhos de disco, endereços de e-mail). Do XSTest não se publica o texto de nenhuma resposta, apenas a sua classificação.

Meça-nos você mesmo

Uma medição independente vale mais do que a nossa. O código do banco ainda não é público: se quiser repetir a medição, ou medir a camada com o seu próprio harness ou o seu tráfego, escreva-nos e damos-lhe o que precisar para o fazer.

Escreva-nos para support@bivelio.com

Enviar um e-mail